aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-23 17:39:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-23 17:39:09 -0400
commite317234975cb7463b8ca21a93bb6862d9dcf113f (patch)
tree4446fa3a21364f3cba23a22aa2a94027f169d8df /drivers/media
parentf37ab0fba271e43edab0e3ae9fe644fcda455402 (diff)
parent7483d45f0aee3afc0646d185cabd4af9f6cab58c (diff)
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - V4L2 API additions to better support JPEG compression control - media API additions to properly support MPEG decoders - V4L2 API additions for image crop/scaling - a few other V4L2 API DocBook fixes/improvements - two new DVB frontend drivers: m88rs2000 and rtl2830 - two new DVB drivers: az6007 and rtl28xxu - a framework for ISA drivers, that removed lots of common code found at the ISA radio drivers - a new FM transmitter driver (radio-keene) - a GPIO-based IR receiver driver - a new sensor driver: mt9m032 - some new video drivers: adv7183, blackfin, mx2_emmaprp, sii9234_drv, vs6624 - several new board additions, driver fixes, improvements and cleanups. * 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (295 commits) [media] update CARDLIST.em28xx [media] partially reverts changeset fa5527c [media] stb0899: fix the limits for signal strength values [media] em28xx: support for 2304:0242 PCTV QuatroStick (510e) [media] em28xx: support for 2013:0251 PCTV QuatroStick nano (520e) [media] -EINVAL -> -ENOTTY [media] gspca - sn9c20x: Cleanup source [media] gspca - sn9c20x: Simplify register write for capture start/stop [media] gspca - sn9c20x: Add automatic JPEG compression mechanism [media] gspca - sn9c20x: Greater delay in case of sensor no response [media] gspca - sn9c20x: Optimize the code of write sequences [media] gspca - sn9c20x: Add the JPEG compression quality control [media] gspca - sn9c20x: Add a delay after Omnivision sensor reset [media] gspca - sn9c20x: Propagate USB errors to higher level [media] gspca - sn9c20x: Use the new video control mechanism [media] gspca - sn9c20x: Fix loss of frame start [media] gspca - zc3xx: Lack of register 08 value for sensor cs2102k [media] gspca - ov534_9: Add brightness to OmniVision 5621 sensor [media] gspca - zc3xx: Add V4L2_CID_JPEG_COMPRESSION_QUALITY control support [media] pvrusb2: fix 7MHz & 8MHz DVB-T tuner support for HVR1900 rev D1F5 ...
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/common/tuners/Makefile4
-rw-r--r--drivers/media/common/tuners/max2165.c9
-rw-r--r--drivers/media/common/tuners/mt2063.c4
-rw-r--r--drivers/media/common/tuners/mt2063.h4
-rw-r--r--drivers/media/common/tuners/tuner-types.c4
-rw-r--r--drivers/media/common/tuners/xc5000.c47
-rw-r--r--drivers/media/common/tuners/xc5000.h5
-rw-r--r--drivers/media/dvb/ddbridge/ddbridge-core.c1
-rw-r--r--drivers/media/dvb/ddbridge/ddbridge.h2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c2
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig19
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile14
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c49
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.h2
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.c38
-rw-r--r--drivers/media/dvb/dvb-usb/az6007.c957
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c10
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h8
-rw-r--r--drivers/media/dvb/dvb-usb/it913x.c170
-rw-r--r--drivers/media/dvb/dvb-usb/lmedm04.c285
-rw-r--r--drivers/media/dvb/dvb-usb/lmedm04.h1
-rw-r--r--drivers/media/dvb/dvb-usb/mxl111sf.c6
-rw-r--r--drivers/media/dvb/dvb-usb/rtl28xxu.c982
-rw-r--r--drivers/media/dvb/dvb-usb/rtl28xxu.h264
-rw-r--r--drivers/media/dvb/frontends/Kconfig15
-rw-r--r--drivers/media/dvb/frontends/Makefile6
-rw-r--r--drivers/media/dvb/frontends/au8522_decoder.c13
-rw-r--r--drivers/media/dvb/frontends/au8522_dig.c10
-rw-r--r--drivers/media/dvb/frontends/cx22702.c22
-rw-r--r--drivers/media/dvb/frontends/dib0090.c2
-rw-r--r--drivers/media/dvb/frontends/dib9000.c121
-rw-r--r--drivers/media/dvb/frontends/drxd_hard.c6
-rw-r--r--drivers/media/dvb/frontends/drxk.h23
-rw-r--r--drivers/media/dvb/frontends/drxk_hard.c46
-rw-r--r--drivers/media/dvb/frontends/drxk_hard.h1
-rw-r--r--drivers/media/dvb/frontends/it913x-fe-priv.h5
-rw-r--r--drivers/media/dvb/frontends/it913x-fe.c91
-rw-r--r--drivers/media/dvb/frontends/it913x-fe.h4
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.c6
-rw-r--r--drivers/media/dvb/frontends/m88rs2000.c904
-rw-r--r--drivers/media/dvb/frontends/m88rs2000.h66
-rw-r--r--drivers/media/dvb/frontends/rtl2830.c562
-rw-r--r--drivers/media/dvb/frontends/rtl2830.h97
-rw-r--r--drivers/media/dvb/frontends/rtl2830_priv.h57
-rw-r--r--drivers/media/dvb/frontends/stb0899_drv.c12
-rw-r--r--drivers/media/dvb/frontends/stv0288.c2
-rw-r--r--drivers/media/dvb/frontends/tda10071.c2
-rw-r--r--drivers/media/dvb/ngene/ngene-cards.c1
-rw-r--r--drivers/media/dvb/pt1/pt1.c93
-rw-r--r--drivers/media/media-devnode.c2
-rw-r--r--drivers/media/radio/Kconfig125
-rw-r--r--drivers/media/radio/Makefile2
-rw-r--r--drivers/media/radio/radio-aimslab.c440
-rw-r--r--drivers/media/radio/radio-aztech.c372
-rw-r--r--drivers/media/radio/radio-gemtek.c494
-rw-r--r--drivers/media/radio/radio-isa.c340
-rw-r--r--drivers/media/radio/radio-isa.h105
-rw-r--r--drivers/media/radio/radio-keene.c427
-rw-r--r--drivers/media/radio/radio-maxiradio.c379
-rw-r--r--drivers/media/radio/radio-rtrack2.c332
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c61
-rw-r--r--drivers/media/radio/radio-tea5764.c19
-rw-r--r--drivers/media/radio/radio-terratec.c365
-rw-r--r--drivers/media/radio/radio-trust.c388
-rw-r--r--drivers/media/radio/radio-typhoon.c366
-rw-r--r--drivers/media/radio/radio-zoltrix.c442
-rw-r--r--drivers/media/radio/saa7706h.c13
-rw-r--r--drivers/media/radio/si470x/radio-si470x-i2c.c28
-rw-r--r--drivers/media/radio/si4713-i2c.c15
-rw-r--r--drivers/media/radio/tef6862.c14
-rw-r--r--drivers/media/rc/Kconfig9
-rw-r--r--drivers/media/rc/Makefile1
-rw-r--r--drivers/media/rc/fintek-cir.c26
-rw-r--r--drivers/media/rc/fintek-cir.h4
-rw-r--r--drivers/media/rc/gpio-ir-recv.c205
-rw-r--r--drivers/media/rc/ir-sony-decoder.c2
-rw-r--r--drivers/media/rc/keymaps/Makefile3
-rw-r--r--drivers/media/rc/keymaps/rc-it913x-v1.c95
-rw-r--r--drivers/media/rc/keymaps/rc-it913x-v2.c94
-rw-r--r--drivers/media/rc/keymaps/rc-kworld-pc150u.c102
-rw-r--r--drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c52
-rw-r--r--drivers/media/rc/mceusb.c2
-rw-r--r--drivers/media/rc/rc-core-priv.h2
-rw-r--r--drivers/media/rc/rc-main.c9
-rw-r--r--drivers/media/video/Kconfig49
-rw-r--r--drivers/media/video/Makefile24
-rw-r--r--drivers/media/video/adp1653.c20
-rw-r--r--drivers/media/video/adv7170.c13
-rw-r--r--drivers/media/video/adv7175.c13
-rw-r--r--drivers/media/video/adv7180.c14
-rw-r--r--drivers/media/video/adv7183.c699
-rw-r--r--drivers/media/video/adv7183_regs.h107
-rw-r--r--drivers/media/video/adv7343.c13
-rw-r--r--drivers/media/video/ak881x.c13
-rw-r--r--drivers/media/video/aptina-pll.c174
-rw-r--r--drivers/media/video/aptina-pll.h56
-rw-r--r--drivers/media/video/as3645a.c19
-rw-r--r--drivers/media/video/blackfin/Kconfig10
-rw-r--r--drivers/media/video/blackfin/Makefile2
-rw-r--r--drivers/media/video/blackfin/bfin_capture.c1059
-rw-r--r--drivers/media/video/blackfin/ppi.c271
-rw-r--r--drivers/media/video/bt819.c13
-rw-r--r--drivers/media/video/bt856.c13
-rw-r--r--drivers/media/video/bt866.c13
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c4
-rw-r--r--drivers/media/video/cs5345.c13
-rw-r--r--drivers/media/video/cs53l32a.c13
-rw-r--r--drivers/media/video/cx18/cx18-driver.c8
-rw-r--r--drivers/media/video/cx18/cx18-driver.h2
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c4
-rw-r--r--drivers/media/video/cx231xx/cx231xx-417.c1
-rw-r--r--drivers/media/video/cx231xx/cx231xx-cards.c1
-rw-r--r--drivers/media/video/cx231xx/cx231xx-video.c6
-rw-r--r--drivers/media/video/cx25821/cx25821-core.c9
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c13
-rw-r--r--drivers/media/video/davinci/vpif.h2
-rw-r--r--drivers/media/video/davinci/vpif_display.c2
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c114
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c145
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c96
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c8
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c10
-rw-r--r--drivers/media/video/em28xx/em28xx.h29
-rw-r--r--drivers/media/video/gspca/gl860/Makefile2
-rw-r--r--drivers/media/video/gspca/m5602/Makefile2
-rw-r--r--drivers/media/video/gspca/ov534_9.c49
-rw-r--r--drivers/media/video/gspca/pac7302.c583
-rw-r--r--drivers/media/video/gspca/sn9c20x.c1138
-rw-r--r--drivers/media/video/gspca/sonixj.c185
-rw-r--r--drivers/media/video/gspca/stv06xx/Makefile2
-rw-r--r--drivers/media/video/gspca/zc3xx.c328
-rw-r--r--drivers/media/video/imx074.c13
-rw-r--r--drivers/media/video/indycam.c13
-rw-r--r--drivers/media/video/ir-kbd-i2c.c17
-rw-r--r--drivers/media/video/ivtv/Makefile8
-rw-r--r--drivers/media/video/ivtv/ivtv-controls.c62
-rw-r--r--drivers/media/video/ivtv/ivtv-controls.h2
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c41
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h12
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c188
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c20
-rw-r--r--drivers/media/video/ks0127.c13
-rw-r--r--drivers/media/video/m52790.c13
-rw-r--r--drivers/media/video/m5mols/m5mols_core.c15
-rw-r--r--drivers/media/video/marvell-ccic/mcam-core.c35
-rw-r--r--drivers/media/video/marvell-ccic/mcam-core.h1
-rw-r--r--drivers/media/video/marvell-ccic/mmp-driver.c13
-rw-r--r--drivers/media/video/msp3400-driver.c13
-rw-r--r--drivers/media/video/mt9m001.c13
-rw-r--r--drivers/media/video/mt9m032.c868
-rw-r--r--drivers/media/video/mt9m111.c13
-rw-r--r--drivers/media/video/mt9p031.c80
-rw-r--r--drivers/media/video/mt9t001.c13
-rw-r--r--drivers/media/video/mt9t031.c13
-rw-r--r--drivers/media/video/mt9t112.c16
-rw-r--r--drivers/media/video/mt9v011.c13
-rw-r--r--drivers/media/video/mt9v022.c13
-rw-r--r--drivers/media/video/mt9v032.c13
-rw-r--r--drivers/media/video/mx2_camera.c1214
-rw-r--r--drivers/media/video/mx2_emmaprp.c1008
-rw-r--r--drivers/media/video/noon010pc30.c15
-rw-r--r--drivers/media/video/omap/omap_vout.c3
-rw-r--r--drivers/media/video/ov2640.c16
-rw-r--r--drivers/media/video/ov5642.c13
-rw-r--r--drivers/media/video/ov6650.c13
-rw-r--r--drivers/media/video/ov7670.c13
-rw-r--r--drivers/media/video/ov772x.c17
-rw-r--r--drivers/media/video/ov9640.c13
-rw-r--r--drivers/media/video/ov9740.c13
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.c10
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c1
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c10
-rw-r--r--drivers/media/video/pxa_camera.c4
-rw-r--r--drivers/media/video/rj54n1cb0c.c13
-rw-r--r--drivers/media/video/s2255drv.c33
-rw-r--r--drivers/media/video/s5k6aa.c15
-rw-r--r--drivers/media/video/s5p-fimc/fimc-capture.c121
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.c85
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.h2
-rw-r--r--drivers/media/video/s5p-fimc/fimc-mdevice.c7
-rw-r--r--drivers/media/video/s5p-fimc/mipi-csis.c111
-rw-r--r--drivers/media/video/s5p-g2d/g2d-hw.c5
-rw-r--r--drivers/media/video/s5p-g2d/g2d.c63
-rw-r--r--drivers/media/video/s5p-g2d/g2d.h6
-rw-r--r--drivers/media/video/s5p-jpeg/jpeg-core.c199
-rw-r--r--drivers/media/video/s5p-jpeg/jpeg-core.h11
-rw-r--r--drivers/media/video/s5p-jpeg/jpeg-hw.h18
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_pm.c24
-rw-r--r--drivers/media/video/s5p-tv/Kconfig10
-rw-r--r--drivers/media/video/s5p-tv/Makefile2
-rw-r--r--drivers/media/video/s5p-tv/hdmi_drv.c120
-rw-r--r--drivers/media/video/s5p-tv/hdmiphy_drv.c12
-rw-r--r--drivers/media/video/s5p-tv/mixer_drv.c2
-rw-r--r--drivers/media/video/s5p-tv/sdo_drv.c26
-rw-r--r--drivers/media/video/s5p-tv/sii9234_drv.c432
-rw-r--r--drivers/media/video/saa6588.c13
-rw-r--r--drivers/media/video/saa7110.c13
-rw-r--r--drivers/media/video/saa7115.c13
-rw-r--r--drivers/media/video/saa7127.c13
-rw-r--r--drivers/media/video/saa7134/Makefile8
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c13
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c59
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c44
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c14
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c63
-rw-r--r--drivers/media/video/saa7134/saa7134.h5
-rw-r--r--drivers/media/video/saa7164/Makefile8
-rw-r--r--drivers/media/video/saa7164/saa7164-encoder.c6
-rw-r--r--drivers/media/video/saa7164/saa7164-vbi.c6
-rw-r--r--drivers/media/video/saa717x.c13
-rw-r--r--drivers/media/video/saa7185.c13
-rw-r--r--drivers/media/video/saa7191.c13
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c35
-rw-r--r--drivers/media/video/soc_camera.c32
-rw-r--r--drivers/media/video/sr030pc30.c13
-rw-r--r--drivers/media/video/tda7432.c13
-rw-r--r--drivers/media/video/tda9840.c13
-rw-r--r--drivers/media/video/tea6415c.c13
-rw-r--r--drivers/media/video/tea6420.c13
-rw-r--r--drivers/media/video/ths7303.c14
-rw-r--r--drivers/media/video/tlv320aic23b.c13
-rw-r--r--drivers/media/video/tm6000/tm6000-input.c3
-rw-r--r--drivers/media/video/tuner-core.c28
-rw-r--r--drivers/media/video/tvaudio.c13
-rw-r--r--drivers/media/video/tveeprom.c10
-rw-r--r--drivers/media/video/tvp514x.c13
-rw-r--r--drivers/media/video/tvp5150.c141
-rw-r--r--drivers/media/video/tvp7002.c25
-rw-r--r--drivers/media/video/tw9910.c16
-rw-r--r--drivers/media/video/upd64031a.c13
-rw-r--r--drivers/media/video/upd64083.c13
-rw-r--r--drivers/media/video/uvc/uvc_driver.c11
-rw-r--r--drivers/media/video/uvc/uvc_queue.c2
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c207
-rw-r--r--drivers/media/video/v4l2-compat-ioctl32.c22
-rw-r--r--drivers/media/video/v4l2-ctrls.c91
-rw-r--r--drivers/media/video/v4l2-dev.c2
-rw-r--r--drivers/media/video/v4l2-ioctl.c42
-rw-r--r--drivers/media/video/v4l2-subdev.c12
-rw-r--r--drivers/media/video/videobuf2-vmalloc.c70
-rw-r--r--drivers/media/video/vivi.c26
-rw-r--r--drivers/media/video/vp27smpx.c13
-rw-r--r--drivers/media/video/vpx3220.c13
-rw-r--r--drivers/media/video/vs6624.c928
-rw-r--r--drivers/media/video/vs6624_regs.h337
-rw-r--r--drivers/media/video/w9966.c4
-rw-r--r--drivers/media/video/wm8739.c13
-rw-r--r--drivers/media/video/wm8775.c13
249 files changed, 16874 insertions, 6652 deletions
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile
index 8295854ab94b..f80407eb8998 100644
--- a/drivers/media/common/tuners/Makefile
+++ b/drivers/media/common/tuners/Makefile
@@ -29,5 +29,5 @@ obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o
29obj-$(CONFIG_MEDIA_TUNER_TDA18218) += tda18218.o 29obj-$(CONFIG_MEDIA_TUNER_TDA18218) += tda18218.o
30obj-$(CONFIG_MEDIA_TUNER_TDA18212) += tda18212.o 30obj-$(CONFIG_MEDIA_TUNER_TDA18212) += tda18212.o
31 31
32ccflags-y += -Idrivers/media/dvb/dvb-core 32ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
33ccflags-y += -Idrivers/media/dvb/frontends 33ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
diff --git a/drivers/media/common/tuners/max2165.c b/drivers/media/common/tuners/max2165.c
index cb2c98fbad1b..ba84936aafd6 100644
--- a/drivers/media/common/tuners/max2165.c
+++ b/drivers/media/common/tuners/max2165.c
@@ -168,7 +168,7 @@ int fixpt_div32(u32 dividend, u32 divisor, u32 *quotient, u32 *fraction)
168 int i; 168 int i;
169 169
170 if (0 == divisor) 170 if (0 == divisor)
171 return -1; 171 return -EINVAL;
172 172
173 q = dividend / divisor; 173 q = dividend / divisor;
174 remainder = dividend - q * divisor; 174 remainder = dividend - q * divisor;
@@ -194,10 +194,13 @@ static int max2165_set_rf(struct max2165_priv *priv, u32 freq)
194 u8 tf_ntch; 194 u8 tf_ntch;
195 u32 t; 195 u32 t;
196 u32 quotient, fraction; 196 u32 quotient, fraction;
197 int ret;
197 198
198 /* Set PLL divider according to RF frequency */ 199 /* Set PLL divider according to RF frequency */
199 fixpt_div32(freq / 1000, priv->config->osc_clk * 1000, 200 ret = fixpt_div32(freq / 1000, priv->config->osc_clk * 1000,
200 &quotient, &fraction); 201 &quotient, &fraction);
202 if (ret != 0)
203 return ret;
201 204
202 /* 20-bit fraction */ 205 /* 20-bit fraction */
203 fraction >>= 12; 206 fraction >>= 12;
diff --git a/drivers/media/common/tuners/mt2063.c b/drivers/media/common/tuners/mt2063.c
index c89af3cd5eba..0ed9091ff48e 100644
--- a/drivers/media/common/tuners/mt2063.c
+++ b/drivers/media/common/tuners/mt2063.c
@@ -350,7 +350,7 @@ static int MT2063_Sleep(struct dvb_frontend *fe)
350 /* 350 /*
351 * ToDo: Add code here to implement a OS blocking 351 * ToDo: Add code here to implement a OS blocking
352 */ 352 */
353 msleep(10); 353 msleep(100);
354 354
355 return 0; 355 return 0;
356} 356}
@@ -2226,7 +2226,7 @@ static struct dvb_tuner_ops mt2063_ops = {
2226 .info = { 2226 .info = {
2227 .name = "MT2063 Silicon Tuner", 2227 .name = "MT2063 Silicon Tuner",
2228 .frequency_min = 45000000, 2228 .frequency_min = 45000000,
2229 .frequency_max = 850000000, 2229 .frequency_max = 865000000,
2230 .frequency_step = 0, 2230 .frequency_step = 0,
2231 }, 2231 },
2232 2232
diff --git a/drivers/media/common/tuners/mt2063.h b/drivers/media/common/tuners/mt2063.h
index 62d0e8ec4e99..3f5cfd93713f 100644
--- a/drivers/media/common/tuners/mt2063.h
+++ b/drivers/media/common/tuners/mt2063.h
@@ -23,10 +23,6 @@ static inline struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
23 return NULL; 23 return NULL;
24} 24}
25 25
26int mt2063_setTune(struct dvb_frontend *fe, u32 f_in,
27 u32 bw_in,
28 enum MTTune_atv_standard tv_type);
29
30/* FIXME: Should use the standard DVB attachment interfaces */ 26/* FIXME: Should use the standard DVB attachment interfaces */
31unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe); 27unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe);
32unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe); 28unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe);
diff --git a/drivers/media/common/tuners/tuner-types.c b/drivers/media/common/tuners/tuner-types.c
index e13683bab6b3..2da4440c16ee 100644
--- a/drivers/media/common/tuners/tuner-types.c
+++ b/drivers/media/common/tuners/tuner-types.c
@@ -1868,6 +1868,10 @@ struct tunertype tuners[] = {
1868 .params = tuner_tena_tnf_5337_params, 1868 .params = tuner_tena_tnf_5337_params,
1869 .count = ARRAY_SIZE(tuner_tena_tnf_5337_params), 1869 .count = ARRAY_SIZE(tuner_tena_tnf_5337_params),
1870 }, 1870 },
1871 [TUNER_XC5000C] = { /* Xceive 5000C */
1872 .name = "Xceive 5000C tuner",
1873 /* see xc5000.c for details */
1874 },
1871}; 1875};
1872EXPORT_SYMBOL(tuners); 1876EXPORT_SYMBOL(tuners);
1873 1877
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index 296df05b8cda..7f98984e4fad 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -49,9 +49,6 @@ static LIST_HEAD(hybrid_tuner_instance_list);
49#define dprintk(level, fmt, arg...) if (debug >= level) \ 49#define dprintk(level, fmt, arg...) if (debug >= level) \
50 printk(KERN_INFO "%s: " fmt, "xc5000", ## arg) 50 printk(KERN_INFO "%s: " fmt, "xc5000", ## arg)
51 51
52#define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.6.114.fw"
53#define XC5000_DEFAULT_FIRMWARE_SIZE 12401
54
55struct xc5000_priv { 52struct xc5000_priv {
56 struct tuner_i2c_props i2c_props; 53 struct tuner_i2c_props i2c_props;
57 struct list_head hybrid_tuner_instance_list; 54 struct list_head hybrid_tuner_instance_list;
@@ -62,6 +59,8 @@ struct xc5000_priv {
62 u8 video_standard; 59 u8 video_standard;
63 u8 rf_mode; 60 u8 rf_mode;
64 u8 radio_input; 61 u8 radio_input;
62
63 int chip_id;
65}; 64};
66 65
67/* Misc Defines */ 66/* Misc Defines */
@@ -204,6 +203,33 @@ static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
204 {"FM Radio-INPUT1_MONO", 0x0278, 0x9002} 203 {"FM Radio-INPUT1_MONO", 0x0278, 0x9002}
205}; 204};
206 205
206
207struct xc5000_fw_cfg {
208 char *name;
209 u16 size;
210};
211
212static const struct xc5000_fw_cfg xc5000a_1_6_114 = {
213 .name = "dvb-fe-xc5000-1.6.114.fw",
214 .size = 12401,
215};
216
217static const struct xc5000_fw_cfg xc5000c_41_024_5_31875 = {
218 .name = "dvb-fe-xc5000c-41.024.5-31875.fw",
219 .size = 16503,
220};
221
222static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id)
223{
224 switch (chip_id) {
225 default:
226 case XC5000A:
227 return &xc5000a_1_6_114;
228 case XC5000C:
229 return &xc5000c_41_024_5_31875;
230 }
231}
232
207static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe); 233static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
208static int xc5000_is_firmware_loaded(struct dvb_frontend *fe); 234static int xc5000_is_firmware_loaded(struct dvb_frontend *fe);
209static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val); 235static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val);
@@ -552,12 +578,14 @@ static int xc5000_fwupload(struct dvb_frontend *fe)
552 struct xc5000_priv *priv = fe->tuner_priv; 578 struct xc5000_priv *priv = fe->tuner_priv;
553 const struct firmware *fw; 579 const struct firmware *fw;
554 int ret; 580 int ret;
581 const struct xc5000_fw_cfg *desired_fw =
582 xc5000_assign_firmware(priv->chip_id);
555 583
556 /* request the firmware, this will block and timeout */ 584 /* request the firmware, this will block and timeout */
557 printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n", 585 printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n",
558 XC5000_DEFAULT_FIRMWARE); 586 desired_fw->name);
559 587
560 ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE, 588 ret = request_firmware(&fw, desired_fw->name,
561 priv->i2c_props.adap->dev.parent); 589 priv->i2c_props.adap->dev.parent);
562 if (ret) { 590 if (ret) {
563 printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n"); 591 printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
@@ -569,7 +597,7 @@ static int xc5000_fwupload(struct dvb_frontend *fe)
569 ret = XC_RESULT_SUCCESS; 597 ret = XC_RESULT_SUCCESS;
570 } 598 }
571 599
572 if (fw->size != XC5000_DEFAULT_FIRMWARE_SIZE) { 600 if (fw->size != desired_fw->size) {
573 printk(KERN_ERR "xc5000: firmware incorrect size\n"); 601 printk(KERN_ERR "xc5000: firmware incorrect size\n");
574 ret = XC_RESULT_RESET_FAILURE; 602 ret = XC_RESULT_RESET_FAILURE;
575 } else { 603 } else {
@@ -1139,6 +1167,13 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
1139 if (priv->radio_input == 0) 1167 if (priv->radio_input == 0)
1140 priv->radio_input = cfg->radio_input; 1168 priv->radio_input = cfg->radio_input;
1141 1169
1170 /* don't override chip id if it's already been set
1171 unless explicitly specified */
1172 if ((priv->chip_id == 0) || (cfg->chip_id))
1173 /* use default chip id if none specified, set to 0 so
1174 it can be overridden if this is a hybrid driver */
1175 priv->chip_id = (cfg->chip_id) ? cfg->chip_id : 0;
1176
1142 /* Check if firmware has been loaded. It is possible that another 1177 /* Check if firmware has been loaded. It is possible that another
1143 instance of the driver has loaded the firmware. 1178 instance of the driver has loaded the firmware.
1144 */ 1179 */
diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h
index e2957451b532..3396f8e02b40 100644
--- a/drivers/media/common/tuners/xc5000.h
+++ b/drivers/media/common/tuners/xc5000.h
@@ -27,10 +27,15 @@
27struct dvb_frontend; 27struct dvb_frontend;
28struct i2c_adapter; 28struct i2c_adapter;
29 29
30#define XC5000A 1
31#define XC5000C 2
32
30struct xc5000_config { 33struct xc5000_config {
31 u8 i2c_address; 34 u8 i2c_address;
32 u32 if_khz; 35 u32 if_khz;
33 u8 radio_input; 36 u8 radio_input;
37
38 int chip_id;
34}; 39};
35 40
36/* xc5000 callback command */ 41/* xc5000 callback command */
diff --git a/drivers/media/dvb/ddbridge/ddbridge-core.c b/drivers/media/dvb/ddbridge/ddbridge-core.c
index ce4f85849e7b..d88c4aa7d24d 100644
--- a/drivers/media/dvb/ddbridge/ddbridge-core.c
+++ b/drivers/media/dvb/ddbridge/ddbridge-core.c
@@ -578,6 +578,7 @@ static int demod_attach_drxk(struct ddb_input *input)
578 struct drxk_config config; 578 struct drxk_config config;
579 579
580 memset(&config, 0, sizeof(config)); 580 memset(&config, 0, sizeof(config));
581 config.microcode_name = "drxk_a3.mc";
581 config.adr = 0x29 + (input->nr & 1); 582 config.adr = 0x29 + (input->nr & 1);
582 583
583 fe = input->fe = dvb_attach(drxk_attach, &config, i2c); 584 fe = input->fe = dvb_attach(drxk_attach, &config, i2c);
diff --git a/drivers/media/dvb/ddbridge/ddbridge.h b/drivers/media/dvb/ddbridge/ddbridge.h
index 6d14893218f4..8b1b41d2a52d 100644
--- a/drivers/media/dvb/ddbridge/ddbridge.h
+++ b/drivers/media/dvb/ddbridge/ddbridge.h
@@ -32,8 +32,6 @@
32#include <asm/dma.h> 32#include <asm/dma.h>
33#include <linux/dvb/frontend.h> 33#include <linux/dvb/frontend.h>
34#include <linux/dvb/ca.h> 34#include <linux/dvb/ca.h>
35#include <linux/dvb/video.h>
36#include <linux/dvb/audio.h>
37#include <linux/socket.h> 35#include <linux/socket.h>
38 36
39#include "dmxdev.h" 37#include "dmxdev.h"
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index fbbe545a74cb..4555baa383b2 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -655,6 +655,8 @@ restart:
655 dprintk("%s: Retune requested, FESTATE_RETUNE\n", __func__); 655 dprintk("%s: Retune requested, FESTATE_RETUNE\n", __func__);
656 re_tune = true; 656 re_tune = true;
657 fepriv->state = FESTATE_TUNED; 657 fepriv->state = FESTATE_TUNED;
658 } else {
659 re_tune = false;
658 } 660 }
659 661
660 if (fe->ops.tune) 662 if (fe->ops.tune)
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 9f203c6767a6..63bf45679f98 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -361,6 +361,14 @@ config DVB_USB_EC168
361 help 361 help
362 Say Y here to support the E3C EC168 DVB-T USB2.0 receiver. 362 Say Y here to support the E3C EC168 DVB-T USB2.0 receiver.
363 363
364config DVB_USB_AZ6007
365 tristate "AzureWave 6007 and clones DVB-T/C USB2.0 support"
366 depends on DVB_USB
367 select DVB_DRXK if !DVB_FE_CUSTOMISE
368 select MEDIA_TUNER_MT2063 if !DVB_FE_CUSTOMISE
369 help
370 Say Y here to support theAfatech AF9005 based DVB-T/DVB-C receivers.
371
364config DVB_USB_AZ6027 372config DVB_USB_AZ6027
365 tristate "Azurewave DVB-S/S2 USB2.0 AZ6027 support" 373 tristate "Azurewave DVB-S/S2 USB2.0 AZ6027 support"
366 depends on DVB_USB 374 depends on DVB_USB
@@ -378,6 +386,7 @@ config DVB_USB_LME2510
378 select DVB_IX2505V if !DVB_FE_CUSTOMISE 386 select DVB_IX2505V if !DVB_FE_CUSTOMISE
379 select DVB_STV0299 if !DVB_FE_CUSTOMISE 387 select DVB_STV0299 if !DVB_FE_CUSTOMISE
380 select DVB_PLL if !DVB_FE_CUSTOMISE 388 select DVB_PLL if !DVB_FE_CUSTOMISE
389 select DVB_M88RS2000 if !DVB_FE_CUSTOMISE
381 help 390 help
382 Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 . 391 Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 .
383 392
@@ -403,3 +412,13 @@ config DVB_USB_MXL111SF
403 select VIDEO_TVEEPROM 412 select VIDEO_TVEEPROM
404 help 413 help
405 Say Y here to support the MxL111SF USB2.0 DTV receiver. 414 Say Y here to support the MxL111SF USB2.0 DTV receiver.
415
416config DVB_USB_RTL28XXU
417 tristate "Realtek RTL28xxU DVB USB support"
418 depends on DVB_USB && EXPERIMENTAL
419 select DVB_RTL2830
420 select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
421 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
422 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
423 help
424 Say Y here to support the Realtek RTL28xxU DVB USB receiver.
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 26c8b9e57050..b76acb5387e6 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -54,7 +54,6 @@ obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o
54dvb-usb-opera-objs = opera1.o 54dvb-usb-opera-objs = opera1.o
55obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o 55obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o
56 56
57
58dvb-usb-af9005-objs = af9005.o af9005-fe.o 57dvb-usb-af9005-objs = af9005.o af9005-fe.o
59obj-$(CONFIG_DVB_USB_AF9005) += dvb-usb-af9005.o 58obj-$(CONFIG_DVB_USB_AF9005) += dvb-usb-af9005.o
60 59
@@ -88,6 +87,9 @@ obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o
88dvb-usb-ec168-objs = ec168.o 87dvb-usb-ec168-objs = ec168.o
89obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o 88obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o
90 89
90dvb-usb-az6007-objs = az6007.o
91obj-$(CONFIG_DVB_USB_AZ6007) += dvb-usb-az6007.o
92
91dvb-usb-az6027-objs = az6027.o 93dvb-usb-az6027-objs = az6027.o
92obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o 94obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
93 95
@@ -105,8 +107,12 @@ obj-$(CONFIG_DVB_USB_MXL111SF) += dvb-usb-mxl111sf.o
105obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-demod.o 107obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-demod.o
106obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-tuner.o 108obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-tuner.o
107 109
108ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 110dvb-usb-rtl28xxu-objs = rtl28xxu.o
111obj-$(CONFIG_DVB_USB_RTL28XXU) += dvb-usb-rtl28xxu.o
112
113ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
114ccflags-y += -I$(srctree)/drivers/media/dvb/frontends/
109# due to tuner-xc3028 115# due to tuner-xc3028
110ccflags-y += -Idrivers/media/common/tuners 116ccflags-y += -I$(srctree)/drivers/media/common/tuners
111EXTRA_CFLAGS += -Idrivers/media/dvb/ttpci 117ccflags-y += -I$(srctree)/drivers/media/dvb/ttpci
112 118
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index 282a43d648df..7e70ea50ef26 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -1164,6 +1164,41 @@ static int af9015_af9013_sleep(struct dvb_frontend *fe)
1164 return ret; 1164 return ret;
1165} 1165}
1166 1166
1167/* override tuner callbacks for resource locking */
1168static int af9015_tuner_init(struct dvb_frontend *fe)
1169{
1170 int ret;
1171 struct dvb_usb_adapter *adap = fe->dvb->priv;
1172 struct af9015_state *priv = adap->dev->priv;
1173
1174 if (mutex_lock_interruptible(&adap->dev->usb_mutex))
1175 return -EAGAIN;
1176
1177 ret = priv->tuner_init[adap->id](fe);
1178
1179 mutex_unlock(&adap->dev->usb_mutex);
1180
1181 return ret;
1182}
1183
1184/* override tuner callbacks for resource locking */
1185static int af9015_tuner_sleep(struct dvb_frontend *fe)
1186{
1187 int ret;
1188 struct dvb_usb_adapter *adap = fe->dvb->priv;
1189 struct af9015_state *priv = adap->dev->priv;
1190
1191 if (mutex_lock_interruptible(&adap->dev->usb_mutex))
1192 return -EAGAIN;
1193
1194 ret = priv->tuner_sleep[adap->id](fe);
1195
1196 mutex_unlock(&adap->dev->usb_mutex);
1197
1198 return ret;
1199}
1200
1201
1167static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) 1202static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
1168{ 1203{
1169 int ret; 1204 int ret;
@@ -1283,6 +1318,7 @@ static struct mxl5007t_config af9015_mxl5007t_config = {
1283static int af9015_tuner_attach(struct dvb_usb_adapter *adap) 1318static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
1284{ 1319{
1285 int ret; 1320 int ret;
1321 struct af9015_state *state = adap->dev->priv;
1286 deb_info("%s:\n", __func__); 1322 deb_info("%s:\n", __func__);
1287 1323
1288 switch (af9015_af9013_config[adap->id].tuner) { 1324 switch (af9015_af9013_config[adap->id].tuner) {
@@ -1340,6 +1376,19 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
1340 err("Unknown tuner id:%d", 1376 err("Unknown tuner id:%d",
1341 af9015_af9013_config[adap->id].tuner); 1377 af9015_af9013_config[adap->id].tuner);
1342 } 1378 }
1379
1380 if (adap->fe_adap[0].fe->ops.tuner_ops.init) {
1381 state->tuner_init[adap->id] =
1382 adap->fe_adap[0].fe->ops.tuner_ops.init;
1383 adap->fe_adap[0].fe->ops.tuner_ops.init = af9015_tuner_init;
1384 }
1385
1386 if (adap->fe_adap[0].fe->ops.tuner_ops.sleep) {
1387 state->tuner_sleep[adap->id] =
1388 adap->fe_adap[0].fe->ops.tuner_ops.sleep;
1389 adap->fe_adap[0].fe->ops.tuner_ops.sleep = af9015_tuner_sleep;
1390 }
1391
1343 return ret; 1392 return ret;
1344} 1393}
1345 1394
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
index f619063fa72f..2f68419e899b 100644
--- a/drivers/media/dvb/dvb-usb/af9015.h
+++ b/drivers/media/dvb/dvb-usb/af9015.h
@@ -108,6 +108,8 @@ struct af9015_state {
108 int (*read_status[2]) (struct dvb_frontend *fe, fe_status_t *status); 108 int (*read_status[2]) (struct dvb_frontend *fe, fe_status_t *status);
109 int (*init[2]) (struct dvb_frontend *fe); 109 int (*init[2]) (struct dvb_frontend *fe);
110 int (*sleep[2]) (struct dvb_frontend *fe); 110 int (*sleep[2]) (struct dvb_frontend *fe);
111 int (*tuner_init[2]) (struct dvb_frontend *fe);
112 int (*tuner_sleep[2]) (struct dvb_frontend *fe);
111}; 113};
112 114
113struct af9015_config { 115struct af9015_config {
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
index cf0c318d6989..03c28655af1b 100644
--- a/drivers/media/dvb/dvb-usb/anysee.c
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -58,7 +58,7 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
58 u8 *rbuf, u8 rlen) 58 u8 *rbuf, u8 rlen)
59{ 59{
60 struct anysee_state *state = d->priv; 60 struct anysee_state *state = d->priv;
61 int act_len, ret; 61 int act_len, ret, i;
62 u8 buf[64]; 62 u8 buf[64];
63 63
64 memcpy(&buf[0], sbuf, slen); 64 memcpy(&buf[0], sbuf, slen);
@@ -73,26 +73,52 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
73 /* We need receive one message more after dvb_usb_generic_rw due 73 /* We need receive one message more after dvb_usb_generic_rw due
74 to weird transaction flow, which is 1 x send + 2 x receive. */ 74 to weird transaction flow, which is 1 x send + 2 x receive. */
75 ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0); 75 ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0);
76 if (!ret) { 76 if (ret)
77 goto error_unlock;
78
79 /* TODO FIXME: dvb_usb_generic_rw() fails rarely with error code -32
80 * (EPIPE, Broken pipe). Function supports currently msleep() as a
81 * parameter but I would not like to use it, since according to
82 * Documentation/timers/timers-howto.txt it should not be used such
83 * short, under < 20ms, sleeps. Repeating failed message would be
84 * better choice as not to add unwanted delays...
85 * Fixing that correctly is one of those or both;
86 * 1) use repeat if possible
87 * 2) add suitable delay
88 */
89
90 /* get answer, retry few times if error returned */
91 for (i = 0; i < 3; i++) {
77 /* receive 2nd answer */ 92 /* receive 2nd answer */
78 ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, 93 ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
79 d->props.generic_bulk_ctrl_endpoint), buf, sizeof(buf), 94 d->props.generic_bulk_ctrl_endpoint), buf, sizeof(buf),
80 &act_len, 2000); 95 &act_len, 2000);
81 if (ret) 96
82 err("%s: recv bulk message failed: %d", __func__, ret); 97 if (ret) {
83 else { 98 deb_info("%s: recv bulk message failed: %d",
99 __func__, ret);
100 } else {
84 deb_xfer("<<< "); 101 deb_xfer("<<< ");
85 debug_dump(buf, rlen, deb_xfer); 102 debug_dump(buf, rlen, deb_xfer);
86 103
87 if (buf[63] != 0x4f) 104 if (buf[63] != 0x4f)
88 deb_info("%s: cmd failed\n", __func__); 105 deb_info("%s: cmd failed\n", __func__);
106
107 break;
89 } 108 }
90 } 109 }
91 110
111 if (ret) {
112 /* all retries failed, it is fatal */
113 err("%s: recv bulk message failed: %d", __func__, ret);
114 goto error_unlock;
115 }
116
92 /* read request, copy returned data to return buf */ 117 /* read request, copy returned data to return buf */
93 if (!ret && rbuf && rlen) 118 if (rbuf && rlen)
94 memcpy(rbuf, buf, rlen); 119 memcpy(rbuf, buf, rlen);
95 120
121error_unlock:
96 mutex_unlock(&anysee_usb_mutex); 122 mutex_unlock(&anysee_usb_mutex);
97 123
98 return ret; 124 return ret;
diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c
new file mode 100644
index 000000000000..4008b9c50fbd
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/az6007.c
@@ -0,0 +1,957 @@
1/*
2 * Driver for AzureWave 6007 DVB-C/T USB2.0 and clones
3 *
4 * Copyright (c) Henry Wang <Henry.wang@AzureWave.com>
5 *
6 * This driver was made publicly available by Terratec, at:
7 * http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz
8 * The original driver's license is GPL, as declared with MODULE_LICENSE()
9 *
10 * Copyright (c) 2010-2011 Mauro Carvalho Chehab <mchehab@redhat.com>
11 * Driver modified by in order to work with upstream drxk driver, and
12 * tons of bugs got fixed.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation under version 2 of the License.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 */
23
24#include "drxk.h"
25#include "mt2063.h"
26#include "dvb_ca_en50221.h"
27
28#define DVB_USB_LOG_PREFIX "az6007"
29#include "dvb-usb.h"
30
31/* debug */
32int dvb_usb_az6007_debug;
33module_param_named(debug, dvb_usb_az6007_debug, int, 0644);
34MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))."
35 DVB_USB_DEBUG_STATUS);
36
37#define deb_info(args...) dprintk(dvb_usb_az6007_debug, 0x01, args)
38#define deb_xfer(args...) dprintk(dvb_usb_az6007_debug, 0x02, args)
39#define deb_rc(args...) dprintk(dvb_usb_az6007_debug, 0x04, args)
40#define deb_fe(args...) dprintk(dvb_usb_az6007_debug, 0x08, args)
41
42DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
43
44/* Known requests (Cypress FX2 firmware + az6007 "private" ones*/
45
46#define FX2_OED 0xb5
47#define AZ6007_READ_DATA 0xb7
48#define AZ6007_I2C_RD 0xb9
49#define AZ6007_POWER 0xbc
50#define AZ6007_I2C_WR 0xbd
51#define FX2_SCON1 0xc0
52#define AZ6007_TS_THROUGH 0xc7
53#define AZ6007_READ_IR 0xb4
54
55struct az6007_device_state {
56 struct mutex mutex;
57 struct mutex ca_mutex;
58 struct dvb_ca_en50221 ca;
59 unsigned warm:1;
60 int (*gate_ctrl) (struct dvb_frontend *, int);
61 unsigned char data[4096];
62};
63
64static struct drxk_config terratec_h7_drxk = {
65 .adr = 0x29,
66 .parallel_ts = true,
67 .dynamic_clk = true,
68 .single_master = true,
69 .enable_merr_cfg = true,
70 .no_i2c_bridge = false,
71 .chunk_size = 64,
72 .mpeg_out_clk_strength = 0x02,
73 .microcode_name = "dvb-usb-terratec-h7-drxk.fw",
74};
75
76static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
77{
78 struct dvb_usb_adapter *adap = fe->sec_priv;
79 struct az6007_device_state *st;
80 int status = 0;
81
82 deb_info("%s: %s\n", __func__, enable ? "enable" : "disable");
83
84 if (!adap)
85 return -EINVAL;
86
87 st = adap->dev->priv;
88
89 if (!st)
90 return -EINVAL;
91
92 if (enable)
93 status = st->gate_ctrl(fe, 1);
94 else
95 status = st->gate_ctrl(fe, 0);
96
97 return status;
98}
99
100static struct mt2063_config az6007_mt2063_config = {
101 .tuner_address = 0x60,
102 .refclock = 36125000,
103};
104
105static int __az6007_read(struct usb_device *udev, u8 req, u16 value,
106 u16 index, u8 *b, int blen)
107{
108 int ret;
109
110 ret = usb_control_msg(udev,
111 usb_rcvctrlpipe(udev, 0),
112 req,
113 USB_TYPE_VENDOR | USB_DIR_IN,
114 value, index, b, blen, 5000);
115 if (ret < 0) {
116 warn("usb read operation failed. (%d)", ret);
117 return -EIO;
118 }
119
120 deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ", req, value,
121 index);
122 debug_dump(b, blen, deb_xfer);
123
124 return ret;
125}
126
127static int az6007_read(struct dvb_usb_device *d, u8 req, u16 value,
128 u16 index, u8 *b, int blen)
129{
130 struct az6007_device_state *st = d->priv;
131 int ret;
132
133 if (mutex_lock_interruptible(&st->mutex) < 0)
134 return -EAGAIN;
135
136 ret = __az6007_read(d->udev, req, value, index, b, blen);
137
138 mutex_unlock(&st->mutex);
139
140 return ret;
141}
142
143static int __az6007_write(struct usb_device *udev, u8 req, u16 value,
144 u16 index, u8 *b, int blen)
145{
146 int ret;
147
148 deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ", req, value,
149 index);
150 debug_dump(b, blen, deb_xfer);
151
152 if (blen > 64) {
153 err("az6007: tried to write %d bytes, but I2C max size is 64 bytes\n",
154 blen);
155 return -EOPNOTSUPP;
156 }
157
158 ret = usb_control_msg(udev,
159 usb_sndctrlpipe(udev, 0),
160 req,
161 USB_TYPE_VENDOR | USB_DIR_OUT,
162 value, index, b, blen, 5000);
163 if (ret != blen) {
164 err("usb write operation failed. (%d)", ret);
165 return -EIO;
166 }
167
168 return 0;
169}
170
171static int az6007_write(struct dvb_usb_device *d, u8 req, u16 value,
172 u16 index, u8 *b, int blen)
173{
174 struct az6007_device_state *st = d->priv;
175 int ret;
176
177 if (mutex_lock_interruptible(&st->mutex) < 0)
178 return -EAGAIN;
179
180 ret = __az6007_write(d->udev, req, value, index, b, blen);
181
182 mutex_unlock(&st->mutex);
183
184 return ret;
185}
186
187static int az6007_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
188{
189 struct dvb_usb_device *d = adap->dev;
190
191 deb_info("%s: %s", __func__, onoff ? "enable" : "disable");
192
193 return az6007_write(d, 0xbc, onoff, 0, NULL, 0);
194}
195
196/* remote control stuff (does not work with my box) */
197static int az6007_rc_query(struct dvb_usb_device *d)
198{
199 struct az6007_device_state *st = d->priv;
200 unsigned code = 0;
201
202 az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10);
203
204 if (st->data[1] == 0x44)
205 return 0;
206
207 if ((st->data[1] ^ st->data[2]) == 0xff)
208 code = st->data[1];
209 else
210 code = st->data[1] << 8 | st->data[2];
211
212 if ((st->data[3] ^ st->data[4]) == 0xff)
213 code = code << 8 | st->data[3];
214 else
215 code = code << 16 | st->data[3] << 8 | st->data[4];
216
217 rc_keydown(d->rc_dev, code, st->data[5]);
218
219 return 0;
220}
221
222static int az6007_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
223 int slot,
224 int address)
225{
226 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
227 struct az6007_device_state *state = (struct az6007_device_state *)d->priv;
228
229 int ret;
230 u8 req;
231 u16 value;
232 u16 index;
233 int blen;
234 u8 *b;
235
236 if (slot != 0)
237 return -EINVAL;
238
239 b = kmalloc(12, GFP_KERNEL);
240 if (!b)
241 return -ENOMEM;
242
243 mutex_lock(&state->ca_mutex);
244
245 req = 0xC1;
246 value = address;
247 index = 0;
248 blen = 1;
249
250 ret = az6007_read(d, req, value, index, b, blen);
251 if (ret < 0) {
252 warn("usb in operation failed. (%d)", ret);
253 ret = -EINVAL;
254 } else {
255 ret = b[0];
256 }
257
258 mutex_unlock(&state->ca_mutex);
259 kfree(b);
260 return ret;
261}
262
263static int az6007_ci_write_attribute_mem(struct dvb_ca_en50221 *ca,
264 int slot,
265 int address,
266 u8 value)
267{
268 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
269 struct az6007_device_state *state = (struct az6007_device_state *)d->priv;
270
271 int ret;
272 u8 req;
273 u16 value1;
274 u16 index;
275 int blen;
276
277 deb_info("%s %d", __func__, slot);
278 if (slot != 0)
279 return -EINVAL;
280
281 mutex_lock(&state->ca_mutex);
282 req = 0xC2;
283 value1 = address;
284 index = value;
285 blen = 0;
286
287 ret = az6007_write(d, req, value1, index, NULL, blen);
288 if (ret != 0)
289 warn("usb out operation failed. (%d)", ret);
290
291 mutex_unlock(&state->ca_mutex);
292 return ret;
293}
294
295static int az6007_ci_read_cam_control(struct dvb_ca_en50221 *ca,
296 int slot,
297 u8 address)
298{
299 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
300 struct az6007_device_state *state = (struct az6007_device_state *)d->priv;
301
302 int ret;
303 u8 req;
304 u16 value;
305 u16 index;
306 int blen;
307 u8 *b;
308
309 if (slot != 0)
310 return -EINVAL;
311
312 b = kmalloc(12, GFP_KERNEL);
313 if (!b)
314 return -ENOMEM;
315
316 mutex_lock(&state->ca_mutex);
317
318 req = 0xC3;
319 value = address;
320 index = 0;
321 blen = 2;
322
323 ret = az6007_read(d, req, value, index, b, blen);
324 if (ret < 0) {
325 warn("usb in operation failed. (%d)", ret);
326 ret = -EINVAL;
327 } else {
328 if (b[0] == 0)
329 warn("Read CI IO error");
330
331 ret = b[1];
332 deb_info("read cam data = %x from 0x%x", b[1], value);
333 }
334
335 mutex_unlock(&state->ca_mutex);
336 kfree(b);
337 return ret;
338}
339
340static int az6007_ci_write_cam_control(struct dvb_ca_en50221 *ca,
341 int slot,
342 u8 address,
343 u8 value)
344{
345 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
346 struct az6007_device_state *state = (struct az6007_device_state *)d->priv;
347
348 int ret;
349 u8 req;
350 u16 value1;
351 u16 index;
352 int blen;
353
354 if (slot != 0)
355 return -EINVAL;
356
357 mutex_lock(&state->ca_mutex);
358 req = 0xC4;
359 value1 = address;
360 index = value;
361 blen = 0;
362
363 ret = az6007_write(d, req, value1, index, NULL, blen);
364 if (ret != 0) {
365 warn("usb out operation failed. (%d)", ret);
366 goto failed;
367 }
368
369failed:
370 mutex_unlock(&state->ca_mutex);
371 return ret;
372}
373
374static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot)
375{
376 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
377
378 int ret;
379 u8 req;
380 u16 value;
381 u16 index;
382 int blen;
383 u8 *b;
384
385 b = kmalloc(12, GFP_KERNEL);
386 if (!b)
387 return -ENOMEM;
388
389 req = 0xC8;
390 value = 0;
391 index = 0;
392 blen = 1;
393
394 ret = az6007_read(d, req, value, index, b, blen);
395 if (ret < 0) {
396 warn("usb in operation failed. (%d)", ret);
397 ret = -EIO;
398 } else{
399 ret = b[0];
400 }
401 kfree(b);
402 return ret;
403}
404
405static int az6007_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
406{
407 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
408 struct az6007_device_state *state = (struct az6007_device_state *)d->priv;
409
410 int ret, i;
411 u8 req;
412 u16 value;
413 u16 index;
414 int blen;
415
416 mutex_lock(&state->ca_mutex);
417
418 req = 0xC6;
419 value = 1;
420 index = 0;
421 blen = 0;
422
423 ret = az6007_write(d, req, value, index, NULL, blen);
424 if (ret != 0) {
425 warn("usb out operation failed. (%d)", ret);
426 goto failed;
427 }
428
429 msleep(500);
430 req = 0xC6;
431 value = 0;
432 index = 0;
433 blen = 0;
434
435 ret = az6007_write(d, req, value, index, NULL, blen);
436 if (ret != 0) {
437 warn("usb out operation failed. (%d)", ret);
438 goto failed;
439 }
440
441 for (i = 0; i < 15; i++) {
442 msleep(100);
443
444 if (CI_CamReady(ca, slot)) {
445 deb_info("CAM Ready");
446 break;
447 }
448 }
449 msleep(5000);
450
451failed:
452 mutex_unlock(&state->ca_mutex);
453 return ret;
454}
455
456static int az6007_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
457{
458 return 0;
459}
460
461static int az6007_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
462{
463 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
464 struct az6007_device_state *state = (struct az6007_device_state *)d->priv;
465
466 int ret;
467 u8 req;
468 u16 value;
469 u16 index;
470 int blen;
471
472 deb_info("%s", __func__);
473 mutex_lock(&state->ca_mutex);
474 req = 0xC7;
475 value = 1;
476 index = 0;
477 blen = 0;
478
479 ret = az6007_write(d, req, value, index, NULL, blen);
480 if (ret != 0) {
481 warn("usb out operation failed. (%d)", ret);
482 goto failed;
483 }
484
485failed:
486 mutex_unlock(&state->ca_mutex);
487 return ret;
488}
489
490static int az6007_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
491{
492 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
493 struct az6007_device_state *state = (struct az6007_device_state *)d->priv;
494 int ret;
495 u8 req;
496 u16 value;
497 u16 index;
498 int blen;
499 u8 *b;
500
501 b = kmalloc(12, GFP_KERNEL);
502 if (!b)
503 return -ENOMEM;
504 mutex_lock(&state->ca_mutex);
505
506 req = 0xC5;
507 value = 0;
508 index = 0;
509 blen = 1;
510
511 ret = az6007_read(d, req, value, index, b, blen);
512 if (ret < 0) {
513 warn("usb in operation failed. (%d)", ret);
514 ret = -EIO;
515 } else
516 ret = 0;
517
518 if (!ret && b[0] == 1) {
519 ret = DVB_CA_EN50221_POLL_CAM_PRESENT |
520 DVB_CA_EN50221_POLL_CAM_READY;
521 }
522
523 mutex_unlock(&state->ca_mutex);
524 kfree(b);
525 return ret;
526}
527
528
529static void az6007_ci_uninit(struct dvb_usb_device *d)
530{
531 struct az6007_device_state *state;
532
533 deb_info("%s", __func__);
534
535 if (NULL == d)
536 return;
537
538 state = (struct az6007_device_state *)d->priv;
539 if (NULL == state)
540 return;
541
542 if (NULL == state->ca.data)
543 return;
544
545 dvb_ca_en50221_release(&state->ca);
546
547 memset(&state->ca, 0, sizeof(state->ca));
548}
549
550
551static int az6007_ci_init(struct dvb_usb_adapter *a)
552{
553 struct dvb_usb_device *d = a->dev;
554 struct az6007_device_state *state = (struct az6007_device_state *)d->priv;
555 int ret;
556
557 deb_info("%s", __func__);
558
559 mutex_init(&state->ca_mutex);
560
561 state->ca.owner = THIS_MODULE;
562 state->ca.read_attribute_mem = az6007_ci_read_attribute_mem;
563 state->ca.write_attribute_mem = az6007_ci_write_attribute_mem;
564 state->ca.read_cam_control = az6007_ci_read_cam_control;
565 state->ca.write_cam_control = az6007_ci_write_cam_control;
566 state->ca.slot_reset = az6007_ci_slot_reset;
567 state->ca.slot_shutdown = az6007_ci_slot_shutdown;
568 state->ca.slot_ts_enable = az6007_ci_slot_ts_enable;
569 state->ca.poll_slot_status = az6007_ci_poll_slot_status;
570 state->ca.data = d;
571
572 ret = dvb_ca_en50221_init(&a->dvb_adap,
573 &state->ca,
574 0, /* flags */
575 1);/* n_slots */
576 if (ret != 0) {
577 err("Cannot initialize CI: Error %d.", ret);
578 memset(&state->ca, 0, sizeof(state->ca));
579 return ret;
580 }
581
582 deb_info("CI initialized.");
583
584 return 0;
585}
586
587static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6])
588{
589 struct az6007_device_state *st = d->priv;
590 int ret;
591
592 ret = az6007_read(d, AZ6007_READ_DATA, 6, 0, st->data, 6);
593 memcpy(mac, st->data, sizeof(mac));
594
595 if (ret > 0)
596 deb_info("%s: mac is %02x:%02x:%02x:%02x:%02x:%02x\n",
597 __func__, mac[0], mac[1], mac[2],
598 mac[3], mac[4], mac[5]);
599
600 return ret;
601}
602
603static int az6007_frontend_attach(struct dvb_usb_adapter *adap)
604{
605 struct az6007_device_state *st = adap->dev->priv;
606
607 deb_info("attaching demod drxk");
608
609 adap->fe_adap[0].fe = dvb_attach(drxk_attach, &terratec_h7_drxk,
610 &adap->dev->i2c_adap);
611 if (!adap->fe_adap[0].fe)
612 return -EINVAL;
613
614 adap->fe_adap[0].fe->sec_priv = adap;
615 st->gate_ctrl = adap->fe_adap[0].fe->ops.i2c_gate_ctrl;
616 adap->fe_adap[0].fe->ops.i2c_gate_ctrl = drxk_gate_ctrl;
617
618 az6007_ci_init(adap);
619
620 return 0;
621}
622
623static int az6007_tuner_attach(struct dvb_usb_adapter *adap)
624{
625 deb_info("attaching tuner mt2063");
626
627 /* Attach mt2063 to DVB-C frontend */
628 if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)
629 adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 1);
630 if (!dvb_attach(mt2063_attach, adap->fe_adap[0].fe,
631 &az6007_mt2063_config,
632 &adap->dev->i2c_adap))
633 return -EINVAL;
634
635 if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)
636 adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 0);
637
638 return 0;
639}
640
641int az6007_power_ctrl(struct dvb_usb_device *d, int onoff)
642{
643 struct az6007_device_state *st = d->priv;
644 int ret;
645
646 deb_info("%s()\n", __func__);
647
648 if (!st->warm) {
649 mutex_init(&st->mutex);
650
651 ret = az6007_write(d, AZ6007_POWER, 0, 2, NULL, 0);
652 if (ret < 0)
653 return ret;
654 msleep(60);
655 ret = az6007_write(d, AZ6007_POWER, 1, 4, NULL, 0);
656 if (ret < 0)
657 return ret;
658 msleep(100);
659 ret = az6007_write(d, AZ6007_POWER, 1, 3, NULL, 0);
660 if (ret < 0)
661 return ret;
662 msleep(20);
663 ret = az6007_write(d, AZ6007_POWER, 1, 4, NULL, 0);
664 if (ret < 0)
665 return ret;
666
667 msleep(400);
668 ret = az6007_write(d, FX2_SCON1, 0, 3, NULL, 0);
669 if (ret < 0)
670 return ret;
671 msleep(150);
672 ret = az6007_write(d, FX2_SCON1, 1, 3, NULL, 0);
673 if (ret < 0)
674 return ret;
675 msleep(430);
676 ret = az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0);
677 if (ret < 0)
678 return ret;
679
680 st->warm = true;
681
682 return 0;
683 }
684
685 if (!onoff)
686 return 0;
687
688 az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0);
689 az6007_write(d, AZ6007_TS_THROUGH, 0, 0, NULL, 0);
690
691 return 0;
692}
693
694/* I2C */
695static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
696 int num)
697{
698 struct dvb_usb_device *d = i2c_get_adapdata(adap);
699 struct az6007_device_state *st = d->priv;
700 int i, j, len;
701 int ret = 0;
702 u16 index;
703 u16 value;
704 int length;
705 u8 req, addr;
706
707 if (mutex_lock_interruptible(&st->mutex) < 0)
708 return -EAGAIN;
709
710 for (i = 0; i < num; i++) {
711 addr = msgs[i].addr << 1;
712 if (((i + 1) < num)
713 && (msgs[i].len == 1)
714 && (!msgs[i].flags & I2C_M_RD)
715 && (msgs[i + 1].flags & I2C_M_RD)
716 && (msgs[i].addr == msgs[i + 1].addr)) {
717 /*
718 * A write + read xfer for the same address, where
719 * the first xfer has just 1 byte length.
720 * Need to join both into one operation
721 */
722 if (dvb_usb_az6007_debug & 2)
723 printk(KERN_DEBUG
724 "az6007 I2C xfer write+read addr=0x%x len=%d/%d: ",
725 addr, msgs[i].len, msgs[i + 1].len);
726 req = AZ6007_I2C_RD;
727 index = msgs[i].buf[0];
728 value = addr | (1 << 8);
729 length = 6 + msgs[i + 1].len;
730 len = msgs[i + 1].len;
731 ret = __az6007_read(d->udev, req, value, index,
732 st->data, length);
733 if (ret >= len) {
734 for (j = 0; j < len; j++) {
735 msgs[i + 1].buf[j] = st->data[j + 5];
736 if (dvb_usb_az6007_debug & 2)
737 printk(KERN_CONT
738 "0x%02x ",
739 msgs[i + 1].buf[j]);
740 }
741 } else
742 ret = -EIO;
743 i++;
744 } else if (!(msgs[i].flags & I2C_M_RD)) {
745 /* write bytes */
746 if (dvb_usb_az6007_debug & 2)
747 printk(KERN_DEBUG
748 "az6007 I2C xfer write addr=0x%x len=%d: ",
749 addr, msgs[i].len);
750 req = AZ6007_I2C_WR;
751 index = msgs[i].buf[0];
752 value = addr | (1 << 8);
753 length = msgs[i].len - 1;
754 len = msgs[i].len - 1;
755 if (dvb_usb_az6007_debug & 2)
756 printk(KERN_CONT "(0x%02x) ", msgs[i].buf[0]);
757 for (j = 0; j < len; j++) {
758 st->data[j] = msgs[i].buf[j + 1];
759 if (dvb_usb_az6007_debug & 2)
760 printk(KERN_CONT "0x%02x ",
761 st->data[j]);
762 }
763 ret = __az6007_write(d->udev, req, value, index,
764 st->data, length);
765 } else {
766 /* read bytes */
767 if (dvb_usb_az6007_debug & 2)
768 printk(KERN_DEBUG
769 "az6007 I2C xfer read addr=0x%x len=%d: ",
770 addr, msgs[i].len);
771 req = AZ6007_I2C_RD;
772 index = msgs[i].buf[0];
773 value = addr;
774 length = msgs[i].len + 6;
775 len = msgs[i].len;
776 ret = __az6007_read(d->udev, req, value, index,
777 st->data, length);
778 for (j = 0; j < len; j++) {
779 msgs[i].buf[j] = st->data[j + 5];
780 if (dvb_usb_az6007_debug & 2)
781 printk(KERN_CONT
782 "0x%02x ", st->data[j + 5]);
783 }
784 }
785 if (dvb_usb_az6007_debug & 2)
786 printk(KERN_CONT "\n");
787 if (ret < 0)
788 goto err;
789 }
790err:
791 mutex_unlock(&st->mutex);
792
793 if (ret < 0) {
794 info("%s ERROR: %i", __func__, ret);
795 return ret;
796 }
797 return num;
798}
799
800static u32 az6007_i2c_func(struct i2c_adapter *adapter)
801{
802 return I2C_FUNC_I2C;
803}
804
805static struct i2c_algorithm az6007_i2c_algo = {
806 .master_xfer = az6007_i2c_xfer,
807 .functionality = az6007_i2c_func,
808};
809
810int az6007_identify_state(struct usb_device *udev,
811 struct dvb_usb_device_properties *props,
812 struct dvb_usb_device_description **desc, int *cold)
813{
814 int ret;
815 u8 *mac;
816
817 mac = kmalloc(6, GFP_ATOMIC);
818 if (!mac)
819 return -ENOMEM;
820
821 /* Try to read the mac address */
822 ret = __az6007_read(udev, AZ6007_READ_DATA, 6, 0, mac, 6);
823 if (ret == 6)
824 *cold = 0;
825 else
826 *cold = 1;
827
828 kfree(mac);
829
830 if (*cold) {
831 __az6007_write(udev, 0x09, 1, 0, NULL, 0);
832 __az6007_write(udev, 0x00, 0, 0, NULL, 0);
833 __az6007_write(udev, 0x00, 0, 0, NULL, 0);
834 }
835
836 deb_info("Device is on %s state\n", *cold ? "warm" : "cold");
837 return 0;
838}
839
840static struct dvb_usb_device_properties az6007_properties;
841
842static void az6007_usb_disconnect(struct usb_interface *intf)
843{
844 struct dvb_usb_device *d = usb_get_intfdata(intf);
845 az6007_ci_uninit(d);
846 dvb_usb_device_exit(intf);
847}
848
849static int az6007_usb_probe(struct usb_interface *intf,
850 const struct usb_device_id *id)
851{
852 return dvb_usb_device_init(intf, &az6007_properties,
853 THIS_MODULE, NULL, adapter_nr);
854}
855
856static struct usb_device_id az6007_usb_table[] = {
857 {USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_6007)},
858 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7)},
859 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7_2)},
860 {0},
861};
862
863MODULE_DEVICE_TABLE(usb, az6007_usb_table);
864
865static struct dvb_usb_device_properties az6007_properties = {
866 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
867 .usb_ctrl = CYPRESS_FX2,
868 .firmware = "dvb-usb-terratec-h7-az6007.fw",
869 .no_reconnect = 1,
870 .size_of_priv = sizeof(struct az6007_device_state),
871 .identify_state = az6007_identify_state,
872 .num_adapters = 1,
873 .adapter = {
874 {
875 .num_frontends = 1,
876 .fe = {{
877 .streaming_ctrl = az6007_streaming_ctrl,
878 .tuner_attach = az6007_tuner_attach,
879 .frontend_attach = az6007_frontend_attach,
880
881 /* parameter for the MPEG2-data transfer */
882 .stream = {
883 .type = USB_BULK,
884 .count = 10,
885 .endpoint = 0x02,
886 .u = {
887 .bulk = {
888 .buffersize = 4096,
889 }
890 }
891 },
892 } }
893 } },
894 .power_ctrl = az6007_power_ctrl,
895 .read_mac_address = az6007_read_mac_addr,
896
897 .rc.core = {
898 .rc_interval = 400,
899 .rc_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS,
900 .module_name = "az6007",
901 .rc_query = az6007_rc_query,
902 .allowed_protos = RC_TYPE_NEC,
903 },
904 .i2c_algo = &az6007_i2c_algo,
905
906 .num_device_descs = 2,
907 .devices = {
908 { .name = "AzureWave DTV StarBox DVB-T/C USB2.0 (az6007)",
909 .cold_ids = { &az6007_usb_table[0], NULL },
910 .warm_ids = { NULL },
911 },
912 { .name = "TerraTec DTV StarBox DVB-T/C USB2.0 (az6007)",
913 .cold_ids = { &az6007_usb_table[1], &az6007_usb_table[2], NULL },
914 .warm_ids = { NULL },
915 },
916 { NULL },
917 }
918};
919
920/* usb specific object needed to register this driver with the usb subsystem */
921static struct usb_driver az6007_usb_driver = {
922 .name = "dvb_usb_az6007",
923 .probe = az6007_usb_probe,
924 .disconnect = az6007_usb_disconnect,
925 .id_table = az6007_usb_table,
926};
927
928/* module stuff */
929static int __init az6007_usb_module_init(void)
930{
931 int result;
932 deb_info("az6007 usb module init\n");
933
934 result = usb_register(&az6007_usb_driver);
935 if (result) {
936 err("usb_register failed. (%d)", result);
937 return result;
938 }
939
940 return 0;
941}
942
943static void __exit az6007_usb_module_exit(void)
944{
945 /* deregister this driver from the USB subsystem */
946 deb_info("az6007 usb module exit\n");
947 usb_deregister(&az6007_usb_driver);
948}
949
950module_init(az6007_usb_module_init);
951module_exit(az6007_usb_module_exit);
952
953MODULE_AUTHOR("Henry Wang <Henry.wang@AzureWave.com>");
954MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
955MODULE_DESCRIPTION("Driver for AzureWave 6007 DVB-C/T USB2.0 and clones");
956MODULE_VERSION("1.1");
957MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
index 070e82aa53f5..02290c60f72f 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -677,11 +677,9 @@ static void dib0700_rc_urb_completion(struct urb *purb)
677 u8 toggle; 677 u8 toggle;
678 678
679 deb_info("%s()\n", __func__); 679 deb_info("%s()\n", __func__);
680 if (d == NULL)
681 return;
682
683 if (d->rc_dev == NULL) { 680 if (d->rc_dev == NULL) {
684 /* This will occur if disable_rc_polling=1 */ 681 /* This will occur if disable_rc_polling=1 */
682 kfree(purb->transfer_buffer);
685 usb_free_urb(purb); 683 usb_free_urb(purb);
686 return; 684 return;
687 } 685 }
@@ -690,6 +688,7 @@ static void dib0700_rc_urb_completion(struct urb *purb)
690 688
691 if (purb->status < 0) { 689 if (purb->status < 0) {
692 deb_info("discontinuing polling\n"); 690 deb_info("discontinuing polling\n");
691 kfree(purb->transfer_buffer);
693 usb_free_urb(purb); 692 usb_free_urb(purb);
694 return; 693 return;
695 } 694 }
@@ -784,8 +783,11 @@ int dib0700_rc_setup(struct dvb_usb_device *d)
784 dib0700_rc_urb_completion, d); 783 dib0700_rc_urb_completion, d);
785 784
786 ret = usb_submit_urb(purb, GFP_ATOMIC); 785 ret = usb_submit_urb(purb, GFP_ATOMIC);
787 if (ret) 786 if (ret) {
788 err("rc submit urb failed\n"); 787 err("rc submit urb failed\n");
788 kfree(purb->transfer_buffer);
789 usb_free_urb(purb);
790 }
789 791
790 return ret; 792 return ret;
791} 793}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index d390ddaa5a53..397d8f232731 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -51,6 +51,7 @@
51#define USB_VID_PINNACLE 0x2304 51#define USB_VID_PINNACLE 0x2304
52#define USB_VID_PCTV 0x2013 52#define USB_VID_PCTV 0x2013
53#define USB_VID_PIXELVIEW 0x1554 53#define USB_VID_PIXELVIEW 0x1554
54#define USB_VID_REALTEK 0x0bda
54#define USB_VID_TECHNOTREND 0x0b48 55#define USB_VID_TECHNOTREND 0x0b48
55#define USB_VID_TERRATEC 0x0ccd 56#define USB_VID_TERRATEC 0x0ccd
56#define USB_VID_TELESTAR 0x10b9 57#define USB_VID_TELESTAR 0x10b9
@@ -80,6 +81,7 @@
80#define USB_PID_ANSONIC_DVBT_USB 0x6000 81#define USB_PID_ANSONIC_DVBT_USB 0x6000
81#define USB_PID_ANYSEE 0x861f 82#define USB_PID_ANYSEE 0x861f
82#define USB_PID_AZUREWAVE_AD_TU700 0x3237 83#define USB_PID_AZUREWAVE_AD_TU700 0x3237
84#define USB_PID_AZUREWAVE_6007 0x0ccd
83#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001 85#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001
84#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002 86#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002
85#define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800 87#define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800
@@ -125,6 +127,8 @@
125#define USB_PID_E3C_EC168_3 0xfffb 127#define USB_PID_E3C_EC168_3 0xfffb
126#define USB_PID_E3C_EC168_4 0x1001 128#define USB_PID_E3C_EC168_4 0x1001
127#define USB_PID_E3C_EC168_5 0x1002 129#define USB_PID_E3C_EC168_5 0x1002
130#define USB_PID_FREECOM_DVBT 0x0160
131#define USB_PID_FREECOM_DVBT_2 0x0161
128#define USB_PID_UNIWILL_STK7700P 0x6003 132#define USB_PID_UNIWILL_STK7700P 0x6003
129#define USB_PID_GENIUS_TVGO_DVB_T03 0x4012 133#define USB_PID_GENIUS_TVGO_DVB_T03 0x4012
130#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 134#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
@@ -226,6 +230,8 @@
226#define USB_PID_TERRATEC_CINERGY_T_EXPRESS 0x0062 230#define USB_PID_TERRATEC_CINERGY_T_EXPRESS 0x0062
227#define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078 231#define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078
228#define USB_PID_TERRATEC_CINERGY_T_XXS_2 0x00ab 232#define USB_PID_TERRATEC_CINERGY_T_XXS_2 0x00ab
233#define USB_PID_TERRATEC_H7 0x10b4
234#define USB_PID_TERRATEC_H7_2 0x10a3
229#define USB_PID_TERRATEC_T3 0x10a0 235#define USB_PID_TERRATEC_T3 0x10a0
230#define USB_PID_TERRATEC_T5 0x10a1 236#define USB_PID_TERRATEC_T5 0x10a1
231#define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e 237#define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e
@@ -249,6 +255,8 @@
249#define USB_PID_PCTV_400E 0x020f 255#define USB_PID_PCTV_400E 0x020f
250#define USB_PID_PCTV_450E 0x0222 256#define USB_PID_PCTV_450E 0x0222
251#define USB_PID_PCTV_452E 0x021f 257#define USB_PID_PCTV_452E 0x021f
258#define USB_PID_REALTEK_RTL2831U 0x2831
259#define USB_PID_REALTEK_RTL2832U 0x2832
252#define USB_PID_TECHNOTREND_CONNECT_S2_3600 0x3007 260#define USB_PID_TECHNOTREND_CONNECT_S2_3600 0x3007
253#define USB_PID_TECHNOTREND_CONNECT_S2_3650_CI 0x300a 261#define USB_PID_TECHNOTREND_CONNECT_S2_3650_CI 0x300a
254#define USB_PID_NEBULA_DIGITV 0x0201 262#define USB_PID_NEBULA_DIGITV 0x0201
diff --git a/drivers/media/dvb/dvb-usb/it913x.c b/drivers/media/dvb/dvb-usb/it913x.c
index 9f01cd7a6e3f..3b7b102f20ae 100644
--- a/drivers/media/dvb/dvb-usb/it913x.c
+++ b/drivers/media/dvb/dvb-usb/it913x.c
@@ -64,6 +64,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
64struct it913x_state { 64struct it913x_state {
65 u8 id; 65 u8 id;
66 struct ite_config it913x_config; 66 struct ite_config it913x_config;
67 u8 pid_filter_onoff;
67}; 68};
68 69
69struct ite_config it913x_config; 70struct ite_config it913x_config;
@@ -259,15 +260,16 @@ static u32 it913x_query(struct usb_device *udev, u8 pro)
259 260
260static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) 261static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
261{ 262{
263 struct it913x_state *st = adap->dev->priv;
262 struct usb_device *udev = adap->dev->udev; 264 struct usb_device *udev = adap->dev->udev;
263 int ret; 265 int ret;
264 u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD; 266 u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
265 267
266 if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) 268 mutex_lock(&adap->dev->i2c_mutex);
267 return -EAGAIN; 269
268 deb_info(1, "PID_C (%02x)", onoff); 270 deb_info(1, "PID_C (%02x)", onoff);
269 271
270 ret = it913x_wr_reg(udev, pro, PID_EN, onoff); 272 ret = it913x_wr_reg(udev, pro, PID_EN, st->pid_filter_onoff);
271 273
272 mutex_unlock(&adap->dev->i2c_mutex); 274 mutex_unlock(&adap->dev->i2c_mutex);
273 return ret; 275 return ret;
@@ -276,12 +278,13 @@ static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
276static int it913x_pid_filter(struct dvb_usb_adapter *adap, 278static int it913x_pid_filter(struct dvb_usb_adapter *adap,
277 int index, u16 pid, int onoff) 279 int index, u16 pid, int onoff)
278{ 280{
281 struct it913x_state *st = adap->dev->priv;
279 struct usb_device *udev = adap->dev->udev; 282 struct usb_device *udev = adap->dev->udev;
280 int ret; 283 int ret;
281 u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD; 284 u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
282 285
283 if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) 286 mutex_lock(&adap->dev->i2c_mutex);
284 return -EAGAIN; 287
285 deb_info(1, "PID_F (%02x)", onoff); 288 deb_info(1, "PID_F (%02x)", onoff);
286 289
287 ret = it913x_wr_reg(udev, pro, PID_LSB, (u8)(pid & 0xff)); 290 ret = it913x_wr_reg(udev, pro, PID_LSB, (u8)(pid & 0xff));
@@ -292,6 +295,13 @@ static int it913x_pid_filter(struct dvb_usb_adapter *adap,
292 295
293 ret |= it913x_wr_reg(udev, pro, PID_INX, (u8)(index & 0x1f)); 296 ret |= it913x_wr_reg(udev, pro, PID_INX, (u8)(index & 0x1f));
294 297
298 if (udev->speed == USB_SPEED_HIGH && pid == 0x2000) {
299 ret |= it913x_wr_reg(udev, pro, PID_EN, !onoff);
300 st->pid_filter_onoff = !onoff;
301 } else
302 st->pid_filter_onoff =
303 adap->fe_adap[adap->active_fe].pid_filtering;
304
295 mutex_unlock(&adap->dev->i2c_mutex); 305 mutex_unlock(&adap->dev->i2c_mutex);
296 return 0; 306 return 0;
297} 307}
@@ -316,8 +326,8 @@ static int it913x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
316 int ret; 326 int ret;
317 u32 reg; 327 u32 reg;
318 u8 pro; 328 u8 pro;
319 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 329
320 return -EAGAIN; 330 mutex_lock(&d->i2c_mutex);
321 331
322 debug_data_snipet(1, "Message out", msg[0].buf); 332 debug_data_snipet(1, "Message out", msg[0].buf);
323 deb_info(2, "num of messages %d address %02x", num, msg[0].addr); 333 deb_info(2, "num of messages %d address %02x", num, msg[0].addr);
@@ -358,8 +368,7 @@ static int it913x_rc_query(struct dvb_usb_device *d)
358 int ret; 368 int ret;
359 u32 key; 369 u32 key;
360 /* Avoid conflict with frontends*/ 370 /* Avoid conflict with frontends*/
361 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 371 mutex_lock(&d->i2c_mutex);
362 return -EAGAIN;
363 372
364 ret = it913x_io(d->udev, READ_LONG, PRO_LINK, CMD_IR_GET, 373 ret = it913x_io(d->udev, READ_LONG, PRO_LINK, CMD_IR_GET,
365 0, 0, &ibuf[0], sizeof(ibuf)); 374 0, 0, &ibuf[0], sizeof(ibuf));
@@ -388,19 +397,12 @@ static int ite_firmware_select(struct usb_device *udev,
388{ 397{
389 int sw; 398 int sw;
390 /* auto switch */ 399 /* auto switch */
391 if (le16_to_cpu(udev->descriptor.idProduct) == 400 if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_KWORLD_2)
392 USB_PID_ITETECH_IT9135) 401 sw = IT9137_FW;
393 sw = IT9135_V1_FW; 402 else if (it913x_config.chip_ver == 1)
394 else if (le16_to_cpu(udev->descriptor.idProduct) ==
395 USB_PID_ITETECH_IT9135_9005)
396 sw = IT9135_V1_FW; 403 sw = IT9135_V1_FW;
397 else if (le16_to_cpu(udev->descriptor.idProduct) == 404 else
398 USB_PID_ITETECH_IT9135_9006) {
399 sw = IT9135_V2_FW; 405 sw = IT9135_V2_FW;
400 if (it913x_config.tuner_id_0 == 0)
401 it913x_config.tuner_id_0 = IT9135_60;
402 } else
403 sw = IT9137_FW;
404 406
405 /* force switch */ 407 /* force switch */
406 if (dvb_usb_it913x_firmware != IT9135_AUTO) 408 if (dvb_usb_it913x_firmware != IT9135_AUTO)
@@ -410,41 +412,103 @@ static int ite_firmware_select(struct usb_device *udev,
410 case IT9135_V1_FW: 412 case IT9135_V1_FW:
411 it913x_config.firmware_ver = 1; 413 it913x_config.firmware_ver = 1;
412 it913x_config.adc_x2 = 1; 414 it913x_config.adc_x2 = 1;
415 it913x_config.read_slevel = false;
413 props->firmware = fw_it9135_v1; 416 props->firmware = fw_it9135_v1;
414 break; 417 break;
415 case IT9135_V2_FW: 418 case IT9135_V2_FW:
416 it913x_config.firmware_ver = 1; 419 it913x_config.firmware_ver = 1;
417 it913x_config.adc_x2 = 1; 420 it913x_config.adc_x2 = 1;
421 it913x_config.read_slevel = false;
418 props->firmware = fw_it9135_v2; 422 props->firmware = fw_it9135_v2;
423 switch (it913x_config.tuner_id_0) {
424 case IT9135_61:
425 case IT9135_62:
426 break;
427 default:
428 info("Unknown tuner ID applying default 0x60");
429 case IT9135_60:
430 it913x_config.tuner_id_0 = IT9135_60;
431 }
419 break; 432 break;
420 case IT9137_FW: 433 case IT9137_FW:
421 default: 434 default:
422 it913x_config.firmware_ver = 0; 435 it913x_config.firmware_ver = 0;
423 it913x_config.adc_x2 = 0; 436 it913x_config.adc_x2 = 0;
437 it913x_config.read_slevel = true;
424 props->firmware = fw_it9137; 438 props->firmware = fw_it9137;
425 } 439 }
426 440
427 return 0; 441 return 0;
428} 442}
429 443
444static void it913x_select_remote(struct usb_device *udev,
445 struct dvb_usb_device_properties *props)
446{
447 switch (le16_to_cpu(udev->descriptor.idProduct)) {
448 case USB_PID_ITETECH_IT9135_9005:
449 props->rc.core.rc_codes = RC_MAP_IT913X_V2;
450 return;
451 default:
452 props->rc.core.rc_codes = RC_MAP_IT913X_V1;
453 }
454 return;
455}
456
430#define TS_MPEG_PKT_SIZE 188 457#define TS_MPEG_PKT_SIZE 188
431#define EP_LOW 21 458#define EP_LOW 21
432#define TS_BUFFER_SIZE_PID (EP_LOW*TS_MPEG_PKT_SIZE) 459#define TS_BUFFER_SIZE_PID (EP_LOW*TS_MPEG_PKT_SIZE)
433#define EP_HIGH 348 460#define EP_HIGH 348
434#define TS_BUFFER_SIZE_MAX (EP_HIGH*TS_MPEG_PKT_SIZE) 461#define TS_BUFFER_SIZE_MAX (EP_HIGH*TS_MPEG_PKT_SIZE)
435 462
436static int it913x_identify_state(struct usb_device *udev, 463static int it913x_select_config(struct usb_device *udev,
437 struct dvb_usb_device_properties *props, 464 struct dvb_usb_device_properties *props)
438 struct dvb_usb_device_description **desc,
439 int *cold)
440{ 465{
441 int ret = 0, firm_no; 466 int ret = 0, reg;
442 u8 reg, remote; 467 bool proprietary_ir = false;
443 468
444 firm_no = it913x_return_status(udev); 469 if (it913x_config.chip_ver == 0x02
470 && it913x_config.chip_type == 0x9135)
471 reg = it913x_read_reg(udev, 0x461d);
472 else
473 reg = it913x_read_reg(udev, 0x461b);
445 474
446 /* checnk for dual mode */ 475 if (reg < 0)
447 it913x_config.dual_mode = it913x_read_reg(udev, 0x49c5); 476 return reg;
477
478 if (reg == 0) {
479 it913x_config.dual_mode = 0;
480 it913x_config.tuner_id_0 = IT9135_38;
481 proprietary_ir = true;
482 } else {
483 /* TS mode */
484 reg = it913x_read_reg(udev, 0x49c5);
485 if (reg < 0)
486 return reg;
487 it913x_config.dual_mode = reg;
488
489 /* IR mode type */
490 reg = it913x_read_reg(udev, 0x49ac);
491 if (reg < 0)
492 return reg;
493 if (reg == 5) {
494 info("Remote propriety (raw) mode");
495 proprietary_ir = true;
496 } else if (reg == 1) {
497 info("Remote HID mode NOT SUPPORTED");
498 proprietary_ir = false;
499 props->rc.core.rc_codes = NULL;
500 } else
501 props->rc.core.rc_codes = NULL;
502
503 /* Tuner_id */
504 reg = it913x_read_reg(udev, 0x49d0);
505 if (reg < 0)
506 return reg;
507 it913x_config.tuner_id_0 = reg;
508 }
509
510 if (proprietary_ir)
511 it913x_select_remote(udev, props);
448 512
449 if (udev->speed != USB_SPEED_HIGH) { 513 if (udev->speed != USB_SPEED_HIGH) {
450 props->adapter[0].fe[0].pid_filter_count = 5; 514 props->adapter[0].fe[0].pid_filter_count = 5;
@@ -459,17 +523,6 @@ static int it913x_identify_state(struct usb_device *udev,
459 if(props->adapter[0].fe[0].pid_filter_count == 5) 523 if(props->adapter[0].fe[0].pid_filter_count == 5)
460 props->adapter[0].fe[0].pid_filter_count = 31; 524 props->adapter[0].fe[0].pid_filter_count = 31;
461 525
462 /* TODO different remotes */
463 remote = it913x_read_reg(udev, 0x49ac); /* Remote */
464 if (remote == 0)
465 props->rc.core.rc_codes = NULL;
466
467 /* TODO at the moment tuner_id is always assigned to 0x38 */
468 it913x_config.tuner_id_0 = it913x_read_reg(udev, 0x49d0);
469
470 info("Dual mode=%x Remote=%x Tuner Type=%x", it913x_config.dual_mode
471 , remote, it913x_config.tuner_id_0);
472
473 /* Select Stream Buffer Size and pid filter option*/ 526 /* Select Stream Buffer Size and pid filter option*/
474 if (pid_filter) { 527 if (pid_filter) {
475 props->adapter[0].fe[0].stream.u.bulk.buffersize = 528 props->adapter[0].fe[0].stream.u.bulk.buffersize =
@@ -490,8 +543,29 @@ static int it913x_identify_state(struct usb_device *udev,
490 } else 543 } else
491 props->num_adapters = 1; 544 props->num_adapters = 1;
492 545
546 info("Dual mode=%x Tuner Type=%x", it913x_config.dual_mode,
547 it913x_config.tuner_id_0);
548
493 ret = ite_firmware_select(udev, props); 549 ret = ite_firmware_select(udev, props);
494 550
551 return ret;
552}
553
554static int it913x_identify_state(struct usb_device *udev,
555 struct dvb_usb_device_properties *props,
556 struct dvb_usb_device_description **desc,
557 int *cold)
558{
559 int ret = 0, firm_no;
560 u8 reg;
561
562 firm_no = it913x_return_status(udev);
563
564 /* Read and select config */
565 ret = it913x_select_config(udev, props);
566 if (ret < 0)
567 return ret;
568
495 if (firm_no > 0) { 569 if (firm_no > 0) {
496 *cold = 0; 570 *cold = 0;
497 return 0; 571 return 0;
@@ -538,18 +612,22 @@ static int it913x_identify_state(struct usb_device *udev,
538 612
539static int it913x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 613static int it913x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
540{ 614{
615 struct it913x_state *st = adap->dev->priv;
541 int ret = 0; 616 int ret = 0;
542 u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD; 617 u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
543 618
544 if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0)
545 return -EAGAIN;
546 deb_info(1, "STM (%02x)", onoff); 619 deb_info(1, "STM (%02x)", onoff);
547 620
548 if (!onoff) 621 if (!onoff) {
622 mutex_lock(&adap->dev->i2c_mutex);
623
549 ret = it913x_wr_reg(adap->dev->udev, pro, PID_RST, 0x1); 624 ret = it913x_wr_reg(adap->dev->udev, pro, PID_RST, 0x1);
550 625
626 mutex_unlock(&adap->dev->i2c_mutex);
627 st->pid_filter_onoff =
628 adap->fe_adap[adap->active_fe].pid_filtering;
551 629
552 mutex_unlock(&adap->dev->i2c_mutex); 630 }
553 631
554 return ret; 632 return ret;
555} 633}
@@ -789,7 +867,7 @@ static struct dvb_usb_device_properties it913x_properties = {
789 .rc_query = it913x_rc_query, 867 .rc_query = it913x_rc_query,
790 .rc_interval = IT913X_POLL, 868 .rc_interval = IT913X_POLL,
791 .allowed_protos = RC_TYPE_NEC, 869 .allowed_protos = RC_TYPE_NEC,
792 .rc_codes = RC_MAP_MSI_DIGIVOX_III, 870 .rc_codes = RC_MAP_IT913X_V1,
793 }, 871 },
794 .i2c_algo = &it913x_i2c_algo, 872 .i2c_algo = &it913x_i2c_algo,
795 .num_device_descs = 5, 873 .num_device_descs = 5,
@@ -823,5 +901,5 @@ module_usb_driver(it913x_driver);
823 901
824MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); 902MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
825MODULE_DESCRIPTION("it913x USB 2 Driver"); 903MODULE_DESCRIPTION("it913x USB 2 Driver");
826MODULE_VERSION("1.22"); 904MODULE_VERSION("1.27");
827MODULE_LICENSE("GPL"); 905MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c
index 291f6b110399..5dde06d066ff 100644
--- a/drivers/media/dvb/dvb-usb/lmedm04.c
+++ b/drivers/media/dvb/dvb-usb/lmedm04.c
@@ -77,6 +77,7 @@
77#include "stv0299.h" 77#include "stv0299.h"
78#include "dvb-pll.h" 78#include "dvb-pll.h"
79#include "z0194a.h" 79#include "z0194a.h"
80#include "m88rs2000.h"
80 81
81 82
82 83
@@ -104,7 +105,7 @@ MODULE_PARM_DESC(firmware, "set default firmware 0=Sharp7395 1=LG");
104 105
105static int pid_filter; 106static int pid_filter;
106module_param_named(pid, pid_filter, int, 0644); 107module_param_named(pid, pid_filter, int, 0644);
107MODULE_PARM_DESC(pid, "set default 0=on 1=off"); 108MODULE_PARM_DESC(pid, "set default 0=default 1=off 2=on");
108 109
109 110
110DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 111DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
@@ -113,6 +114,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
113#define TUNER_LG 0x1 114#define TUNER_LG 0x1
114#define TUNER_S7395 0x2 115#define TUNER_S7395 0x2
115#define TUNER_S0194 0x3 116#define TUNER_S0194 0x3
117#define TUNER_RS2000 0x4
116 118
117struct lme2510_state { 119struct lme2510_state {
118 u8 id; 120 u8 id;
@@ -121,6 +123,8 @@ struct lme2510_state {
121 u8 signal_level; 123 u8 signal_level;
122 u8 signal_sn; 124 u8 signal_sn;
123 u8 time_key; 125 u8 time_key;
126 u8 last_key;
127 u8 key_timeout;
124 u8 i2c_talk_onoff; 128 u8 i2c_talk_onoff;
125 u8 i2c_gate; 129 u8 i2c_gate;
126 u8 i2c_tuner_gate_w; 130 u8 i2c_tuner_gate_w;
@@ -128,6 +132,7 @@ struct lme2510_state {
128 u8 i2c_tuner_addr; 132 u8 i2c_tuner_addr;
129 u8 stream_on; 133 u8 stream_on;
130 u8 pid_size; 134 u8 pid_size;
135 u8 pid_off;
131 void *buffer; 136 void *buffer;
132 struct urb *lme_urb; 137 struct urb *lme_urb;
133 void *usb_buffer; 138 void *usb_buffer;
@@ -178,14 +183,8 @@ static int lme2510_usb_talk(struct dvb_usb_device *d,
178 /* the read/write capped at 64 */ 183 /* the read/write capped at 64 */
179 memcpy(buff, wbuf, (wlen < 64) ? wlen : 64); 184 memcpy(buff, wbuf, (wlen < 64) ? wlen : 64);
180 185
181 ret |= usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, 0x01));
182
183 ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x01); 186 ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x01);
184 187
185 msleep(10);
186
187 ret |= usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x01));
188
189 ret |= lme2510_bulk_read(d->udev, buff, (rlen < 64) ? 188 ret |= lme2510_bulk_read(d->udev, buff, (rlen < 64) ?
190 rlen : 64 , 0x01); 189 rlen : 64 , 0x01);
191 190
@@ -199,9 +198,14 @@ static int lme2510_usb_talk(struct dvb_usb_device *d,
199 198
200static int lme2510_stream_restart(struct dvb_usb_device *d) 199static int lme2510_stream_restart(struct dvb_usb_device *d)
201{ 200{
202 static u8 stream_on[] = LME_ST_ON_W; 201 struct lme2510_state *st = d->priv;
202 u8 all_pids[] = LME_ALL_PIDS;
203 u8 stream_on[] = LME_ST_ON_W;
203 int ret; 204 int ret;
204 u8 rbuff[10]; 205 u8 rbuff[1];
206 if (st->pid_off)
207 ret = lme2510_usb_talk(d, all_pids, sizeof(all_pids),
208 rbuff, sizeof(rbuff));
205 /*Restart Stream Command*/ 209 /*Restart Stream Command*/
206 ret = lme2510_usb_talk(d, stream_on, sizeof(stream_on), 210 ret = lme2510_usb_talk(d, stream_on, sizeof(stream_on),
207 rbuff, sizeof(rbuff)); 211 rbuff, sizeof(rbuff));
@@ -308,6 +312,14 @@ static void lme2510_int_response(struct urb *lme_urb)
308 ((ibuf[2] & 0x01) << 0x03); 312 ((ibuf[2] & 0x01) << 0x03);
309 } 313 }
310 break; 314 break;
315 case TUNER_RS2000:
316 if (ibuf[2] > 0)
317 st->signal_lock = 0xff;
318 else
319 st->signal_lock = 0xf0;
320 st->signal_level = ibuf[4];
321 st->signal_sn = ibuf[5];
322 st->time_key = ibuf[7];
311 default: 323 default:
312 break; 324 break;
313 } 325 }
@@ -359,19 +371,20 @@ static int lme2510_int_read(struct dvb_usb_adapter *adap)
359static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) 371static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
360{ 372{
361 struct lme2510_state *st = adap->dev->priv; 373 struct lme2510_state *st = adap->dev->priv;
362 static u8 clear_pid_reg[] = LME_CLEAR_PID; 374 static u8 clear_pid_reg[] = LME_ALL_PIDS;
363 static u8 rbuf[1]; 375 static u8 rbuf[1];
364 int ret; 376 int ret;
365 377
366 deb_info(1, "PID Clearing Filter"); 378 deb_info(1, "PID Clearing Filter");
367 379
368 ret = mutex_lock_interruptible(&adap->dev->i2c_mutex); 380 mutex_lock(&adap->dev->i2c_mutex);
369 if (ret < 0)
370 return -EAGAIN;
371 381
372 if (!onoff) 382 if (!onoff) {
373 ret |= lme2510_usb_talk(adap->dev, clear_pid_reg, 383 ret |= lme2510_usb_talk(adap->dev, clear_pid_reg,
374 sizeof(clear_pid_reg), rbuf, sizeof(rbuf)); 384 sizeof(clear_pid_reg), rbuf, sizeof(rbuf));
385 st->pid_off = true;
386 } else
387 st->pid_off = false;
375 388
376 st->pid_size = 0; 389 st->pid_size = 0;
377 390
@@ -389,11 +402,9 @@ static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
389 pid, index, onoff); 402 pid, index, onoff);
390 403
391 if (onoff) { 404 if (onoff) {
392 ret = mutex_lock_interruptible(&adap->dev->i2c_mutex); 405 mutex_lock(&adap->dev->i2c_mutex);
393 if (ret < 0) 406 ret |= lme2510_enable_pid(adap->dev, index, pid);
394 return -EAGAIN; 407 mutex_unlock(&adap->dev->i2c_mutex);
395 ret |= lme2510_enable_pid(adap->dev, index, pid);
396 mutex_unlock(&adap->dev->i2c_mutex);
397 } 408 }
398 409
399 410
@@ -425,9 +436,6 @@ static int lme2510_msg(struct dvb_usb_device *d,
425 int ret = 0; 436 int ret = 0;
426 struct lme2510_state *st = d->priv; 437 struct lme2510_state *st = d->priv;
427 438
428 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
429 return -EAGAIN;
430
431 if (st->i2c_talk_onoff == 1) { 439 if (st->i2c_talk_onoff == 1) {
432 440
433 ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen); 441 ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
@@ -456,8 +464,6 @@ static int lme2510_msg(struct dvb_usb_device *d,
456 st->i2c_talk_onoff = 0; 464 st->i2c_talk_onoff = 0;
457 } 465 }
458 } 466 }
459 if ((wbuf[3] != 0x6) & (wbuf[3] != 0x5))
460 msleep(5);
461 } 467 }
462 break; 468 break;
463 case TUNER_S0194: 469 case TUNER_S0194:
@@ -472,10 +478,12 @@ static int lme2510_msg(struct dvb_usb_device *d,
472 } 478 }
473 } 479 }
474 break; 480 break;
481 case TUNER_RS2000:
475 default: 482 default:
476 break; 483 break;
477 } 484 }
478 } else { 485 } else {
486 /* TODO rewrite this section */
479 switch (st->tuner_config) { 487 switch (st->tuner_config) {
480 case TUNER_LG: 488 case TUNER_LG:
481 switch (wbuf[3]) { 489 switch (wbuf[3]) {
@@ -559,6 +567,24 @@ static int lme2510_msg(struct dvb_usb_device *d,
559 break; 567 break;
560 } 568 }
561 break; 569 break;
570 case TUNER_RS2000:
571 switch (wbuf[3]) {
572 case 0x8c:
573 rbuf[0] = 0x55;
574 rbuf[1] = 0xff;
575 if (st->last_key == st->time_key) {
576 st->key_timeout++;
577 if (st->key_timeout > 5)
578 rbuf[1] = 0;
579 } else
580 st->key_timeout = 0;
581 st->last_key = st->time_key;
582 break;
583 default:
584 lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
585 st->i2c_talk_onoff = 1;
586 break;
587 }
562 default: 588 default:
563 break; 589 break;
564 } 590 }
@@ -568,8 +594,6 @@ static int lme2510_msg(struct dvb_usb_device *d,
568 594
569 } 595 }
570 596
571 mutex_unlock(&d->i2c_mutex);
572
573 return ret; 597 return ret;
574} 598}
575 599
@@ -584,6 +608,8 @@ static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
584 u16 len; 608 u16 len;
585 u8 gate = st->i2c_gate; 609 u8 gate = st->i2c_gate;
586 610
611 mutex_lock(&d->i2c_mutex);
612
587 if (gate == 0) 613 if (gate == 0)
588 gate = 5; 614 gate = 5;
589 615
@@ -622,6 +648,7 @@ static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
622 648
623 if (lme2510_msg(d, obuf, len, ibuf, 64) < 0) { 649 if (lme2510_msg(d, obuf, len, ibuf, 64) < 0) {
624 deb_info(1, "i2c transfer failed."); 650 deb_info(1, "i2c transfer failed.");
651 mutex_unlock(&d->i2c_mutex);
625 return -EAGAIN; 652 return -EAGAIN;
626 } 653 }
627 654
@@ -634,6 +661,8 @@ static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
634 } 661 }
635 } 662 }
636 } 663 }
664
665 mutex_unlock(&d->i2c_mutex);
637 return i; 666 return i;
638} 667}
639 668
@@ -653,7 +682,7 @@ static int lme2510_identify_state(struct usb_device *udev,
653 struct dvb_usb_device_description **desc, 682 struct dvb_usb_device_description **desc,
654 int *cold) 683 int *cold)
655{ 684{
656 if (pid_filter > 0) 685 if (pid_filter != 2)
657 props->adapter[0].fe[0].caps &= 686 props->adapter[0].fe[0].caps &=
658 ~DVB_USB_ADAP_NEED_PID_FILTERING; 687 ~DVB_USB_ADAP_NEED_PID_FILTERING;
659 *cold = 0; 688 *cold = 0;
@@ -663,7 +692,7 @@ static int lme2510_identify_state(struct usb_device *udev,
663static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 692static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
664{ 693{
665 struct lme2510_state *st = adap->dev->priv; 694 struct lme2510_state *st = adap->dev->priv;
666 static u8 clear_reg_3[] = LME_CLEAR_PID; 695 static u8 clear_reg_3[] = LME_ALL_PIDS;
667 static u8 rbuf[1]; 696 static u8 rbuf[1];
668 int ret = 0, rlen = sizeof(rbuf); 697 int ret = 0, rlen = sizeof(rbuf);
669 698
@@ -675,8 +704,7 @@ static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
675 else { 704 else {
676 deb_info(1, "STM Steam Off"); 705 deb_info(1, "STM Steam Off");
677 /* mutex is here only to avoid collision with I2C */ 706 /* mutex is here only to avoid collision with I2C */
678 if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) 707 mutex_lock(&adap->dev->i2c_mutex);
679 return -EAGAIN;
680 708
681 ret = lme2510_usb_talk(adap->dev, clear_reg_3, 709 ret = lme2510_usb_talk(adap->dev, clear_reg_3,
682 sizeof(clear_reg_3), rbuf, rlen); 710 sizeof(clear_reg_3), rbuf, rlen);
@@ -781,16 +809,18 @@ static int lme_firmware_switch(struct usb_device *udev, int cold)
781 const char fw_c_s7395[] = "dvb-usb-lme2510c-s7395.fw"; 809 const char fw_c_s7395[] = "dvb-usb-lme2510c-s7395.fw";
782 const char fw_c_lg[] = "dvb-usb-lme2510c-lg.fw"; 810 const char fw_c_lg[] = "dvb-usb-lme2510c-lg.fw";
783 const char fw_c_s0194[] = "dvb-usb-lme2510c-s0194.fw"; 811 const char fw_c_s0194[] = "dvb-usb-lme2510c-s0194.fw";
812 const char fw_c_rs2000[] = "dvb-usb-lme2510c-rs2000.fw";
784 const char fw_lg[] = "dvb-usb-lme2510-lg.fw"; 813 const char fw_lg[] = "dvb-usb-lme2510-lg.fw";
785 const char fw_s0194[] = "dvb-usb-lme2510-s0194.fw"; 814 const char fw_s0194[] = "dvb-usb-lme2510-s0194.fw";
786 const char *fw_lme; 815 const char *fw_lme;
787 int ret, cold_fw; 816 int ret = 0, cold_fw;
788 817
789 cold = (cold > 0) ? (cold & 1) : 0; 818 cold = (cold > 0) ? (cold & 1) : 0;
790 819
791 cold_fw = !cold; 820 cold_fw = !cold;
792 821
793 if (le16_to_cpu(udev->descriptor.idProduct) == 0x1122) { 822 switch (le16_to_cpu(udev->descriptor.idProduct)) {
823 case 0x1122:
794 switch (dvb_usb_lme2510_firmware) { 824 switch (dvb_usb_lme2510_firmware) {
795 default: 825 default:
796 dvb_usb_lme2510_firmware = TUNER_S0194; 826 dvb_usb_lme2510_firmware = TUNER_S0194;
@@ -813,7 +843,8 @@ static int lme_firmware_switch(struct usb_device *udev, int cold)
813 cold_fw = 0; 843 cold_fw = 0;
814 break; 844 break;
815 } 845 }
816 } else { 846 break;
847 case 0x1120:
817 switch (dvb_usb_lme2510_firmware) { 848 switch (dvb_usb_lme2510_firmware) {
818 default: 849 default:
819 dvb_usb_lme2510_firmware = TUNER_S7395; 850 dvb_usb_lme2510_firmware = TUNER_S7395;
@@ -842,8 +873,17 @@ static int lme_firmware_switch(struct usb_device *udev, int cold)
842 cold_fw = 0; 873 cold_fw = 0;
843 break; 874 break;
844 } 875 }
876 break;
877 case 0x22f0:
878 fw_lme = fw_c_rs2000;
879 ret = request_firmware(&fw, fw_lme, &udev->dev);
880 dvb_usb_lme2510_firmware = TUNER_RS2000;
881 break;
882 default:
883 fw_lme = fw_c_s7395;
845 } 884 }
846 885
886
847 if (cold_fw) { 887 if (cold_fw) {
848 info("FRM Loading %s file", fw_lme); 888 info("FRM Loading %s file", fw_lme);
849 ret = lme2510_download_firmware(udev, fw); 889 ret = lme2510_download_firmware(udev, fw);
@@ -906,6 +946,29 @@ static struct stv0299_config sharp_z0194_config = {
906 .set_symbol_rate = sharp_z0194a_set_symbol_rate, 946 .set_symbol_rate = sharp_z0194a_set_symbol_rate,
907}; 947};
908 948
949static int dm04_rs2000_set_ts_param(struct dvb_frontend *fe,
950 int caller)
951{
952 struct dvb_usb_adapter *adap = fe->dvb->priv;
953 struct dvb_usb_device *d = adap->dev;
954 struct lme2510_state *st = d->priv;
955
956 mutex_lock(&d->i2c_mutex);
957 if ((st->i2c_talk_onoff == 1) && (st->stream_on & 1)) {
958 st->i2c_talk_onoff = 0;
959 lme2510_stream_restart(d);
960 }
961 mutex_unlock(&d->i2c_mutex);
962
963 return 0;
964}
965
966static struct m88rs2000_config m88rs2000_config = {
967 .demod_addr = 0xd0,
968 .tuner_addr = 0xc0,
969 .set_ts_params = dm04_rs2000_set_ts_param,
970};
971
909static int dm04_lme2510_set_voltage(struct dvb_frontend *fe, 972static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
910 fe_sec_voltage_t voltage) 973 fe_sec_voltage_t voltage)
911{ 974{
@@ -915,8 +978,7 @@ static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
915 static u8 rbuf[1]; 978 static u8 rbuf[1];
916 int ret = 0, len = 3, rlen = 1; 979 int ret = 0, len = 3, rlen = 1;
917 980
918 if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0) 981 mutex_lock(&adap->dev->i2c_mutex);
919 return -EAGAIN;
920 982
921 switch (voltage) { 983 switch (voltage) {
922 case SEC_VOLTAGE_18: 984 case SEC_VOLTAGE_18:
@@ -937,12 +999,31 @@ static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
937 return (ret < 0) ? -ENODEV : 0; 999 return (ret < 0) ? -ENODEV : 0;
938} 1000}
939 1001
1002static int dm04_rs2000_read_signal_strength(struct dvb_frontend *fe,
1003 u16 *strength)
1004{
1005 struct dvb_usb_adapter *adap = fe->dvb->priv;
1006 struct lme2510_state *st = adap->dev->priv;
1007
1008 *strength = (u16)((u32)st->signal_level * 0xffff / 0x7f);
1009 return 0;
1010}
1011
1012static int dm04_rs2000_read_snr(struct dvb_frontend *fe, u16 *snr)
1013{
1014 struct dvb_usb_adapter *adap = fe->dvb->priv;
1015 struct lme2510_state *st = adap->dev->priv;
1016
1017 *snr = (u16)((u32)st->signal_sn * 0xffff / 0xff);
1018 return 0;
1019}
1020
940static int lme_name(struct dvb_usb_adapter *adap) 1021static int lme_name(struct dvb_usb_adapter *adap)
941{ 1022{
942 struct lme2510_state *st = adap->dev->priv; 1023 struct lme2510_state *st = adap->dev->priv;
943 const char *desc = adap->dev->desc->name; 1024 const char *desc = adap->dev->desc->name;
944 char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395", 1025 char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395",
945 " SHARP:BS2F7HZ0194"}; 1026 " SHARP:BS2F7HZ0194", " RS2000"};
946 char *name = adap->fe_adap[0].fe->ops.info.name; 1027 char *name = adap->fe_adap[0].fe->ops.info.name;
947 1028
948 strlcpy(name, desc, 128); 1029 strlcpy(name, desc, 128);
@@ -958,60 +1039,82 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
958 int ret = 0; 1039 int ret = 0;
959 1040
960 st->i2c_talk_onoff = 1; 1041 st->i2c_talk_onoff = 1;
1042 switch (le16_to_cpu(adap->dev->udev->descriptor.idProduct)) {
1043 case 0x1122:
1044 case 0x1120:
1045 st->i2c_gate = 4;
1046 adap->fe_adap[0].fe = dvb_attach(tda10086_attach,
1047 &tda10086_config, &adap->dev->i2c_adap);
1048 if (adap->fe_adap[0].fe) {
1049 info("TUN Found Frontend TDA10086");
1050 st->i2c_tuner_gate_w = 4;
1051 st->i2c_tuner_gate_r = 4;
1052 st->i2c_tuner_addr = 0xc0;
1053 st->tuner_config = TUNER_LG;
1054 if (dvb_usb_lme2510_firmware != TUNER_LG) {
1055 dvb_usb_lme2510_firmware = TUNER_LG;
1056 ret = lme_firmware_switch(adap->dev->udev, 1);
1057 }
1058 break;
1059 }
961 1060
962 st->i2c_gate = 4; 1061 st->i2c_gate = 4;
963 adap->fe_adap[0].fe = dvb_attach(tda10086_attach, &tda10086_config, 1062 adap->fe_adap[0].fe = dvb_attach(stv0299_attach,
964 &adap->dev->i2c_adap); 1063 &sharp_z0194_config, &adap->dev->i2c_adap);
965 1064 if (adap->fe_adap[0].fe) {
966 if (adap->fe_adap[0].fe) { 1065 info("FE Found Stv0299");
967 info("TUN Found Frontend TDA10086"); 1066 st->i2c_tuner_gate_w = 4;
968 st->i2c_tuner_gate_w = 4; 1067 st->i2c_tuner_gate_r = 5;
969 st->i2c_tuner_gate_r = 4; 1068 st->i2c_tuner_addr = 0xc0;
970 st->i2c_tuner_addr = 0xc0; 1069 st->tuner_config = TUNER_S0194;
971 st->tuner_config = TUNER_LG; 1070 if (dvb_usb_lme2510_firmware != TUNER_S0194) {
972 if (dvb_usb_lme2510_firmware != TUNER_LG) { 1071 dvb_usb_lme2510_firmware = TUNER_S0194;
973 dvb_usb_lme2510_firmware = TUNER_LG; 1072 ret = lme_firmware_switch(adap->dev->udev, 1);
974 ret = lme_firmware_switch(adap->dev->udev, 1); 1073 }
1074 break;
975 } 1075 }
976 goto end;
977 }
978 1076
979 st->i2c_gate = 4; 1077 st->i2c_gate = 5;
980 adap->fe_adap[0].fe = dvb_attach(stv0299_attach, &sharp_z0194_config, 1078 adap->fe_adap[0].fe = dvb_attach(stv0288_attach, &lme_config,
981 &adap->dev->i2c_adap); 1079 &adap->dev->i2c_adap);
982 if (adap->fe_adap[0].fe) { 1080
983 info("FE Found Stv0299"); 1081 if (adap->fe_adap[0].fe) {
984 st->i2c_tuner_gate_w = 4; 1082 info("FE Found Stv0288");
985 st->i2c_tuner_gate_r = 5; 1083 st->i2c_tuner_gate_w = 4;
986 st->i2c_tuner_addr = 0xc0; 1084 st->i2c_tuner_gate_r = 5;
987 st->tuner_config = TUNER_S0194; 1085 st->i2c_tuner_addr = 0xc0;
988 if (dvb_usb_lme2510_firmware != TUNER_S0194) { 1086 st->tuner_config = TUNER_S7395;
989 dvb_usb_lme2510_firmware = TUNER_S0194; 1087 if (dvb_usb_lme2510_firmware != TUNER_S7395) {
990 ret = lme_firmware_switch(adap->dev->udev, 1); 1088 dvb_usb_lme2510_firmware = TUNER_S7395;
1089 ret = lme_firmware_switch(adap->dev->udev, 1);
1090 }
1091 break;
991 } 1092 }
992 goto end; 1093 case 0x22f0:
993 } 1094 st->i2c_gate = 5;
1095 adap->fe_adap[0].fe = dvb_attach(m88rs2000_attach,
1096 &m88rs2000_config, &adap->dev->i2c_adap);
994 1097
995 st->i2c_gate = 5; 1098 if (adap->fe_adap[0].fe) {
996 adap->fe_adap[0].fe = dvb_attach(stv0288_attach, &lme_config, 1099 info("FE Found M88RS2000");
997 &adap->dev->i2c_adap); 1100 st->i2c_tuner_gate_w = 5;
998 if (adap->fe_adap[0].fe) { 1101 st->i2c_tuner_gate_r = 5;
999 info("FE Found Stv0288"); 1102 st->i2c_tuner_addr = 0xc0;
1000 st->i2c_tuner_gate_w = 4; 1103 st->tuner_config = TUNER_RS2000;
1001 st->i2c_tuner_gate_r = 5; 1104 adap->fe_adap[0].fe->ops.read_signal_strength =
1002 st->i2c_tuner_addr = 0xc0; 1105 dm04_rs2000_read_signal_strength;
1003 st->tuner_config = TUNER_S7395; 1106 adap->fe_adap[0].fe->ops.read_snr =
1004 if (dvb_usb_lme2510_firmware != TUNER_S7395) { 1107 dm04_rs2000_read_snr;
1005 dvb_usb_lme2510_firmware = TUNER_S7395;
1006 ret = lme_firmware_switch(adap->dev->udev, 1);
1007 } 1108 }
1008 } else { 1109 break;
1009 info("DM04 Not Supported");
1010 return -ENODEV;
1011 } 1110 }
1012 1111
1112 if (adap->fe_adap[0].fe == NULL) {
1113 info("DM04/QQBOX Not Powered up or not Supported");
1114 return -ENODEV;
1115 }
1013 1116
1014end: if (ret) { 1117 if (ret) {
1015 if (adap->fe_adap[0].fe) { 1118 if (adap->fe_adap[0].fe) {
1016 dvb_frontend_detach(adap->fe_adap[0].fe); 1119 dvb_frontend_detach(adap->fe_adap[0].fe);
1017 adap->fe_adap[0].fe = NULL; 1120 adap->fe_adap[0].fe = NULL;
@@ -1028,7 +1131,7 @@ end: if (ret) {
1028static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap) 1131static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
1029{ 1132{
1030 struct lme2510_state *st = adap->dev->priv; 1133 struct lme2510_state *st = adap->dev->priv;
1031 char *tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA"}; 1134 char *tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA", "RS2000"};
1032 int ret = 0; 1135 int ret = 0;
1033 1136
1034 switch (st->tuner_config) { 1137 switch (st->tuner_config) {
@@ -1047,6 +1150,9 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
1047 &adap->dev->i2c_adap, DVB_PLL_OPERA1)) 1150 &adap->dev->i2c_adap, DVB_PLL_OPERA1))
1048 ret = st->tuner_config; 1151 ret = st->tuner_config;
1049 break; 1152 break;
1153 case TUNER_RS2000:
1154 ret = st->tuner_config;
1155 break;
1050 default: 1156 default:
1051 break; 1157 break;
1052 } 1158 }
@@ -1075,10 +1181,9 @@ static int lme2510_powerup(struct dvb_usb_device *d, int onoff)
1075 static u8 lnb_on[] = LNB_ON; 1181 static u8 lnb_on[] = LNB_ON;
1076 static u8 lnb_off[] = LNB_OFF; 1182 static u8 lnb_off[] = LNB_OFF;
1077 static u8 rbuf[1]; 1183 static u8 rbuf[1];
1078 int ret, len = 3, rlen = 1; 1184 int ret = 0, len = 3, rlen = 1;
1079 1185
1080 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 1186 mutex_lock(&d->i2c_mutex);
1081 return -EAGAIN;
1082 1187
1083 if (onoff) 1188 if (onoff)
1084 ret = lme2510_usb_talk(d, lnb_on, len, rbuf, rlen); 1189 ret = lme2510_usb_talk(d, lnb_on, len, rbuf, rlen);
@@ -1136,6 +1241,7 @@ static int lme2510_probe(struct usb_interface *intf,
1136static struct usb_device_id lme2510_table[] = { 1241static struct usb_device_id lme2510_table[] = {
1137 { USB_DEVICE(0x3344, 0x1122) }, /* LME2510 */ 1242 { USB_DEVICE(0x3344, 0x1122) }, /* LME2510 */
1138 { USB_DEVICE(0x3344, 0x1120) }, /* LME2510C */ 1243 { USB_DEVICE(0x3344, 0x1120) }, /* LME2510C */
1244 { USB_DEVICE(0x3344, 0x22f0) }, /* LME2510C RS2000 */
1139 {} /* Terminating entry */ 1245 {} /* Terminating entry */
1140}; 1246};
1141 1247
@@ -1153,7 +1259,7 @@ static struct dvb_usb_device_properties lme2510_properties = {
1153 DVB_USB_ADAP_NEED_PID_FILTERING| 1259 DVB_USB_ADAP_NEED_PID_FILTERING|
1154 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, 1260 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1155 .streaming_ctrl = lme2510_streaming_ctrl, 1261 .streaming_ctrl = lme2510_streaming_ctrl,
1156 .pid_filter_count = 15, 1262 .pid_filter_count = 32,
1157 .pid_filter = lme2510_pid_filter, 1263 .pid_filter = lme2510_pid_filter,
1158 .pid_filter_ctrl = lme2510_pid_filter_ctrl, 1264 .pid_filter_ctrl = lme2510_pid_filter_ctrl,
1159 .frontend_attach = dm04_lme2510_frontend_attach, 1265 .frontend_attach = dm04_lme2510_frontend_attach,
@@ -1204,7 +1310,7 @@ static struct dvb_usb_device_properties lme2510c_properties = {
1204 DVB_USB_ADAP_NEED_PID_FILTERING| 1310 DVB_USB_ADAP_NEED_PID_FILTERING|
1205 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, 1311 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1206 .streaming_ctrl = lme2510_streaming_ctrl, 1312 .streaming_ctrl = lme2510_streaming_ctrl,
1207 .pid_filter_count = 15, 1313 .pid_filter_count = 32,
1208 .pid_filter = lme2510_pid_filter, 1314 .pid_filter = lme2510_pid_filter,
1209 .pid_filter_ctrl = lme2510_pid_filter_ctrl, 1315 .pid_filter_ctrl = lme2510_pid_filter_ctrl,
1210 .frontend_attach = dm04_lme2510_frontend_attach, 1316 .frontend_attach = dm04_lme2510_frontend_attach,
@@ -1234,11 +1340,14 @@ static struct dvb_usb_device_properties lme2510c_properties = {
1234 .identify_state = lme2510_identify_state, 1340 .identify_state = lme2510_identify_state,
1235 .i2c_algo = &lme2510_i2c_algo, 1341 .i2c_algo = &lme2510_i2c_algo,
1236 .generic_bulk_ctrl_endpoint = 0, 1342 .generic_bulk_ctrl_endpoint = 0,
1237 .num_device_descs = 1, 1343 .num_device_descs = 2,
1238 .devices = { 1344 .devices = {
1239 { "DM04_LME2510C_DVB-S", 1345 { "DM04_LME2510C_DVB-S",
1240 { &lme2510_table[1], NULL }, 1346 { &lme2510_table[1], NULL },
1241 }, 1347 },
1348 { "DM04_LME2510C_DVB-S RS2000",
1349 { &lme2510_table[2], NULL },
1350 },
1242 } 1351 }
1243}; 1352};
1244 1353
@@ -1295,5 +1404,5 @@ module_usb_driver(lme2510_driver);
1295 1404
1296MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); 1405MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
1297MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0"); 1406MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0");
1298MODULE_VERSION("1.91"); 1407MODULE_VERSION("1.99");
1299MODULE_LICENSE("GPL"); 1408MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.h b/drivers/media/dvb/dvb-usb/lmedm04.h
index ab21e2ef53fa..e9c207205c2f 100644
--- a/drivers/media/dvb/dvb-usb/lmedm04.h
+++ b/drivers/media/dvb/dvb-usb/lmedm04.h
@@ -41,6 +41,7 @@
41#define LME_ST_ON_W {0x06, 0x00} 41#define LME_ST_ON_W {0x06, 0x00}
42#define LME_CLEAR_PID {0x03, 0x02, 0x20, 0xa0} 42#define LME_CLEAR_PID {0x03, 0x02, 0x20, 0xa0}
43#define LME_ZERO_PID {0x03, 0x06, 0x00, 0x00, 0x01, 0x00, 0x20, 0x9c} 43#define LME_ZERO_PID {0x03, 0x06, 0x00, 0x00, 0x01, 0x00, 0x20, 0x9c}
44#define LME_ALL_PIDS {0x03, 0x06, 0x00, 0xff, 0x01, 0x1f, 0x20, 0x81}
44 45
45/* LNB Voltage 46/* LNB Voltage
46 * 07 XX XX 47 * 07 XX XX
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf.c b/drivers/media/dvb/dvb-usb/mxl111sf.c
index 38ef0253d3b5..81305de2fea5 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf.c
+++ b/drivers/media/dvb/dvb-usb/mxl111sf.c
@@ -351,15 +351,13 @@ static int mxl111sf_ep6_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
351 adap_state->ep6_clockphase, 351 adap_state->ep6_clockphase,
352 0, 0); 352 0, 0);
353 mxl_fail(ret); 353 mxl_fail(ret);
354#if 0
354 } else { 355 } else {
355 ret = mxl111sf_disable_656_port(state); 356 ret = mxl111sf_disable_656_port(state);
356 mxl_fail(ret); 357 mxl_fail(ret);
358#endif
357 } 359 }
358 360
359 mxl111sf_read_reg(state, 0x12, &tmp);
360 tmp &= ~0x04;
361 mxl111sf_write_reg(state, 0x12, tmp);
362
363 return ret; 361 return ret;
364} 362}
365 363
diff --git a/drivers/media/dvb/dvb-usb/rtl28xxu.c b/drivers/media/dvb/dvb-usb/rtl28xxu.c
new file mode 100644
index 000000000000..8f4736a10fc8
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/rtl28xxu.c
@@ -0,0 +1,982 @@
1/*
2 * Realtek RTL28xxU DVB USB driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#include "rtl28xxu.h"
23
24#include "rtl2830.h"
25
26#include "qt1010.h"
27#include "mt2060.h"
28#include "mxl5005s.h"
29
30/* debug */
31static int dvb_usb_rtl28xxu_debug;
32module_param_named(debug, dvb_usb_rtl28xxu_debug, int, 0644);
33MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
34DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
35
36static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req)
37{
38 int ret;
39 unsigned int pipe;
40 u8 requesttype;
41 u8 *buf;
42
43 buf = kmalloc(req->size, GFP_KERNEL);
44 if (!buf) {
45 ret = -ENOMEM;
46 goto err;
47 }
48
49 if (req->index & CMD_WR_FLAG) {
50 /* write */
51 memcpy(buf, req->data, req->size);
52 requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
53 pipe = usb_sndctrlpipe(d->udev, 0);
54 } else {
55 /* read */
56 requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
57 pipe = usb_rcvctrlpipe(d->udev, 0);
58 }
59
60 ret = usb_control_msg(d->udev, pipe, 0, requesttype, req->value,
61 req->index, buf, req->size, 1000);
62 if (ret > 0)
63 ret = 0;
64
65 deb_dump(0, requesttype, req->value, req->index, buf, req->size,
66 deb_xfer);
67
68 /* read request, copy returned data to return buf */
69 if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
70 memcpy(req->data, buf, req->size);
71
72 kfree(buf);
73
74 if (ret)
75 goto err;
76
77 return ret;
78err:
79 deb_info("%s: failed=%d\n", __func__, ret);
80 return ret;
81}
82
83static int rtl2831_wr_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int len)
84{
85 struct rtl28xxu_req req;
86
87 if (reg < 0x3000)
88 req.index = CMD_USB_WR;
89 else if (reg < 0x4000)
90 req.index = CMD_SYS_WR;
91 else
92 req.index = CMD_IR_WR;
93
94 req.value = reg;
95 req.size = len;
96 req.data = val;
97
98 return rtl28xxu_ctrl_msg(d, &req);
99}
100
101static int rtl2831_rd_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int len)
102{
103 struct rtl28xxu_req req;
104
105 if (reg < 0x3000)
106 req.index = CMD_USB_RD;
107 else if (reg < 0x4000)
108 req.index = CMD_SYS_RD;
109 else
110 req.index = CMD_IR_RD;
111
112 req.value = reg;
113 req.size = len;
114 req.data = val;
115
116 return rtl28xxu_ctrl_msg(d, &req);
117}
118
119static int rtl2831_wr_reg(struct dvb_usb_device *d, u16 reg, u8 val)
120{
121 return rtl2831_wr_regs(d, reg, &val, 1);
122}
123
124static int rtl2831_rd_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
125{
126 return rtl2831_rd_regs(d, reg, val, 1);
127}
128
129/* I2C */
130static int rtl28xxu_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
131 int num)
132{
133 int ret;
134 struct dvb_usb_device *d = i2c_get_adapdata(adap);
135 struct rtl28xxu_priv *priv = d->priv;
136 struct rtl28xxu_req req;
137
138 /*
139 * It is not known which are real I2C bus xfer limits, but testing
140 * with RTL2831U + MT2060 gives max RD 24 and max WR 22 bytes.
141 * TODO: find out RTL2832U lens
142 */
143
144 /*
145 * I2C adapter logic looks rather complicated due to fact it handles
146 * three different access methods. Those methods are;
147 * 1) integrated demod access
148 * 2) old I2C access
149 * 3) new I2C access
150 *
151 * Used method is selected in order 1, 2, 3. Method 3 can handle all
152 * requests but there is two reasons why not use it always;
153 * 1) It is most expensive, usually two USB messages are needed
154 * 2) At least RTL2831U does not support it
155 *
156 * Method 3 is needed in case of I2C write+read (typical register read)
157 * where write is more than one byte.
158 */
159
160 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
161 return -EAGAIN;
162
163 if (num == 2 && !(msg[0].flags & I2C_M_RD) &&
164 (msg[1].flags & I2C_M_RD)) {
165 if (msg[0].len > 24 || msg[1].len > 24) {
166 /* TODO: check msg[0].len max */
167 ret = -EOPNOTSUPP;
168 goto err_mutex_unlock;
169 } else if (msg[0].addr == 0x10) {
170 /* method 1 - integrated demod */
171 req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1);
172 req.index = CMD_DEMOD_RD | priv->page;
173 req.size = msg[1].len;
174 req.data = &msg[1].buf[0];
175 ret = rtl28xxu_ctrl_msg(d, &req);
176 } else if (msg[0].len < 2) {
177 /* method 2 - old I2C */
178 req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1);
179 req.index = CMD_I2C_RD;
180 req.size = msg[1].len;
181 req.data = &msg[1].buf[0];
182 ret = rtl28xxu_ctrl_msg(d, &req);
183 } else {
184 /* method 3 - new I2C */
185 req.value = (msg[0].addr << 1);
186 req.index = CMD_I2C_DA_WR;
187 req.size = msg[0].len;
188 req.data = msg[0].buf;
189 ret = rtl28xxu_ctrl_msg(d, &req);
190 if (ret)
191 goto err_mutex_unlock;
192
193 req.value = (msg[0].addr << 1);
194 req.index = CMD_I2C_DA_RD;
195 req.size = msg[1].len;
196 req.data = msg[1].buf;
197 ret = rtl28xxu_ctrl_msg(d, &req);
198 }
199 } else if (num == 1 && !(msg[0].flags & I2C_M_RD)) {
200 if (msg[0].len > 22) {
201 /* TODO: check msg[0].len max */
202 ret = -EOPNOTSUPP;
203 goto err_mutex_unlock;
204 } else if (msg[0].addr == 0x10) {
205 /* method 1 - integrated demod */
206 if (msg[0].buf[0] == 0x00) {
207 /* save demod page for later demod access */
208 priv->page = msg[0].buf[1];
209 ret = 0;
210 } else {
211 req.value = (msg[0].buf[0] << 8) |
212 (msg[0].addr << 1);
213 req.index = CMD_DEMOD_WR | priv->page;
214 req.size = msg[0].len-1;
215 req.data = &msg[0].buf[1];
216 ret = rtl28xxu_ctrl_msg(d, &req);
217 }
218 } else if (msg[0].len < 23) {
219 /* method 2 - old I2C */
220 req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1);
221 req.index = CMD_I2C_WR;
222 req.size = msg[0].len-1;
223 req.data = &msg[0].buf[1];
224 ret = rtl28xxu_ctrl_msg(d, &req);
225 } else {
226 /* method 3 - new I2C */
227 req.value = (msg[0].addr << 1);
228 req.index = CMD_I2C_DA_WR;
229 req.size = msg[0].len;
230 req.data = msg[0].buf;
231 ret = rtl28xxu_ctrl_msg(d, &req);
232 }
233 } else {
234 ret = -EINVAL;
235 }
236
237err_mutex_unlock:
238 mutex_unlock(&d->i2c_mutex);
239
240 return ret ? ret : num;
241}
242
243static u32 rtl28xxu_i2c_func(struct i2c_adapter *adapter)
244{
245 return I2C_FUNC_I2C;
246}
247
248static struct i2c_algorithm rtl28xxu_i2c_algo = {
249 .master_xfer = rtl28xxu_i2c_xfer,
250 .functionality = rtl28xxu_i2c_func,
251};
252
253static struct rtl2830_config rtl28xxu_rtl2830_mt2060_config = {
254 .i2c_addr = 0x10, /* 0x20 */
255 .xtal = 28800000,
256 .ts_mode = 0,
257 .spec_inv = 1,
258 .if_dvbt = 36150000,
259 .vtop = 0x20,
260 .krf = 0x04,
261 .agc_targ_val = 0x2d,
262
263};
264
265static struct rtl2830_config rtl28xxu_rtl2830_qt1010_config = {
266 .i2c_addr = 0x10, /* 0x20 */
267 .xtal = 28800000,
268 .ts_mode = 0,
269 .spec_inv = 1,
270 .if_dvbt = 36125000,
271 .vtop = 0x20,
272 .krf = 0x04,
273 .agc_targ_val = 0x2d,
274};
275
276static struct rtl2830_config rtl28xxu_rtl2830_mxl5005s_config = {
277 .i2c_addr = 0x10, /* 0x20 */
278 .xtal = 28800000,
279 .ts_mode = 0,
280 .spec_inv = 0,
281 .if_dvbt = 4570000,
282 .vtop = 0x3f,
283 .krf = 0x04,
284 .agc_targ_val = 0x3e,
285};
286
287static int rtl2831u_frontend_attach(struct dvb_usb_adapter *adap)
288{
289 int ret;
290 struct rtl28xxu_priv *priv = adap->dev->priv;
291 u8 buf[1];
292 struct rtl2830_config *rtl2830_config;
293 /* open RTL2831U/RTL2830 I2C gate */
294 struct rtl28xxu_req req_gate = { 0x0120, 0x0011, 0x0001, "\x08" };
295 /* for MT2060 tuner probe */
296 struct rtl28xxu_req req_mt2060 = { 0x00c0, CMD_I2C_RD, 1, buf };
297 /* for QT1010 tuner probe */
298 struct rtl28xxu_req req_qt1010 = { 0x0fc4, CMD_I2C_RD, 1, buf };
299
300 deb_info("%s:\n", __func__);
301
302 /*
303 * RTL2831U GPIOs
304 * =========================================================
305 * GPIO0 | tuner#0 | 0 off | 1 on | MXL5005S (?)
306 * GPIO2 | LED | 0 off | 1 on |
307 * GPIO4 | tuner#1 | 0 on | 1 off | MT2060
308 */
309
310 /* GPIO direction */
311 ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_DIR, 0x0a);
312 if (ret)
313 goto err;
314
315 /* enable as output GPIO0, GPIO2, GPIO4 */
316 ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_OUT_EN, 0x15);
317 if (ret)
318 goto err;
319
320 /*
321 * Probe used tuner. We need to know used tuner before demod attach
322 * since there is some demod params needed to set according to tuner.
323 */
324
325 /* open demod I2C gate */
326 ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate);
327 if (ret)
328 goto err;
329
330 /* check QT1010 ID(?) register; reg=0f val=2c */
331 ret = rtl28xxu_ctrl_msg(adap->dev, &req_qt1010);
332 if (ret == 0 && buf[0] == 0x2c) {
333 priv->tuner = TUNER_RTL2830_QT1010;
334 rtl2830_config = &rtl28xxu_rtl2830_qt1010_config;
335 deb_info("%s: QT1010\n", __func__);
336 goto found;
337 } else {
338 deb_info("%s: QT1010 probe failed=%d - %02x\n",
339 __func__, ret, buf[0]);
340 }
341
342 /* open demod I2C gate */
343 ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate);
344 if (ret)
345 goto err;
346
347 /* check MT2060 ID register; reg=00 val=63 */
348 ret = rtl28xxu_ctrl_msg(adap->dev, &req_mt2060);
349 if (ret == 0 && buf[0] == 0x63) {
350 priv->tuner = TUNER_RTL2830_MT2060;
351 rtl2830_config = &rtl28xxu_rtl2830_mt2060_config;
352 deb_info("%s: MT2060\n", __func__);
353 goto found;
354 } else {
355 deb_info("%s: MT2060 probe failed=%d - %02x\n",
356 __func__, ret, buf[0]);
357 }
358
359 /* assume MXL5005S */
360 ret = 0;
361 priv->tuner = TUNER_RTL2830_MXL5005S;
362 rtl2830_config = &rtl28xxu_rtl2830_mxl5005s_config;
363 deb_info("%s: MXL5005S\n", __func__);
364 goto found;
365
366found:
367 /* attach demodulator */
368 adap->fe_adap[0].fe = dvb_attach(rtl2830_attach, rtl2830_config,
369 &adap->dev->i2c_adap);
370 if (adap->fe_adap[0].fe == NULL) {
371 ret = -ENODEV;
372 goto err;
373 }
374
375 return ret;
376err:
377 deb_info("%s: failed=%d\n", __func__, ret);
378 return ret;
379}
380
381static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
382{
383 int ret;
384 struct rtl28xxu_priv *priv = adap->dev->priv;
385 u8 buf[1];
386 /* open RTL2832U/RTL2832 I2C gate */
387 struct rtl28xxu_req req_gate_open = {0x0120, 0x0011, 0x0001, "\x18"};
388 /* close RTL2832U/RTL2832 I2C gate */
389 struct rtl28xxu_req req_gate_close = {0x0120, 0x0011, 0x0001, "\x10"};
390 /* for FC2580 tuner probe */
391 struct rtl28xxu_req req_fc2580 = {0x01ac, CMD_I2C_RD, 1, buf};
392
393 deb_info("%s:\n", __func__);
394
395 /* GPIO direction */
396 ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_DIR, 0x0a);
397 if (ret)
398 goto err;
399
400 /* enable as output GPIO0, GPIO2, GPIO4 */
401 ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_OUT_EN, 0x15);
402 if (ret)
403 goto err;
404
405 ret = rtl2831_wr_reg(adap->dev, SYS_DEMOD_CTL, 0xe8);
406 if (ret)
407 goto err;
408
409 /*
410 * Probe used tuner. We need to know used tuner before demod attach
411 * since there is some demod params needed to set according to tuner.
412 */
413
414 /* open demod I2C gate */
415 ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate_open);
416 if (ret)
417 goto err;
418
419 /* check FC2580 ID register; reg=01 val=56 */
420 ret = rtl28xxu_ctrl_msg(adap->dev, &req_fc2580);
421 if (ret == 0 && buf[0] == 0x56) {
422 priv->tuner = TUNER_RTL2832_FC2580;
423 deb_info("%s: FC2580\n", __func__);
424 goto found;
425 } else {
426 deb_info("%s: FC2580 probe failed=%d - %02x\n",
427 __func__, ret, buf[0]);
428 }
429
430 /* close demod I2C gate */
431 ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate_close);
432 if (ret)
433 goto err;
434
435 /* tuner not found */
436 ret = -ENODEV;
437 goto err;
438
439found:
440 /* close demod I2C gate */
441 ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate_close);
442 if (ret)
443 goto err;
444
445 /* attach demodulator */
446 /* TODO: */
447
448 return ret;
449err:
450 deb_info("%s: failed=%d\n", __func__, ret);
451 return ret;
452}
453
454static struct qt1010_config rtl28xxu_qt1010_config = {
455 .i2c_address = 0x62, /* 0xc4 */
456};
457
458static struct mt2060_config rtl28xxu_mt2060_config = {
459 .i2c_address = 0x60, /* 0xc0 */
460 .clock_out = 0,
461};
462
463static struct mxl5005s_config rtl28xxu_mxl5005s_config = {
464 .i2c_address = 0x63, /* 0xc6 */
465 .if_freq = IF_FREQ_4570000HZ,
466 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
467 .agc_mode = MXL_SINGLE_AGC,
468 .tracking_filter = MXL_TF_C_H,
469 .rssi_enable = MXL_RSSI_ENABLE,
470 .cap_select = MXL_CAP_SEL_ENABLE,
471 .div_out = MXL_DIV_OUT_4,
472 .clock_out = MXL_CLOCK_OUT_DISABLE,
473 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
474 .top = MXL5005S_TOP_25P2,
475 .mod_mode = MXL_DIGITAL_MODE,
476 .if_mode = MXL_ZERO_IF,
477 .AgcMasterByte = 0x00,
478};
479
480static int rtl2831u_tuner_attach(struct dvb_usb_adapter *adap)
481{
482 int ret;
483 struct rtl28xxu_priv *priv = adap->dev->priv;
484 struct i2c_adapter *rtl2830_tuner_i2c;
485 struct dvb_frontend *fe;
486
487 deb_info("%s:\n", __func__);
488
489 /* use rtl2830 driver I2C adapter, for more info see rtl2830 driver */
490 rtl2830_tuner_i2c = rtl2830_get_tuner_i2c_adapter(adap->fe_adap[0].fe);
491
492 switch (priv->tuner) {
493 case TUNER_RTL2830_QT1010:
494 fe = dvb_attach(qt1010_attach, adap->fe_adap[0].fe,
495 rtl2830_tuner_i2c, &rtl28xxu_qt1010_config);
496 break;
497 case TUNER_RTL2830_MT2060:
498 fe = dvb_attach(mt2060_attach, adap->fe_adap[0].fe,
499 rtl2830_tuner_i2c, &rtl28xxu_mt2060_config,
500 1220);
501 break;
502 case TUNER_RTL2830_MXL5005S:
503 fe = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe,
504 rtl2830_tuner_i2c, &rtl28xxu_mxl5005s_config);
505 break;
506 default:
507 fe = NULL;
508 err("unknown tuner=%d", priv->tuner);
509 }
510
511 if (fe == NULL) {
512 ret = -ENODEV;
513 goto err;
514 }
515
516 return 0;
517err:
518 deb_info("%s: failed=%d\n", __func__, ret);
519 return ret;
520}
521
522static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
523{
524 int ret;
525 struct rtl28xxu_priv *priv = adap->dev->priv;
526 struct dvb_frontend *fe;
527
528 deb_info("%s:\n", __func__);
529
530 switch (priv->tuner) {
531 case TUNER_RTL2832_FC2580:
532 /* TODO: */
533 fe = NULL;
534 break;
535 default:
536 fe = NULL;
537 err("unknown tuner=%d", priv->tuner);
538 }
539
540 if (fe == NULL) {
541 ret = -ENODEV;
542 goto err;
543 }
544
545 return 0;
546err:
547 deb_info("%s: failed=%d\n", __func__, ret);
548 return ret;
549}
550
551static int rtl28xxu_streaming_ctrl(struct dvb_usb_adapter *adap , int onoff)
552{
553 int ret;
554 u8 buf[2], gpio;
555
556 deb_info("%s: onoff=%d\n", __func__, onoff);
557
558 ret = rtl2831_rd_reg(adap->dev, SYS_GPIO_OUT_VAL, &gpio);
559 if (ret)
560 goto err;
561
562 if (onoff) {
563 buf[0] = 0x00;
564 buf[1] = 0x00;
565 gpio |= 0x04; /* LED on */
566 } else {
567 buf[0] = 0x10; /* stall EPA */
568 buf[1] = 0x02; /* reset EPA */
569 gpio &= (~0x04); /* LED off */
570 }
571
572 ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_OUT_VAL, gpio);
573 if (ret)
574 goto err;
575
576 ret = rtl2831_wr_regs(adap->dev, USB_EPA_CTL, buf, 2);
577 if (ret)
578 goto err;
579
580 return ret;
581err:
582 deb_info("%s: failed=%d\n", __func__, ret);
583 return ret;
584}
585
586static int rtl28xxu_power_ctrl(struct dvb_usb_device *d, int onoff)
587{
588 int ret;
589 u8 gpio, sys0;
590
591 deb_info("%s: onoff=%d\n", __func__, onoff);
592
593 /* demod adc */
594 ret = rtl2831_rd_reg(d, SYS_SYS0, &sys0);
595 if (ret)
596 goto err;
597
598 /* tuner power, read GPIOs */
599 ret = rtl2831_rd_reg(d, SYS_GPIO_OUT_VAL, &gpio);
600 if (ret)
601 goto err;
602
603 deb_info("%s: RD SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__, sys0, gpio);
604
605 if (onoff) {
606 gpio |= 0x01; /* GPIO0 = 1 */
607 gpio &= (~0x10); /* GPIO4 = 0 */
608 sys0 = sys0 & 0x0f;
609 sys0 |= 0xe0;
610 } else {
611 gpio &= (~0x01); /* GPIO0 = 0 */
612 gpio |= 0x10; /* GPIO4 = 1 */
613 sys0 = sys0 & (~0xc0);
614 }
615
616 deb_info("%s: WR SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__, sys0, gpio);
617
618 /* demod adc */
619 ret = rtl2831_wr_reg(d, SYS_SYS0, sys0);
620 if (ret)
621 goto err;
622
623 /* tuner power, write GPIOs */
624 ret = rtl2831_wr_reg(d, SYS_GPIO_OUT_VAL, gpio);
625 if (ret)
626 goto err;
627
628 return ret;
629err:
630 deb_info("%s: failed=%d\n", __func__, ret);
631 return ret;
632}
633
634static int rtl2831u_rc_query(struct dvb_usb_device *d)
635{
636 int ret, i;
637 struct rtl28xxu_priv *priv = d->priv;
638 u8 buf[5];
639 u32 rc_code;
640 struct rtl28xxu_reg_val rc_nec_tab[] = {
641 { 0x3033, 0x80 },
642 { 0x3020, 0x43 },
643 { 0x3021, 0x16 },
644 { 0x3022, 0x16 },
645 { 0x3023, 0x5a },
646 { 0x3024, 0x2d },
647 { 0x3025, 0x16 },
648 { 0x3026, 0x01 },
649 { 0x3028, 0xb0 },
650 { 0x3029, 0x04 },
651 { 0x302c, 0x88 },
652 { 0x302e, 0x13 },
653 { 0x3030, 0xdf },
654 { 0x3031, 0x05 },
655 };
656
657 /* init remote controller */
658 if (!priv->rc_active) {
659 for (i = 0; i < ARRAY_SIZE(rc_nec_tab); i++) {
660 ret = rtl2831_wr_reg(d, rc_nec_tab[i].reg,
661 rc_nec_tab[i].val);
662 if (ret)
663 goto err;
664 }
665 priv->rc_active = true;
666 }
667
668 ret = rtl2831_rd_regs(d, SYS_IRRC_RP, buf, 5);
669 if (ret)
670 goto err;
671
672 if (buf[4] & 0x01) {
673 if (buf[2] == (u8) ~buf[3]) {
674 if (buf[0] == (u8) ~buf[1]) {
675 /* NEC standard (16 bit) */
676 rc_code = buf[0] << 8 | buf[2];
677 } else {
678 /* NEC extended (24 bit) */
679 rc_code = buf[0] << 16 |
680 buf[1] << 8 | buf[2];
681 }
682 } else {
683 /* NEC full (32 bit) */
684 rc_code = buf[0] << 24 | buf[1] << 16 |
685 buf[2] << 8 | buf[3];
686 }
687
688 rc_keydown(d->rc_dev, rc_code, 0);
689
690 ret = rtl2831_wr_reg(d, SYS_IRRC_SR, 1);
691 if (ret)
692 goto err;
693
694 /* repeated intentionally to avoid extra keypress */
695 ret = rtl2831_wr_reg(d, SYS_IRRC_SR, 1);
696 if (ret)
697 goto err;
698 }
699
700 return ret;
701err:
702 deb_info("%s: failed=%d\n", __func__, ret);
703 return ret;
704}
705
706static int rtl2832u_rc_query(struct dvb_usb_device *d)
707{
708 int ret, i;
709 struct rtl28xxu_priv *priv = d->priv;
710 u8 buf[128];
711 int len;
712 struct rtl28xxu_reg_val rc_nec_tab[] = {
713 { IR_RX_CTRL, 0x20 },
714 { IR_RX_BUF_CTRL, 0x80 },
715 { IR_RX_IF, 0xff },
716 { IR_RX_IE, 0xff },
717 { IR_MAX_DURATION0, 0xd0 },
718 { IR_MAX_DURATION1, 0x07 },
719 { IR_IDLE_LEN0, 0xc0 },
720 { IR_IDLE_LEN1, 0x00 },
721 { IR_GLITCH_LEN, 0x03 },
722 { IR_RX_CLK, 0x09 },
723 { IR_RX_CFG, 0x1c },
724 { IR_MAX_H_TOL_LEN, 0x1e },
725 { IR_MAX_L_TOL_LEN, 0x1e },
726 { IR_RX_CTRL, 0x80 },
727 };
728
729 /* init remote controller */
730 if (!priv->rc_active) {
731 for (i = 0; i < ARRAY_SIZE(rc_nec_tab); i++) {
732 ret = rtl2831_wr_reg(d, rc_nec_tab[i].reg,
733 rc_nec_tab[i].val);
734 if (ret)
735 goto err;
736 }
737 priv->rc_active = true;
738 }
739
740 ret = rtl2831_rd_reg(d, IR_RX_IF, &buf[0]);
741 if (ret)
742 goto err;
743
744 if (buf[0] != 0x83)
745 goto exit;
746
747 ret = rtl2831_rd_reg(d, IR_RX_BC, &buf[0]);
748 if (ret)
749 goto err;
750
751 len = buf[0];
752 ret = rtl2831_rd_regs(d, IR_RX_BUF, buf, len);
753
754 /* TODO: pass raw IR to Kernel IR decoder */
755
756 ret = rtl2831_wr_reg(d, IR_RX_IF, 0x03);
757 ret = rtl2831_wr_reg(d, IR_RX_BUF_CTRL, 0x80);
758 ret = rtl2831_wr_reg(d, IR_RX_CTRL, 0x80);
759
760exit:
761 return ret;
762err:
763 deb_info("%s: failed=%d\n", __func__, ret);
764 return ret;
765}
766
767enum rtl28xxu_usb_table_entry {
768 RTL2831U_0BDA_2831,
769 RTL2831U_14AA_0160,
770 RTL2831U_14AA_0161,
771};
772
773static struct usb_device_id rtl28xxu_table[] = {
774 /* RTL2831U */
775 [RTL2831U_0BDA_2831] = {
776 USB_DEVICE(USB_VID_REALTEK, USB_PID_REALTEK_RTL2831U)},
777 [RTL2831U_14AA_0160] = {
778 USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_FREECOM_DVBT)},
779 [RTL2831U_14AA_0161] = {
780 USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_FREECOM_DVBT_2)},
781
782 /* RTL2832U */
783 {} /* terminating entry */
784};
785
786MODULE_DEVICE_TABLE(usb, rtl28xxu_table);
787
788static struct dvb_usb_device_properties rtl28xxu_properties[] = {
789 {
790 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
791
792 .usb_ctrl = DEVICE_SPECIFIC,
793 .no_reconnect = 1,
794
795 .size_of_priv = sizeof(struct rtl28xxu_priv),
796
797 .num_adapters = 1,
798 .adapter = {
799 {
800 .num_frontends = 1,
801 .fe = {
802 {
803 .frontend_attach = rtl2831u_frontend_attach,
804 .tuner_attach = rtl2831u_tuner_attach,
805 .streaming_ctrl = rtl28xxu_streaming_ctrl,
806 .stream = {
807 .type = USB_BULK,
808 .count = 6,
809 .endpoint = 0x81,
810 .u = {
811 .bulk = {
812 .buffersize = 8*512,
813 }
814 }
815 }
816 }
817 }
818 }
819 },
820
821 .power_ctrl = rtl28xxu_power_ctrl,
822
823 .rc.core = {
824 .protocol = RC_TYPE_NEC,
825 .module_name = "rtl28xxu",
826 .rc_query = rtl2831u_rc_query,
827 .rc_interval = 400,
828 .allowed_protos = RC_TYPE_NEC,
829 .rc_codes = RC_MAP_EMPTY,
830 },
831
832 .i2c_algo = &rtl28xxu_i2c_algo,
833
834 .num_device_descs = 2,
835 .devices = {
836 {
837 .name = "Realtek RTL2831U reference design",
838 .warm_ids = {
839 &rtl28xxu_table[RTL2831U_0BDA_2831],
840 },
841 },
842 {
843 .name = "Freecom USB2.0 DVB-T",
844 .warm_ids = {
845 &rtl28xxu_table[RTL2831U_14AA_0160],
846 &rtl28xxu_table[RTL2831U_14AA_0161],
847 },
848 },
849 }
850 },
851 {
852 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
853
854 .usb_ctrl = DEVICE_SPECIFIC,
855 .no_reconnect = 1,
856
857 .size_of_priv = sizeof(struct rtl28xxu_priv),
858
859 .num_adapters = 1,
860 .adapter = {
861 {
862 .num_frontends = 1,
863 .fe = {
864 {
865 .frontend_attach = rtl2832u_frontend_attach,
866 .tuner_attach = rtl2832u_tuner_attach,
867 .streaming_ctrl = rtl28xxu_streaming_ctrl,
868 .stream = {
869 .type = USB_BULK,
870 .count = 6,
871 .endpoint = 0x81,
872 .u = {
873 .bulk = {
874 .buffersize = 8*512,
875 }
876 }
877 }
878 }
879 }
880 }
881 },
882
883 .power_ctrl = rtl28xxu_power_ctrl,
884
885 .rc.core = {
886 .protocol = RC_TYPE_NEC,
887 .module_name = "rtl28xxu",
888 .rc_query = rtl2832u_rc_query,
889 .rc_interval = 400,
890 .allowed_protos = RC_TYPE_NEC,
891 .rc_codes = RC_MAP_EMPTY,
892 },
893
894 .i2c_algo = &rtl28xxu_i2c_algo,
895
896 .num_device_descs = 0, /* disabled as no support for RTL2832 */
897 .devices = {
898 {
899 .name = "Realtek RTL2832U reference design",
900 },
901 }
902 },
903
904};
905
906static int rtl28xxu_probe(struct usb_interface *intf,
907 const struct usb_device_id *id)
908{
909 int ret, i;
910 int properties_count = ARRAY_SIZE(rtl28xxu_properties);
911 struct dvb_usb_device *d;
912
913 deb_info("%s: interface=%d\n", __func__,
914 intf->cur_altsetting->desc.bInterfaceNumber);
915
916 if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
917 return 0;
918
919 for (i = 0; i < properties_count; i++) {
920 ret = dvb_usb_device_init(intf, &rtl28xxu_properties[i],
921 THIS_MODULE, &d, adapter_nr);
922 if (ret == 0 || ret != -ENODEV)
923 break;
924 }
925
926 if (ret)
927 goto err;
928
929 /* init USB endpoints */
930 ret = rtl2831_wr_reg(d, USB_SYSCTL_0, 0x09);
931 if (ret)
932 goto err;
933
934 ret = rtl2831_wr_regs(d, USB_EPA_MAXPKT, "\x00\x02\x00\x00", 4);
935 if (ret)
936 goto err;
937
938 ret = rtl2831_wr_regs(d, USB_EPA_FIFO_CFG, "\x14\x00\x00\x00", 4);
939 if (ret)
940 goto err;
941
942 return ret;
943err:
944 deb_info("%s: failed=%d\n", __func__, ret);
945 return ret;
946}
947
948static struct usb_driver rtl28xxu_driver = {
949 .name = "dvb_usb_rtl28xxu",
950 .probe = rtl28xxu_probe,
951 .disconnect = dvb_usb_device_exit,
952 .id_table = rtl28xxu_table,
953};
954
955/* module stuff */
956static int __init rtl28xxu_module_init(void)
957{
958 int ret;
959
960 deb_info("%s:\n", __func__);
961
962 ret = usb_register(&rtl28xxu_driver);
963 if (ret)
964 err("usb_register failed=%d", ret);
965
966 return ret;
967}
968
969static void __exit rtl28xxu_module_exit(void)
970{
971 deb_info("%s:\n", __func__);
972
973 /* deregister this driver from the USB subsystem */
974 usb_deregister(&rtl28xxu_driver);
975}
976
977module_init(rtl28xxu_module_init);
978module_exit(rtl28xxu_module_exit);
979
980MODULE_DESCRIPTION("Realtek RTL28xxU DVB USB driver");
981MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
982MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/rtl28xxu.h b/drivers/media/dvb/dvb-usb/rtl28xxu.h
new file mode 100644
index 000000000000..90f3bb4f4c0e
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/rtl28xxu.h
@@ -0,0 +1,264 @@
1/*
2 * Realtek RTL28xxU DVB USB driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#ifndef RTL28XXU_H
23#define RTL28XXU_H
24
25#define DVB_USB_LOG_PREFIX "rtl28xxu"
26#include "dvb-usb.h"
27
28#define deb_info(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x01, args)
29#define deb_rc(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x02, args)
30#define deb_xfer(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x04, args)
31#define deb_reg(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x08, args)
32#define deb_i2c(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x10, args)
33#define deb_fw(args...) dprintk(dvb_usb_rtl28xxu_debug, 0x20, args)
34
35#define deb_dump(r, t, v, i, b, l, func) { \
36 int loop_; \
37 func("%02x %02x %02x %02x %02x %02x %02x %02x", \
38 t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, l & 0xff, l >> 8); \
39 if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
40 func(" >>> "); \
41 else \
42 func(" <<< "); \
43 for (loop_ = 0; loop_ < l; loop_++) \
44 func("%02x ", b[loop_]); \
45 func("\n");\
46}
47
48/*
49 * USB commands
50 * (usb_control_msg() index parameter)
51 */
52
53#define DEMOD 0x0000
54#define USB 0x0100
55#define SYS 0x0200
56#define I2C 0x0300
57#define I2C_DA 0x0600
58
59#define CMD_WR_FLAG 0x0010
60#define CMD_DEMOD_RD 0x0000
61#define CMD_DEMOD_WR 0x0010
62#define CMD_USB_RD 0x0100
63#define CMD_USB_WR 0x0110
64#define CMD_SYS_RD 0x0200
65#define CMD_IR_RD 0x0201
66#define CMD_IR_WR 0x0211
67#define CMD_SYS_WR 0x0210
68#define CMD_I2C_RD 0x0300
69#define CMD_I2C_WR 0x0310
70#define CMD_I2C_DA_RD 0x0600
71#define CMD_I2C_DA_WR 0x0610
72
73
74struct rtl28xxu_priv {
75 u8 chip_id;
76 u8 tuner;
77 u8 page; /* integrated demod active register page */
78 bool rc_active;
79};
80
81enum rtl28xxu_chip_id {
82 CHIP_ID_NONE,
83 CHIP_ID_RTL2831U,
84 CHIP_ID_RTL2832U,
85};
86
87enum rtl28xxu_tuner {
88 TUNER_NONE,
89
90 TUNER_RTL2830_QT1010,
91 TUNER_RTL2830_MT2060,
92 TUNER_RTL2830_MXL5005S,
93
94 TUNER_RTL2832_MT2266,
95 TUNER_RTL2832_FC2580,
96 TUNER_RTL2832_MT2063,
97 TUNER_RTL2832_MAX3543,
98 TUNER_RTL2832_TUA9001,
99 TUNER_RTL2832_MXL5007T,
100 TUNER_RTL2832_FC0012,
101 TUNER_RTL2832_E4000,
102 TUNER_RTL2832_TDA18272,
103 TUNER_RTL2832_FC0013,
104};
105
106struct rtl28xxu_req {
107 u16 value;
108 u16 index;
109 u16 size;
110 u8 *data;
111};
112
113struct rtl28xxu_reg_val {
114 u16 reg;
115 u8 val;
116};
117
118/*
119 * memory map
120 *
121 * 0x0000 DEMOD : demodulator
122 * 0x2000 USB : SIE, USB endpoint, debug, DMA
123 * 0x3000 SYS : system
124 * 0xfc00 RC : remote controller (not RTL2831U)
125 */
126
127/*
128 * USB registers
129 */
130/* SIE Control Registers */
131#define USB_SYSCTL 0x2000 /* USB system control */
132#define USB_SYSCTL_0 0x2000 /* USB system control */
133#define USB_SYSCTL_1 0x2001 /* USB system control */
134#define USB_SYSCTL_2 0x2002 /* USB system control */
135#define USB_SYSCTL_3 0x2003 /* USB system control */
136#define USB_IRQSTAT 0x2008 /* SIE interrupt status */
137#define USB_IRQEN 0x200C /* SIE interrupt enable */
138#define USB_CTRL 0x2010 /* USB control */
139#define USB_STAT 0x2014 /* USB status */
140#define USB_DEVADDR 0x2018 /* USB device address */
141#define USB_TEST 0x201C /* USB test mode */
142#define USB_FRAME_NUMBER 0x2020 /* frame number */
143#define USB_FIFO_ADDR 0x2028 /* address of SIE FIFO RAM */
144#define USB_FIFO_CMD 0x202A /* SIE FIFO RAM access command */
145#define USB_FIFO_DATA 0x2030 /* SIE FIFO RAM data */
146/* Endpoint Registers */
147#define EP0_SETUPA 0x20F8 /* EP 0 setup packet lower byte */
148#define EP0_SETUPB 0x20FC /* EP 0 setup packet higher byte */
149#define USB_EP0_CFG 0x2104 /* EP 0 configure */
150#define USB_EP0_CTL 0x2108 /* EP 0 control */
151#define USB_EP0_STAT 0x210C /* EP 0 status */
152#define USB_EP0_IRQSTAT 0x2110 /* EP 0 interrupt status */
153#define USB_EP0_IRQEN 0x2114 /* EP 0 interrupt enable */
154#define USB_EP0_MAXPKT 0x2118 /* EP 0 max packet size */
155#define USB_EP0_BC 0x2120 /* EP 0 FIFO byte counter */
156#define USB_EPA_CFG 0x2144 /* EP A configure */
157#define USB_EPA_CFG_0 0x2144 /* EP A configure */
158#define USB_EPA_CFG_1 0x2145 /* EP A configure */
159#define USB_EPA_CFG_2 0x2146 /* EP A configure */
160#define USB_EPA_CFG_3 0x2147 /* EP A configure */
161#define USB_EPA_CTL 0x2148 /* EP A control */
162#define USB_EPA_CTL_0 0x2148 /* EP A control */
163#define USB_EPA_CTL_1 0x2149 /* EP A control */
164#define USB_EPA_CTL_2 0x214A /* EP A control */
165#define USB_EPA_CTL_3 0x214B /* EP A control */
166#define USB_EPA_STAT 0x214C /* EP A status */
167#define USB_EPA_IRQSTAT 0x2150 /* EP A interrupt status */
168#define USB_EPA_IRQEN 0x2154 /* EP A interrupt enable */
169#define USB_EPA_MAXPKT 0x2158 /* EP A max packet size */
170#define USB_EPA_MAXPKT_0 0x2158 /* EP A max packet size */
171#define USB_EPA_MAXPKT_1 0x2159 /* EP A max packet size */
172#define USB_EPA_MAXPKT_2 0x215A /* EP A max packet size */
173#define USB_EPA_MAXPKT_3 0x215B /* EP A max packet size */
174#define USB_EPA_FIFO_CFG 0x2160 /* EP A FIFO configure */
175#define USB_EPA_FIFO_CFG_0 0x2160 /* EP A FIFO configure */
176#define USB_EPA_FIFO_CFG_1 0x2161 /* EP A FIFO configure */
177#define USB_EPA_FIFO_CFG_2 0x2162 /* EP A FIFO configure */
178#define USB_EPA_FIFO_CFG_3 0x2163 /* EP A FIFO configure */
179/* Debug Registers */
180#define USB_PHYTSTDIS 0x2F04 /* PHY test disable */
181#define USB_TOUT_VAL 0x2F08 /* USB time-out time */
182#define USB_VDRCTRL 0x2F10 /* UTMI vendor signal control */
183#define USB_VSTAIN 0x2F14 /* UTMI vendor signal status in */
184#define USB_VLOADM 0x2F18 /* UTMI load vendor signal status in */
185#define USB_VSTAOUT 0x2F1C /* UTMI vendor signal status out */
186#define USB_UTMI_TST 0x2F80 /* UTMI test */
187#define USB_UTMI_STATUS 0x2F84 /* UTMI status */
188#define USB_TSTCTL 0x2F88 /* test control */
189#define USB_TSTCTL2 0x2F8C /* test control 2 */
190#define USB_PID_FORCE 0x2F90 /* force PID */
191#define USB_PKTERR_CNT 0x2F94 /* packet error counter */
192#define USB_RXERR_CNT 0x2F98 /* RX error counter */
193#define USB_MEM_BIST 0x2F9C /* MEM BIST test */
194#define USB_SLBBIST 0x2FA0 /* self-loop-back BIST */
195#define USB_CNTTEST 0x2FA4 /* counter test */
196#define USB_PHYTST 0x2FC0 /* USB PHY test */
197#define USB_DBGIDX 0x2FF0 /* select individual block debug signal */
198#define USB_DBGMUX 0x2FF4 /* debug signal module mux */
199
200/*
201 * SYS registers
202 */
203/* demod control registers */
204#define SYS_SYS0 0x3000 /* include DEMOD_CTL, GPO, GPI, GPOE */
205#define SYS_DEMOD_CTL 0x3000 /* control register for DVB-T demodulator */
206/* GPIO registers */
207#define SYS_GPIO_OUT_VAL 0x3001 /* output value of GPIO */
208#define SYS_GPIO_IN_VAL 0x3002 /* input value of GPIO */
209#define SYS_GPIO_OUT_EN 0x3003 /* output enable of GPIO */
210#define SYS_SYS1 0x3004 /* include GPD, SYSINTE, SYSINTS, GP_CFG0 */
211#define SYS_GPIO_DIR 0x3004 /* direction control for GPIO */
212#define SYS_SYSINTE 0x3005 /* system interrupt enable */
213#define SYS_SYSINTS 0x3006 /* system interrupt status */
214#define SYS_GPIO_CFG0 0x3007 /* PAD configuration for GPIO0-GPIO3 */
215#define SYS_SYS2 0x3008 /* include GP_CFG1 and 3 reserved bytes */
216#define SYS_GPIO_CFG1 0x3008 /* PAD configuration for GPIO4 */
217#define SYS_DEMOD_CTL1 0x300B
218
219/* IrDA registers */
220#define SYS_IRRC_PSR 0x3020 /* IR protocol selection */
221#define SYS_IRRC_PER 0x3024 /* IR protocol extension */
222#define SYS_IRRC_SF 0x3028 /* IR sampling frequency */
223#define SYS_IRRC_DPIR 0x302C /* IR data package interval */
224#define SYS_IRRC_CR 0x3030 /* IR control */
225#define SYS_IRRC_RP 0x3034 /* IR read port */
226#define SYS_IRRC_SR 0x3038 /* IR status */
227/* I2C master registers */
228#define SYS_I2CCR 0x3040 /* I2C clock */
229#define SYS_I2CMCR 0x3044 /* I2C master control */
230#define SYS_I2CMSTR 0x3048 /* I2C master SCL timing */
231#define SYS_I2CMSR 0x304C /* I2C master status */
232#define SYS_I2CMFR 0x3050 /* I2C master FIFO */
233
234/*
235 * IR registers
236 */
237#define IR_RX_BUF 0xFC00
238#define IR_RX_IE 0xFD00
239#define IR_RX_IF 0xFD01
240#define IR_RX_CTRL 0xFD02
241#define IR_RX_CFG 0xFD03
242#define IR_MAX_DURATION0 0xFD04
243#define IR_MAX_DURATION1 0xFD05
244#define IR_IDLE_LEN0 0xFD06
245#define IR_IDLE_LEN1 0xFD07
246#define IR_GLITCH_LEN 0xFD08
247#define IR_RX_BUF_CTRL 0xFD09
248#define IR_RX_BUF_DATA 0xFD0A
249#define IR_RX_BC 0xFD0B
250#define IR_RX_CLK 0xFD0C
251#define IR_RX_C_COUNT_L 0xFD0D
252#define IR_RX_C_COUNT_H 0xFD0E
253#define IR_SUSPEND_CTRL 0xFD10
254#define IR_ERR_TOL_CTRL 0xFD11
255#define IR_UNIT_LEN 0xFD12
256#define IR_ERR_TOL_LEN 0xFD13
257#define IR_MAX_H_TOL_LEN 0xFD14
258#define IR_MAX_L_TOL_LEN 0xFD15
259#define IR_MASK_CTRL 0xFD16
260#define IR_MASK_DATA 0xFD17
261#define IR_RES_MASK_ADDR 0xFD18
262#define IR_RES_MASK_T_LEN 0xFD19
263
264#endif
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index ebb5ed7a7783..21246707fbfb 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -425,6 +425,13 @@ config DVB_CXD2820R
425 help 425 help
426 Say Y when you want to support this frontend. 426 Say Y when you want to support this frontend.
427 427
428config DVB_RTL2830
429 tristate "Realtek RTL2830 DVB-T"
430 depends on DVB_CORE && I2C
431 default m if DVB_FE_CUSTOMISE
432 help
433 Say Y when you want to support this frontend.
434
428comment "DVB-C (cable) frontends" 435comment "DVB-C (cable) frontends"
429 depends on DVB_CORE 436 depends on DVB_CORE
430 437
@@ -698,6 +705,14 @@ config DVB_IT913X_FE
698 A DVB-T tuner module. 705 A DVB-T tuner module.
699 Say Y when you want to support this frontend. 706 Say Y when you want to support this frontend.
700 707
708config DVB_M88RS2000
709 tristate "M88RS2000 DVB-S demodulator and tuner"
710 depends on DVB_CORE && I2C
711 default m if DVB_FE_CUSTOMISE
712 help
713 A DVB-S tuner module.
714 Say Y when you want to support this frontend.
715
701comment "Tools to develop new frontends" 716comment "Tools to develop new frontends"
702 717
703config DVB_DUMMY_FE 718config DVB_DUMMY_FE
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 00a20636df62..86fa808bf589 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -2,8 +2,8 @@
2# Makefile for the kernel DVB frontend device drivers. 2# Makefile for the kernel DVB frontend device drivers.
3# 3#
4 4
5ccflags-y += -Idrivers/media/dvb/dvb-core/ 5ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core/
6ccflags-y += -Idrivers/media/common/tuners/ 6ccflags-y += -I$(srctree)/drivers/media/common/tuners/
7 7
8stb0899-objs = stb0899_drv.o stb0899_algo.o 8stb0899-objs = stb0899_drv.o stb0899_algo.o
9stv0900-objs = stv0900_core.o stv0900_sw.o 9stv0900-objs = stv0900_core.o stv0900_sw.o
@@ -96,4 +96,6 @@ obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o
96obj-$(CONFIG_DVB_IT913X_FE) += it913x-fe.o 96obj-$(CONFIG_DVB_IT913X_FE) += it913x-fe.o
97obj-$(CONFIG_DVB_A8293) += a8293.o 97obj-$(CONFIG_DVB_A8293) += a8293.o
98obj-$(CONFIG_DVB_TDA10071) += tda10071.o 98obj-$(CONFIG_DVB_TDA10071) += tda10071.o
99obj-$(CONFIG_DVB_RTL2830) += rtl2830.o
100obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
99 101
diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c
index 2b248c12f404..55b6390198e3 100644
--- a/drivers/media/dvb/frontends/au8522_decoder.c
+++ b/drivers/media/dvb/frontends/au8522_decoder.c
@@ -839,15 +839,4 @@ static struct i2c_driver au8522_driver = {
839 .id_table = au8522_id, 839 .id_table = au8522_id,
840}; 840};
841 841
842static __init int init_au8522(void) 842module_i2c_driver(au8522_driver);
843{
844 return i2c_add_driver(&au8522_driver);
845}
846
847static __exit void exit_au8522(void)
848{
849 i2c_del_driver(&au8522_driver);
850}
851
852module_init(init_au8522);
853module_exit(exit_au8522);
diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c
index c688b95df486..25f650934c73 100644
--- a/drivers/media/dvb/frontends/au8522_dig.c
+++ b/drivers/media/dvb/frontends/au8522_dig.c
@@ -588,11 +588,6 @@ static int au8522_set_frontend(struct dvb_frontend *fe)
588 (state->current_modulation == c->modulation)) 588 (state->current_modulation == c->modulation))
589 return 0; 589 return 0;
590 590
591 au8522_enable_modulation(fe, c->modulation);
592
593 /* Allow the demod to settle */
594 msleep(100);
595
596 if (fe->ops.tuner_ops.set_params) { 591 if (fe->ops.tuner_ops.set_params) {
597 if (fe->ops.i2c_gate_ctrl) 592 if (fe->ops.i2c_gate_ctrl)
598 fe->ops.i2c_gate_ctrl(fe, 1); 593 fe->ops.i2c_gate_ctrl(fe, 1);
@@ -604,6 +599,11 @@ static int au8522_set_frontend(struct dvb_frontend *fe)
604 if (ret < 0) 599 if (ret < 0)
605 return ret; 600 return ret;
606 601
602 /* Allow the tuner to settle */
603 msleep(100);
604
605 au8522_enable_modulation(fe, c->modulation);
606
607 state->current_frequency = c->frequency; 607 state->current_frequency = c->frequency;
608 608
609 return 0; 609 return 0;
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c
index faba82485086..edc8eafc5c09 100644
--- a/drivers/media/dvb/frontends/cx22702.c
+++ b/drivers/media/dvb/frontends/cx22702.c
@@ -502,10 +502,26 @@ static int cx22702_read_signal_strength(struct dvb_frontend *fe,
502 u16 *signal_strength) 502 u16 *signal_strength)
503{ 503{
504 struct cx22702_state *state = fe->demodulator_priv; 504 struct cx22702_state *state = fe->demodulator_priv;
505 u8 reg23;
505 506
506 u16 rs_ber; 507 /*
507 rs_ber = cx22702_readreg(state, 0x23); 508 * Experience suggests that the strength signal register works as
508 *signal_strength = (rs_ber << 8) | rs_ber; 509 * follows:
510 * - In the absence of signal, value is 0xff.
511 * - In the presence of a weak signal, bit 7 is set, not sure what
512 * the lower 7 bits mean.
513 * - In the presence of a strong signal, the register holds a 7-bit
514 * value (bit 7 is cleared), with greater values standing for
515 * weaker signals.
516 */
517 reg23 = cx22702_readreg(state, 0x23);
518 if (reg23 & 0x80) {
519 *signal_strength = 0;
520 } else {
521 reg23 = ~reg23 & 0x7f;
522 /* Scale to 16 bit */
523 *signal_strength = (reg23 << 9) | (reg23 << 2) | (reg23 >> 5);
524 }
509 525
510 return 0; 526 return 0;
511} 527}
diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c
index 224d81e85091..d9fe60b4be48 100644
--- a/drivers/media/dvb/frontends/dib0090.c
+++ b/drivers/media/dvb/frontends/dib0090.c
@@ -519,7 +519,7 @@ static int dib0090_fw_identify(struct dvb_frontend *fe)
519 return 0; 519 return 0;
520 520
521identification_error: 521identification_error:
522 return -EIO;; 522 return -EIO;
523} 523}
524 524
525static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg) 525static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
diff --git a/drivers/media/dvb/frontends/dib9000.c b/drivers/media/dvb/frontends/dib9000.c
index 863ef3cfab9f..80848b4c15d4 100644
--- a/drivers/media/dvb/frontends/dib9000.c
+++ b/drivers/media/dvb/frontends/dib9000.c
@@ -33,7 +33,7 @@ struct i2c_device {
33 33
34/* lock */ 34/* lock */
35#define DIB_LOCK struct mutex 35#define DIB_LOCK struct mutex
36#define DibAcquireLock(lock) do { if (mutex_lock_interruptible(lock) < 0) dprintk("could not get the lock"); } while (0) 36#define DibAcquireLock(lock) mutex_lock_interruptible(lock)
37#define DibReleaseLock(lock) mutex_unlock(lock) 37#define DibReleaseLock(lock) mutex_unlock(lock)
38#define DibInitLock(lock) mutex_init(lock) 38#define DibInitLock(lock) mutex_init(lock)
39#define DibFreeLock(lock) 39#define DibFreeLock(lock)
@@ -446,7 +446,10 @@ static int dib9000_risc_mem_read(struct dib9000_state *state, u8 cmd, u8 * b, u1
446 if (!state->platform.risc.fw_is_running) 446 if (!state->platform.risc.fw_is_running)
447 return -EIO; 447 return -EIO;
448 448
449 DibAcquireLock(&state->platform.risc.mem_lock); 449 if (DibAcquireLock(&state->platform.risc.mem_lock) < 0) {
450 dprintk("could not get the lock");
451 return -EINTR;
452 }
450 dib9000_risc_mem_setup(state, cmd | 0x80); 453 dib9000_risc_mem_setup(state, cmd | 0x80);
451 dib9000_risc_mem_read_chunks(state, b, len); 454 dib9000_risc_mem_read_chunks(state, b, len);
452 DibReleaseLock(&state->platform.risc.mem_lock); 455 DibReleaseLock(&state->platform.risc.mem_lock);
@@ -459,7 +462,10 @@ static int dib9000_risc_mem_write(struct dib9000_state *state, u8 cmd, const u8
459 if (!state->platform.risc.fw_is_running) 462 if (!state->platform.risc.fw_is_running)
460 return -EIO; 463 return -EIO;
461 464
462 DibAcquireLock(&state->platform.risc.mem_lock); 465 if (DibAcquireLock(&state->platform.risc.mem_lock) < 0) {
466 dprintk("could not get the lock");
467 return -EINTR;
468 }
463 dib9000_risc_mem_setup(state, cmd); 469 dib9000_risc_mem_setup(state, cmd);
464 dib9000_risc_mem_write_chunks(state, b, m->size); 470 dib9000_risc_mem_write_chunks(state, b, m->size);
465 DibReleaseLock(&state->platform.risc.mem_lock); 471 DibReleaseLock(&state->platform.risc.mem_lock);
@@ -531,7 +537,10 @@ static int dib9000_mbx_send_attr(struct dib9000_state *state, u8 id, u16 * data,
531 if (!state->platform.risc.fw_is_running) 537 if (!state->platform.risc.fw_is_running)
532 return -EINVAL; 538 return -EINVAL;
533 539
534 DibAcquireLock(&state->platform.risc.mbx_if_lock); 540 if (DibAcquireLock(&state->platform.risc.mbx_if_lock) < 0) {
541 dprintk("could not get the lock");
542 return -EINTR;
543 }
535 tmp = MAX_MAILBOX_TRY; 544 tmp = MAX_MAILBOX_TRY;
536 do { 545 do {
537 size = dib9000_read_word_attr(state, 1043, attr) & 0xff; 546 size = dib9000_read_word_attr(state, 1043, attr) & 0xff;
@@ -593,7 +602,10 @@ static u8 dib9000_mbx_read(struct dib9000_state *state, u16 * data, u8 risc_id,
593 if (!state->platform.risc.fw_is_running) 602 if (!state->platform.risc.fw_is_running)
594 return 0; 603 return 0;
595 604
596 DibAcquireLock(&state->platform.risc.mbx_if_lock); 605 if (DibAcquireLock(&state->platform.risc.mbx_if_lock) < 0) {
606 dprintk("could not get the lock");
607 return 0;
608 }
597 if (risc_id == 1) 609 if (risc_id == 1)
598 mc_base = 16; 610 mc_base = 16;
599 else 611 else
@@ -701,7 +713,10 @@ static int dib9000_mbx_process(struct dib9000_state *state, u16 attr)
701 if (!state->platform.risc.fw_is_running) 713 if (!state->platform.risc.fw_is_running)
702 return -1; 714 return -1;
703 715
704 DibAcquireLock(&state->platform.risc.mbx_lock); 716 if (DibAcquireLock(&state->platform.risc.mbx_lock) < 0) {
717 dprintk("could not get the lock");
718 return -1;
719 }
705 720
706 if (dib9000_mbx_count(state, 1, attr)) /* 1=RiscB */ 721 if (dib9000_mbx_count(state, 1, attr)) /* 1=RiscB */
707 ret = dib9000_mbx_fetch_to_cache(state, attr); 722 ret = dib9000_mbx_fetch_to_cache(state, attr);
@@ -1178,7 +1193,10 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe)
1178 struct dibDVBTChannel *ch; 1193 struct dibDVBTChannel *ch;
1179 int ret = 0; 1194 int ret = 0;
1180 1195
1181 DibAcquireLock(&state->platform.risc.mem_mbx_lock); 1196 if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) {
1197 dprintk("could not get the lock");
1198 return -EINTR;
1199 }
1182 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { 1200 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
1183 ret = -EIO; 1201 ret = -EIO;
1184 goto error; 1202 goto error;
@@ -1660,7 +1678,10 @@ static int dib9000_fw_component_bus_xfer(struct i2c_adapter *i2c_adap, struct i2
1660 p[12] = 0; 1678 p[12] = 0;
1661 } 1679 }
1662 1680
1663 DibAcquireLock(&state->platform.risc.mem_mbx_lock); 1681 if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) {
1682 dprintk("could not get the lock");
1683 return 0;
1684 }
1664 1685
1665 dib9000_risc_mem_write(state, FE_MM_W_COMPONENT_ACCESS, p); 1686 dib9000_risc_mem_write(state, FE_MM_W_COMPONENT_ACCESS, p);
1666 1687
@@ -1768,7 +1789,10 @@ int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1768 return 0; 1789 return 0;
1769 } 1790 }
1770 1791
1771 DibAcquireLock(&state->demod_lock); 1792 if (DibAcquireLock(&state->demod_lock) < 0) {
1793 dprintk("could not get the lock");
1794 return -EINTR;
1795 }
1772 1796
1773 val = dib9000_read_word(state, 294 + 1) & 0xffef; 1797 val = dib9000_read_word(state, 294 + 1) & 0xffef;
1774 val |= (onoff & 0x1) << 4; 1798 val |= (onoff & 0x1) << 4;
@@ -1800,7 +1824,10 @@ int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1800 return 0; 1824 return 0;
1801 } 1825 }
1802 1826
1803 DibAcquireLock(&state->demod_lock); 1827 if (DibAcquireLock(&state->demod_lock) < 0) {
1828 dprintk("could not get the lock");
1829 return -EINTR;
1830 }
1804 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff); 1831 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
1805 ret = dib9000_write_word(state, 300 + 1 + id, 1832 ret = dib9000_write_word(state, 300 + 1 + id,
1806 onoff ? (1 << 13) | pid : 0); 1833 onoff ? (1 << 13) | pid : 0);
@@ -1848,7 +1875,10 @@ static int dib9000_sleep(struct dvb_frontend *fe)
1848 u8 index_frontend; 1875 u8 index_frontend;
1849 int ret = 0; 1876 int ret = 0;
1850 1877
1851 DibAcquireLock(&state->demod_lock); 1878 if (DibAcquireLock(&state->demod_lock) < 0) {
1879 dprintk("could not get the lock");
1880 return -EINTR;
1881 }
1852 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { 1882 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1853 ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]); 1883 ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
1854 if (ret < 0) 1884 if (ret < 0)
@@ -1874,8 +1904,12 @@ static int dib9000_get_frontend(struct dvb_frontend *fe)
1874 fe_status_t stat; 1904 fe_status_t stat;
1875 int ret = 0; 1905 int ret = 0;
1876 1906
1877 if (state->get_frontend_internal == 0) 1907 if (state->get_frontend_internal == 0) {
1878 DibAcquireLock(&state->demod_lock); 1908 if (DibAcquireLock(&state->demod_lock) < 0) {
1909 dprintk("could not get the lock");
1910 return -EINTR;
1911 }
1912 }
1879 1913
1880 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { 1914 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1881 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat); 1915 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
@@ -1978,7 +2012,10 @@ static int dib9000_set_frontend(struct dvb_frontend *fe)
1978 } 2012 }
1979 2013
1980 state->pid_ctrl_index = -1; /* postpone the pid filtering cmd */ 2014 state->pid_ctrl_index = -1; /* postpone the pid filtering cmd */
1981 DibAcquireLock(&state->demod_lock); 2015 if (DibAcquireLock(&state->demod_lock) < 0) {
2016 dprintk("could not get the lock");
2017 return 0;
2018 }
1982 2019
1983 fe->dtv_property_cache.delivery_system = SYS_DVBT; 2020 fe->dtv_property_cache.delivery_system = SYS_DVBT;
1984 2021
@@ -2138,7 +2175,10 @@ static int dib9000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
2138 u8 index_frontend; 2175 u8 index_frontend;
2139 u16 lock = 0, lock_slave = 0; 2176 u16 lock = 0, lock_slave = 0;
2140 2177
2141 DibAcquireLock(&state->demod_lock); 2178 if (DibAcquireLock(&state->demod_lock) < 0) {
2179 dprintk("could not get the lock");
2180 return -EINTR;
2181 }
2142 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) 2182 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2143 lock_slave |= dib9000_read_lock(state->fe[index_frontend]); 2183 lock_slave |= dib9000_read_lock(state->fe[index_frontend]);
2144 2184
@@ -2168,8 +2208,15 @@ static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber)
2168 u16 *c; 2208 u16 *c;
2169 int ret = 0; 2209 int ret = 0;
2170 2210
2171 DibAcquireLock(&state->demod_lock); 2211 if (DibAcquireLock(&state->demod_lock) < 0) {
2172 DibAcquireLock(&state->platform.risc.mem_mbx_lock); 2212 dprintk("could not get the lock");
2213 return -EINTR;
2214 }
2215 if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) {
2216 dprintk("could not get the lock");
2217 ret = -EINTR;
2218 goto error;
2219 }
2173 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { 2220 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
2174 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2221 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2175 ret = -EIO; 2222 ret = -EIO;
@@ -2196,7 +2243,10 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2196 u16 val; 2243 u16 val;
2197 int ret = 0; 2244 int ret = 0;
2198 2245
2199 DibAcquireLock(&state->demod_lock); 2246 if (DibAcquireLock(&state->demod_lock) < 0) {
2247 dprintk("could not get the lock");
2248 return -EINTR;
2249 }
2200 *strength = 0; 2250 *strength = 0;
2201 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { 2251 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2202 state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val); 2252 state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
@@ -2206,8 +2256,13 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2206 *strength += val; 2256 *strength += val;
2207 } 2257 }
2208 2258
2209 DibAcquireLock(&state->platform.risc.mem_mbx_lock); 2259 if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) {
2260 dprintk("could not get the lock");
2261 ret = -EINTR;
2262 goto error;
2263 }
2210 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { 2264 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
2265 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2211 ret = -EIO; 2266 ret = -EIO;
2212 goto error; 2267 goto error;
2213 } 2268 }
@@ -2232,9 +2287,14 @@ static u32 dib9000_get_snr(struct dvb_frontend *fe)
2232 u32 n, s, exp; 2287 u32 n, s, exp;
2233 u16 val; 2288 u16 val;
2234 2289
2235 DibAcquireLock(&state->platform.risc.mem_mbx_lock); 2290 if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) {
2236 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) 2291 dprintk("could not get the lock");
2237 return -EIO; 2292 return 0;
2293 }
2294 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
2295 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2296 return 0;
2297 }
2238 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2); 2298 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
2239 DibReleaseLock(&state->platform.risc.mem_mbx_lock); 2299 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2240 2300
@@ -2266,7 +2326,10 @@ static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr)
2266 u8 index_frontend; 2326 u8 index_frontend;
2267 u32 snr_master; 2327 u32 snr_master;
2268 2328
2269 DibAcquireLock(&state->demod_lock); 2329 if (DibAcquireLock(&state->demod_lock) < 0) {
2330 dprintk("could not get the lock");
2331 return -EINTR;
2332 }
2270 snr_master = dib9000_get_snr(fe); 2333 snr_master = dib9000_get_snr(fe);
2271 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) 2334 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2272 snr_master += dib9000_get_snr(state->fe[index_frontend]); 2335 snr_master += dib9000_get_snr(state->fe[index_frontend]);
@@ -2288,9 +2351,17 @@ static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
2288 u16 *c = (u16 *)state->i2c_read_buffer; 2351 u16 *c = (u16 *)state->i2c_read_buffer;
2289 int ret = 0; 2352 int ret = 0;
2290 2353
2291 DibAcquireLock(&state->demod_lock); 2354 if (DibAcquireLock(&state->demod_lock) < 0) {
2292 DibAcquireLock(&state->platform.risc.mem_mbx_lock); 2355 dprintk("could not get the lock");
2356 return -EINTR;
2357 }
2358 if (DibAcquireLock(&state->platform.risc.mem_mbx_lock) < 0) {
2359 dprintk("could not get the lock");
2360 ret = -EINTR;
2361 goto error;
2362 }
2293 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { 2363 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
2364 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2294 ret = -EIO; 2365 ret = -EIO;
2295 goto error; 2366 goto error;
2296 } 2367 }
diff --git a/drivers/media/dvb/frontends/drxd_hard.c b/drivers/media/dvb/frontends/drxd_hard.c
index 7bf39cda83c5..f380eb43e9d5 100644
--- a/drivers/media/dvb/frontends/drxd_hard.c
+++ b/drivers/media/dvb/frontends/drxd_hard.c
@@ -101,9 +101,9 @@ struct SCfgAgc {
101 101
102struct SNoiseCal { 102struct SNoiseCal {
103 int cpOpt; 103 int cpOpt;
104 u16 cpNexpOfs; 104 short cpNexpOfs;
105 u16 tdCal2k; 105 short tdCal2k;
106 u16 tdCal8k; 106 short tdCal8k;
107}; 107};
108 108
109enum app_env { 109enum app_env {
diff --git a/drivers/media/dvb/frontends/drxk.h b/drivers/media/dvb/frontends/drxk.h
index 020981844a86..9d64e4fea066 100644
--- a/drivers/media/dvb/frontends/drxk.h
+++ b/drivers/media/dvb/frontends/drxk.h
@@ -7,15 +7,19 @@
7/** 7/**
8 * struct drxk_config - Configure the initial parameters for DRX-K 8 * struct drxk_config - Configure the initial parameters for DRX-K
9 * 9 *
10 * adr: I2C Address of the DRX-K 10 * @adr: I2C Address of the DRX-K
11 * parallel_ts: true means that the device uses parallel TS, 11 * @parallel_ts: True means that the device uses parallel TS,
12 * Serial otherwise. 12 * Serial otherwise.
13 * single_master: Device is on the single master mode 13 * @dynamic_clk: True means that the clock will be dynamically
14 * no_i2c_bridge: Don't switch the I2C bridge to talk with tuner 14 * adjusted. Static clock otherwise.
15 * antenna_gpio: GPIO bit used to control the antenna 15 * @enable_merr_cfg: Enable SIO_PDR_PERR_CFG/SIO_PDR_MVAL_CFG.
16 * antenna_dvbt: GPIO bit for changing antenna to DVB-C. A value of 1 16 * @single_master: Device is on the single master mode
17 * @no_i2c_bridge: Don't switch the I2C bridge to talk with tuner
18 * @antenna_gpio: GPIO bit used to control the antenna
19 * @antenna_dvbt: GPIO bit for changing antenna to DVB-C. A value of 1
17 * means that 1=DVBC, 0 = DVBT. Zero means the opposite. 20 * means that 1=DVBC, 0 = DVBT. Zero means the opposite.
18 * microcode_name: Name of the firmware file with the microcode 21 * @mpeg_out_clk_strength: DRXK Mpeg output clock drive strength.
22 * @microcode_name: Name of the firmware file with the microcode
19 * 23 *
20 * On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is 24 * On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is
21 * UIO-3. 25 * UIO-3.
@@ -25,11 +29,14 @@ struct drxk_config {
25 bool single_master; 29 bool single_master;
26 bool no_i2c_bridge; 30 bool no_i2c_bridge;
27 bool parallel_ts; 31 bool parallel_ts;
32 bool dynamic_clk;
33 bool enable_merr_cfg;
28 34
29 bool antenna_dvbt; 35 bool antenna_dvbt;
30 u16 antenna_gpio; 36 u16 antenna_gpio;
31 37
32 int chunk_size; 38 u8 mpeg_out_clk_strength;
39 int chunk_size;
33 40
34 const char *microcode_name; 41 const char *microcode_name;
35}; 42};
diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c
index 5ab53795bd7a..36d11756492f 100644
--- a/drivers/media/dvb/frontends/drxk_hard.c
+++ b/drivers/media/dvb/frontends/drxk_hard.c
@@ -90,10 +90,6 @@ bool IsA1WithRomCode(struct drxk_state *state)
90#define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03) 90#define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
91#endif 91#endif
92 92
93#ifndef DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH
94#define DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH (0x06)
95#endif
96
97#define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700 93#define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
98#define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500 94#define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
99 95
@@ -649,9 +645,6 @@ static int init_state(struct drxk_state *state)
649 u32 ulQual83 = DEFAULT_MER_83; 645 u32 ulQual83 = DEFAULT_MER_83;
650 u32 ulQual93 = DEFAULT_MER_93; 646 u32 ulQual93 = DEFAULT_MER_93;
651 647
652 u32 ulDVBTStaticTSClock = 1;
653 u32 ulDVBCStaticTSClock = 1;
654
655 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT; 648 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
656 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT; 649 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
657 650
@@ -661,7 +654,6 @@ static int init_state(struct drxk_state *state)
661 u32 ulGPIOCfg = 0x0113; 654 u32 ulGPIOCfg = 0x0113;
662 u32 ulInvertTSClock = 0; 655 u32 ulInvertTSClock = 0;
663 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH; 656 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
664 u32 ulTSClockkStrength = DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH;
665 u32 ulDVBTBitrate = 50000000; 657 u32 ulDVBTBitrate = 50000000;
666 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8; 658 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
667 659
@@ -814,8 +806,7 @@ static int init_state(struct drxk_state *state)
814 state->m_invertSTR = false; /* If TRUE; invert STR signals */ 806 state->m_invertSTR = false; /* If TRUE; invert STR signals */
815 state->m_invertVAL = false; /* If TRUE; invert VAL signals */ 807 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
816 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */ 808 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
817 state->m_DVBTStaticCLK = (ulDVBTStaticTSClock != 0); 809
818 state->m_DVBCStaticCLK = (ulDVBCStaticTSClock != 0);
819 /* If TRUE; static MPEG clockrate will be used; 810 /* If TRUE; static MPEG clockrate will be used;
820 otherwise clockrate will adapt to the bitrate of the TS */ 811 otherwise clockrate will adapt to the bitrate of the TS */
821 812
@@ -823,7 +814,6 @@ static int init_state(struct drxk_state *state)
823 state->m_DVBCBitrate = ulDVBCBitrate; 814 state->m_DVBCBitrate = ulDVBCBitrate;
824 815
825 state->m_TSDataStrength = (ulTSDataStrength & 0x07); 816 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
826 state->m_TSClockkStrength = (ulTSClockkStrength & 0x07);
827 817
828 /* Maximum bitrate in b/s in case static clockrate is selected */ 818 /* Maximum bitrate in b/s in case static clockrate is selected */
829 state->m_mpegTsStaticBitrate = 19392658; 819 state->m_mpegTsStaticBitrate = 19392658;
@@ -1188,6 +1178,7 @@ static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1188 int status = -1; 1178 int status = -1;
1189 u16 sioPdrMclkCfg = 0; 1179 u16 sioPdrMclkCfg = 0;
1190 u16 sioPdrMdxCfg = 0; 1180 u16 sioPdrMdxCfg = 0;
1181 u16 err_cfg = 0;
1191 1182
1192 dprintk(1, ": mpeg %s, %s mode\n", 1183 dprintk(1, ": mpeg %s, %s mode\n",
1193 mpegEnable ? "enable" : "disable", 1184 mpegEnable ? "enable" : "disable",
@@ -1253,12 +1244,17 @@ static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1253 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg); 1244 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
1254 if (status < 0) 1245 if (status < 0)
1255 goto error; 1246 goto error;
1256 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000); /* Disable */ 1247
1248 if (state->enable_merr_cfg)
1249 err_cfg = sioPdrMdxCfg;
1250
1251 status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg);
1257 if (status < 0) 1252 if (status < 0)
1258 goto error; 1253 goto error;
1259 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000); /* Disable */ 1254 status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg);
1260 if (status < 0) 1255 if (status < 0)
1261 goto error; 1256 goto error;
1257
1262 if (state->m_enableParallel == true) { 1258 if (state->m_enableParallel == true) {
1263 /* paralel -> enable MD1 to MD7 */ 1259 /* paralel -> enable MD1 to MD7 */
1264 status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg); 1260 status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
@@ -6069,9 +6065,7 @@ static int init_drxk(struct drxk_state *state)
6069 if (status < 0) 6065 if (status < 0)
6070 goto error; 6066 goto error;
6071 6067
6072 if (!state->microcode_name) 6068 if (state->microcode_name)
6073 load_microcode(state, "drxk_a3.mc");
6074 else
6075 load_microcode(state, state->microcode_name); 6069 load_microcode(state, state->microcode_name);
6076 6070
6077 /* disable token-ring bus through OFDM block for possible ucode upload */ 6071 /* disable token-ring bus through OFDM block for possible ucode upload */
@@ -6322,15 +6316,12 @@ static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_t
6322 switch (p->delivery_system) { 6316 switch (p->delivery_system) {
6323 case SYS_DVBC_ANNEX_A: 6317 case SYS_DVBC_ANNEX_A:
6324 case SYS_DVBC_ANNEX_C: 6318 case SYS_DVBC_ANNEX_C:
6319 case SYS_DVBT:
6325 sets->min_delay_ms = 3000; 6320 sets->min_delay_ms = 3000;
6326 sets->max_drift = 0; 6321 sets->max_drift = 0;
6327 sets->step_size = 0; 6322 sets->step_size = 0;
6328 return 0; 6323 return 0;
6329 default: 6324 default:
6330 /*
6331 * For DVB-T, let it use the default DVB core way, that is:
6332 * fepriv->step_size = fe->ops.info.frequency_stepsize * 2
6333 */
6334 return -EINVAL; 6325 return -EINVAL;
6335 } 6326 }
6336} 6327}
@@ -6390,6 +6381,21 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config,
6390 state->antenna_gpio = config->antenna_gpio; 6381 state->antenna_gpio = config->antenna_gpio;
6391 state->antenna_dvbt = config->antenna_dvbt; 6382 state->antenna_dvbt = config->antenna_dvbt;
6392 state->m_ChunkSize = config->chunk_size; 6383 state->m_ChunkSize = config->chunk_size;
6384 state->enable_merr_cfg = config->enable_merr_cfg;
6385
6386 if (config->dynamic_clk) {
6387 state->m_DVBTStaticCLK = 0;
6388 state->m_DVBCStaticCLK = 0;
6389 } else {
6390 state->m_DVBTStaticCLK = 1;
6391 state->m_DVBCStaticCLK = 1;
6392 }
6393
6394
6395 if (config->mpeg_out_clk_strength)
6396 state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07;
6397 else
6398 state->m_TSClockkStrength = 0x06;
6393 6399
6394 if (config->parallel_ts) 6400 if (config->parallel_ts)
6395 state->m_enableParallel = true; 6401 state->m_enableParallel = true;
diff --git a/drivers/media/dvb/frontends/drxk_hard.h b/drivers/media/dvb/frontends/drxk_hard.h
index 3a58b73eb9b9..4bbf841de83a 100644
--- a/drivers/media/dvb/frontends/drxk_hard.h
+++ b/drivers/media/dvb/frontends/drxk_hard.h
@@ -332,6 +332,7 @@ struct drxk_state {
332 332
333 u16 UIO_mask; /* Bits used by UIO */ 333 u16 UIO_mask; /* Bits used by UIO */
334 334
335 bool enable_merr_cfg;
335 bool single_master; 336 bool single_master;
336 bool no_i2c_bridge; 337 bool no_i2c_bridge;
337 bool antenna_dvbt; 338 bool antenna_dvbt;
diff --git a/drivers/media/dvb/frontends/it913x-fe-priv.h b/drivers/media/dvb/frontends/it913x-fe-priv.h
index 93b086ea7e1c..eb6fd8aebdb3 100644
--- a/drivers/media/dvb/frontends/it913x-fe-priv.h
+++ b/drivers/media/dvb/frontends/it913x-fe-priv.h
@@ -201,6 +201,11 @@ fe_modulation_t fe_con[] = {
201 QAM_64, 201 QAM_64,
202}; 202};
203 203
204enum {
205 PRIORITY_HIGH = 0, /* High-priority stream */
206 PRIORITY_LOW, /* Low-priority stream */
207};
208
204/* Standard demodulator functions */ 209/* Standard demodulator functions */
205static struct it913xset set_solo_fe[] = { 210static struct it913xset set_solo_fe[] = {
206 {PRO_LINK, GPIOH5_EN, {0x01}, 0x01}, 211 {PRO_LINK, GPIOH5_EN, {0x01}, 0x01},
diff --git a/drivers/media/dvb/frontends/it913x-fe.c b/drivers/media/dvb/frontends/it913x-fe.c
index ccc36bf2deb4..84df03c29179 100644
--- a/drivers/media/dvb/frontends/it913x-fe.c
+++ b/drivers/media/dvb/frontends/it913x-fe.c
@@ -57,6 +57,7 @@ struct it913x_fe_state {
57 u32 frequency; 57 u32 frequency;
58 fe_modulation_t constellation; 58 fe_modulation_t constellation;
59 fe_transmit_mode_t transmission_mode; 59 fe_transmit_mode_t transmission_mode;
60 u8 priority;
60 u32 crystalFrequency; 61 u32 crystalFrequency;
61 u32 adcFrequency; 62 u32 adcFrequency;
62 u8 tuner_type; 63 u8 tuner_type;
@@ -500,19 +501,87 @@ static int it913x_fe_read_status(struct dvb_frontend *fe, fe_status_t *status)
500 return 0; 501 return 0;
501} 502}
502 503
504/* FEC values based on fe_code_rate_t non supported values 0*/
505int it913x_qpsk_pval[] = {0, -93, -91, -90, 0, -89, -88};
506int it913x_16qam_pval[] = {0, -87, -85, -84, 0, -83, -82};
507int it913x_64qam_pval[] = {0, -82, -80, -78, 0, -77, -76};
508
509static int it913x_get_signal_strength(struct dvb_frontend *fe)
510{
511 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
512 struct it913x_fe_state *state = fe->demodulator_priv;
513 u8 code_rate;
514 int ret, temp;
515 u8 lna_gain_os;
516
517 ret = it913x_read_reg_u8(state, VAR_P_INBAND);
518 if (ret < 0)
519 return ret;
520
521 /* VHF/UHF gain offset */
522 if (state->frequency < 300000000)
523 lna_gain_os = 7;
524 else
525 lna_gain_os = 14;
526
527 temp = (ret - 100) - lna_gain_os;
528
529 if (state->priority == PRIORITY_HIGH)
530 code_rate = p->code_rate_HP;
531 else
532 code_rate = p->code_rate_LP;
533
534 if (code_rate >= ARRAY_SIZE(it913x_qpsk_pval))
535 return -EINVAL;
536
537 deb_info("Reg VAR_P_INBAND:%d Calc Offset Value:%d", ret, temp);
538
539 /* Apply FEC offset values*/
540 switch (p->modulation) {
541 case QPSK:
542 temp -= it913x_qpsk_pval[code_rate];
543 break;
544 case QAM_16:
545 temp -= it913x_16qam_pval[code_rate];
546 break;
547 case QAM_64:
548 temp -= it913x_64qam_pval[code_rate];
549 break;
550 default:
551 return -EINVAL;
552 }
553
554 if (temp < -15)
555 ret = 0;
556 else if ((-15 <= temp) && (temp < 0))
557 ret = (2 * (temp + 15)) / 3;
558 else if ((0 <= temp) && (temp < 20))
559 ret = 4 * temp + 10;
560 else if ((20 <= temp) && (temp < 35))
561 ret = (2 * (temp - 20)) / 3 + 90;
562 else if (temp >= 35)
563 ret = 100;
564
565 deb_info("Signal Strength :%d", ret);
566
567 return ret;
568}
569
503static int it913x_fe_read_signal_strength(struct dvb_frontend *fe, 570static int it913x_fe_read_signal_strength(struct dvb_frontend *fe,
504 u16 *strength) 571 u16 *strength)
505{ 572{
506 struct it913x_fe_state *state = fe->demodulator_priv; 573 struct it913x_fe_state *state = fe->demodulator_priv;
507 int ret = it913x_read_reg_u8(state, SIGNAL_LEVEL); 574 int ret = 0;
508 /*SIGNAL_LEVEL always returns 100%! so using FE_HAS_SIGNAL as switch*/ 575 if (state->config->read_slevel) {
509 if (state->it913x_status & FE_HAS_SIGNAL) 576 if (state->it913x_status & FE_HAS_SIGNAL)
510 ret = (ret * 0xff) / 0x64; 577 ret = it913x_read_reg_u8(state, SIGNAL_LEVEL);
511 else 578 } else
512 ret = 0x0; 579 ret = it913x_get_signal_strength(fe);
513 ret |= ret << 0x8; 580
514 *strength = ret; 581 if (ret >= 0)
515 return 0; 582 *strength = (u16)((u32)ret * 0xffff / 0x64);
583
584 return (ret < 0) ? -ENODEV : 0;
516} 585}
517 586
518static int it913x_fe_read_snr(struct dvb_frontend *fe, u16 *snr) 587static int it913x_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
@@ -606,6 +675,8 @@ static int it913x_fe_get_frontend(struct dvb_frontend *fe)
606 if (reg[2] < 4) 675 if (reg[2] < 4)
607 p->hierarchy = fe_hi[reg[2]]; 676 p->hierarchy = fe_hi[reg[2]];
608 677
678 state->priority = reg[5];
679
609 p->code_rate_HP = (reg[6] < 6) ? fe_code[reg[6]] : FEC_NONE; 680 p->code_rate_HP = (reg[6] < 6) ? fe_code[reg[6]] : FEC_NONE;
610 p->code_rate_LP = (reg[7] < 6) ? fe_code[reg[7]] : FEC_NONE; 681 p->code_rate_LP = (reg[7] < 6) ? fe_code[reg[7]] : FEC_NONE;
611 682
@@ -972,5 +1043,5 @@ static struct dvb_frontend_ops it913x_fe_ofdm_ops = {
972 1043
973MODULE_DESCRIPTION("it913x Frontend and it9137 tuner"); 1044MODULE_DESCRIPTION("it913x Frontend and it9137 tuner");
974MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com"); 1045MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
975MODULE_VERSION("1.13"); 1046MODULE_VERSION("1.15");
976MODULE_LICENSE("GPL"); 1047MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/it913x-fe.h b/drivers/media/dvb/frontends/it913x-fe.h
index c4a908e354e0..07fa4594c12b 100644
--- a/drivers/media/dvb/frontends/it913x-fe.h
+++ b/drivers/media/dvb/frontends/it913x-fe.h
@@ -34,6 +34,8 @@ struct ite_config {
34 u8 tuner_id_1; 34 u8 tuner_id_1;
35 u8 dual_mode; 35 u8 dual_mode;
36 u8 adf; 36 u8 adf;
37 /* option to read SIGNAL_LEVEL */
38 u8 read_slevel;
37}; 39};
38 40
39#if defined(CONFIG_DVB_IT913X_FE) || (defined(CONFIG_DVB_IT913X_FE_MODULE) && \ 41#if defined(CONFIG_DVB_IT913X_FE) || (defined(CONFIG_DVB_IT913X_FE_MODULE) && \
@@ -168,6 +170,8 @@ static inline struct dvb_frontend *it913x_fe_attach(
168#define EST_SIGNAL_LEVEL 0x004a 170#define EST_SIGNAL_LEVEL 0x004a
169#define FREE_BAND 0x004b 171#define FREE_BAND 0x004b
170#define SUSPEND_FLAG 0x004c 172#define SUSPEND_FLAG 0x004c
173#define VAR_P_INBAND 0x00f7
174
171/* Build in tuner types */ 175/* Build in tuner types */
172#define IT9137 0x38 176#define IT9137 0x38
173#define IT9135_38 0x38 177#define IT9135_38 0x38
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
index c990d35a13dc..e046622df0e4 100644
--- a/drivers/media/dvb/frontends/lgdt330x.c
+++ b/drivers/media/dvb/frontends/lgdt330x.c
@@ -104,8 +104,8 @@ static int i2c_write_demod_bytes (struct lgdt330x_state* state,
104 * then reads the data returned for (len) bytes. 104 * then reads the data returned for (len) bytes.
105 */ 105 */
106 106
107static u8 i2c_read_demod_bytes (struct lgdt330x_state* state, 107static int i2c_read_demod_bytes(struct lgdt330x_state *state,
108 enum I2C_REG reg, u8* buf, int len) 108 enum I2C_REG reg, u8 *buf, int len)
109{ 109{
110 u8 wr [] = { reg }; 110 u8 wr [] = { reg };
111 struct i2c_msg msg [] = { 111 struct i2c_msg msg [] = {
@@ -118,6 +118,8 @@ static u8 i2c_read_demod_bytes (struct lgdt330x_state* state,
118 ret = i2c_transfer(state->i2c, msg, 2); 118 ret = i2c_transfer(state->i2c, msg, 2);
119 if (ret != 2) { 119 if (ret != 2) {
120 printk(KERN_WARNING "lgdt330x: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __func__, state->config->demod_address, reg, ret); 120 printk(KERN_WARNING "lgdt330x: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __func__, state->config->demod_address, reg, ret);
121 if (ret >= 0)
122 ret = -EIO;
121 } else { 123 } else {
122 ret = 0; 124 ret = 0;
123 } 125 }
diff --git a/drivers/media/dvb/frontends/m88rs2000.c b/drivers/media/dvb/frontends/m88rs2000.c
new file mode 100644
index 000000000000..045ee5a6f7ae
--- /dev/null
+++ b/drivers/media/dvb/frontends/m88rs2000.c
@@ -0,0 +1,904 @@
1/*
2 Driver for M88RS2000 demodulator and tuner
3
4 Copyright (C) 2012 Malcolm Priestley (tvboxspy@gmail.com)
5 Beta Driver
6
7 Include various calculation code from DS3000 driver.
8 Copyright (C) 2009 Konstantin Dimitrov.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
24*/
25#include <linux/init.h>
26#include <linux/module.h>
27#include <linux/device.h>
28#include <linux/jiffies.h>
29#include <linux/string.h>
30#include <linux/slab.h>
31#include <linux/types.h>
32
33
34#include "dvb_frontend.h"
35#include "m88rs2000.h"
36
37struct m88rs2000_state {
38 struct i2c_adapter *i2c;
39 const struct m88rs2000_config *config;
40 struct dvb_frontend frontend;
41 u8 no_lock_count;
42 u32 tuner_frequency;
43 u32 symbol_rate;
44 fe_code_rate_t fec_inner;
45 u8 tuner_level;
46 int errmode;
47};
48
49static int m88rs2000_debug;
50
51module_param_named(debug, m88rs2000_debug, int, 0644);
52MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
53
54#define dprintk(level, args...) do { \
55 if (level & m88rs2000_debug) \
56 printk(KERN_DEBUG "m88rs2000-fe: " args); \
57} while (0)
58
59#define deb_info(args...) dprintk(0x01, args)
60#define info(format, arg...) \
61 printk(KERN_INFO "m88rs2000-fe: " format "\n" , ## arg)
62
63static int m88rs2000_writereg(struct m88rs2000_state *state, u8 tuner,
64 u8 reg, u8 data)
65{
66 int ret;
67 u8 addr = (tuner == 0) ? state->config->tuner_addr :
68 state->config->demod_addr;
69 u8 buf[] = { reg, data };
70 struct i2c_msg msg = {
71 .addr = addr,
72 .flags = 0,
73 .buf = buf,
74 .len = 2
75 };
76
77 ret = i2c_transfer(state->i2c, &msg, 1);
78
79 if (ret != 1)
80 deb_info("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
81 "ret == %i)\n", __func__, reg, data, ret);
82
83 return (ret != 1) ? -EREMOTEIO : 0;
84}
85
86static int m88rs2000_demod_write(struct m88rs2000_state *state, u8 reg, u8 data)
87{
88 return m88rs2000_writereg(state, 1, reg, data);
89}
90
91static int m88rs2000_tuner_write(struct m88rs2000_state *state, u8 reg, u8 data)
92{
93 m88rs2000_demod_write(state, 0x81, 0x84);
94 udelay(10);
95 return m88rs2000_writereg(state, 0, reg, data);
96
97}
98
99static int m88rs2000_write(struct dvb_frontend *fe, const u8 buf[], int len)
100{
101 struct m88rs2000_state *state = fe->demodulator_priv;
102
103 if (len != 2)
104 return -EINVAL;
105
106 return m88rs2000_writereg(state, 1, buf[0], buf[1]);
107}
108
109static u8 m88rs2000_readreg(struct m88rs2000_state *state, u8 tuner, u8 reg)
110{
111 int ret;
112 u8 b0[] = { reg };
113 u8 b1[] = { 0 };
114 u8 addr = (tuner == 0) ? state->config->tuner_addr :
115 state->config->demod_addr;
116 struct i2c_msg msg[] = {
117 {
118 .addr = addr,
119 .flags = 0,
120 .buf = b0,
121 .len = 1
122 }, {
123 .addr = addr,
124 .flags = I2C_M_RD,
125 .buf = b1,
126 .len = 1
127 }
128 };
129
130 ret = i2c_transfer(state->i2c, msg, 2);
131
132 if (ret != 2)
133 deb_info("%s: readreg error (reg == 0x%02x, ret == %i)\n",
134 __func__, reg, ret);
135
136 return b1[0];
137}
138
139static u8 m88rs2000_demod_read(struct m88rs2000_state *state, u8 reg)
140{
141 return m88rs2000_readreg(state, 1, reg);
142}
143
144static u8 m88rs2000_tuner_read(struct m88rs2000_state *state, u8 reg)
145{
146 m88rs2000_demod_write(state, 0x81, 0x85);
147 udelay(10);
148 return m88rs2000_readreg(state, 0, reg);
149}
150
151static int m88rs2000_set_symbolrate(struct dvb_frontend *fe, u32 srate)
152{
153 struct m88rs2000_state *state = fe->demodulator_priv;
154 int ret;
155 u32 temp;
156 u8 b[3];
157
158 if ((srate < 1000000) || (srate > 45000000))
159 return -EINVAL;
160
161 temp = srate / 1000;
162 temp *= 11831;
163 temp /= 68;
164 temp -= 3;
165
166 b[0] = (u8) (temp >> 16) & 0xff;
167 b[1] = (u8) (temp >> 8) & 0xff;
168 b[2] = (u8) temp & 0xff;
169 ret = m88rs2000_demod_write(state, 0x93, b[2]);
170 ret |= m88rs2000_demod_write(state, 0x94, b[1]);
171 ret |= m88rs2000_demod_write(state, 0x95, b[0]);
172
173 deb_info("m88rs2000: m88rs2000_set_symbolrate\n");
174 return ret;
175}
176
177static int m88rs2000_send_diseqc_msg(struct dvb_frontend *fe,
178 struct dvb_diseqc_master_cmd *m)
179{
180 struct m88rs2000_state *state = fe->demodulator_priv;
181
182 int i;
183 u8 reg;
184 deb_info("%s\n", __func__);
185 m88rs2000_demod_write(state, 0x9a, 0x30);
186 reg = m88rs2000_demod_read(state, 0xb2);
187 reg &= 0x3f;
188 m88rs2000_demod_write(state, 0xb2, reg);
189 for (i = 0; i < m->msg_len; i++)
190 m88rs2000_demod_write(state, 0xb3 + i, m->msg[i]);
191
192 reg = m88rs2000_demod_read(state, 0xb1);
193 reg &= 0x87;
194 reg |= ((m->msg_len - 1) << 3) | 0x07;
195 reg &= 0x7f;
196 m88rs2000_demod_write(state, 0xb1, reg);
197
198 for (i = 0; i < 15; i++) {
199 if ((m88rs2000_demod_read(state, 0xb1) & 0x40) == 0x0)
200 break;
201 msleep(20);
202 }
203
204 reg = m88rs2000_demod_read(state, 0xb1);
205 if ((reg & 0x40) > 0x0) {
206 reg &= 0x7f;
207 reg |= 0x40;
208 m88rs2000_demod_write(state, 0xb1, reg);
209 }
210
211 reg = m88rs2000_demod_read(state, 0xb2);
212 reg &= 0x3f;
213 reg |= 0x80;
214 m88rs2000_demod_write(state, 0xb2, reg);
215 m88rs2000_demod_write(state, 0x9a, 0xb0);
216
217
218 return 0;
219}
220
221static int m88rs2000_send_diseqc_burst(struct dvb_frontend *fe,
222 fe_sec_mini_cmd_t burst)
223{
224 struct m88rs2000_state *state = fe->demodulator_priv;
225 u8 reg0, reg1;
226 deb_info("%s\n", __func__);
227 m88rs2000_demod_write(state, 0x9a, 0x30);
228 msleep(50);
229 reg0 = m88rs2000_demod_read(state, 0xb1);
230 reg1 = m88rs2000_demod_read(state, 0xb2);
231 /* TODO complete this section */
232 m88rs2000_demod_write(state, 0xb2, reg1);
233 m88rs2000_demod_write(state, 0xb1, reg0);
234 m88rs2000_demod_write(state, 0x9a, 0xb0);
235
236 return 0;
237}
238
239static int m88rs2000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
240{
241 struct m88rs2000_state *state = fe->demodulator_priv;
242 u8 reg0, reg1;
243 m88rs2000_demod_write(state, 0x9a, 0x30);
244 reg0 = m88rs2000_demod_read(state, 0xb1);
245 reg1 = m88rs2000_demod_read(state, 0xb2);
246
247 reg1 &= 0x3f;
248
249 switch (tone) {
250 case SEC_TONE_ON:
251 reg0 |= 0x4;
252 reg0 &= 0xbc;
253 break;
254 case SEC_TONE_OFF:
255 reg1 |= 0x80;
256 break;
257 default:
258 break;
259 }
260 m88rs2000_demod_write(state, 0xb2, reg1);
261 m88rs2000_demod_write(state, 0xb1, reg0);
262 m88rs2000_demod_write(state, 0x9a, 0xb0);
263 return 0;
264}
265
266struct inittab {
267 u8 cmd;
268 u8 reg;
269 u8 val;
270};
271
272struct inittab m88rs2000_setup[] = {
273 {DEMOD_WRITE, 0x9a, 0x30},
274 {DEMOD_WRITE, 0x00, 0x01},
275 {WRITE_DELAY, 0x19, 0x00},
276 {DEMOD_WRITE, 0x00, 0x00},
277 {DEMOD_WRITE, 0x9a, 0xb0},
278 {DEMOD_WRITE, 0x81, 0xc1},
279 {TUNER_WRITE, 0x42, 0x73},
280 {TUNER_WRITE, 0x05, 0x07},
281 {TUNER_WRITE, 0x20, 0x27},
282 {TUNER_WRITE, 0x07, 0x02},
283 {TUNER_WRITE, 0x11, 0xff},
284 {TUNER_WRITE, 0x60, 0xf9},
285 {TUNER_WRITE, 0x08, 0x01},
286 {TUNER_WRITE, 0x00, 0x41},
287 {DEMOD_WRITE, 0x81, 0x81},
288 {DEMOD_WRITE, 0x86, 0xc6},
289 {DEMOD_WRITE, 0x9a, 0x30},
290 {DEMOD_WRITE, 0xf0, 0x22},
291 {DEMOD_WRITE, 0xf1, 0xbf},
292 {DEMOD_WRITE, 0xb0, 0x45},
293 {DEMOD_WRITE, 0xb2, 0x01}, /* set voltage pin always set 1*/
294 {DEMOD_WRITE, 0x9a, 0xb0},
295 {0xff, 0xaa, 0xff}
296};
297
298struct inittab m88rs2000_shutdown[] = {
299 {DEMOD_WRITE, 0x9a, 0x30},
300 {DEMOD_WRITE, 0xb0, 0x00},
301 {DEMOD_WRITE, 0xf1, 0x89},
302 {DEMOD_WRITE, 0x00, 0x01},
303 {DEMOD_WRITE, 0x9a, 0xb0},
304 {TUNER_WRITE, 0x00, 0x40},
305 {DEMOD_WRITE, 0x81, 0x81},
306 {0xff, 0xaa, 0xff}
307};
308
309struct inittab tuner_reset[] = {
310 {TUNER_WRITE, 0x42, 0x73},
311 {TUNER_WRITE, 0x05, 0x07},
312 {TUNER_WRITE, 0x20, 0x27},
313 {TUNER_WRITE, 0x07, 0x02},
314 {TUNER_WRITE, 0x11, 0xff},
315 {TUNER_WRITE, 0x60, 0xf9},
316 {TUNER_WRITE, 0x08, 0x01},
317 {TUNER_WRITE, 0x00, 0x41},
318 {0xff, 0xaa, 0xff}
319};
320
321struct inittab fe_reset[] = {
322 {DEMOD_WRITE, 0x00, 0x01},
323 {DEMOD_WRITE, 0xf1, 0xbf},
324 {DEMOD_WRITE, 0x00, 0x01},
325 {DEMOD_WRITE, 0x20, 0x81},
326 {DEMOD_WRITE, 0x21, 0x80},
327 {DEMOD_WRITE, 0x10, 0x33},
328 {DEMOD_WRITE, 0x11, 0x44},
329 {DEMOD_WRITE, 0x12, 0x07},
330 {DEMOD_WRITE, 0x18, 0x20},
331 {DEMOD_WRITE, 0x28, 0x04},
332 {DEMOD_WRITE, 0x29, 0x8e},
333 {DEMOD_WRITE, 0x3b, 0xff},
334 {DEMOD_WRITE, 0x32, 0x10},
335 {DEMOD_WRITE, 0x33, 0x02},
336 {DEMOD_WRITE, 0x34, 0x30},
337 {DEMOD_WRITE, 0x35, 0xff},
338 {DEMOD_WRITE, 0x38, 0x50},
339 {DEMOD_WRITE, 0x39, 0x68},
340 {DEMOD_WRITE, 0x3c, 0x7f},
341 {DEMOD_WRITE, 0x3d, 0x0f},
342 {DEMOD_WRITE, 0x45, 0x20},
343 {DEMOD_WRITE, 0x46, 0x24},
344 {DEMOD_WRITE, 0x47, 0x7c},
345 {DEMOD_WRITE, 0x48, 0x16},
346 {DEMOD_WRITE, 0x49, 0x04},
347 {DEMOD_WRITE, 0x4a, 0x01},
348 {DEMOD_WRITE, 0x4b, 0x78},
349 {DEMOD_WRITE, 0X4d, 0xd2},
350 {DEMOD_WRITE, 0x4e, 0x6d},
351 {DEMOD_WRITE, 0x50, 0x30},
352 {DEMOD_WRITE, 0x51, 0x30},
353 {DEMOD_WRITE, 0x54, 0x7b},
354 {DEMOD_WRITE, 0x56, 0x09},
355 {DEMOD_WRITE, 0x58, 0x59},
356 {DEMOD_WRITE, 0x59, 0x37},
357 {DEMOD_WRITE, 0x63, 0xfa},
358 {0xff, 0xaa, 0xff}
359};
360
361struct inittab fe_trigger[] = {
362 {DEMOD_WRITE, 0x97, 0x04},
363 {DEMOD_WRITE, 0x99, 0x77},
364 {DEMOD_WRITE, 0x9b, 0x64},
365 {DEMOD_WRITE, 0x9e, 0x00},
366 {DEMOD_WRITE, 0x9f, 0xf8},
367 {DEMOD_WRITE, 0xa0, 0x20},
368 {DEMOD_WRITE, 0xa1, 0xe0},
369 {DEMOD_WRITE, 0xa3, 0x38},
370 {DEMOD_WRITE, 0x98, 0xff},
371 {DEMOD_WRITE, 0xc0, 0x0f},
372 {DEMOD_WRITE, 0x89, 0x01},
373 {DEMOD_WRITE, 0x00, 0x00},
374 {WRITE_DELAY, 0x0a, 0x00},
375 {DEMOD_WRITE, 0x00, 0x01},
376 {DEMOD_WRITE, 0x00, 0x00},
377 {DEMOD_WRITE, 0x9a, 0xb0},
378 {0xff, 0xaa, 0xff}
379};
380
381static int m88rs2000_tab_set(struct m88rs2000_state *state,
382 struct inittab *tab)
383{
384 int ret = 0;
385 u8 i;
386 if (tab == NULL)
387 return -EINVAL;
388
389 for (i = 0; i < 255; i++) {
390 switch (tab[i].cmd) {
391 case 0x01:
392 ret = m88rs2000_demod_write(state, tab[i].reg,
393 tab[i].val);
394 break;
395 case 0x02:
396 ret = m88rs2000_tuner_write(state, tab[i].reg,
397 tab[i].val);
398 break;
399 case 0x10:
400 if (tab[i].reg > 0)
401 mdelay(tab[i].reg);
402 break;
403 case 0xff:
404 if (tab[i].reg == 0xaa && tab[i].val == 0xff)
405 return 0;
406 case 0x00:
407 break;
408 default:
409 return -EINVAL;
410 }
411 if (ret < 0)
412 return -ENODEV;
413 }
414 return 0;
415}
416
417static int m88rs2000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
418{
419 deb_info("%s: %s\n", __func__,
420 volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
421 volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
422
423 return 0;
424}
425
426static int m88rs2000_startup(struct m88rs2000_state *state)
427{
428 int ret = 0;
429 u8 reg;
430
431 reg = m88rs2000_tuner_read(state, 0x00);
432 if ((reg & 0x40) == 0)
433 ret = -ENODEV;
434
435 return ret;
436}
437
438static int m88rs2000_init(struct dvb_frontend *fe)
439{
440 struct m88rs2000_state *state = fe->demodulator_priv;
441 int ret;
442
443 deb_info("m88rs2000: init chip\n");
444 /* Setup frontend from shutdown/cold */
445 ret = m88rs2000_tab_set(state, m88rs2000_setup);
446
447 return ret;
448}
449
450static int m88rs2000_sleep(struct dvb_frontend *fe)
451{
452 struct m88rs2000_state *state = fe->demodulator_priv;
453 int ret;
454 /* Shutdown the frondend */
455 ret = m88rs2000_tab_set(state, m88rs2000_shutdown);
456 return ret;
457}
458
459static int m88rs2000_read_status(struct dvb_frontend *fe, fe_status_t *status)
460{
461 struct m88rs2000_state *state = fe->demodulator_priv;
462 u8 reg = m88rs2000_demod_read(state, 0x8c);
463
464 *status = 0;
465
466 if ((reg & 0x7) == 0x7) {
467 *status = FE_HAS_CARRIER | FE_HAS_SIGNAL | FE_HAS_VITERBI
468 | FE_HAS_LOCK;
469 if (state->config->set_ts_params)
470 state->config->set_ts_params(fe, CALL_IS_READ);
471 }
472 return 0;
473}
474
475/* Extact code for these unknown but lmedm04 driver uses interupt callbacks */
476
477static int m88rs2000_read_ber(struct dvb_frontend *fe, u32 *ber)
478{
479 deb_info("m88rs2000_read_ber %d\n", *ber);
480 *ber = 0;
481 return 0;
482}
483
484static int m88rs2000_read_signal_strength(struct dvb_frontend *fe,
485 u16 *strength)
486{
487 *strength = 0;
488 return 0;
489}
490
491static int m88rs2000_read_snr(struct dvb_frontend *fe, u16 *snr)
492{
493 deb_info("m88rs2000_read_snr %d\n", *snr);
494 *snr = 0;
495 return 0;
496}
497
498static int m88rs2000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
499{
500 deb_info("m88rs2000_read_ber %d\n", *ucblocks);
501 *ucblocks = 0;
502 return 0;
503}
504
505static int m88rs2000_tuner_gate_ctrl(struct m88rs2000_state *state, u8 offset)
506{
507 int ret;
508 ret = m88rs2000_tuner_write(state, 0x51, 0x1f - offset);
509 ret |= m88rs2000_tuner_write(state, 0x51, 0x1f);
510 ret |= m88rs2000_tuner_write(state, 0x50, offset);
511 ret |= m88rs2000_tuner_write(state, 0x50, 0x00);
512 msleep(20);
513 return ret;
514}
515
516static int m88rs2000_set_tuner_rf(struct dvb_frontend *fe)
517{
518 struct m88rs2000_state *state = fe->demodulator_priv;
519 int reg;
520 reg = m88rs2000_tuner_read(state, 0x3d);
521 reg &= 0x7f;
522 if (reg < 0x16)
523 reg = 0xa1;
524 else if (reg == 0x16)
525 reg = 0x99;
526 else
527 reg = 0xf9;
528
529 m88rs2000_tuner_write(state, 0x60, reg);
530 reg = m88rs2000_tuner_gate_ctrl(state, 0x08);
531
532 if (fe->ops.i2c_gate_ctrl)
533 fe->ops.i2c_gate_ctrl(fe, 0);
534 return reg;
535}
536
537static int m88rs2000_set_tuner(struct dvb_frontend *fe, u16 *offset)
538{
539 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
540 struct m88rs2000_state *state = fe->demodulator_priv;
541 int ret;
542 u32 frequency = c->frequency;
543 s32 offset_khz;
544 s32 tmp;
545 u32 symbol_rate = (c->symbol_rate / 1000);
546 u32 f3db, gdiv28;
547 u16 value, ndiv, lpf_coeff;
548 u8 lpf_mxdiv, mlpf_max, mlpf_min, nlpf;
549 u8 lo = 0x01, div4 = 0x0;
550
551 /* Reset Tuner */
552 ret = m88rs2000_tab_set(state, tuner_reset);
553
554 /* Calculate frequency divider */
555 if (frequency < 1060000) {
556 lo |= 0x10;
557 div4 = 0x1;
558 ndiv = (frequency * 14 * 4) / FE_CRYSTAL_KHZ;
559 } else
560 ndiv = (frequency * 14 * 2) / FE_CRYSTAL_KHZ;
561 ndiv = ndiv + ndiv % 2;
562 ndiv = ndiv - 1024;
563
564 ret = m88rs2000_tuner_write(state, 0x10, 0x80 | lo);
565
566 /* Set frequency divider */
567 ret |= m88rs2000_tuner_write(state, 0x01, (ndiv >> 8) & 0xf);
568 ret |= m88rs2000_tuner_write(state, 0x02, ndiv & 0xff);
569
570 ret |= m88rs2000_tuner_write(state, 0x03, 0x06);
571 ret |= m88rs2000_tuner_gate_ctrl(state, 0x10);
572 if (ret < 0)
573 return -ENODEV;
574
575 /* Tuner Frequency Range */
576 ret = m88rs2000_tuner_write(state, 0x10, lo);
577
578 ret |= m88rs2000_tuner_gate_ctrl(state, 0x08);
579
580 /* Tuner RF */
581 ret |= m88rs2000_set_tuner_rf(fe);
582
583 gdiv28 = (FE_CRYSTAL_KHZ / 1000 * 1694 + 500) / 1000;
584 ret |= m88rs2000_tuner_write(state, 0x04, gdiv28 & 0xff);
585 ret |= m88rs2000_tuner_gate_ctrl(state, 0x04);
586 if (ret < 0)
587 return -ENODEV;
588
589 value = m88rs2000_tuner_read(state, 0x26);
590
591 f3db = (symbol_rate * 135) / 200 + 2000;
592 f3db += FREQ_OFFSET_LOW_SYM_RATE;
593 if (f3db < 7000)
594 f3db = 7000;
595 if (f3db > 40000)
596 f3db = 40000;
597
598 gdiv28 = gdiv28 * 207 / (value * 2 + 151);
599 mlpf_max = gdiv28 * 135 / 100;
600 mlpf_min = gdiv28 * 78 / 100;
601 if (mlpf_max > 63)
602 mlpf_max = 63;
603
604 lpf_coeff = 2766;
605
606 nlpf = (f3db * gdiv28 * 2 / lpf_coeff /
607 (FE_CRYSTAL_KHZ / 1000) + 1) / 2;
608 if (nlpf > 23)
609 nlpf = 23;
610 if (nlpf < 1)
611 nlpf = 1;
612
613 lpf_mxdiv = (nlpf * (FE_CRYSTAL_KHZ / 1000)
614 * lpf_coeff * 2 / f3db + 1) / 2;
615
616 if (lpf_mxdiv < mlpf_min) {
617 nlpf++;
618 lpf_mxdiv = (nlpf * (FE_CRYSTAL_KHZ / 1000)
619 * lpf_coeff * 2 / f3db + 1) / 2;
620 }
621
622 if (lpf_mxdiv > mlpf_max)
623 lpf_mxdiv = mlpf_max;
624
625 ret = m88rs2000_tuner_write(state, 0x04, lpf_mxdiv);
626 ret |= m88rs2000_tuner_write(state, 0x06, nlpf);
627
628 ret |= m88rs2000_tuner_gate_ctrl(state, 0x04);
629
630 ret |= m88rs2000_tuner_gate_ctrl(state, 0x01);
631
632 msleep(80);
633 /* calculate offset assuming 96000kHz*/
634 offset_khz = (ndiv - ndiv % 2 + 1024) * FE_CRYSTAL_KHZ
635 / 14 / (div4 + 1) / 2;
636
637 offset_khz -= frequency;
638
639 tmp = offset_khz;
640 tmp *= 65536;
641
642 tmp = (2 * tmp + 96000) / (2 * 96000);
643 if (tmp < 0)
644 tmp += 65536;
645
646 *offset = tmp & 0xffff;
647
648 if (fe->ops.i2c_gate_ctrl)
649 fe->ops.i2c_gate_ctrl(fe, 0);
650
651 return (ret < 0) ? -EINVAL : 0;
652}
653
654static int m88rs2000_set_fec(struct m88rs2000_state *state,
655 fe_code_rate_t fec)
656{
657 int ret;
658 u16 fec_set;
659 switch (fec) {
660 /* This is not confirmed kept for reference */
661/* case FEC_1_2:
662 fec_set = 0x88;
663 break;
664 case FEC_2_3:
665 fec_set = 0x68;
666 break;
667 case FEC_3_4:
668 fec_set = 0x48;
669 break;
670 case FEC_5_6:
671 fec_set = 0x28;
672 break;
673 case FEC_7_8:
674 fec_set = 0x18;
675 break; */
676 case FEC_AUTO:
677 default:
678 fec_set = 0x08;
679 }
680 ret = m88rs2000_demod_write(state, 0x76, fec_set);
681
682 return 0;
683}
684
685
686static fe_code_rate_t m88rs2000_get_fec(struct m88rs2000_state *state)
687{
688 u8 reg;
689 m88rs2000_demod_write(state, 0x9a, 0x30);
690 reg = m88rs2000_demod_read(state, 0x76);
691 m88rs2000_demod_write(state, 0x9a, 0xb0);
692
693 switch (reg) {
694 case 0x88:
695 return FEC_1_2;
696 case 0x68:
697 return FEC_2_3;
698 case 0x48:
699 return FEC_3_4;
700 case 0x28:
701 return FEC_5_6;
702 case 0x18:
703 return FEC_7_8;
704 case 0x08:
705 default:
706 break;
707 }
708
709 return FEC_AUTO;
710}
711
712static int m88rs2000_set_frontend(struct dvb_frontend *fe)
713{
714 struct m88rs2000_state *state = fe->demodulator_priv;
715 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
716 fe_status_t status;
717 int i, ret;
718 u16 offset = 0;
719 u8 reg;
720
721 state->no_lock_count = 0;
722
723 if (c->delivery_system != SYS_DVBS) {
724 deb_info("%s: unsupported delivery "
725 "system selected (%d)\n",
726 __func__, c->delivery_system);
727 return -EOPNOTSUPP;
728 }
729
730 /* Set Tuner */
731 ret = m88rs2000_set_tuner(fe, &offset);
732 if (ret < 0)
733 return -ENODEV;
734
735 ret = m88rs2000_demod_write(state, 0x9a, 0x30);
736 /* Unknown usually 0xc6 sometimes 0xc1 */
737 reg = m88rs2000_demod_read(state, 0x86);
738 ret |= m88rs2000_demod_write(state, 0x86, reg);
739 /* Offset lower nibble always 0 */
740 ret |= m88rs2000_demod_write(state, 0x9c, (offset >> 8));
741 ret |= m88rs2000_demod_write(state, 0x9d, offset & 0xf0);
742
743
744 /* Reset Demod */
745 ret = m88rs2000_tab_set(state, fe_reset);
746 if (ret < 0)
747 return -ENODEV;
748
749 /* Unknown */
750 reg = m88rs2000_demod_read(state, 0x70);
751 ret = m88rs2000_demod_write(state, 0x70, reg);
752
753 /* Set FEC */
754 ret |= m88rs2000_set_fec(state, c->fec_inner);
755 ret |= m88rs2000_demod_write(state, 0x85, 0x1);
756 ret |= m88rs2000_demod_write(state, 0x8a, 0xbf);
757 ret |= m88rs2000_demod_write(state, 0x8d, 0x1e);
758 ret |= m88rs2000_demod_write(state, 0x90, 0xf1);
759 ret |= m88rs2000_demod_write(state, 0x91, 0x08);
760
761 if (ret < 0)
762 return -ENODEV;
763
764 /* Set Symbol Rate */
765 ret = m88rs2000_set_symbolrate(fe, c->symbol_rate);
766 if (ret < 0)
767 return -ENODEV;
768
769 /* Set up Demod */
770 ret = m88rs2000_tab_set(state, fe_trigger);
771 if (ret < 0)
772 return -ENODEV;
773
774 for (i = 0; i < 25; i++) {
775 u8 reg = m88rs2000_demod_read(state, 0x8c);
776 if ((reg & 0x7) == 0x7) {
777 status = FE_HAS_LOCK;
778 break;
779 }
780 state->no_lock_count++;
781 if (state->no_lock_count > 15) {
782 reg = m88rs2000_demod_read(state, 0x70);
783 reg ^= 0x4;
784 m88rs2000_demod_write(state, 0x70, reg);
785 state->no_lock_count = 0;
786 }
787 if (state->no_lock_count == 20)
788 m88rs2000_set_tuner_rf(fe);
789 msleep(20);
790 }
791
792 if (status & FE_HAS_LOCK) {
793 state->fec_inner = m88rs2000_get_fec(state);
794 /* Uknown suspect SNR level */
795 reg = m88rs2000_demod_read(state, 0x65);
796 }
797
798 state->tuner_frequency = c->frequency;
799 state->symbol_rate = c->symbol_rate;
800 return 0;
801}
802
803static int m88rs2000_get_frontend(struct dvb_frontend *fe)
804{
805 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
806 struct m88rs2000_state *state = fe->demodulator_priv;
807 c->fec_inner = state->fec_inner;
808 c->frequency = state->tuner_frequency;
809 c->symbol_rate = state->symbol_rate;
810 return 0;
811}
812
813static int m88rs2000_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
814{
815 struct m88rs2000_state *state = fe->demodulator_priv;
816
817 if (enable)
818 m88rs2000_demod_write(state, 0x81, 0x84);
819 else
820 m88rs2000_demod_write(state, 0x81, 0x81);
821 udelay(10);
822 return 0;
823}
824
825static void m88rs2000_release(struct dvb_frontend *fe)
826{
827 struct m88rs2000_state *state = fe->demodulator_priv;
828 kfree(state);
829}
830
831static struct dvb_frontend_ops m88rs2000_ops = {
832 .delsys = { SYS_DVBS },
833 .info = {
834 .name = "M88RS2000 DVB-S",
835 .frequency_min = 950000,
836 .frequency_max = 2150000,
837 .frequency_stepsize = 1000, /* kHz for QPSK frontends */
838 .frequency_tolerance = 5000,
839 .symbol_rate_min = 1000000,
840 .symbol_rate_max = 45000000,
841 .symbol_rate_tolerance = 500, /* ppm */
842 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
843 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
844 FE_CAN_QPSK |
845 FE_CAN_FEC_AUTO
846 },
847
848 .release = m88rs2000_release,
849 .init = m88rs2000_init,
850 .sleep = m88rs2000_sleep,
851 .write = m88rs2000_write,
852 .i2c_gate_ctrl = m88rs2000_i2c_gate_ctrl,
853 .read_status = m88rs2000_read_status,
854 .read_ber = m88rs2000_read_ber,
855 .read_signal_strength = m88rs2000_read_signal_strength,
856 .read_snr = m88rs2000_read_snr,
857 .read_ucblocks = m88rs2000_read_ucblocks,
858 .diseqc_send_master_cmd = m88rs2000_send_diseqc_msg,
859 .diseqc_send_burst = m88rs2000_send_diseqc_burst,
860 .set_tone = m88rs2000_set_tone,
861 .set_voltage = m88rs2000_set_voltage,
862
863 .set_frontend = m88rs2000_set_frontend,
864 .get_frontend = m88rs2000_get_frontend,
865};
866
867struct dvb_frontend *m88rs2000_attach(const struct m88rs2000_config *config,
868 struct i2c_adapter *i2c)
869{
870 struct m88rs2000_state *state = NULL;
871
872 /* allocate memory for the internal state */
873 state = kzalloc(sizeof(struct m88rs2000_state), GFP_KERNEL);
874 if (state == NULL)
875 goto error;
876
877 /* setup the state */
878 state->config = config;
879 state->i2c = i2c;
880 state->tuner_frequency = 0;
881 state->symbol_rate = 0;
882 state->fec_inner = 0;
883
884 if (m88rs2000_startup(state) < 0)
885 goto error;
886
887 /* create dvb_frontend */
888 memcpy(&state->frontend.ops, &m88rs2000_ops,
889 sizeof(struct dvb_frontend_ops));
890 state->frontend.demodulator_priv = state;
891 return &state->frontend;
892
893error:
894 kfree(state);
895
896 return NULL;
897}
898EXPORT_SYMBOL(m88rs2000_attach);
899
900MODULE_DESCRIPTION("M88RS2000 DVB-S Demodulator driver");
901MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
902MODULE_LICENSE("GPL");
903MODULE_VERSION("1.13");
904
diff --git a/drivers/media/dvb/frontends/m88rs2000.h b/drivers/media/dvb/frontends/m88rs2000.h
new file mode 100644
index 000000000000..59acdb696873
--- /dev/null
+++ b/drivers/media/dvb/frontends/m88rs2000.h
@@ -0,0 +1,66 @@
1/*
2 Driver for M88RS2000 demodulator
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18*/
19
20#ifndef M88RS2000_H
21#define M88RS2000_H
22
23#include <linux/dvb/frontend.h>
24#include "dvb_frontend.h"
25
26struct m88rs2000_config {
27 /* Demodulator i2c address */
28 u8 demod_addr;
29 /* Tuner address */
30 u8 tuner_addr;
31
32 u8 *inittab;
33
34 /* minimum delay before retuning */
35 int min_delay_ms;
36
37 int (*set_ts_params)(struct dvb_frontend *, int);
38};
39
40enum {
41 CALL_IS_SET_FRONTEND = 0x0,
42 CALL_IS_READ,
43};
44
45#if defined(CONFIG_DVB_M88RS2000) || (defined(CONFIG_DVB_M88RS2000_MODULE) && \
46 defined(MODULE))
47extern struct dvb_frontend *m88rs2000_attach(
48 const struct m88rs2000_config *config, struct i2c_adapter *i2c);
49#else
50static inline struct dvb_frontend *m88rs2000_attach(
51 const struct m88rs2000_config *config, struct i2c_adapter *i2c)
52{
53 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
54 return NULL;
55}
56#endif /* CONFIG_DVB_M88RS2000 */
57
58#define FE_CRYSTAL_KHZ 27000
59#define FREQ_OFFSET_LOW_SYM_RATE 3000
60
61enum {
62 DEMOD_WRITE = 0x1,
63 TUNER_WRITE,
64 WRITE_DELAY = 0x10,
65};
66#endif /* M88RS2000_H */
diff --git a/drivers/media/dvb/frontends/rtl2830.c b/drivers/media/dvb/frontends/rtl2830.c
new file mode 100644
index 000000000000..45196c5b0736
--- /dev/null
+++ b/drivers/media/dvb/frontends/rtl2830.c
@@ -0,0 +1,562 @@
1/*
2 * Realtek RTL2830 DVB-T demodulator driver
3 *
4 * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
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 along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21
22/*
23 * Driver implements own I2C-adapter for tuner I2C access. That's since chip
24 * have unusual I2C-gate control which closes gate automatically after each
25 * I2C transfer. Using own I2C adapter we can workaround that.
26 */
27
28#include "rtl2830_priv.h"
29
30int rtl2830_debug;
31module_param_named(debug, rtl2830_debug, int, 0644);
32MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
33
34/* write multiple hardware registers */
35static int rtl2830_wr(struct rtl2830_priv *priv, u8 reg, u8 *val, int len)
36{
37 int ret;
38 u8 buf[1+len];
39 struct i2c_msg msg[1] = {
40 {
41 .addr = priv->cfg.i2c_addr,
42 .flags = 0,
43 .len = 1+len,
44 .buf = buf,
45 }
46 };
47
48 buf[0] = reg;
49 memcpy(&buf[1], val, len);
50
51 ret = i2c_transfer(priv->i2c, msg, 1);
52 if (ret == 1) {
53 ret = 0;
54 } else {
55 warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len);
56 ret = -EREMOTEIO;
57 }
58 return ret;
59}
60
61/* read multiple hardware registers */
62static int rtl2830_rd(struct rtl2830_priv *priv, u8 reg, u8 *val, int len)
63{
64 int ret;
65 struct i2c_msg msg[2] = {
66 {
67 .addr = priv->cfg.i2c_addr,
68 .flags = 0,
69 .len = 1,
70 .buf = &reg,
71 }, {
72 .addr = priv->cfg.i2c_addr,
73 .flags = I2C_M_RD,
74 .len = len,
75 .buf = val,
76 }
77 };
78
79 ret = i2c_transfer(priv->i2c, msg, 2);
80 if (ret == 2) {
81 ret = 0;
82 } else {
83 warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len);
84 ret = -EREMOTEIO;
85 }
86 return ret;
87}
88
89/* write multiple registers */
90static int rtl2830_wr_regs(struct rtl2830_priv *priv, u16 reg, u8 *val, int len)
91{
92 int ret;
93 u8 reg2 = (reg >> 0) & 0xff;
94 u8 page = (reg >> 8) & 0xff;
95
96 /* switch bank if needed */
97 if (page != priv->page) {
98 ret = rtl2830_wr(priv, 0x00, &page, 1);
99 if (ret)
100 return ret;
101
102 priv->page = page;
103 }
104
105 return rtl2830_wr(priv, reg2, val, len);
106}
107
108/* read multiple registers */
109static int rtl2830_rd_regs(struct rtl2830_priv *priv, u16 reg, u8 *val, int len)
110{
111 int ret;
112 u8 reg2 = (reg >> 0) & 0xff;
113 u8 page = (reg >> 8) & 0xff;
114
115 /* switch bank if needed */
116 if (page != priv->page) {
117 ret = rtl2830_wr(priv, 0x00, &page, 1);
118 if (ret)
119 return ret;
120
121 priv->page = page;
122 }
123
124 return rtl2830_rd(priv, reg2, val, len);
125}
126
127#if 0 /* currently not used */
128/* write single register */
129static int rtl2830_wr_reg(struct rtl2830_priv *priv, u16 reg, u8 val)
130{
131 return rtl2830_wr_regs(priv, reg, &val, 1);
132}
133#endif
134
135/* read single register */
136static int rtl2830_rd_reg(struct rtl2830_priv *priv, u16 reg, u8 *val)
137{
138 return rtl2830_rd_regs(priv, reg, val, 1);
139}
140
141/* write single register with mask */
142int rtl2830_wr_reg_mask(struct rtl2830_priv *priv, u16 reg, u8 val, u8 mask)
143{
144 int ret;
145 u8 tmp;
146
147 /* no need for read if whole reg is written */
148 if (mask != 0xff) {
149 ret = rtl2830_rd_regs(priv, reg, &tmp, 1);
150 if (ret)
151 return ret;
152
153 val &= mask;
154 tmp &= ~mask;
155 val |= tmp;
156 }
157
158 return rtl2830_wr_regs(priv, reg, &val, 1);
159}
160
161/* read single register with mask */
162int rtl2830_rd_reg_mask(struct rtl2830_priv *priv, u16 reg, u8 *val, u8 mask)
163{
164 int ret, i;
165 u8 tmp;
166
167 ret = rtl2830_rd_regs(priv, reg, &tmp, 1);
168 if (ret)
169 return ret;
170
171 tmp &= mask;
172
173 /* find position of the first bit */
174 for (i = 0; i < 8; i++) {
175 if ((mask >> i) & 0x01)
176 break;
177 }
178 *val = tmp >> i;
179
180 return 0;
181}
182
183static int rtl2830_init(struct dvb_frontend *fe)
184{
185 struct rtl2830_priv *priv = fe->demodulator_priv;
186 int ret, i;
187 u64 num;
188 u8 buf[3], tmp;
189 u32 if_ctl;
190 struct rtl2830_reg_val_mask tab[] = {
191 { 0x00d, 0x01, 0x03 },
192 { 0x00d, 0x10, 0x10 },
193 { 0x104, 0x00, 0x1e },
194 { 0x105, 0x80, 0x80 },
195 { 0x110, 0x02, 0x03 },
196 { 0x110, 0x08, 0x0c },
197 { 0x17b, 0x00, 0x40 },
198 { 0x17d, 0x05, 0x0f },
199 { 0x17d, 0x50, 0xf0 },
200 { 0x18c, 0x08, 0x0f },
201 { 0x18d, 0x00, 0xc0 },
202 { 0x188, 0x05, 0x0f },
203 { 0x189, 0x00, 0xfc },
204 { 0x2d5, 0x02, 0x02 },
205 { 0x2f1, 0x02, 0x06 },
206 { 0x2f1, 0x20, 0xf8 },
207 { 0x16d, 0x00, 0x01 },
208 { 0x1a6, 0x00, 0x80 },
209 { 0x106, priv->cfg.vtop, 0x3f },
210 { 0x107, priv->cfg.krf, 0x3f },
211 { 0x112, 0x28, 0xff },
212 { 0x103, priv->cfg.agc_targ_val, 0xff },
213 { 0x00a, 0x02, 0x07 },
214 { 0x140, 0x0c, 0x3c },
215 { 0x140, 0x40, 0xc0 },
216 { 0x15b, 0x05, 0x07 },
217 { 0x15b, 0x28, 0x38 },
218 { 0x15c, 0x05, 0x07 },
219 { 0x15c, 0x28, 0x38 },
220 { 0x115, priv->cfg.spec_inv, 0x01 },
221 { 0x16f, 0x01, 0x07 },
222 { 0x170, 0x18, 0x38 },
223 { 0x172, 0x0f, 0x0f },
224 { 0x173, 0x08, 0x38 },
225 { 0x175, 0x01, 0x07 },
226 { 0x176, 0x00, 0xc0 },
227 };
228
229 for (i = 0; i < ARRAY_SIZE(tab); i++) {
230 ret = rtl2830_wr_reg_mask(priv, tab[i].reg, tab[i].val,
231 tab[i].mask);
232 if (ret)
233 goto err;
234 }
235
236 ret = rtl2830_wr_regs(priv, 0x18f, "\x28\x00", 2);
237 if (ret)
238 goto err;
239
240 ret = rtl2830_wr_regs(priv, 0x195,
241 "\x04\x06\x0a\x12\x0a\x12\x1e\x28", 8);
242 if (ret)
243 goto err;
244
245 num = priv->cfg.if_dvbt % priv->cfg.xtal;
246 num *= 0x400000;
247 num = div_u64(num, priv->cfg.xtal);
248 num = -num;
249 if_ctl = num & 0x3fffff;
250 dbg("%s: if_ctl=%08x", __func__, if_ctl);
251
252 ret = rtl2830_rd_reg_mask(priv, 0x119, &tmp, 0xc0); /* b[7:6] */
253 if (ret)
254 goto err;
255
256 buf[0] = tmp << 6;
257 buf[0] = (if_ctl >> 16) & 0x3f;
258 buf[1] = (if_ctl >> 8) & 0xff;
259 buf[2] = (if_ctl >> 0) & 0xff;
260
261 ret = rtl2830_wr_regs(priv, 0x119, buf, 3);
262 if (ret)
263 goto err;
264
265 /* TODO: spec init */
266
267 /* soft reset */
268 ret = rtl2830_wr_reg_mask(priv, 0x101, 0x04, 0x04);
269 if (ret)
270 goto err;
271
272 ret = rtl2830_wr_reg_mask(priv, 0x101, 0x00, 0x04);
273 if (ret)
274 goto err;
275
276 priv->sleeping = false;
277
278 return ret;
279err:
280 dbg("%s: failed=%d", __func__, ret);
281 return ret;
282}
283
284static int rtl2830_sleep(struct dvb_frontend *fe)
285{
286 struct rtl2830_priv *priv = fe->demodulator_priv;
287 priv->sleeping = true;
288 return 0;
289}
290
291int rtl2830_get_tune_settings(struct dvb_frontend *fe,
292 struct dvb_frontend_tune_settings *s)
293{
294 s->min_delay_ms = 500;
295 s->step_size = fe->ops.info.frequency_stepsize * 2;
296 s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
297
298 return 0;
299}
300
301static int rtl2830_set_frontend(struct dvb_frontend *fe)
302{
303 struct rtl2830_priv *priv = fe->demodulator_priv;
304 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
305 int ret, i;
306 static u8 bw_params1[3][34] = {
307 {
308 0x1f, 0xf0, 0x1f, 0xf0, 0x1f, 0xfa, 0x00, 0x17, 0x00, 0x41,
309 0x00, 0x64, 0x00, 0x67, 0x00, 0x38, 0x1f, 0xde, 0x1f, 0x7a,
310 0x1f, 0x47, 0x1f, 0x7c, 0x00, 0x30, 0x01, 0x4b, 0x02, 0x82,
311 0x03, 0x73, 0x03, 0xcf, /* 6 MHz */
312 }, {
313 0x1f, 0xfa, 0x1f, 0xda, 0x1f, 0xc1, 0x1f, 0xb3, 0x1f, 0xca,
314 0x00, 0x07, 0x00, 0x4d, 0x00, 0x6d, 0x00, 0x40, 0x1f, 0xca,
315 0x1f, 0x4d, 0x1f, 0x2a, 0x1f, 0xb2, 0x00, 0xec, 0x02, 0x7e,
316 0x03, 0xd0, 0x04, 0x53, /* 7 MHz */
317 }, {
318 0x00, 0x10, 0x00, 0x0e, 0x1f, 0xf7, 0x1f, 0xc9, 0x1f, 0xa0,
319 0x1f, 0xa6, 0x1f, 0xec, 0x00, 0x4e, 0x00, 0x7d, 0x00, 0x3a,
320 0x1f, 0x98, 0x1f, 0x10, 0x1f, 0x40, 0x00, 0x75, 0x02, 0x5f,
321 0x04, 0x24, 0x04, 0xdb, /* 8 MHz */
322 },
323 };
324 static u8 bw_params2[3][6] = {
325 {0xc3, 0x0c, 0x44, 0x33, 0x33, 0x30,}, /* 6 MHz */
326 {0xb8, 0xe3, 0x93, 0x99, 0x99, 0x98,}, /* 7 MHz */
327 {0xae, 0xba, 0xf3, 0x26, 0x66, 0x64,}, /* 8 MHz */
328 };
329
330
331 dbg("%s: frequency=%d bandwidth_hz=%d inversion=%d", __func__,
332 c->frequency, c->bandwidth_hz, c->inversion);
333
334 /* program tuner */
335 if (fe->ops.tuner_ops.set_params)
336 fe->ops.tuner_ops.set_params(fe);
337
338 switch (c->bandwidth_hz) {
339 case 6000000:
340 i = 0;
341 break;
342 case 7000000:
343 i = 1;
344 break;
345 case 8000000:
346 i = 2;
347 break;
348 default:
349 dbg("invalid bandwidth");
350 return -EINVAL;
351 }
352
353 ret = rtl2830_wr_reg_mask(priv, 0x008, i << 1, 0x06);
354 if (ret)
355 goto err;
356
357 /* 1/2 split I2C write */
358 ret = rtl2830_wr_regs(priv, 0x11c, &bw_params1[i][0], 17);
359 if (ret)
360 goto err;
361
362 /* 2/2 split I2C write */
363 ret = rtl2830_wr_regs(priv, 0x12d, &bw_params1[i][17], 17);
364 if (ret)
365 goto err;
366
367 ret = rtl2830_wr_regs(priv, 0x19d, bw_params2[i], 6);
368 if (ret)
369 goto err;
370
371 return ret;
372err:
373 dbg("%s: failed=%d", __func__, ret);
374 return ret;
375}
376
377static int rtl2830_read_status(struct dvb_frontend *fe, fe_status_t *status)
378{
379 struct rtl2830_priv *priv = fe->demodulator_priv;
380 int ret;
381 u8 tmp;
382 *status = 0;
383
384 if (priv->sleeping)
385 return 0;
386
387 ret = rtl2830_rd_reg_mask(priv, 0x351, &tmp, 0x78); /* [6:3] */
388 if (ret)
389 goto err;
390
391 if (tmp == 11) {
392 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
393 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
394 } else if (tmp == 10) {
395 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
396 FE_HAS_VITERBI;
397 }
398
399 return ret;
400err:
401 dbg("%s: failed=%d", __func__, ret);
402 return ret;
403}
404
405static int rtl2830_read_snr(struct dvb_frontend *fe, u16 *snr)
406{
407 *snr = 0;
408 return 0;
409}
410
411static int rtl2830_read_ber(struct dvb_frontend *fe, u32 *ber)
412{
413 *ber = 0;
414 return 0;
415}
416
417static int rtl2830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
418{
419 *ucblocks = 0;
420 return 0;
421}
422
423static int rtl2830_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
424{
425 *strength = 0;
426 return 0;
427}
428
429static struct dvb_frontend_ops rtl2830_ops;
430
431static u32 rtl2830_tuner_i2c_func(struct i2c_adapter *adapter)
432{
433 return I2C_FUNC_I2C;
434}
435
436static int rtl2830_tuner_i2c_xfer(struct i2c_adapter *i2c_adap,
437 struct i2c_msg msg[], int num)
438{
439 struct rtl2830_priv *priv = i2c_get_adapdata(i2c_adap);
440 int ret;
441
442 /* open i2c-gate */
443 ret = rtl2830_wr_reg_mask(priv, 0x101, 0x08, 0x08);
444 if (ret)
445 goto err;
446
447 ret = i2c_transfer(priv->i2c, msg, num);
448 if (ret < 0)
449 warn("tuner i2c failed=%d", ret);
450
451 return ret;
452err:
453 dbg("%s: failed=%d", __func__, ret);
454 return ret;
455}
456
457static struct i2c_algorithm rtl2830_tuner_i2c_algo = {
458 .master_xfer = rtl2830_tuner_i2c_xfer,
459 .functionality = rtl2830_tuner_i2c_func,
460};
461
462struct i2c_adapter *rtl2830_get_tuner_i2c_adapter(struct dvb_frontend *fe)
463{
464 struct rtl2830_priv *priv = fe->demodulator_priv;
465 return &priv->tuner_i2c_adapter;
466}
467EXPORT_SYMBOL(rtl2830_get_tuner_i2c_adapter);
468
469static void rtl2830_release(struct dvb_frontend *fe)
470{
471 struct rtl2830_priv *priv = fe->demodulator_priv;
472
473 i2c_del_adapter(&priv->tuner_i2c_adapter);
474 kfree(priv);
475}
476
477struct dvb_frontend *rtl2830_attach(const struct rtl2830_config *cfg,
478 struct i2c_adapter *i2c)
479{
480 struct rtl2830_priv *priv = NULL;
481 int ret = 0;
482 u8 tmp;
483
484 /* allocate memory for the internal state */
485 priv = kzalloc(sizeof(struct rtl2830_priv), GFP_KERNEL);
486 if (priv == NULL)
487 goto err;
488
489 /* setup the priv */
490 priv->i2c = i2c;
491 memcpy(&priv->cfg, cfg, sizeof(struct rtl2830_config));
492
493 /* check if the demod is there */
494 ret = rtl2830_rd_reg(priv, 0x000, &tmp);
495 if (ret)
496 goto err;
497
498 /* create dvb_frontend */
499 memcpy(&priv->fe.ops, &rtl2830_ops, sizeof(struct dvb_frontend_ops));
500 priv->fe.demodulator_priv = priv;
501
502 /* create tuner i2c adapter */
503 strlcpy(priv->tuner_i2c_adapter.name, "RTL2830 tuner I2C adapter",
504 sizeof(priv->tuner_i2c_adapter.name));
505 priv->tuner_i2c_adapter.algo = &rtl2830_tuner_i2c_algo;
506 priv->tuner_i2c_adapter.algo_data = NULL;
507 i2c_set_adapdata(&priv->tuner_i2c_adapter, priv);
508 if (i2c_add_adapter(&priv->tuner_i2c_adapter) < 0) {
509 err("tuner I2C bus could not be initialized");
510 goto err;
511 }
512
513 priv->sleeping = true;
514
515 return &priv->fe;
516err:
517 dbg("%s: failed=%d", __func__, ret);
518 kfree(priv);
519 return NULL;
520}
521EXPORT_SYMBOL(rtl2830_attach);
522
523static struct dvb_frontend_ops rtl2830_ops = {
524 .delsys = { SYS_DVBT },
525 .info = {
526 .name = "Realtek RTL2830 (DVB-T)",
527 .caps = FE_CAN_FEC_1_2 |
528 FE_CAN_FEC_2_3 |
529 FE_CAN_FEC_3_4 |
530 FE_CAN_FEC_5_6 |
531 FE_CAN_FEC_7_8 |
532 FE_CAN_FEC_AUTO |
533 FE_CAN_QPSK |
534 FE_CAN_QAM_16 |
535 FE_CAN_QAM_64 |
536 FE_CAN_QAM_AUTO |
537 FE_CAN_TRANSMISSION_MODE_AUTO |
538 FE_CAN_GUARD_INTERVAL_AUTO |
539 FE_CAN_HIERARCHY_AUTO |
540 FE_CAN_RECOVER |
541 FE_CAN_MUTE_TS
542 },
543
544 .release = rtl2830_release,
545
546 .init = rtl2830_init,
547 .sleep = rtl2830_sleep,
548
549 .get_tune_settings = rtl2830_get_tune_settings,
550
551 .set_frontend = rtl2830_set_frontend,
552
553 .read_status = rtl2830_read_status,
554 .read_snr = rtl2830_read_snr,
555 .read_ber = rtl2830_read_ber,
556 .read_ucblocks = rtl2830_read_ucblocks,
557 .read_signal_strength = rtl2830_read_signal_strength,
558};
559
560MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
561MODULE_DESCRIPTION("Realtek RTL2830 DVB-T demodulator driver");
562MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/rtl2830.h b/drivers/media/dvb/frontends/rtl2830.h
new file mode 100644
index 000000000000..1c6ee91749c2
--- /dev/null
+++ b/drivers/media/dvb/frontends/rtl2830.h
@@ -0,0 +1,97 @@
1/*
2 * Realtek RTL2830 DVB-T demodulator driver
3 *
4 * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
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 along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#ifndef RTL2830_H
22#define RTL2830_H
23
24#include <linux/dvb/frontend.h>
25
26struct rtl2830_config {
27 /*
28 * Demodulator I2C address.
29 */
30 u8 i2c_addr;
31
32 /*
33 * Xtal frequency.
34 * Hz
35 * 4000000, 16000000, 25000000, 28800000
36 */
37 u32 xtal;
38
39 /*
40 * TS output mode.
41 */
42 u8 ts_mode;
43
44 /*
45 * Spectrum inversion.
46 */
47 bool spec_inv;
48
49 /*
50 * IFs for all used modes.
51 * Hz
52 * 4570000, 4571429, 36000000, 36125000, 36166667, 44000000
53 */
54 u32 if_dvbt;
55
56 /*
57 */
58 u8 vtop;
59
60 /*
61 */
62 u8 krf;
63
64 /*
65 */
66 u8 agc_targ_val;
67};
68
69#if defined(CONFIG_DVB_RTL2830) || \
70 (defined(CONFIG_DVB_RTL2830_MODULE) && defined(MODULE))
71extern struct dvb_frontend *rtl2830_attach(
72 const struct rtl2830_config *config,
73 struct i2c_adapter *i2c
74);
75
76extern struct i2c_adapter *rtl2830_get_tuner_i2c_adapter(
77 struct dvb_frontend *fe
78);
79#else
80static inline struct dvb_frontend *rtl2830_attach(
81 const struct rtl2830_config *config,
82 struct i2c_adapter *i2c
83)
84{
85 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
86 return NULL;
87}
88
89static inline struct i2c_adapter *rtl2830_get_tuner_i2c_adapter(
90 struct dvb_frontend *fe
91)
92{
93 return NULL;
94}
95#endif
96
97#endif /* RTL2830_H */
diff --git a/drivers/media/dvb/frontends/rtl2830_priv.h b/drivers/media/dvb/frontends/rtl2830_priv.h
new file mode 100644
index 000000000000..4a464761b5b8
--- /dev/null
+++ b/drivers/media/dvb/frontends/rtl2830_priv.h
@@ -0,0 +1,57 @@
1/*
2 * Realtek RTL2830 DVB-T demodulator driver
3 *
4 * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
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 along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#ifndef RTL2830_PRIV_H
22#define RTL2830_PRIV_H
23
24#include "dvb_frontend.h"
25#include "rtl2830.h"
26
27#define LOG_PREFIX "rtl2830"
28
29#undef dbg
30#define dbg(f, arg...) \
31 if (rtl2830_debug) \
32 printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
33#undef err
34#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
35#undef info
36#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
37#undef warn
38#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
39
40struct rtl2830_priv {
41 struct i2c_adapter *i2c;
42 struct dvb_frontend fe;
43 struct rtl2830_config cfg;
44 struct i2c_adapter tuner_i2c_adapter;
45
46 bool sleeping;
47
48 u8 page; /* active register page */
49};
50
51struct rtl2830_reg_val_mask {
52 u16 reg;
53 u8 val;
54 u8 mask;
55};
56
57#endif /* RTL2830_PRIV_H */
diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c
index 38565beafe23..dd08f4ac64a8 100644
--- a/drivers/media/dvb/frontends/stb0899_drv.c
+++ b/drivers/media/dvb/frontends/stb0899_drv.c
@@ -67,7 +67,7 @@ static const struct stb0899_tab stb0899_cn_tab[] = {
67 * Crude linear extrapolation below -84.8dBm and above -8.0dBm. 67 * Crude linear extrapolation below -84.8dBm and above -8.0dBm.
68 */ 68 */
69static const struct stb0899_tab stb0899_dvbsrf_tab[] = { 69static const struct stb0899_tab stb0899_dvbsrf_tab[] = {
70 { -950, -128 }, 70 { -750, -128 },
71 { -748, -94 }, 71 { -748, -94 },
72 { -745, -92 }, 72 { -745, -92 },
73 { -735, -90 }, 73 { -735, -90 },
@@ -131,7 +131,7 @@ static const struct stb0899_tab stb0899_dvbs2rf_tab[] = {
131 { -730, 13645 }, 131 { -730, 13645 },
132 { -750, 13909 }, 132 { -750, 13909 },
133 { -766, 14153 }, 133 { -766, 14153 },
134 { -999, 16383 } 134 { -950, 16383 }
135}; 135};
136 136
137/* DVB-S2 Es/N0 quant in dB/100 vs read value * 100*/ 137/* DVB-S2 Es/N0 quant in dB/100 vs read value * 100*/
@@ -964,6 +964,7 @@ static int stb0899_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
964 964
965 int val; 965 int val;
966 u32 reg; 966 u32 reg;
967 *strength = 0;
967 switch (state->delsys) { 968 switch (state->delsys) {
968 case SYS_DVBS: 969 case SYS_DVBS:
969 case SYS_DSS: 970 case SYS_DSS:
@@ -983,11 +984,11 @@ static int stb0899_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
983 break; 984 break;
984 case SYS_DVBS2: 985 case SYS_DVBS2:
985 if (internal->lock) { 986 if (internal->lock) {
986 reg = STB0899_READ_S2REG(STB0899_DEMOD, IF_AGC_GAIN); 987 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_GAIN);
987 val = STB0899_GETFIELD(IF_AGC_GAIN, reg); 988 val = STB0899_GETFIELD(IF_AGC_GAIN, reg);
988 989
989 *strength = stb0899_table_lookup(stb0899_dvbs2rf_tab, ARRAY_SIZE(stb0899_dvbs2rf_tab) - 1, val); 990 *strength = stb0899_table_lookup(stb0899_dvbs2rf_tab, ARRAY_SIZE(stb0899_dvbs2rf_tab) - 1, val);
990 *strength += 750; 991 *strength += 950;
991 dprintk(state->verbose, FE_DEBUG, 1, "IF_AGC_GAIN = 0x%04x, C = %d * 0.1 dBm", 992 dprintk(state->verbose, FE_DEBUG, 1, "IF_AGC_GAIN = 0x%04x, C = %d * 0.1 dBm",
992 val & 0x3fff, *strength); 993 val & 0x3fff, *strength);
993 } 994 }
@@ -1009,6 +1010,7 @@ static int stb0899_read_snr(struct dvb_frontend *fe, u16 *snr)
1009 u8 buf[2]; 1010 u8 buf[2];
1010 u32 reg; 1011 u32 reg;
1011 1012
1013 *snr = 0;
1012 reg = stb0899_read_reg(state, STB0899_VSTATUS); 1014 reg = stb0899_read_reg(state, STB0899_VSTATUS);
1013 switch (state->delsys) { 1015 switch (state->delsys) {
1014 case SYS_DVBS: 1016 case SYS_DVBS:
@@ -1071,7 +1073,7 @@ static int stb0899_read_status(struct dvb_frontend *fe, enum fe_status *status)
1071 reg = stb0899_read_reg(state, STB0899_VSTATUS); 1073 reg = stb0899_read_reg(state, STB0899_VSTATUS);
1072 if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) { 1074 if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) {
1073 dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_CARRIER | FE_HAS_LOCK"); 1075 dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_CARRIER | FE_HAS_LOCK");
1074 *status |= FE_HAS_CARRIER | FE_HAS_LOCK; 1076 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
1075 1077
1076 reg = stb0899_read_reg(state, STB0899_PLPARM); 1078 reg = stb0899_read_reg(state, STB0899_PLPARM);
1077 if (STB0899_GETFIELD(VITCURPUN, reg)) { 1079 if (STB0899_GETFIELD(VITCURPUN, reg)) {
diff --git a/drivers/media/dvb/frontends/stv0288.c b/drivers/media/dvb/frontends/stv0288.c
index fb5548a82208..632b25156e4c 100644
--- a/drivers/media/dvb/frontends/stv0288.c
+++ b/drivers/media/dvb/frontends/stv0288.c
@@ -506,7 +506,7 @@ static int stv0288_set_frontend(struct dvb_frontend *fe)
506 tda[1] = (unsigned char)tm; 506 tda[1] = (unsigned char)tm;
507 stv0288_writeregI(state, 0x2b, tda[1]); 507 stv0288_writeregI(state, 0x2b, tda[1]);
508 stv0288_writeregI(state, 0x2c, tda[2]); 508 stv0288_writeregI(state, 0x2c, tda[2]);
509 udelay(30); 509 msleep(30);
510 } 510 }
511 state->tuner_frequency = c->frequency; 511 state->tuner_frequency = c->frequency;
512 state->fec_inner = FEC_AUTO; 512 state->fec_inner = FEC_AUTO;
diff --git a/drivers/media/dvb/frontends/tda10071.c b/drivers/media/dvb/frontends/tda10071.c
index a99205026751..c21bc92d2811 100644
--- a/drivers/media/dvb/frontends/tda10071.c
+++ b/drivers/media/dvb/frontends/tda10071.c
@@ -1215,7 +1215,7 @@ error:
1215EXPORT_SYMBOL(tda10071_attach); 1215EXPORT_SYMBOL(tda10071_attach);
1216 1216
1217static struct dvb_frontend_ops tda10071_ops = { 1217static struct dvb_frontend_ops tda10071_ops = {
1218 .delsys = { SYS_DVBT, SYS_DVBT2 }, 1218 .delsys = { SYS_DVBS, SYS_DVBS2 },
1219 .info = { 1219 .info = {
1220 .name = "NXP TDA10071", 1220 .name = "NXP TDA10071",
1221 .frequency_min = 950000, 1221 .frequency_min = 950000,
diff --git a/drivers/media/dvb/ngene/ngene-cards.c b/drivers/media/dvb/ngene/ngene-cards.c
index 8418c02bcefe..7539a5d71029 100644
--- a/drivers/media/dvb/ngene/ngene-cards.c
+++ b/drivers/media/dvb/ngene/ngene-cards.c
@@ -216,6 +216,7 @@ static int demod_attach_drxk(struct ngene_channel *chan,
216 struct drxk_config config; 216 struct drxk_config config;
217 217
218 memset(&config, 0, sizeof(config)); 218 memset(&config, 0, sizeof(config));
219 config.microcode_name = "drxk_a3.mc";
219 config.adr = 0x29 + (chan->number ^ 2); 220 config.adr = 0x29 + (chan->number ^ 2);
220 221
221 chan->fe = dvb_attach(drxk_attach, &config, i2c); 222 chan->fe = dvb_attach(drxk_attach, &config, i2c);
diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c
index b81df5fafe26..15b35c4725f1 100644
--- a/drivers/media/dvb/pt1/pt1.c
+++ b/drivers/media/dvb/pt1/pt1.c
@@ -28,6 +28,7 @@
28#include <linux/pci.h> 28#include <linux/pci.h>
29#include <linux/kthread.h> 29#include <linux/kthread.h>
30#include <linux/freezer.h> 30#include <linux/freezer.h>
31#include <linux/ratelimit.h>
31 32
32#include "dvbdev.h" 33#include "dvbdev.h"
33#include "dvb_demux.h" 34#include "dvb_demux.h"
@@ -77,6 +78,8 @@ struct pt1 {
77 struct pt1_adapter *adaps[PT1_NR_ADAPS]; 78 struct pt1_adapter *adaps[PT1_NR_ADAPS];
78 struct pt1_table *tables; 79 struct pt1_table *tables;
79 struct task_struct *kthread; 80 struct task_struct *kthread;
81 int table_index;
82 int buf_index;
80 83
81 struct mutex lock; 84 struct mutex lock;
82 int power; 85 int power;
@@ -90,12 +93,12 @@ struct pt1_adapter {
90 u8 *buf; 93 u8 *buf;
91 int upacket_count; 94 int upacket_count;
92 int packet_count; 95 int packet_count;
96 int st_count;
93 97
94 struct dvb_adapter adap; 98 struct dvb_adapter adap;
95 struct dvb_demux demux; 99 struct dvb_demux demux;
96 int users; 100 int users;
97 struct dmxdev dmxdev; 101 struct dmxdev dmxdev;
98 struct dvb_net net;
99 struct dvb_frontend *fe; 102 struct dvb_frontend *fe;
100 int (*orig_set_voltage)(struct dvb_frontend *fe, 103 int (*orig_set_voltage)(struct dvb_frontend *fe,
101 fe_sec_voltage_t voltage); 104 fe_sec_voltage_t voltage);
@@ -119,7 +122,7 @@ static u32 pt1_read_reg(struct pt1 *pt1, int reg)
119 return readl(pt1->regs + reg * 4); 122 return readl(pt1->regs + reg * 4);
120} 123}
121 124
122static int pt1_nr_tables = 64; 125static int pt1_nr_tables = 8;
123module_param_named(nr_tables, pt1_nr_tables, int, 0); 126module_param_named(nr_tables, pt1_nr_tables, int, 0);
124 127
125static void pt1_increment_table_count(struct pt1 *pt1) 128static void pt1_increment_table_count(struct pt1 *pt1)
@@ -264,6 +267,7 @@ static int pt1_filter(struct pt1 *pt1, struct pt1_buffer_page *page)
264 struct pt1_adapter *adap; 267 struct pt1_adapter *adap;
265 int offset; 268 int offset;
266 u8 *buf; 269 u8 *buf;
270 int sc;
267 271
268 if (!page->upackets[PT1_NR_UPACKETS - 1]) 272 if (!page->upackets[PT1_NR_UPACKETS - 1])
269 return 0; 273 return 0;
@@ -280,6 +284,16 @@ static int pt1_filter(struct pt1 *pt1, struct pt1_buffer_page *page)
280 else if (!adap->upacket_count) 284 else if (!adap->upacket_count)
281 continue; 285 continue;
282 286
287 if (upacket >> 24 & 1)
288 printk_ratelimited(KERN_INFO "earth-pt1: device "
289 "buffer overflowing. table[%d] buf[%d]\n",
290 pt1->table_index, pt1->buf_index);
291 sc = upacket >> 26 & 0x7;
292 if (adap->st_count != -1 && sc != ((adap->st_count + 1) & 0x7))
293 printk_ratelimited(KERN_INFO "earth-pt1: data loss"
294 " in streamID(adapter)[%d]\n", index);
295 adap->st_count = sc;
296
283 buf = adap->buf; 297 buf = adap->buf;
284 offset = adap->packet_count * 188 + adap->upacket_count * 3; 298 offset = adap->packet_count * 188 + adap->upacket_count * 3;
285 buf[offset] = upacket >> 16; 299 buf[offset] = upacket >> 16;
@@ -303,30 +317,25 @@ static int pt1_filter(struct pt1 *pt1, struct pt1_buffer_page *page)
303static int pt1_thread(void *data) 317static int pt1_thread(void *data)
304{ 318{
305 struct pt1 *pt1; 319 struct pt1 *pt1;
306 int table_index;
307 int buf_index;
308 struct pt1_buffer_page *page; 320 struct pt1_buffer_page *page;
309 321
310 pt1 = data; 322 pt1 = data;
311 set_freezable(); 323 set_freezable();
312 324
313 table_index = 0;
314 buf_index = 0;
315
316 while (!kthread_should_stop()) { 325 while (!kthread_should_stop()) {
317 try_to_freeze(); 326 try_to_freeze();
318 327
319 page = pt1->tables[table_index].bufs[buf_index].page; 328 page = pt1->tables[pt1->table_index].bufs[pt1->buf_index].page;
320 if (!pt1_filter(pt1, page)) { 329 if (!pt1_filter(pt1, page)) {
321 schedule_timeout_interruptible((HZ + 999) / 1000); 330 schedule_timeout_interruptible((HZ + 999) / 1000);
322 continue; 331 continue;
323 } 332 }
324 333
325 if (++buf_index >= PT1_NR_BUFS) { 334 if (++pt1->buf_index >= PT1_NR_BUFS) {
326 pt1_increment_table_count(pt1); 335 pt1_increment_table_count(pt1);
327 buf_index = 0; 336 pt1->buf_index = 0;
328 if (++table_index >= pt1_nr_tables) 337 if (++pt1->table_index >= pt1_nr_tables)
329 table_index = 0; 338 pt1->table_index = 0;
330 } 339 }
331 } 340 }
332 341
@@ -477,21 +486,60 @@ err:
477 return ret; 486 return ret;
478} 487}
479 488
489static int pt1_start_polling(struct pt1 *pt1)
490{
491 int ret = 0;
492
493 mutex_lock(&pt1->lock);
494 if (!pt1->kthread) {
495 pt1->kthread = kthread_run(pt1_thread, pt1, "earth-pt1");
496 if (IS_ERR(pt1->kthread)) {
497 ret = PTR_ERR(pt1->kthread);
498 pt1->kthread = NULL;
499 }
500 }
501 mutex_unlock(&pt1->lock);
502 return ret;
503}
504
480static int pt1_start_feed(struct dvb_demux_feed *feed) 505static int pt1_start_feed(struct dvb_demux_feed *feed)
481{ 506{
482 struct pt1_adapter *adap; 507 struct pt1_adapter *adap;
483 adap = container_of(feed->demux, struct pt1_adapter, demux); 508 adap = container_of(feed->demux, struct pt1_adapter, demux);
484 if (!adap->users++) 509 if (!adap->users++) {
510 int ret;
511
512 ret = pt1_start_polling(adap->pt1);
513 if (ret)
514 return ret;
485 pt1_set_stream(adap->pt1, adap->index, 1); 515 pt1_set_stream(adap->pt1, adap->index, 1);
516 }
486 return 0; 517 return 0;
487} 518}
488 519
520static void pt1_stop_polling(struct pt1 *pt1)
521{
522 int i, count;
523
524 mutex_lock(&pt1->lock);
525 for (i = 0, count = 0; i < PT1_NR_ADAPS; i++)
526 count += pt1->adaps[i]->users;
527
528 if (count == 0 && pt1->kthread) {
529 kthread_stop(pt1->kthread);
530 pt1->kthread = NULL;
531 }
532 mutex_unlock(&pt1->lock);
533}
534
489static int pt1_stop_feed(struct dvb_demux_feed *feed) 535static int pt1_stop_feed(struct dvb_demux_feed *feed)
490{ 536{
491 struct pt1_adapter *adap; 537 struct pt1_adapter *adap;
492 adap = container_of(feed->demux, struct pt1_adapter, demux); 538 adap = container_of(feed->demux, struct pt1_adapter, demux);
493 if (!--adap->users) 539 if (!--adap->users) {
494 pt1_set_stream(adap->pt1, adap->index, 0); 540 pt1_set_stream(adap->pt1, adap->index, 0);
541 pt1_stop_polling(adap->pt1);
542 }
495 return 0; 543 return 0;
496} 544}
497 545
@@ -575,7 +623,6 @@ static int pt1_wakeup(struct dvb_frontend *fe)
575 623
576static void pt1_free_adapter(struct pt1_adapter *adap) 624static void pt1_free_adapter(struct pt1_adapter *adap)
577{ 625{
578 dvb_net_release(&adap->net);
579 adap->demux.dmx.close(&adap->demux.dmx); 626 adap->demux.dmx.close(&adap->demux.dmx);
580 dvb_dmxdev_release(&adap->dmxdev); 627 dvb_dmxdev_release(&adap->dmxdev);
581 dvb_dmx_release(&adap->demux); 628 dvb_dmx_release(&adap->demux);
@@ -616,6 +663,7 @@ pt1_alloc_adapter(struct pt1 *pt1)
616 adap->buf = buf; 663 adap->buf = buf;
617 adap->upacket_count = 0; 664 adap->upacket_count = 0;
618 adap->packet_count = 0; 665 adap->packet_count = 0;
666 adap->st_count = -1;
619 667
620 dvb_adap = &adap->adap; 668 dvb_adap = &adap->adap;
621 dvb_adap->priv = adap; 669 dvb_adap->priv = adap;
@@ -644,8 +692,6 @@ pt1_alloc_adapter(struct pt1 *pt1)
644 if (ret < 0) 692 if (ret < 0)
645 goto err_dmx_release; 693 goto err_dmx_release;
646 694
647 dvb_net_init(dvb_adap, &adap->net, &demux->dmx);
648
649 return adap; 695 return adap;
650 696
651err_dmx_release: 697err_dmx_release:
@@ -1020,7 +1066,8 @@ static void __devexit pt1_remove(struct pci_dev *pdev)
1020 pt1 = pci_get_drvdata(pdev); 1066 pt1 = pci_get_drvdata(pdev);
1021 regs = pt1->regs; 1067 regs = pt1->regs;
1022 1068
1023 kthread_stop(pt1->kthread); 1069 if (pt1->kthread)
1070 kthread_stop(pt1->kthread);
1024 pt1_cleanup_tables(pt1); 1071 pt1_cleanup_tables(pt1);
1025 pt1_cleanup_frontends(pt1); 1072 pt1_cleanup_frontends(pt1);
1026 pt1_disable_ram(pt1); 1073 pt1_disable_ram(pt1);
@@ -1043,7 +1090,6 @@ pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1043 void __iomem *regs; 1090 void __iomem *regs;
1044 struct pt1 *pt1; 1091 struct pt1 *pt1;
1045 struct i2c_adapter *i2c_adap; 1092 struct i2c_adapter *i2c_adap;
1046 struct task_struct *kthread;
1047 1093
1048 ret = pci_enable_device(pdev); 1094 ret = pci_enable_device(pdev);
1049 if (ret < 0) 1095 if (ret < 0)
@@ -1139,17 +1185,8 @@ pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1139 if (ret < 0) 1185 if (ret < 0)
1140 goto err_pt1_cleanup_frontends; 1186 goto err_pt1_cleanup_frontends;
1141 1187
1142 kthread = kthread_run(pt1_thread, pt1, "pt1");
1143 if (IS_ERR(kthread)) {
1144 ret = PTR_ERR(kthread);
1145 goto err_pt1_cleanup_tables;
1146 }
1147
1148 pt1->kthread = kthread;
1149 return 0; 1188 return 0;
1150 1189
1151err_pt1_cleanup_tables:
1152 pt1_cleanup_tables(pt1);
1153err_pt1_cleanup_frontends: 1190err_pt1_cleanup_frontends:
1154 pt1_cleanup_frontends(pt1); 1191 pt1_cleanup_frontends(pt1);
1155err_pt1_disable_ram: 1192err_pt1_disable_ram:
diff --git a/drivers/media/media-devnode.c b/drivers/media/media-devnode.c
index 7b42ace419d9..421cf73858d3 100644
--- a/drivers/media/media-devnode.c
+++ b/drivers/media/media-devnode.c
@@ -312,7 +312,7 @@ static void __exit media_devnode_exit(void)
312 unregister_chrdev_region(media_dev_t, MEDIA_NUM_DEVICES); 312 unregister_chrdev_region(media_dev_t, MEDIA_NUM_DEVICES);
313} 313}
314 314
315module_init(media_devnode_init) 315subsys_initcall(media_devnode_init);
316module_exit(media_devnode_exit) 316module_exit(media_devnode_exit)
317 317
318MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); 318MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index e954781c90bf..8db2d7f4b52a 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -43,7 +43,7 @@ config USB_DSBR
43 43
44config RADIO_MAXIRADIO 44config RADIO_MAXIRADIO
45 tristate "Guillemot MAXI Radio FM 2000 radio" 45 tristate "Guillemot MAXI Radio FM 2000 radio"
46 depends on VIDEO_V4L2 && PCI 46 depends on VIDEO_V4L2 && PCI && SND
47 ---help--- 47 ---help---
48 Choose Y here if you have this radio card. This card may also be 48 Choose Y here if you have this radio card. This card may also be
49 found as Gemtek PCI FM. 49 found as Gemtek PCI FM.
@@ -80,6 +80,16 @@ config RADIO_SI4713
80 To compile this driver as a module, choose M here: the 80 To compile this driver as a module, choose M here: the
81 module will be called radio-si4713. 81 module will be called radio-si4713.
82 82
83config USB_KEENE
84 tristate "Keene FM Transmitter USB support"
85 depends on USB && VIDEO_V4L2
86 ---help---
87 Say Y here if you want to connect this type of FM transmitter
88 to your computer's USB port.
89
90 To compile this driver as a module, choose M here: the
91 module will be called radio-keene.
92
83config RADIO_TEA5764 93config RADIO_TEA5764
84 tristate "TEA5764 I2C FM radio support" 94 tristate "TEA5764 I2C FM radio support"
85 depends on I2C && VIDEO_V4L2 95 depends on I2C && VIDEO_V4L2
@@ -167,6 +177,10 @@ menuconfig V4L_RADIO_ISA_DRIVERS
167 177
168if V4L_RADIO_ISA_DRIVERS 178if V4L_RADIO_ISA_DRIVERS
169 179
180config RADIO_ISA
181 depends on ISA
182 tristate
183
170config RADIO_CADET 184config RADIO_CADET
171 tristate "ADS Cadet AM/FM Tuner" 185 tristate "ADS Cadet AM/FM Tuner"
172 depends on ISA && VIDEO_V4L2 186 depends on ISA && VIDEO_V4L2
@@ -174,20 +188,13 @@ config RADIO_CADET
174 Choose Y here if you have one of these AM/FM radio cards, and then 188 Choose Y here if you have one of these AM/FM radio cards, and then
175 fill in the port address below. 189 fill in the port address below.
176 190
177 In order to control your radio card, you will need to use programs
178 that are compatible with the Video For Linux API. Information on
179 this API and pointers to "v4l" programs may be found at
180 <file:Documentation/video4linux/API.html>.
181
182 Further documentation on this driver can be found on the WWW at
183 <http://linux.blackhawke.net/cadet/>.
184
185 To compile this driver as a module, choose M here: the 191 To compile this driver as a module, choose M here: the
186 module will be called radio-cadet. 192 module will be called radio-cadet.
187 193
188config RADIO_RTRACK 194config RADIO_RTRACK
189 tristate "AIMSlab RadioTrack (aka RadioReveal) support" 195 tristate "AIMSlab RadioTrack (aka RadioReveal) support"
190 depends on ISA && VIDEO_V4L2 196 depends on ISA && VIDEO_V4L2
197 select RADIO_ISA
191 ---help--- 198 ---help---
192 Choose Y here if you have one of these FM radio cards, and then fill 199 Choose Y here if you have one of these FM radio cards, and then fill
193 in the port address below. 200 in the port address below.
@@ -201,11 +208,7 @@ config RADIO_RTRACK
201 You must also pass the module a suitable io parameter, 0x248 has 208 You must also pass the module a suitable io parameter, 0x248 has
202 been reported to be used by these cards. 209 been reported to be used by these cards.
203 210
204 In order to control your radio card, you will need to use programs 211 More information is contained in the file
205 that are compatible with the Video For Linux API. Information on
206 this API and pointers to "v4l" programs may be found at
207 <file:Documentation/video4linux/API.html>. More information is
208 contained in the file
209 <file:Documentation/video4linux/radiotrack.txt>. 212 <file:Documentation/video4linux/radiotrack.txt>.
210 213
211 To compile this driver as a module, choose M here: the 214 To compile this driver as a module, choose M here: the
@@ -214,7 +217,7 @@ config RADIO_RTRACK
214config RADIO_RTRACK_PORT 217config RADIO_RTRACK_PORT
215 hex "RadioTrack i/o port (0x20f or 0x30f)" 218 hex "RadioTrack i/o port (0x20f or 0x30f)"
216 depends on RADIO_RTRACK=y 219 depends on RADIO_RTRACK=y
217 default "20f" 220 default "30f"
218 help 221 help
219 Enter either 0x30f or 0x20f here. The card default is 0x30f, if you 222 Enter either 0x30f or 0x20f here. The card default is 0x30f, if you
220 haven't changed the jumper setting on the card. 223 haven't changed the jumper setting on the card.
@@ -222,14 +225,14 @@ config RADIO_RTRACK_PORT
222config RADIO_RTRACK2 225config RADIO_RTRACK2
223 tristate "AIMSlab RadioTrack II support" 226 tristate "AIMSlab RadioTrack II support"
224 depends on ISA && VIDEO_V4L2 227 depends on ISA && VIDEO_V4L2
228 select RADIO_ISA
225 ---help--- 229 ---help---
226 Choose Y here if you have this FM radio card, and then fill in the 230 Choose Y here if you have this FM radio card, and then fill in the
227 port address below. 231 port address below.
228 232
229 In order to control your radio card, you will need to use programs 233 Note: this driver hasn't been tested since a long time due to lack
230 that are compatible with the Video For Linux API. Information on 234 of hardware. If you have this hardware, then please contact the
231 this API and pointers to "v4l" programs may be found at 235 linux-media mailinglist.
232 <file:Documentation/video4linux/API.html>.
233 236
234 To compile this driver as a module, choose M here: the 237 To compile this driver as a module, choose M here: the
235 module will be called radio-rtrack2. 238 module will be called radio-rtrack2.
@@ -245,15 +248,11 @@ config RADIO_RTRACK2_PORT
245config RADIO_AZTECH 248config RADIO_AZTECH
246 tristate "Aztech/Packard Bell Radio" 249 tristate "Aztech/Packard Bell Radio"
247 depends on ISA && VIDEO_V4L2 250 depends on ISA && VIDEO_V4L2
251 select RADIO_ISA
248 ---help--- 252 ---help---
249 Choose Y here if you have one of these FM radio cards, and then fill 253 Choose Y here if you have one of these FM radio cards, and then fill
250 in the port address below. 254 in the port address below.
251 255
252 In order to control your radio card, you will need to use programs
253 that are compatible with the Video For Linux API. Information on
254 this API and pointers to "v4l" programs may be found at
255 <file:Documentation/video4linux/API.html>.
256
257 To compile this driver as a module, choose M here: the 256 To compile this driver as a module, choose M here: the
258 module will be called radio-aztech. 257 module will be called radio-aztech.
259 258
@@ -269,6 +268,7 @@ config RADIO_AZTECH_PORT
269config RADIO_GEMTEK 268config RADIO_GEMTEK
270 tristate "GemTek Radio card (or compatible) support" 269 tristate "GemTek Radio card (or compatible) support"
271 depends on ISA && VIDEO_V4L2 270 depends on ISA && VIDEO_V4L2
271 select RADIO_ISA
272 ---help--- 272 ---help---
273 Choose Y here if you have this FM radio card, and then fill in the 273 Choose Y here if you have this FM radio card, and then fill in the
274 I/O port address and settings below. The following cards either have 274 I/O port address and settings below. The following cards either have
@@ -278,23 +278,21 @@ config RADIO_GEMTEK
278 - Typhoon Radio card (some models) 278 - Typhoon Radio card (some models)
279 - Hama Radio card 279 - Hama Radio card
280 280
281 In order to control your radio card, you will need to use programs
282 that are compatible with the Video For Linux API. Information on
283 this API and pointers to "v4l" programs may be found at
284 <file:Documentation/video4linux/API.html>.
285
286 To compile this driver as a module, choose M here: the 281 To compile this driver as a module, choose M here: the
287 module will be called radio-gemtek. 282 module will be called radio-gemtek.
288 283
289config RADIO_GEMTEK_PORT 284config RADIO_GEMTEK_PORT
290 hex "Fixed I/O port (0x20c, 0x30c, 0x24c, 0x34c, 0c24c or 0x28c)" 285 hex "Fixed I/O port (0x20c, 0x30c, 0x24c, 0x34c, 0x248 or 0x28c)"
291 depends on RADIO_GEMTEK=y 286 depends on RADIO_GEMTEK=y
292 default "34c" 287 default "34c"
293 help 288 help
294 Enter either 0x20c, 0x30c, 0x24c or 0x34c here. The card default is 289 Enter either 0x20c, 0x30c, 0x24c, 0x34c, 0x248 or 0x28c here. The
295 0x34c, if you haven't changed the jumper setting on the card. On 290 card default is 0x34c, if you haven't changed the jumper setting
296 Sound Vision 16 Gold PnP with FM Radio (ESS1869+FM Gemtek), the I/O 291 on the card.
292
293 On Sound Vision 16 Gold PnP with FM Radio (ESS1869+FM Gemtek), the I/O
297 port is 0x20c, 0x248 or 0x28c. 294 port is 0x20c, 0x248 or 0x28c.
295
298 If automatic I/O port probing is enabled this port will be used only 296 If automatic I/O port probing is enabled this port will be used only
299 in case of automatic probing failure, ie. as a fallback. 297 in case of automatic probing failure, ie. as a fallback.
300 298
@@ -318,11 +316,6 @@ config RADIO_MIROPCM20
318 sound card driver "Miro miroSOUND PCM1pro/PCM12/PCM20radio" as this 316 sound card driver "Miro miroSOUND PCM1pro/PCM12/PCM20radio" as this
319 is required for the radio-miropcm20. 317 is required for the radio-miropcm20.
320 318
321 In order to control your radio card, you will need to use programs
322 that are compatible with the Video For Linux API. Information on
323 this API and pointers to "v4l" programs may be found at
324 <file:Documentation/video4linux/API.html>.
325
326 To compile this driver as a module, choose M here: the 319 To compile this driver as a module, choose M here: the
327 module will be called radio-miropcm20. 320 module will be called radio-miropcm20.
328 321
@@ -332,11 +325,6 @@ config RADIO_SF16FMI
332 ---help--- 325 ---help---
333 Choose Y here if you have one of these FM radio cards. 326 Choose Y here if you have one of these FM radio cards.
334 327
335 In order to control your radio card, you will need to use programs
336 that are compatible with the Video For Linux API. Information on
337 this API and pointers to "v4l" programs may be found at
338 <file:Documentation/video4linux/API.html>.
339
340 To compile this driver as a module, choose M here: the 328 To compile this driver as a module, choose M here: the
341 module will be called radio-sf16fmi. 329 module will be called radio-sf16fmi.
342 330
@@ -346,50 +334,35 @@ config RADIO_SF16FMR2
346 ---help--- 334 ---help---
347 Choose Y here if you have one of these FM radio cards. 335 Choose Y here if you have one of these FM radio cards.
348 336
349 In order to control your radio card, you will need to use programs
350 that are compatible with the Video For Linux API. Information on
351 this API and pointers to "v4l" programs may be found on the WWW at
352 <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
353
354 To compile this driver as a module, choose M here: the 337 To compile this driver as a module, choose M here: the
355 module will be called radio-sf16fmr2. 338 module will be called radio-sf16fmr2.
356 339
357config RADIO_TERRATEC 340config RADIO_TERRATEC
358 tristate "TerraTec ActiveRadio ISA Standalone" 341 tristate "TerraTec ActiveRadio ISA Standalone"
359 depends on ISA && VIDEO_V4L2 342 depends on ISA && VIDEO_V4L2
343 select RADIO_ISA
360 ---help--- 344 ---help---
361 Choose Y here if you have this FM radio card, and then fill in the 345 Choose Y here if you have this FM radio card.
362 port address below. (TODO)
363 346
364 Note: This driver is in its early stages. Right now volume and 347 Note: this driver hasn't been tested since a long time due to lack
365 frequency control and muting works at least for me, but 348 of hardware. If you have this hardware, then please contact the
366 unfortunately I have not found anybody who wants to use this card 349 linux-media mailinglist.
367 with Linux. So if it is this what YOU are trying to do right now,
368 PLEASE DROP ME A NOTE!! Rolf Offermanns <rolf@offermanns.de>.
369
370 In order to control your radio card, you will need to use programs
371 that are compatible with the Video For Linux API. Information on
372 this API and pointers to "v4l" programs may be found at
373 <file:Documentation/video4linux/API.html>.
374 350
375 To compile this driver as a module, choose M here: the 351 To compile this driver as a module, choose M here: the
376 module will be called radio-terratec. 352 module will be called radio-terratec.
377 353
378config RADIO_TERRATEC_PORT
379 hex "Terratec i/o port (normally 0x590)"
380 depends on RADIO_TERRATEC=y
381 default "590"
382 help
383 Fill in the I/O port of your TerraTec FM radio card. If unsure, go
384 with the default.
385
386config RADIO_TRUST 354config RADIO_TRUST
387 tristate "Trust FM radio card" 355 tristate "Trust FM radio card"
388 depends on ISA && VIDEO_V4L2 356 depends on ISA && VIDEO_V4L2
357 select RADIO_ISA
389 help 358 help
390 This is a driver for the Trust FM radio cards. Say Y if you have 359 This is a driver for the Trust FM radio cards. Say Y if you have
391 such a card and want to use it under Linux. 360 such a card and want to use it under Linux.
392 361
362 Note: this driver hasn't been tested since a long time due to lack
363 of hardware. If you have this hardware, then please contact the
364 linux-media mailinglist.
365
393 To compile this driver as a module, choose M here: the 366 To compile this driver as a module, choose M here: the
394 module will be called radio-trust. 367 module will be called radio-trust.
395 368
@@ -404,14 +377,14 @@ config RADIO_TRUST_PORT
404config RADIO_TYPHOON 377config RADIO_TYPHOON
405 tristate "Typhoon Radio (a.k.a. EcoRadio)" 378 tristate "Typhoon Radio (a.k.a. EcoRadio)"
406 depends on ISA && VIDEO_V4L2 379 depends on ISA && VIDEO_V4L2
380 select RADIO_ISA
407 ---help--- 381 ---help---
408 Choose Y here if you have one of these FM radio cards, and then fill 382 Choose Y here if you have one of these FM radio cards, and then fill
409 in the port address and the frequency used for muting below. 383 in the port address and the frequency used for muting below.
410 384
411 In order to control your radio card, you will need to use programs 385 Note: this driver hasn't been tested since a long time due to lack
412 that are compatible with the Video For Linux API. Information on 386 of hardware. If you have this hardware, then please contact the
413 this API and pointers to "v4l" programs may be found at 387 linux-media mailinglist.
414 <file:Documentation/video4linux/API.html>.
415 388
416 To compile this driver as a module, choose M here: the 389 To compile this driver as a module, choose M here: the
417 module will be called radio-typhoon. 390 module will be called radio-typhoon.
@@ -438,14 +411,14 @@ config RADIO_TYPHOON_MUTEFREQ
438config RADIO_ZOLTRIX 411config RADIO_ZOLTRIX
439 tristate "Zoltrix Radio" 412 tristate "Zoltrix Radio"
440 depends on ISA && VIDEO_V4L2 413 depends on ISA && VIDEO_V4L2
414 select RADIO_ISA
441 ---help--- 415 ---help---
442 Choose Y here if you have one of these FM radio cards, and then fill 416 Choose Y here if you have one of these FM radio cards, and then fill
443 in the port address below. 417 in the port address below.
444 418
445 In order to control your radio card, you will need to use programs 419 Note: this driver hasn't been tested since a long time due to lack
446 that are compatible with the Video For Linux API. Information on 420 of hardware. If you have this hardware, then please contact the
447 this API and pointers to "v4l" programs may be found at 421 linux-media mailinglist.
448 <file:Documentation/video4linux/API.html>.
449 422
450 To compile this driver as a module, choose M here: the 423 To compile this driver as a module, choose M here: the
451 module will be called radio-zoltrix. 424 module will be called radio-zoltrix.
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 390daf94d847..ca8c7d134b95 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -2,6 +2,7 @@
2# Makefile for the kernel character device drivers. 2# Makefile for the kernel character device drivers.
3# 3#
4 4
5obj-$(CONFIG_RADIO_ISA) += radio-isa.o
5obj-$(CONFIG_RADIO_AZTECH) += radio-aztech.o 6obj-$(CONFIG_RADIO_AZTECH) += radio-aztech.o
6obj-$(CONFIG_RADIO_RTRACK2) += radio-rtrack2.o 7obj-$(CONFIG_RADIO_RTRACK2) += radio-rtrack2.o
7obj-$(CONFIG_RADIO_SF16FMI) += radio-sf16fmi.o 8obj-$(CONFIG_RADIO_SF16FMI) += radio-sf16fmi.o
@@ -20,6 +21,7 @@ obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o
20obj-$(CONFIG_USB_DSBR) += dsbr100.o 21obj-$(CONFIG_USB_DSBR) += dsbr100.o
21obj-$(CONFIG_RADIO_SI470X) += si470x/ 22obj-$(CONFIG_RADIO_SI470X) += si470x/
22obj-$(CONFIG_USB_MR800) += radio-mr800.o 23obj-$(CONFIG_USB_MR800) += radio-mr800.o
24obj-$(CONFIG_USB_KEENE) += radio-keene.o
23obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o 25obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o
24obj-$(CONFIG_RADIO_SAA7706H) += saa7706h.o 26obj-$(CONFIG_RADIO_SAA7706H) += saa7706h.o
25obj-$(CONFIG_RADIO_TEF6862) += tef6862.o 27obj-$(CONFIG_RADIO_TEF6862) += tef6862.o
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index 1c3f8440a55c..98e0c8c20312 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -1,16 +1,13 @@
1/* radiotrack (radioreveal) driver for Linux radio support 1/*
2 * (c) 1997 M. Kirkwood 2 * AimsLab RadioTrack (aka RadioVeveal) driver
3 *
4 * Copyright 1997 M. Kirkwood
5 *
6 * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com>
3 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> 7 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
4 * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk> 8 * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk>
5 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> 9 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
6 * 10 *
7 * History:
8 * 1999-02-24 Russell Kroll <rkroll@exploits.org>
9 * Fine tuning/VIDEO_TUNER_LOW
10 * Frequency range expanded to start at 87 MHz
11 *
12 * TODO: Allow for more than one of these foolish entities :-)
13 *
14 * Notes on the hardware (reverse engineered from other peoples' 11 * Notes on the hardware (reverse engineered from other peoples'
15 * reverse engineering of AIMS' code :-) 12 * reverse engineering of AIMS' code :-)
16 * 13 *
@@ -26,6 +23,7 @@
26 * wait(a_wee_while); 23 * wait(a_wee_while);
27 * out(port, stop_changing_the_volume); 24 * out(port, stop_changing_the_volume);
28 * 25 *
26 * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool.
29 */ 27 */
30 28
31#include <linux/module.h> /* Modules */ 29#include <linux/module.h> /* Modules */
@@ -34,401 +32,179 @@
34#include <linux/delay.h> /* msleep */ 32#include <linux/delay.h> /* msleep */
35#include <linux/videodev2.h> /* kernel radio structs */ 33#include <linux/videodev2.h> /* kernel radio structs */
36#include <linux/io.h> /* outb, outb_p */ 34#include <linux/io.h> /* outb, outb_p */
35#include <linux/slab.h>
37#include <media/v4l2-device.h> 36#include <media/v4l2-device.h>
38#include <media/v4l2-ioctl.h> 37#include <media/v4l2-ioctl.h>
38#include <media/v4l2-ctrls.h>
39#include "radio-isa.h"
39 40
40MODULE_AUTHOR("M.Kirkwood"); 41MODULE_AUTHOR("M. Kirkwood");
41MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card."); 42MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card.");
42MODULE_LICENSE("GPL"); 43MODULE_LICENSE("GPL");
43MODULE_VERSION("0.0.3"); 44MODULE_VERSION("1.0.0");
44 45
45#ifndef CONFIG_RADIO_RTRACK_PORT 46#ifndef CONFIG_RADIO_RTRACK_PORT
46#define CONFIG_RADIO_RTRACK_PORT -1 47#define CONFIG_RADIO_RTRACK_PORT -1
47#endif 48#endif
48 49
49static int io = CONFIG_RADIO_RTRACK_PORT; 50#define RTRACK_MAX 2
50static int radio_nr = -1;
51 51
52module_param(io, int, 0); 52static int io[RTRACK_MAX] = { [0] = CONFIG_RADIO_RTRACK_PORT,
53MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20f or 0x30f)"); 53 [1 ... (RTRACK_MAX - 1)] = -1 };
54module_param(radio_nr, int, 0); 54static int radio_nr[RTRACK_MAX] = { [0 ... (RTRACK_MAX - 1)] = -1 };
55 55
56struct rtrack 56module_param_array(io, int, NULL, 0444);
57{ 57MODULE_PARM_DESC(io, "I/O addresses of the RadioTrack card (0x20f or 0x30f)");
58 struct v4l2_device v4l2_dev; 58module_param_array(radio_nr, int, NULL, 0444);
59 struct video_device vdev; 59MODULE_PARM_DESC(radio_nr, "Radio device numbers");
60 int port; 60
61struct rtrack {
62 struct radio_isa_card isa;
61 int curvol; 63 int curvol;
62 unsigned long curfreq;
63 int muted;
64 int io;
65 struct mutex lock;
66}; 64};
67 65
68static struct rtrack rtrack_card; 66static struct radio_isa_card *rtrack_alloc(void)
69
70/* local things */
71
72static void rt_decvol(struct rtrack *rt)
73{
74 outb(0x58, rt->io); /* volume down + sigstr + on */
75 msleep(100);
76 outb(0xd8, rt->io); /* volume steady + sigstr + on */
77}
78
79static void rt_incvol(struct rtrack *rt)
80{
81 outb(0x98, rt->io); /* volume up + sigstr + on */
82 msleep(100);
83 outb(0xd8, rt->io); /* volume steady + sigstr + on */
84}
85
86static void rt_mute(struct rtrack *rt)
87{
88 rt->muted = 1;
89 mutex_lock(&rt->lock);
90 outb(0xd0, rt->io); /* volume steady, off */
91 mutex_unlock(&rt->lock);
92}
93
94static int rt_setvol(struct rtrack *rt, int vol)
95{ 67{
96 int i; 68 struct rtrack *rt = kzalloc(sizeof(struct rtrack), GFP_KERNEL);
97
98 mutex_lock(&rt->lock);
99
100 if (vol == rt->curvol) { /* requested volume = current */
101 if (rt->muted) { /* user is unmuting the card */
102 rt->muted = 0;
103 outb(0xd8, rt->io); /* enable card */
104 }
105 mutex_unlock(&rt->lock);
106 return 0;
107 }
108
109 if (vol == 0) { /* volume = 0 means mute the card */
110 outb(0x48, rt->io); /* volume down but still "on" */
111 msleep(2000); /* make sure it's totally down */
112 outb(0xd0, rt->io); /* volume steady, off */
113 rt->curvol = 0; /* track the volume state! */
114 mutex_unlock(&rt->lock);
115 return 0;
116 }
117 69
118 rt->muted = 0; 70 if (rt)
119 if (vol > rt->curvol) 71 rt->curvol = 0xff;
120 for (i = rt->curvol; i < vol; i++) 72 return rt ? &rt->isa : NULL;
121 rt_incvol(rt);
122 else
123 for (i = rt->curvol; i > vol; i--)
124 rt_decvol(rt);
125
126 rt->curvol = vol;
127 mutex_unlock(&rt->lock);
128 return 0;
129} 73}
130 74
131/* the 128+64 on these outb's is to keep the volume stable while tuning 75/* The 128+64 on these outb's is to keep the volume stable while tuning.
132 * without them, the volume _will_ creep up with each frequency change 76 * Without them, the volume _will_ creep up with each frequency change
133 * and bit 4 (+16) is to keep the signal strength meter enabled 77 * and bit 4 (+16) is to keep the signal strength meter enabled.
134 */ 78 */
135 79
136static void send_0_byte(struct rtrack *rt) 80static void send_0_byte(struct radio_isa_card *isa, int on)
137{ 81{
138 if (rt->curvol == 0 || rt->muted) { 82 outb_p(128+64+16+on+1, isa->io); /* wr-enable + data low */
139 outb_p(128+64+16+ 1, rt->io); /* wr-enable + data low */ 83 outb_p(128+64+16+on+2+1, isa->io); /* clock */
140 outb_p(128+64+16+2+1, rt->io); /* clock */
141 }
142 else {
143 outb_p(128+64+16+8+ 1, rt->io); /* on + wr-enable + data low */
144 outb_p(128+64+16+8+2+1, rt->io); /* clock */
145 }
146 msleep(1); 84 msleep(1);
147} 85}
148 86
149static void send_1_byte(struct rtrack *rt) 87static void send_1_byte(struct radio_isa_card *isa, int on)
150{ 88{
151 if (rt->curvol == 0 || rt->muted) { 89 outb_p(128+64+16+on+4+1, isa->io); /* wr-enable+data high */
152 outb_p(128+64+16+4 +1, rt->io); /* wr-enable+data high */ 90 outb_p(128+64+16+on+4+2+1, isa->io); /* clock */
153 outb_p(128+64+16+4+2+1, rt->io); /* clock */
154 }
155 else {
156 outb_p(128+64+16+8+4 +1, rt->io); /* on+wr-enable+data high */
157 outb_p(128+64+16+8+4+2+1, rt->io); /* clock */
158 }
159
160 msleep(1); 91 msleep(1);
161} 92}
162 93
163static int rt_setfreq(struct rtrack *rt, unsigned long freq) 94static int rtrack_s_frequency(struct radio_isa_card *isa, u32 freq)
164{ 95{
96 int on = v4l2_ctrl_g_ctrl(isa->mute) ? 0 : 8;
165 int i; 97 int i;
166 98
167 mutex_lock(&rt->lock); /* Stop other ops interfering */
168
169 rt->curfreq = freq;
170
171 /* now uses VIDEO_TUNER_LOW for fine tuning */
172
173 freq += 171200; /* Add 10.7 MHz IF */ 99 freq += 171200; /* Add 10.7 MHz IF */
174 freq /= 800; /* Convert to 50 kHz units */ 100 freq /= 800; /* Convert to 50 kHz units */
175 101
176 send_0_byte(rt); /* 0: LSB of frequency */ 102 send_0_byte(isa, on); /* 0: LSB of frequency */
177 103
178 for (i = 0; i < 13; i++) /* : frequency bits (1-13) */ 104 for (i = 0; i < 13; i++) /* : frequency bits (1-13) */
179 if (freq & (1 << i)) 105 if (freq & (1 << i))
180 send_1_byte(rt); 106 send_1_byte(isa, on);
181 else 107 else
182 send_0_byte(rt); 108 send_0_byte(isa, on);
183
184 send_0_byte(rt); /* 14: test bit - always 0 */
185 send_0_byte(rt); /* 15: test bit - always 0 */
186
187 send_0_byte(rt); /* 16: band data 0 - always 0 */
188 send_0_byte(rt); /* 17: band data 1 - always 0 */
189 send_0_byte(rt); /* 18: band data 2 - always 0 */
190 send_0_byte(rt); /* 19: time base - always 0 */
191
192 send_0_byte(rt); /* 20: spacing (0 = 25 kHz) */
193 send_1_byte(rt); /* 21: spacing (1 = 25 kHz) */
194 send_0_byte(rt); /* 22: spacing (0 = 25 kHz) */
195 send_1_byte(rt); /* 23: AM/FM (FM = 1, always) */
196
197 if (rt->curvol == 0 || rt->muted)
198 outb(0xd0, rt->io); /* volume steady + sigstr */
199 else
200 outb(0xd8, rt->io); /* volume steady + sigstr + on */
201
202 mutex_unlock(&rt->lock);
203
204 return 0;
205}
206
207static int rt_getsigstr(struct rtrack *rt)
208{
209 int sig = 1;
210
211 mutex_lock(&rt->lock);
212 if (inb(rt->io) & 2) /* bit set = no signal present */
213 sig = 0;
214 mutex_unlock(&rt->lock);
215 return sig;
216}
217
218static int vidioc_querycap(struct file *file, void *priv,
219 struct v4l2_capability *v)
220{
221 strlcpy(v->driver, "radio-aimslab", sizeof(v->driver));
222 strlcpy(v->card, "RadioTrack", sizeof(v->card));
223 strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
224 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
225 return 0;
226}
227
228static int vidioc_g_tuner(struct file *file, void *priv,
229 struct v4l2_tuner *v)
230{
231 struct rtrack *rt = video_drvdata(file);
232 109
233 if (v->index > 0) 110 send_0_byte(isa, on); /* 14: test bit - always 0 */
234 return -EINVAL; 111 send_0_byte(isa, on); /* 15: test bit - always 0 */
235 112
236 strlcpy(v->name, "FM", sizeof(v->name)); 113 send_0_byte(isa, on); /* 16: band data 0 - always 0 */
237 v->type = V4L2_TUNER_RADIO; 114 send_0_byte(isa, on); /* 17: band data 1 - always 0 */
238 v->rangelow = 87 * 16000; 115 send_0_byte(isa, on); /* 18: band data 2 - always 0 */
239 v->rangehigh = 108 * 16000; 116 send_0_byte(isa, on); /* 19: time base - always 0 */
240 v->rxsubchans = V4L2_TUNER_SUB_MONO;
241 v->capability = V4L2_TUNER_CAP_LOW;
242 v->audmode = V4L2_TUNER_MODE_MONO;
243 v->signal = 0xffff * rt_getsigstr(rt);
244 return 0;
245}
246
247static int vidioc_s_tuner(struct file *file, void *priv,
248 struct v4l2_tuner *v)
249{
250 return v->index ? -EINVAL : 0;
251}
252
253static int vidioc_s_frequency(struct file *file, void *priv,
254 struct v4l2_frequency *f)
255{
256 struct rtrack *rt = video_drvdata(file);
257
258 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
259 return -EINVAL;
260 rt_setfreq(rt, f->frequency);
261 return 0;
262}
263 117
264static int vidioc_g_frequency(struct file *file, void *priv, 118 send_0_byte(isa, on); /* 20: spacing (0 = 25 kHz) */
265 struct v4l2_frequency *f) 119 send_1_byte(isa, on); /* 21: spacing (1 = 25 kHz) */
266{ 120 send_0_byte(isa, on); /* 22: spacing (0 = 25 kHz) */
267 struct rtrack *rt = video_drvdata(file); 121 send_1_byte(isa, on); /* 23: AM/FM (FM = 1, always) */
268 122
269 if (f->tuner != 0) 123 outb(0xd0 + on, isa->io); /* volume steady + sigstr */
270 return -EINVAL;
271 f->type = V4L2_TUNER_RADIO;
272 f->frequency = rt->curfreq;
273 return 0; 124 return 0;
274} 125}
275 126
276static int vidioc_queryctrl(struct file *file, void *priv, 127static u32 rtrack_g_signal(struct radio_isa_card *isa)
277 struct v4l2_queryctrl *qc)
278{ 128{
279 switch (qc->id) { 129 /* bit set = no signal present */
280 case V4L2_CID_AUDIO_MUTE: 130 return 0xffff * !(inb(isa->io) & 2);
281 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
282 case V4L2_CID_AUDIO_VOLUME:
283 return v4l2_ctrl_query_fill(qc, 0, 0xff, 1, 0xff);
284 }
285 return -EINVAL;
286} 131}
287 132
288static int vidioc_g_ctrl(struct file *file, void *priv, 133static int rtrack_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol)
289 struct v4l2_control *ctrl)
290{ 134{
291 struct rtrack *rt = video_drvdata(file); 135 struct rtrack *rt = container_of(isa, struct rtrack, isa);
136 int curvol = rt->curvol;
292 137
293 switch (ctrl->id) { 138 if (mute) {
294 case V4L2_CID_AUDIO_MUTE: 139 outb(0xd0, isa->io); /* volume steady + sigstr + off */
295 ctrl->value = rt->muted;
296 return 0;
297 case V4L2_CID_AUDIO_VOLUME:
298 ctrl->value = rt->curvol;
299 return 0; 140 return 0;
300 } 141 }
301 return -EINVAL; 142 if (vol == 0) { /* volume = 0 means mute the card */
302} 143 outb(0x48, isa->io); /* volume down but still "on" */
303 144 msleep(curvol * 3); /* make sure it's totally down */
304static int vidioc_s_ctrl(struct file *file, void *priv, 145 } else if (curvol < vol) {
305 struct v4l2_control *ctrl) 146 outb(0x98, isa->io); /* volume up + sigstr + on */
306{ 147 for (; curvol < vol; curvol++)
307 struct rtrack *rt = video_drvdata(file); 148 udelay(3000);
308 149 } else if (curvol > vol) {
309 switch (ctrl->id) { 150 outb(0x58, isa->io); /* volume down + sigstr + on */
310 case V4L2_CID_AUDIO_MUTE: 151 for (; curvol > vol; curvol--)
311 if (ctrl->value) 152 udelay(3000);
312 rt_mute(rt);
313 else
314 rt_setvol(rt, rt->curvol);
315 return 0;
316 case V4L2_CID_AUDIO_VOLUME:
317 rt_setvol(rt, ctrl->value);
318 return 0;
319 } 153 }
320 return -EINVAL; 154 outb(0xd8, isa->io); /* volume steady + sigstr + on */
321} 155 rt->curvol = vol;
322
323static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
324{
325 *i = 0;
326 return 0; 156 return 0;
327} 157}
328 158
329static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) 159/* Mute card - prevents noisy bootups */
160static int rtrack_initialize(struct radio_isa_card *isa)
330{ 161{
331 return i ? -EINVAL : 0; 162 /* this ensures that the volume is all the way up */
332} 163 outb(0x90, isa->io); /* volume up but still "on" */
333 164 msleep(3000); /* make sure it's totally up */
334static int vidioc_g_audio(struct file *file, void *priv, 165 outb(0xc0, isa->io); /* steady volume, mute card */
335 struct v4l2_audio *a)
336{
337 a->index = 0;
338 strlcpy(a->name, "Radio", sizeof(a->name));
339 a->capability = V4L2_AUDCAP_STEREO;
340 return 0; 166 return 0;
341} 167}
342 168
343static int vidioc_s_audio(struct file *file, void *priv, 169static const struct radio_isa_ops rtrack_ops = {
344 struct v4l2_audio *a) 170 .alloc = rtrack_alloc,
345{ 171 .init = rtrack_initialize,
346 return a->index ? -EINVAL : 0; 172 .s_mute_volume = rtrack_s_mute_volume,
347} 173 .s_frequency = rtrack_s_frequency,
348 174 .g_signal = rtrack_g_signal,
349static const struct v4l2_file_operations rtrack_fops = {
350 .owner = THIS_MODULE,
351 .unlocked_ioctl = video_ioctl2,
352}; 175};
353 176
354static const struct v4l2_ioctl_ops rtrack_ioctl_ops = { 177static const int rtrack_ioports[] = { 0x20f, 0x30f };
355 .vidioc_querycap = vidioc_querycap, 178
356 .vidioc_g_tuner = vidioc_g_tuner, 179static struct radio_isa_driver rtrack_driver = {
357 .vidioc_s_tuner = vidioc_s_tuner, 180 .driver = {
358 .vidioc_g_audio = vidioc_g_audio, 181 .match = radio_isa_match,
359 .vidioc_s_audio = vidioc_s_audio, 182 .probe = radio_isa_probe,
360 .vidioc_g_input = vidioc_g_input, 183 .remove = radio_isa_remove,
361 .vidioc_s_input = vidioc_s_input, 184 .driver = {
362 .vidioc_g_frequency = vidioc_g_frequency, 185 .name = "radio-aimslab",
363 .vidioc_s_frequency = vidioc_s_frequency, 186 },
364 .vidioc_queryctrl = vidioc_queryctrl, 187 },
365 .vidioc_g_ctrl = vidioc_g_ctrl, 188 .io_params = io,
366 .vidioc_s_ctrl = vidioc_s_ctrl, 189 .radio_nr_params = radio_nr,
190 .io_ports = rtrack_ioports,
191 .num_of_io_ports = ARRAY_SIZE(rtrack_ioports),
192 .region_size = 2,
193 .card = "AIMSlab RadioTrack/RadioReveal",
194 .ops = &rtrack_ops,
195 .has_stereo = true,
196 .max_volume = 0xff,
367}; 197};
368 198
369static int __init rtrack_init(void) 199static int __init rtrack_init(void)
370{ 200{
371 struct rtrack *rt = &rtrack_card; 201 return isa_register_driver(&rtrack_driver.driver, RTRACK_MAX);
372 struct v4l2_device *v4l2_dev = &rt->v4l2_dev;
373 int res;
374
375 strlcpy(v4l2_dev->name, "rtrack", sizeof(v4l2_dev->name));
376 rt->io = io;
377
378 if (rt->io == -1) {
379 v4l2_err(v4l2_dev, "you must set an I/O address with io=0x20f or 0x30f\n");
380 return -EINVAL;
381 }
382
383 if (!request_region(rt->io, 2, "rtrack")) {
384 v4l2_err(v4l2_dev, "port 0x%x already in use\n", rt->io);
385 return -EBUSY;
386 }
387
388 res = v4l2_device_register(NULL, v4l2_dev);
389 if (res < 0) {
390 release_region(rt->io, 2);
391 v4l2_err(v4l2_dev, "could not register v4l2_device\n");
392 return res;
393 }
394
395 strlcpy(rt->vdev.name, v4l2_dev->name, sizeof(rt->vdev.name));
396 rt->vdev.v4l2_dev = v4l2_dev;
397 rt->vdev.fops = &rtrack_fops;
398 rt->vdev.ioctl_ops = &rtrack_ioctl_ops;
399 rt->vdev.release = video_device_release_empty;
400 video_set_drvdata(&rt->vdev, rt);
401
402 /* Set up the I/O locking */
403
404 mutex_init(&rt->lock);
405
406 /* mute card - prevents noisy bootups */
407
408 /* this ensures that the volume is all the way down */
409 outb(0x48, rt->io); /* volume down but still "on" */
410 msleep(2000); /* make sure it's totally down */
411 outb(0xc0, rt->io); /* steady volume, mute card */
412
413 if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
414 v4l2_device_unregister(&rt->v4l2_dev);
415 release_region(rt->io, 2);
416 return -EINVAL;
417 }
418 v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n");
419
420 return 0;
421} 202}
422 203
423static void __exit rtrack_exit(void) 204static void __exit rtrack_exit(void)
424{ 205{
425 struct rtrack *rt = &rtrack_card; 206 isa_unregister_driver(&rtrack_driver.driver);
426
427 video_unregister_device(&rt->vdev);
428 v4l2_device_unregister(&rt->v4l2_dev);
429 release_region(rt->io, 2);
430} 207}
431 208
432module_init(rtrack_init); 209module_init(rtrack_init);
433module_exit(rtrack_exit); 210module_exit(rtrack_exit);
434
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index eed7b0840734..177bcbd7a7c1 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -1,5 +1,7 @@
1/* radio-aztech.c - Aztech radio card driver for Linux 2.2 1/*
2 * radio-aztech.c - Aztech radio card driver
2 * 3 *
4 * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@xs4all.nl>
3 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> 5 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
4 * Adapted to support the Video for Linux API by 6 * Adapted to support the Video for Linux API by
5 * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by: 7 * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by:
@@ -10,19 +12,7 @@
10 * Scott McGrath (smcgrath@twilight.vtc.vsc.edu) 12 * Scott McGrath (smcgrath@twilight.vtc.vsc.edu)
11 * William McGrath (wmcgrath@twilight.vtc.vsc.edu) 13 * William McGrath (wmcgrath@twilight.vtc.vsc.edu)
12 * 14 *
13 * The basis for this code may be found at http://bigbang.vtc.vsc.edu/fmradio/ 15 * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool.
14 * along with more information on the card itself.
15 *
16 * History:
17 * 1999-02-24 Russell Kroll <rkroll@exploits.org>
18 * Fine tuning/VIDEO_TUNER_LOW
19 * Range expanded to 87-108 MHz (from 87.9-107.8)
20 *
21 * Notable changes from the original source:
22 * - includes stripped down to the essentials
23 * - for loops used as delays replaced with udelay()
24 * - #defines removed, changed to static values
25 * - tuning structure changed - no more character arrays, other changes
26*/ 16*/
27 17
28#include <linux/module.h> /* Modules */ 18#include <linux/module.h> /* Modules */
@@ -31,126 +21,72 @@
31#include <linux/delay.h> /* udelay */ 21#include <linux/delay.h> /* udelay */
32#include <linux/videodev2.h> /* kernel radio structs */ 22#include <linux/videodev2.h> /* kernel radio structs */
33#include <linux/io.h> /* outb, outb_p */ 23#include <linux/io.h> /* outb, outb_p */
24#include <linux/slab.h>
34#include <media/v4l2-device.h> 25#include <media/v4l2-device.h>
35#include <media/v4l2-ioctl.h> 26#include <media/v4l2-ioctl.h>
27#include <media/v4l2-ctrls.h>
28#include "radio-isa.h"
36 29
37MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath"); 30MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
38MODULE_DESCRIPTION("A driver for the Aztech radio card."); 31MODULE_DESCRIPTION("A driver for the Aztech radio card.");
39MODULE_LICENSE("GPL"); 32MODULE_LICENSE("GPL");
40MODULE_VERSION("0.0.3"); 33MODULE_VERSION("1.0.0");
41 34
42/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */ 35/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
43
44#ifndef CONFIG_RADIO_AZTECH_PORT 36#ifndef CONFIG_RADIO_AZTECH_PORT
45#define CONFIG_RADIO_AZTECH_PORT -1 37#define CONFIG_RADIO_AZTECH_PORT -1
46#endif 38#endif
47 39
48static int io = CONFIG_RADIO_AZTECH_PORT; 40#define AZTECH_MAX 2
49static int radio_nr = -1;
50static int radio_wait_time = 1000;
51 41
52module_param(io, int, 0); 42static int io[AZTECH_MAX] = { [0] = CONFIG_RADIO_AZTECH_PORT,
53module_param(radio_nr, int, 0); 43 [1 ... (AZTECH_MAX - 1)] = -1 };
54MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)"); 44static int radio_nr[AZTECH_MAX] = { [0 ... (AZTECH_MAX - 1)] = -1 };
45static const int radio_wait_time = 1000;
55 46
56struct aztech 47module_param_array(io, int, NULL, 0444);
57{ 48MODULE_PARM_DESC(io, "I/O addresses of the Aztech card (0x350 or 0x358)");
58 struct v4l2_device v4l2_dev; 49module_param_array(radio_nr, int, NULL, 0444);
59 struct video_device vdev; 50MODULE_PARM_DESC(radio_nr, "Radio device numbers");
60 int io; 51
52struct aztech {
53 struct radio_isa_card isa;
61 int curvol; 54 int curvol;
62 unsigned long curfreq;
63 int stereo;
64 struct mutex lock;
65}; 55};
66 56
67static struct aztech aztech_card;
68
69static int volconvert(int level)
70{
71 level >>= 14; /* Map 16bits down to 2 bit */
72 level &= 3;
73
74 /* convert to card-friendly values */
75 switch (level) {
76 case 0:
77 return 0;
78 case 1:
79 return 1;
80 case 2:
81 return 4;
82 case 3:
83 return 5;
84 }
85 return 0; /* Quieten gcc */
86}
87
88static void send_0_byte(struct aztech *az) 57static void send_0_byte(struct aztech *az)
89{ 58{
90 udelay(radio_wait_time); 59 udelay(radio_wait_time);
91 outb_p(2 + volconvert(az->curvol), az->io); 60 outb_p(2 + az->curvol, az->isa.io);
92 outb_p(64 + 2 + volconvert(az->curvol), az->io); 61 outb_p(64 + 2 + az->curvol, az->isa.io);
93} 62}
94 63
95static void send_1_byte(struct aztech *az) 64static void send_1_byte(struct aztech *az)
96{ 65{
97 udelay (radio_wait_time); 66 udelay(radio_wait_time);
98 outb_p(128 + 2 + volconvert(az->curvol), az->io); 67 outb_p(128 + 2 + az->curvol, az->isa.io);
99 outb_p(128 + 64 + 2 + volconvert(az->curvol), az->io); 68 outb_p(128 + 64 + 2 + az->curvol, az->isa.io);
100}
101
102static int az_setvol(struct aztech *az, int vol)
103{
104 mutex_lock(&az->lock);
105 outb(volconvert(vol), az->io);
106 mutex_unlock(&az->lock);
107 return 0;
108}
109
110/* thanks to Michael Dwyer for giving me a dose of clues in
111 * the signal strength department..
112 *
113 * This card has a stereo bit - bit 0 set = mono, not set = stereo
114 * It also has a "signal" bit - bit 1 set = bad signal, not set = good
115 *
116 */
117
118static int az_getsigstr(struct aztech *az)
119{
120 int sig = 1;
121
122 mutex_lock(&az->lock);
123 if (inb(az->io) & 2) /* bit set = no signal present */
124 sig = 0;
125 mutex_unlock(&az->lock);
126 return sig;
127} 69}
128 70
129static int az_getstereo(struct aztech *az) 71static struct radio_isa_card *aztech_alloc(void)
130{ 72{
131 int stereo = 1; 73 struct aztech *az = kzalloc(sizeof(*az), GFP_KERNEL);
132 74
133 mutex_lock(&az->lock); 75 return az ? &az->isa : NULL;
134 if (inb(az->io) & 1) /* bit set = mono */
135 stereo = 0;
136 mutex_unlock(&az->lock);
137 return stereo;
138} 76}
139 77
140static int az_setfreq(struct aztech *az, unsigned long frequency) 78static int aztech_s_frequency(struct radio_isa_card *isa, u32 freq)
141{ 79{
80 struct aztech *az = container_of(isa, struct aztech, isa);
142 int i; 81 int i;
143 82
144 mutex_lock(&az->lock); 83 freq += 171200; /* Add 10.7 MHz IF */
145 84 freq /= 800; /* Convert to 50 kHz units */
146 az->curfreq = frequency;
147 frequency += 171200; /* Add 10.7 MHz IF */
148 frequency /= 800; /* Convert to 50 kHz units */
149 85
150 send_0_byte(az); /* 0: LSB of frequency */ 86 send_0_byte(az); /* 0: LSB of frequency */
151 87
152 for (i = 0; i < 13; i++) /* : frequency bits (1-13) */ 88 for (i = 0; i < 13; i++) /* : frequency bits (1-13) */
153 if (frequency & (1 << i)) 89 if (freq & (1 << i))
154 send_1_byte(az); 90 send_1_byte(az);
155 else 91 else
156 send_0_byte(az); 92 send_0_byte(az);
@@ -158,7 +94,7 @@ static int az_setfreq(struct aztech *az, unsigned long frequency)
158 send_0_byte(az); /* 14: test bit - always 0 */ 94 send_0_byte(az); /* 14: test bit - always 0 */
159 send_0_byte(az); /* 15: test bit - always 0 */ 95 send_0_byte(az); /* 15: test bit - always 0 */
160 send_0_byte(az); /* 16: band data 0 - always 0 */ 96 send_0_byte(az); /* 16: band data 0 - always 0 */
161 if (az->stereo) /* 17: stereo (1 to enable) */ 97 if (isa->stereo) /* 17: stereo (1 to enable) */
162 send_1_byte(az); 98 send_1_byte(az);
163 else 99 else
164 send_0_byte(az); 100 send_0_byte(az);
@@ -173,225 +109,77 @@ static int az_setfreq(struct aztech *az, unsigned long frequency)
173 /* latch frequency */ 109 /* latch frequency */
174 110
175 udelay(radio_wait_time); 111 udelay(radio_wait_time);
176 outb_p(128 + 64 + volconvert(az->curvol), az->io); 112 outb_p(128 + 64 + az->curvol, az->isa.io);
177
178 mutex_unlock(&az->lock);
179
180 return 0;
181}
182
183static int vidioc_querycap(struct file *file, void *priv,
184 struct v4l2_capability *v)
185{
186 strlcpy(v->driver, "radio-aztech", sizeof(v->driver));
187 strlcpy(v->card, "Aztech Radio", sizeof(v->card));
188 strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
189 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
190 return 0;
191}
192
193static int vidioc_g_tuner(struct file *file, void *priv,
194 struct v4l2_tuner *v)
195{
196 struct aztech *az = video_drvdata(file);
197
198 if (v->index > 0)
199 return -EINVAL;
200
201 strlcpy(v->name, "FM", sizeof(v->name));
202 v->type = V4L2_TUNER_RADIO;
203
204 v->rangelow = 87 * 16000;
205 v->rangehigh = 108 * 16000;
206 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
207 v->capability = V4L2_TUNER_CAP_LOW;
208 if (az_getstereo(az))
209 v->audmode = V4L2_TUNER_MODE_STEREO;
210 else
211 v->audmode = V4L2_TUNER_MODE_MONO;
212 v->signal = 0xFFFF * az_getsigstr(az);
213
214 return 0;
215}
216
217static int vidioc_s_tuner(struct file *file, void *priv,
218 struct v4l2_tuner *v)
219{
220 return v->index ? -EINVAL : 0;
221}
222 113
223static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
224{
225 *i = 0;
226 return 0; 114 return 0;
227} 115}
228 116
229static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) 117/* thanks to Michael Dwyer for giving me a dose of clues in
230{ 118 * the signal strength department..
231 return i ? -EINVAL : 0; 119 *
232} 120 * This card has a stereo bit - bit 0 set = mono, not set = stereo
233 121 */
234static int vidioc_g_audio(struct file *file, void *priv, 122static u32 aztech_g_rxsubchans(struct radio_isa_card *isa)
235 struct v4l2_audio *a)
236{
237 a->index = 0;
238 strlcpy(a->name, "Radio", sizeof(a->name));
239 a->capability = V4L2_AUDCAP_STEREO;
240 return 0;
241}
242
243static int vidioc_s_audio(struct file *file, void *priv,
244 struct v4l2_audio *a)
245{ 123{
246 return a->index ? -EINVAL : 0; 124 if (inb(isa->io) & 1)
125 return V4L2_TUNER_SUB_MONO;
126 return V4L2_TUNER_SUB_STEREO;
247} 127}
248 128
249static int vidioc_s_frequency(struct file *file, void *priv, 129static int aztech_s_stereo(struct radio_isa_card *isa, bool stereo)
250 struct v4l2_frequency *f)
251{ 130{
252 struct aztech *az = video_drvdata(file); 131 return aztech_s_frequency(isa, isa->freq);
253
254 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
255 return -EINVAL;
256 az_setfreq(az, f->frequency);
257 return 0;
258} 132}
259 133
260static int vidioc_g_frequency(struct file *file, void *priv, 134static int aztech_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol)
261 struct v4l2_frequency *f)
262{ 135{
263 struct aztech *az = video_drvdata(file); 136 struct aztech *az = container_of(isa, struct aztech, isa);
264 137
265 if (f->tuner != 0) 138 if (mute)
266 return -EINVAL; 139 vol = 0;
267 f->type = V4L2_TUNER_RADIO; 140 az->curvol = (vol & 1) + ((vol & 2) << 1);
268 f->frequency = az->curfreq; 141 outb(az->curvol, isa->io);
269 return 0; 142 return 0;
270} 143}
271 144
272static int vidioc_queryctrl(struct file *file, void *priv, 145static const struct radio_isa_ops aztech_ops = {
273 struct v4l2_queryctrl *qc) 146 .alloc = aztech_alloc,
274{ 147 .s_mute_volume = aztech_s_mute_volume,
275 switch (qc->id) { 148 .s_frequency = aztech_s_frequency,
276 case V4L2_CID_AUDIO_MUTE: 149 .s_stereo = aztech_s_stereo,
277 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); 150 .g_rxsubchans = aztech_g_rxsubchans,
278 case V4L2_CID_AUDIO_VOLUME:
279 return v4l2_ctrl_query_fill(qc, 0, 0xff, 1, 0xff);
280 }
281 return -EINVAL;
282}
283
284static int vidioc_g_ctrl(struct file *file, void *priv,
285 struct v4l2_control *ctrl)
286{
287 struct aztech *az = video_drvdata(file);
288
289 switch (ctrl->id) {
290 case V4L2_CID_AUDIO_MUTE:
291 if (az->curvol == 0)
292 ctrl->value = 1;
293 else
294 ctrl->value = 0;
295 return 0;
296 case V4L2_CID_AUDIO_VOLUME:
297 ctrl->value = az->curvol * 6554;
298 return 0;
299 }
300 return -EINVAL;
301}
302
303static int vidioc_s_ctrl(struct file *file, void *priv,
304 struct v4l2_control *ctrl)
305{
306 struct aztech *az = video_drvdata(file);
307
308 switch (ctrl->id) {
309 case V4L2_CID_AUDIO_MUTE:
310 if (ctrl->value)
311 az_setvol(az, 0);
312 else
313 az_setvol(az, az->curvol);
314 return 0;
315 case V4L2_CID_AUDIO_VOLUME:
316 az_setvol(az, ctrl->value);
317 return 0;
318 }
319 return -EINVAL;
320}
321
322static const struct v4l2_file_operations aztech_fops = {
323 .owner = THIS_MODULE,
324 .unlocked_ioctl = video_ioctl2,
325}; 151};
326 152
327static const struct v4l2_ioctl_ops aztech_ioctl_ops = { 153static const int aztech_ioports[] = { 0x350, 0x358 };
328 .vidioc_querycap = vidioc_querycap, 154
329 .vidioc_g_tuner = vidioc_g_tuner, 155static struct radio_isa_driver aztech_driver = {
330 .vidioc_s_tuner = vidioc_s_tuner, 156 .driver = {
331 .vidioc_g_audio = vidioc_g_audio, 157 .match = radio_isa_match,
332 .vidioc_s_audio = vidioc_s_audio, 158 .probe = radio_isa_probe,
333 .vidioc_g_input = vidioc_g_input, 159 .remove = radio_isa_remove,
334 .vidioc_s_input = vidioc_s_input, 160 .driver = {
335 .vidioc_g_frequency = vidioc_g_frequency, 161 .name = "radio-aztech",
336 .vidioc_s_frequency = vidioc_s_frequency, 162 },
337 .vidioc_queryctrl = vidioc_queryctrl, 163 },
338 .vidioc_g_ctrl = vidioc_g_ctrl, 164 .io_params = io,
339 .vidioc_s_ctrl = vidioc_s_ctrl, 165 .radio_nr_params = radio_nr,
166 .io_ports = aztech_ioports,
167 .num_of_io_ports = ARRAY_SIZE(aztech_ioports),
168 .region_size = 2,
169 .card = "Aztech Radio",
170 .ops = &aztech_ops,
171 .has_stereo = true,
172 .max_volume = 3,
340}; 173};
341 174
342static int __init aztech_init(void) 175static int __init aztech_init(void)
343{ 176{
344 struct aztech *az = &aztech_card; 177 return isa_register_driver(&aztech_driver.driver, AZTECH_MAX);
345 struct v4l2_device *v4l2_dev = &az->v4l2_dev;
346 int res;
347
348 strlcpy(v4l2_dev->name, "aztech", sizeof(v4l2_dev->name));
349 az->io = io;
350
351 if (az->io == -1) {
352 v4l2_err(v4l2_dev, "you must set an I/O address with io=0x350 or 0x358\n");
353 return -EINVAL;
354 }
355
356 if (!request_region(az->io, 2, "aztech")) {
357 v4l2_err(v4l2_dev, "port 0x%x already in use\n", az->io);
358 return -EBUSY;
359 }
360
361 res = v4l2_device_register(NULL, v4l2_dev);
362 if (res < 0) {
363 release_region(az->io, 2);
364 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
365 return res;
366 }
367
368 mutex_init(&az->lock);
369 strlcpy(az->vdev.name, v4l2_dev->name, sizeof(az->vdev.name));
370 az->vdev.v4l2_dev = v4l2_dev;
371 az->vdev.fops = &aztech_fops;
372 az->vdev.ioctl_ops = &aztech_ioctl_ops;
373 az->vdev.release = video_device_release_empty;
374 video_set_drvdata(&az->vdev, az);
375 /* mute card - prevents noisy bootups */
376 outb(0, az->io);
377
378 if (video_register_device(&az->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
379 v4l2_device_unregister(v4l2_dev);
380 release_region(az->io, 2);
381 return -EINVAL;
382 }
383
384 v4l2_info(v4l2_dev, "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n");
385 return 0;
386} 178}
387 179
388static void __exit aztech_exit(void) 180static void __exit aztech_exit(void)
389{ 181{
390 struct aztech *az = &aztech_card; 182 isa_unregister_driver(&aztech_driver.driver);
391
392 video_unregister_device(&az->vdev);
393 v4l2_device_unregister(&az->v4l2_dev);
394 release_region(az->io, 2);
395} 183}
396 184
397module_init(aztech_init); 185module_init(aztech_init);
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 36ce0611c037..2e639ce6f256 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -1,4 +1,7 @@
1/* GemTek radio card driver for Linux (C) 1998 Jonas Munsin <jmunsin@iki.fi> 1/*
2 * GemTek radio card driver
3 *
4 * Copyright 1998 Jonas Munsin <jmunsin@iki.fi>
2 * 5 *
3 * GemTek hasn't released any specs on the card, so the protocol had to 6 * GemTek hasn't released any specs on the card, so the protocol had to
4 * be reverse engineered with dosemu. 7 * be reverse engineered with dosemu.
@@ -11,9 +14,12 @@
11 * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk> 14 * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk>
12 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> 15 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
13 * 16 *
14 * TODO: Allow for more than one of these foolish entities :-) 17 * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com>
15 *
16 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> 18 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
19 *
20 * Note: this card seems to swap the left and right audio channels!
21 *
22 * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool.
17 */ 23 */
18 24
19#include <linux/module.h> /* Modules */ 25#include <linux/module.h> /* Modules */
@@ -23,8 +29,10 @@
23#include <linux/videodev2.h> /* kernel radio structs */ 29#include <linux/videodev2.h> /* kernel radio structs */
24#include <linux/mutex.h> 30#include <linux/mutex.h>
25#include <linux/io.h> /* outb, outb_p */ 31#include <linux/io.h> /* outb, outb_p */
32#include <linux/slab.h>
26#include <media/v4l2-ioctl.h> 33#include <media/v4l2-ioctl.h>
27#include <media/v4l2-device.h> 34#include <media/v4l2-device.h>
35#include "radio-isa.h"
28 36
29/* 37/*
30 * Module info. 38 * Module info.
@@ -33,7 +41,7 @@
33MODULE_AUTHOR("Jonas Munsin, Pekka Seppänen <pexu@kapsi.fi>"); 41MODULE_AUTHOR("Jonas Munsin, Pekka Seppänen <pexu@kapsi.fi>");
34MODULE_DESCRIPTION("A driver for the GemTek Radio card."); 42MODULE_DESCRIPTION("A driver for the GemTek Radio card.");
35MODULE_LICENSE("GPL"); 43MODULE_LICENSE("GPL");
36MODULE_VERSION("0.0.4"); 44MODULE_VERSION("1.0.0");
37 45
38/* 46/*
39 * Module params. 47 * Module params.
@@ -46,45 +54,29 @@ MODULE_VERSION("0.0.4");
46#define CONFIG_RADIO_GEMTEK_PROBE 1 54#define CONFIG_RADIO_GEMTEK_PROBE 1
47#endif 55#endif
48 56
49static int io = CONFIG_RADIO_GEMTEK_PORT; 57#define GEMTEK_MAX 4
50static bool probe = CONFIG_RADIO_GEMTEK_PROBE;
51static bool hardmute;
52static bool shutdown = 1;
53static bool keepmuted = 1;
54static bool initmute = 1;
55static int radio_nr = -1;
56 58
57module_param(io, int, 0444); 59static bool probe = CONFIG_RADIO_GEMTEK_PROBE;
58MODULE_PARM_DESC(io, "Force I/O port for the GemTek Radio card if automatic " 60static bool hardmute;
59 "probing is disabled or fails. The most common I/O ports are: 0x20c " 61static int io[GEMTEK_MAX] = { [0] = CONFIG_RADIO_GEMTEK_PORT,
60 "0x30c, 0x24c or 0x34c (0x20c, 0x248 and 0x28c have been reported to " 62 [1 ... (GEMTEK_MAX - 1)] = -1 };
61 "work for the combined sound/radiocard)."); 63static int radio_nr[GEMTEK_MAX] = { [0 ... (GEMTEK_MAX - 1)] = -1 };
62 64
63module_param(probe, bool, 0444); 65module_param(probe, bool, 0444);
64MODULE_PARM_DESC(probe, "Enable automatic device probing. Note: only the most " 66MODULE_PARM_DESC(probe, "Enable automatic device probing.");
65 "common I/O ports used by the card are probed.");
66 67
67module_param(hardmute, bool, 0644); 68module_param(hardmute, bool, 0644);
68MODULE_PARM_DESC(hardmute, "Enable `hard muting' by shutting down PLL, may " 69MODULE_PARM_DESC(hardmute, "Enable 'hard muting' by shutting down PLL, may "
69 "reduce static noise."); 70 "reduce static noise.");
70 71
71module_param(shutdown, bool, 0644); 72module_param_array(io, int, NULL, 0444);
72MODULE_PARM_DESC(shutdown, "Enable shutting down PLL and muting line when " 73MODULE_PARM_DESC(io, "Force I/O ports for the GemTek Radio card if automatic "
73 "module is unloaded."); 74 "probing is disabled or fails. The most common I/O ports are: 0x20c "
74 75 "0x30c, 0x24c or 0x34c (0x20c, 0x248 and 0x28c have been reported to "
75module_param(keepmuted, bool, 0644); 76 "work for the combined sound/radiocard).");
76MODULE_PARM_DESC(keepmuted, "Keep card muted even when frequency is changed.");
77
78module_param(initmute, bool, 0444);
79MODULE_PARM_DESC(initmute, "Mute card when module is loaded.");
80
81module_param(radio_nr, int, 0444);
82 77
83/* 78module_param_array(radio_nr, int, NULL, 0444);
84 * Functions for controlling the card. 79MODULE_PARM_DESC(radio_nr, "Radio device numbers");
85 */
86#define GEMTEK_LOWFREQ (87*16000)
87#define GEMTEK_HIGHFREQ (108*16000)
88 80
89/* 81/*
90 * Frequency calculation constants. Intermediate frequency 10.52 MHz (nominal 82 * Frequency calculation constants. Intermediate frequency 10.52 MHz (nominal
@@ -108,18 +100,11 @@ module_param(radio_nr, int, 0444);
108#define LONG_DELAY 75 /* usec */ 100#define LONG_DELAY 75 /* usec */
109 101
110struct gemtek { 102struct gemtek {
111 struct v4l2_device v4l2_dev; 103 struct radio_isa_card isa;
112 struct video_device vdev; 104 bool muted;
113 struct mutex lock;
114 unsigned long lastfreq;
115 int muted;
116 int verified;
117 int io;
118 u32 bu2614data; 105 u32 bu2614data;
119}; 106};
120 107
121static struct gemtek gemtek_card;
122
123#define BU2614_FREQ_BITS 16 /* D0..D15, Frequency data */ 108#define BU2614_FREQ_BITS 16 /* D0..D15, Frequency data */
124#define BU2614_PORT_BITS 3 /* P0..P2, Output port control data */ 109#define BU2614_PORT_BITS 3 /* P0..P2, Output port control data */
125#define BU2614_VOID_BITS 4 /* unused */ 110#define BU2614_VOID_BITS 4 /* unused */
@@ -166,31 +151,24 @@ static struct gemtek gemtek_card;
166 */ 151 */
167static void gemtek_bu2614_transmit(struct gemtek *gt) 152static void gemtek_bu2614_transmit(struct gemtek *gt)
168{ 153{
154 struct radio_isa_card *isa = &gt->isa;
169 int i, bit, q, mute; 155 int i, bit, q, mute;
170 156
171 mutex_lock(&gt->lock);
172
173 mute = gt->muted ? GEMTEK_MT : 0x00; 157 mute = gt->muted ? GEMTEK_MT : 0x00;
174 158
175 outb_p(mute | GEMTEK_DA | GEMTEK_CK, gt->io); 159 outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, isa->io);
176 udelay(SHORT_DELAY);
177 outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, gt->io);
178 udelay(LONG_DELAY); 160 udelay(LONG_DELAY);
179 161
180 for (i = 0, q = gt->bu2614data; i < 32; i++, q >>= 1) { 162 for (i = 0, q = gt->bu2614data; i < 32; i++, q >>= 1) {
181 bit = (q & 1) ? GEMTEK_DA : 0; 163 bit = (q & 1) ? GEMTEK_DA : 0;
182 outb_p(mute | GEMTEK_CE | bit, gt->io); 164 outb_p(mute | GEMTEK_CE | bit, isa->io);
183 udelay(SHORT_DELAY); 165 udelay(SHORT_DELAY);
184 outb_p(mute | GEMTEK_CE | bit | GEMTEK_CK, gt->io); 166 outb_p(mute | GEMTEK_CE | bit | GEMTEK_CK, isa->io);
185 udelay(SHORT_DELAY); 167 udelay(SHORT_DELAY);
186 } 168 }
187 169
188 outb_p(mute | GEMTEK_DA | GEMTEK_CK, gt->io); 170 outb_p(mute | GEMTEK_DA | GEMTEK_CK, isa->io);
189 udelay(SHORT_DELAY); 171 udelay(SHORT_DELAY);
190 outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, gt->io);
191 udelay(LONG_DELAY);
192
193 mutex_unlock(&gt->lock);
194} 172}
195 173
196/* 174/*
@@ -198,21 +176,27 @@ static void gemtek_bu2614_transmit(struct gemtek *gt)
198 */ 176 */
199static unsigned long gemtek_convfreq(unsigned long freq) 177static unsigned long gemtek_convfreq(unsigned long freq)
200{ 178{
201 return ((freq<<FSCALE) + IF_OFFSET + REF_FREQ/2) / REF_FREQ; 179 return ((freq << FSCALE) + IF_OFFSET + REF_FREQ / 2) / REF_FREQ;
180}
181
182static struct radio_isa_card *gemtek_alloc(void)
183{
184 struct gemtek *gt = kzalloc(sizeof(*gt), GFP_KERNEL);
185
186 if (gt)
187 gt->muted = true;
188 return gt ? &gt->isa : NULL;
202} 189}
203 190
204/* 191/*
205 * Set FM-frequency. 192 * Set FM-frequency.
206 */ 193 */
207static void gemtek_setfreq(struct gemtek *gt, unsigned long freq) 194static int gemtek_s_frequency(struct radio_isa_card *isa, u32 freq)
208{ 195{
209 if (keepmuted && hardmute && gt->muted) 196 struct gemtek *gt = container_of(isa, struct gemtek, isa);
210 return;
211 197
212 freq = clamp_val(freq, GEMTEK_LOWFREQ, GEMTEK_HIGHFREQ); 198 if (hardmute && gt->muted)
213 199 return 0;
214 gt->lastfreq = freq;
215 gt->muted = 0;
216 200
217 gemtek_bu2614_set(gt, BU2614_PORT, 0); 201 gemtek_bu2614_set(gt, BU2614_PORT, 0);
218 gemtek_bu2614_set(gt, BU2614_FMES, 0); 202 gemtek_bu2614_set(gt, BU2614_FMES, 0);
@@ -220,23 +204,25 @@ static void gemtek_setfreq(struct gemtek *gt, unsigned long freq)
220 gemtek_bu2614_set(gt, BU2614_SWAL, 0); 204 gemtek_bu2614_set(gt, BU2614_SWAL, 0);
221 gemtek_bu2614_set(gt, BU2614_FMUN, 1); /* GT bit set */ 205 gemtek_bu2614_set(gt, BU2614_FMUN, 1); /* GT bit set */
222 gemtek_bu2614_set(gt, BU2614_TEST, 0); 206 gemtek_bu2614_set(gt, BU2614_TEST, 0);
223
224 gemtek_bu2614_set(gt, BU2614_STDF, GEMTEK_STDF_3_125_KHZ); 207 gemtek_bu2614_set(gt, BU2614_STDF, GEMTEK_STDF_3_125_KHZ);
225 gemtek_bu2614_set(gt, BU2614_FREQ, gemtek_convfreq(freq)); 208 gemtek_bu2614_set(gt, BU2614_FREQ, gemtek_convfreq(freq));
226
227 gemtek_bu2614_transmit(gt); 209 gemtek_bu2614_transmit(gt);
210 return 0;
228} 211}
229 212
230/* 213/*
231 * Set mute flag. 214 * Set mute flag.
232 */ 215 */
233static void gemtek_mute(struct gemtek *gt) 216static int gemtek_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol)
234{ 217{
218 struct gemtek *gt = container_of(isa, struct gemtek, isa);
235 int i; 219 int i;
236 220
237 gt->muted = 1; 221 gt->muted = mute;
238
239 if (hardmute) { 222 if (hardmute) {
223 if (!mute)
224 return gemtek_s_frequency(isa, isa->freq);
225
240 /* Turn off PLL, disable data output */ 226 /* Turn off PLL, disable data output */
241 gemtek_bu2614_set(gt, BU2614_PORT, 0); 227 gemtek_bu2614_set(gt, BU2614_PORT, 0);
242 gemtek_bu2614_set(gt, BU2614_FMES, 0); /* CT bit off */ 228 gemtek_bu2614_set(gt, BU2614_FMES, 0); /* CT bit off */
@@ -247,367 +233,85 @@ static void gemtek_mute(struct gemtek *gt)
247 gemtek_bu2614_set(gt, BU2614_STDF, GEMTEK_PLL_OFF); 233 gemtek_bu2614_set(gt, BU2614_STDF, GEMTEK_PLL_OFF);
248 gemtek_bu2614_set(gt, BU2614_FREQ, 0); 234 gemtek_bu2614_set(gt, BU2614_FREQ, 0);
249 gemtek_bu2614_transmit(gt); 235 gemtek_bu2614_transmit(gt);
250 return; 236 return 0;
251 } 237 }
252 238
253 mutex_lock(&gt->lock);
254
255 /* Read bus contents (CE, CK and DA). */ 239 /* Read bus contents (CE, CK and DA). */
256 i = inb_p(gt->io); 240 i = inb_p(isa->io);
257 /* Write it back with mute flag set. */ 241 /* Write it back with mute flag set. */
258 outb_p((i >> 5) | GEMTEK_MT, gt->io); 242 outb_p((i >> 5) | (mute ? GEMTEK_MT : 0), isa->io);
259 udelay(SHORT_DELAY); 243 udelay(SHORT_DELAY);
260 244 return 0;
261 mutex_unlock(&gt->lock);
262}
263
264/*
265 * Unset mute flag.
266 */
267static void gemtek_unmute(struct gemtek *gt)
268{
269 int i;
270
271 gt->muted = 0;
272 if (hardmute) {
273 /* Turn PLL back on. */
274 gemtek_setfreq(gt, gt->lastfreq);
275 return;
276 }
277 mutex_lock(&gt->lock);
278
279 i = inb_p(gt->io);
280 outb_p(i >> 5, gt->io);
281 udelay(SHORT_DELAY);
282
283 mutex_unlock(&gt->lock);
284} 245}
285 246
286/* 247static u32 gemtek_g_rxsubchans(struct radio_isa_card *isa)
287 * Get signal strength (= stereo status).
288 */
289static inline int gemtek_getsigstr(struct gemtek *gt)
290{ 248{
291 int sig; 249 if (inb_p(isa->io) & GEMTEK_NS)
292 250 return V4L2_TUNER_SUB_MONO;
293 mutex_lock(&gt->lock); 251 return V4L2_TUNER_SUB_STEREO;
294 sig = inb_p(gt->io) & GEMTEK_NS ? 0 : 1;
295 mutex_unlock(&gt->lock);
296 return sig;
297} 252}
298 253
299/* 254/*
300 * Check if requested card acts like GemTek Radio card. 255 * Check if requested card acts like GemTek Radio card.
301 */ 256 */
302static int gemtek_verify(struct gemtek *gt, int port) 257static bool gemtek_probe(struct radio_isa_card *isa, int io)
303{ 258{
304 int i, q; 259 int i, q;
305 260
306 if (gt->verified == port) 261 q = inb_p(io); /* Read bus contents before probing. */
307 return 1;
308
309 mutex_lock(&gt->lock);
310
311 q = inb_p(port); /* Read bus contents before probing. */
312 /* Try to turn on CE, CK and DA respectively and check if card responds 262 /* Try to turn on CE, CK and DA respectively and check if card responds
313 properly. */ 263 properly. */
314 for (i = 0; i < 3; ++i) { 264 for (i = 0; i < 3; ++i) {
315 outb_p(1 << i, port); 265 outb_p(1 << i, io);
316 udelay(SHORT_DELAY); 266 udelay(SHORT_DELAY);
317 267
318 if ((inb_p(port) & (~GEMTEK_NS)) != (0x17 | (1 << (i + 5)))) { 268 if ((inb_p(io) & ~GEMTEK_NS) != (0x17 | (1 << (i + 5))))
319 mutex_unlock(&gt->lock); 269 return false;
320 return 0;
321 }
322 } 270 }
323 outb_p(q >> 5, port); /* Write bus contents back. */ 271 outb_p(q >> 5, io); /* Write bus contents back. */
324 udelay(SHORT_DELAY); 272 udelay(SHORT_DELAY);
325 273 return true;
326 mutex_unlock(&gt->lock);
327 gt->verified = port;
328
329 return 1;
330}
331
332/*
333 * Automatic probing for card.
334 */
335static int gemtek_probe(struct gemtek *gt)
336{
337 struct v4l2_device *v4l2_dev = &gt->v4l2_dev;
338 int ioports[] = { 0x20c, 0x30c, 0x24c, 0x34c, 0x248, 0x28c };
339 int i;
340
341 if (!probe) {
342 v4l2_info(v4l2_dev, "Automatic device probing disabled.\n");
343 return -1;
344 }
345
346 v4l2_info(v4l2_dev, "Automatic device probing enabled.\n");
347
348 for (i = 0; i < ARRAY_SIZE(ioports); ++i) {
349 v4l2_info(v4l2_dev, "Trying I/O port 0x%x...\n", ioports[i]);
350
351 if (!request_region(ioports[i], 1, "gemtek-probe")) {
352 v4l2_warn(v4l2_dev, "I/O port 0x%x busy!\n",
353 ioports[i]);
354 continue;
355 }
356
357 if (gemtek_verify(gt, ioports[i])) {
358 v4l2_info(v4l2_dev, "Card found from I/O port "
359 "0x%x!\n", ioports[i]);
360
361 release_region(ioports[i], 1);
362 gt->io = ioports[i];
363 return gt->io;
364 }
365
366 release_region(ioports[i], 1);
367 }
368
369 v4l2_err(v4l2_dev, "Automatic probing failed!\n");
370 return -1;
371} 274}
372 275
373/* 276static const struct radio_isa_ops gemtek_ops = {
374 * Video 4 Linux stuff. 277 .alloc = gemtek_alloc,
375 */ 278 .probe = gemtek_probe,
376 279 .s_mute_volume = gemtek_s_mute_volume,
377static const struct v4l2_file_operations gemtek_fops = { 280 .s_frequency = gemtek_s_frequency,
378 .owner = THIS_MODULE, 281 .g_rxsubchans = gemtek_g_rxsubchans,
379 .unlocked_ioctl = video_ioctl2,
380}; 282};
381 283
382static int vidioc_querycap(struct file *file, void *priv, 284static const int gemtek_ioports[] = { 0x20c, 0x30c, 0x24c, 0x34c, 0x248, 0x28c };
383 struct v4l2_capability *v) 285
384{ 286static struct radio_isa_driver gemtek_driver = {
385 strlcpy(v->driver, "radio-gemtek", sizeof(v->driver)); 287 .driver = {
386 strlcpy(v->card, "GemTek", sizeof(v->card)); 288 .match = radio_isa_match,
387 strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); 289 .probe = radio_isa_probe,
388 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; 290 .remove = radio_isa_remove,
389 return 0; 291 .driver = {
390} 292 .name = "radio-gemtek",
391 293 },
392static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) 294 },
393{ 295 .io_params = io,
394 struct gemtek *gt = video_drvdata(file); 296 .radio_nr_params = radio_nr,
395 297 .io_ports = gemtek_ioports,
396 if (v->index > 0) 298 .num_of_io_ports = ARRAY_SIZE(gemtek_ioports),
397 return -EINVAL; 299 .region_size = 1,
398 300 .card = "GemTek Radio",
399 strlcpy(v->name, "FM", sizeof(v->name)); 301 .ops = &gemtek_ops,
400 v->type = V4L2_TUNER_RADIO; 302 .has_stereo = true,
401 v->rangelow = GEMTEK_LOWFREQ;
402 v->rangehigh = GEMTEK_HIGHFREQ;
403 v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
404 v->signal = 0xffff * gemtek_getsigstr(gt);
405 if (v->signal) {
406 v->audmode = V4L2_TUNER_MODE_STEREO;
407 v->rxsubchans = V4L2_TUNER_SUB_STEREO;
408 } else {
409 v->audmode = V4L2_TUNER_MODE_MONO;
410 v->rxsubchans = V4L2_TUNER_SUB_MONO;
411 }
412 return 0;
413}
414
415static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
416{
417 return (v->index != 0) ? -EINVAL : 0;
418}
419
420static int vidioc_g_frequency(struct file *file, void *priv,
421 struct v4l2_frequency *f)
422{
423 struct gemtek *gt = video_drvdata(file);
424
425 if (f->tuner != 0)
426 return -EINVAL;
427 f->type = V4L2_TUNER_RADIO;
428 f->frequency = gt->lastfreq;
429 return 0;
430}
431
432static int vidioc_s_frequency(struct file *file, void *priv,
433 struct v4l2_frequency *f)
434{
435 struct gemtek *gt = video_drvdata(file);
436
437 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
438 return -EINVAL;
439 gemtek_setfreq(gt, f->frequency);
440 return 0;
441}
442
443static int vidioc_queryctrl(struct file *file, void *priv,
444 struct v4l2_queryctrl *qc)
445{
446 switch (qc->id) {
447 case V4L2_CID_AUDIO_MUTE:
448 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
449 default:
450 return -EINVAL;
451 }
452}
453
454static int vidioc_g_ctrl(struct file *file, void *priv,
455 struct v4l2_control *ctrl)
456{
457 struct gemtek *gt = video_drvdata(file);
458
459 switch (ctrl->id) {
460 case V4L2_CID_AUDIO_MUTE:
461 ctrl->value = gt->muted;
462 return 0;
463 }
464 return -EINVAL;
465}
466
467static int vidioc_s_ctrl(struct file *file, void *priv,
468 struct v4l2_control *ctrl)
469{
470 struct gemtek *gt = video_drvdata(file);
471
472 switch (ctrl->id) {
473 case V4L2_CID_AUDIO_MUTE:
474 if (ctrl->value)
475 gemtek_mute(gt);
476 else
477 gemtek_unmute(gt);
478 return 0;
479 }
480 return -EINVAL;
481}
482
483static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
484{
485 *i = 0;
486 return 0;
487}
488
489static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
490{
491 return (i != 0) ? -EINVAL : 0;
492}
493
494static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
495{
496 a->index = 0;
497 strlcpy(a->name, "Radio", sizeof(a->name));
498 a->capability = V4L2_AUDCAP_STEREO;
499 return 0;
500}
501
502static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
503{
504 return (a->index != 0) ? -EINVAL : 0;
505}
506
507static const struct v4l2_ioctl_ops gemtek_ioctl_ops = {
508 .vidioc_querycap = vidioc_querycap,
509 .vidioc_g_tuner = vidioc_g_tuner,
510 .vidioc_s_tuner = vidioc_s_tuner,
511 .vidioc_g_audio = vidioc_g_audio,
512 .vidioc_s_audio = vidioc_s_audio,
513 .vidioc_g_input = vidioc_g_input,
514 .vidioc_s_input = vidioc_s_input,
515 .vidioc_g_frequency = vidioc_g_frequency,
516 .vidioc_s_frequency = vidioc_s_frequency,
517 .vidioc_queryctrl = vidioc_queryctrl,
518 .vidioc_g_ctrl = vidioc_g_ctrl,
519 .vidioc_s_ctrl = vidioc_s_ctrl
520}; 303};
521 304
522/*
523 * Initialization / cleanup related stuff.
524 */
525
526static int __init gemtek_init(void) 305static int __init gemtek_init(void)
527{ 306{
528 struct gemtek *gt = &gemtek_card; 307 gemtek_driver.probe = probe;
529 struct v4l2_device *v4l2_dev = &gt->v4l2_dev; 308 return isa_register_driver(&gemtek_driver.driver, GEMTEK_MAX);
530 int res;
531
532 strlcpy(v4l2_dev->name, "gemtek", sizeof(v4l2_dev->name));
533
534 v4l2_info(v4l2_dev, "GemTek Radio card driver: v0.0.3\n");
535
536 mutex_init(&gt->lock);
537
538 gt->verified = -1;
539 gt->io = io;
540 gemtek_probe(gt);
541 if (gt->io) {
542 if (!request_region(gt->io, 1, "gemtek")) {
543 v4l2_err(v4l2_dev, "I/O port 0x%x already in use.\n", gt->io);
544 return -EBUSY;
545 }
546
547 if (!gemtek_verify(gt, gt->io))
548 v4l2_warn(v4l2_dev, "Card at I/O port 0x%x does not "
549 "respond properly, check your "
550 "configuration.\n", gt->io);
551 else
552 v4l2_info(v4l2_dev, "Using I/O port 0x%x.\n", gt->io);
553 } else if (probe) {
554 v4l2_err(v4l2_dev, "Automatic probing failed and no "
555 "fixed I/O port defined.\n");
556 return -ENODEV;
557 } else {
558 v4l2_err(v4l2_dev, "Automatic probing disabled but no fixed "
559 "I/O port defined.");
560 return -EINVAL;
561 }
562
563 res = v4l2_device_register(NULL, v4l2_dev);
564 if (res < 0) {
565 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
566 release_region(gt->io, 1);
567 return res;
568 }
569
570 strlcpy(gt->vdev.name, v4l2_dev->name, sizeof(gt->vdev.name));
571 gt->vdev.v4l2_dev = v4l2_dev;
572 gt->vdev.fops = &gemtek_fops;
573 gt->vdev.ioctl_ops = &gemtek_ioctl_ops;
574 gt->vdev.release = video_device_release_empty;
575 video_set_drvdata(&gt->vdev, gt);
576
577 /* Set defaults */
578 gt->lastfreq = GEMTEK_LOWFREQ;
579 gt->bu2614data = 0;
580
581 if (initmute)
582 gemtek_mute(gt);
583
584 if (video_register_device(&gt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
585 v4l2_device_unregister(v4l2_dev);
586 release_region(gt->io, 1);
587 return -EBUSY;
588 }
589
590 return 0;
591} 309}
592 310
593/*
594 * Module cleanup
595 */
596static void __exit gemtek_exit(void) 311static void __exit gemtek_exit(void)
597{ 312{
598 struct gemtek *gt = &gemtek_card; 313 hardmute = 1; /* Turn off PLL */
599 struct v4l2_device *v4l2_dev = &gt->v4l2_dev; 314 isa_unregister_driver(&gemtek_driver.driver);
600
601 if (shutdown) {
602 hardmute = 1; /* Turn off PLL */
603 gemtek_mute(gt);
604 } else {
605 v4l2_info(v4l2_dev, "Module unloaded but card not muted!\n");
606 }
607
608 video_unregister_device(&gt->vdev);
609 v4l2_device_unregister(&gt->v4l2_dev);
610 release_region(gt->io, 1);
611} 315}
612 316
613module_init(gemtek_init); 317module_init(gemtek_init);
diff --git a/drivers/media/radio/radio-isa.c b/drivers/media/radio/radio-isa.c
new file mode 100644
index 000000000000..06f906351fad
--- /dev/null
+++ b/drivers/media/radio/radio-isa.c
@@ -0,0 +1,340 @@
1/*
2 * Framework for ISA radio drivers.
3 * This takes care of all the V4L2 scaffolding, allowing the ISA drivers
4 * to concentrate on the actual hardware operation.
5 *
6 * Copyright (C) 2012 Hans Verkuil <hans.verkuil@cisco.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 */
22
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/ioport.h>
26#include <linux/delay.h>
27#include <linux/videodev2.h>
28#include <linux/io.h>
29#include <linux/slab.h>
30#include <media/v4l2-device.h>
31#include <media/v4l2-ioctl.h>
32#include <media/v4l2-fh.h>
33#include <media/v4l2-ctrls.h>
34#include <media/v4l2-event.h>
35
36#include "radio-isa.h"
37
38MODULE_AUTHOR("Hans Verkuil");
39MODULE_DESCRIPTION("A framework for ISA radio drivers.");
40MODULE_LICENSE("GPL");
41
42#define FREQ_LOW (87U * 16000U)
43#define FREQ_HIGH (108U * 16000U)
44
45static int radio_isa_querycap(struct file *file, void *priv,
46 struct v4l2_capability *v)
47{
48 struct radio_isa_card *isa = video_drvdata(file);
49
50 strlcpy(v->driver, isa->drv->driver.driver.name, sizeof(v->driver));
51 strlcpy(v->card, isa->drv->card, sizeof(v->card));
52 snprintf(v->bus_info, sizeof(v->bus_info), "ISA:%s", isa->v4l2_dev.name);
53
54 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
55 v->device_caps = v->capabilities | V4L2_CAP_DEVICE_CAPS;
56 return 0;
57}
58
59static int radio_isa_g_tuner(struct file *file, void *priv,
60 struct v4l2_tuner *v)
61{
62 struct radio_isa_card *isa = video_drvdata(file);
63 const struct radio_isa_ops *ops = isa->drv->ops;
64
65 if (v->index > 0)
66 return -EINVAL;
67
68 strlcpy(v->name, "FM", sizeof(v->name));
69 v->type = V4L2_TUNER_RADIO;
70 v->rangelow = FREQ_LOW;
71 v->rangehigh = FREQ_HIGH;
72 v->capability = V4L2_TUNER_CAP_LOW;
73 if (isa->drv->has_stereo)
74 v->capability |= V4L2_TUNER_CAP_STEREO;
75
76 if (ops->g_rxsubchans)
77 v->rxsubchans = ops->g_rxsubchans(isa);
78 else
79 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
80 v->audmode = isa->stereo ? V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO;
81 if (ops->g_signal)
82 v->signal = ops->g_signal(isa);
83 else
84 v->signal = (v->rxsubchans & V4L2_TUNER_SUB_STEREO) ?
85 0xffff : 0;
86 return 0;
87}
88
89static int radio_isa_s_tuner(struct file *file, void *priv,
90 struct v4l2_tuner *v)
91{
92 struct radio_isa_card *isa = video_drvdata(file);
93 const struct radio_isa_ops *ops = isa->drv->ops;
94
95 if (v->index)
96 return -EINVAL;
97 if (ops->s_stereo) {
98 isa->stereo = (v->audmode == V4L2_TUNER_MODE_STEREO);
99 return ops->s_stereo(isa, isa->stereo);
100 }
101 return 0;
102}
103
104static int radio_isa_s_frequency(struct file *file, void *priv,
105 struct v4l2_frequency *f)
106{
107 struct radio_isa_card *isa = video_drvdata(file);
108 int res;
109
110 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
111 return -EINVAL;
112 f->frequency = clamp(f->frequency, FREQ_LOW, FREQ_HIGH);
113 res = isa->drv->ops->s_frequency(isa, f->frequency);
114 if (res == 0)
115 isa->freq = f->frequency;
116 return res;
117}
118
119static int radio_isa_g_frequency(struct file *file, void *priv,
120 struct v4l2_frequency *f)
121{
122 struct radio_isa_card *isa = video_drvdata(file);
123
124 if (f->tuner != 0)
125 return -EINVAL;
126 f->type = V4L2_TUNER_RADIO;
127 f->frequency = isa->freq;
128 return 0;
129}
130
131static int radio_isa_s_ctrl(struct v4l2_ctrl *ctrl)
132{
133 struct radio_isa_card *isa =
134 container_of(ctrl->handler, struct radio_isa_card, hdl);
135
136 switch (ctrl->id) {
137 case V4L2_CID_AUDIO_MUTE:
138 return isa->drv->ops->s_mute_volume(isa, ctrl->val,
139 isa->volume ? isa->volume->val : 0);
140 }
141 return -EINVAL;
142}
143
144static int radio_isa_log_status(struct file *file, void *priv)
145{
146 struct radio_isa_card *isa = video_drvdata(file);
147
148 v4l2_info(&isa->v4l2_dev, "I/O Port = 0x%03x\n", isa->io);
149 v4l2_ctrl_handler_log_status(&isa->hdl, isa->v4l2_dev.name);
150 return 0;
151}
152
153static int radio_isa_subscribe_event(struct v4l2_fh *fh,
154 struct v4l2_event_subscription *sub)
155{
156 if (sub->type == V4L2_EVENT_CTRL)
157 return v4l2_event_subscribe(fh, sub, 0);
158 return -EINVAL;
159}
160
161static const struct v4l2_ctrl_ops radio_isa_ctrl_ops = {
162 .s_ctrl = radio_isa_s_ctrl,
163};
164
165static const struct v4l2_file_operations radio_isa_fops = {
166 .owner = THIS_MODULE,
167 .open = v4l2_fh_open,
168 .release = v4l2_fh_release,
169 .poll = v4l2_ctrl_poll,
170 .unlocked_ioctl = video_ioctl2,
171};
172
173static const struct v4l2_ioctl_ops radio_isa_ioctl_ops = {
174 .vidioc_querycap = radio_isa_querycap,
175 .vidioc_g_tuner = radio_isa_g_tuner,
176 .vidioc_s_tuner = radio_isa_s_tuner,
177 .vidioc_g_frequency = radio_isa_g_frequency,
178 .vidioc_s_frequency = radio_isa_s_frequency,
179 .vidioc_log_status = radio_isa_log_status,
180 .vidioc_subscribe_event = radio_isa_subscribe_event,
181 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
182};
183
184int radio_isa_match(struct device *pdev, unsigned int dev)
185{
186 struct radio_isa_driver *drv = pdev->platform_data;
187
188 return drv->probe || drv->io_params[dev] >= 0;
189}
190EXPORT_SYMBOL_GPL(radio_isa_match);
191
192static bool radio_isa_valid_io(const struct radio_isa_driver *drv, int io)
193{
194 int i;
195
196 for (i = 0; i < drv->num_of_io_ports; i++)
197 if (drv->io_ports[i] == io)
198 return true;
199 return false;
200}
201
202int radio_isa_probe(struct device *pdev, unsigned int dev)
203{
204 struct radio_isa_driver *drv = pdev->platform_data;
205 const struct radio_isa_ops *ops = drv->ops;
206 struct v4l2_device *v4l2_dev;
207 struct radio_isa_card *isa;
208 int res;
209
210 isa = drv->ops->alloc();
211 if (isa == NULL)
212 return -ENOMEM;
213 dev_set_drvdata(pdev, isa);
214 isa->drv = drv;
215 isa->io = drv->io_params[dev];
216 v4l2_dev = &isa->v4l2_dev;
217 strlcpy(v4l2_dev->name, dev_name(pdev), sizeof(v4l2_dev->name));
218
219 if (drv->probe && ops->probe) {
220 int i;
221
222 for (i = 0; i < drv->num_of_io_ports; ++i) {
223 int io = drv->io_ports[i];
224
225 if (request_region(io, drv->region_size, v4l2_dev->name)) {
226 bool found = ops->probe(isa, io);
227
228 release_region(io, drv->region_size);
229 if (found) {
230 isa->io = io;
231 break;
232 }
233 }
234 }
235 }
236
237 if (!radio_isa_valid_io(drv, isa->io)) {
238 int i;
239
240 if (isa->io < 0)
241 return -ENODEV;
242 v4l2_err(v4l2_dev, "you must set an I/O address with io=0x%03x",
243 drv->io_ports[0]);
244 for (i = 1; i < drv->num_of_io_ports; i++)
245 printk(KERN_CONT "/0x%03x", drv->io_ports[i]);
246 printk(KERN_CONT ".\n");
247 kfree(isa);
248 return -EINVAL;
249 }
250
251 if (!request_region(isa->io, drv->region_size, v4l2_dev->name)) {
252 v4l2_err(v4l2_dev, "port 0x%x already in use\n", isa->io);
253 kfree(isa);
254 return -EBUSY;
255 }
256
257 res = v4l2_device_register(pdev, v4l2_dev);
258 if (res < 0) {
259 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
260 goto err_dev_reg;
261 }
262
263 v4l2_ctrl_handler_init(&isa->hdl, 1);
264 isa->mute = v4l2_ctrl_new_std(&isa->hdl, &radio_isa_ctrl_ops,
265 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
266 if (drv->max_volume)
267 isa->volume = v4l2_ctrl_new_std(&isa->hdl, &radio_isa_ctrl_ops,
268 V4L2_CID_AUDIO_VOLUME, 0, drv->max_volume, 1,
269 drv->max_volume);
270 v4l2_dev->ctrl_handler = &isa->hdl;
271 if (isa->hdl.error) {
272 res = isa->hdl.error;
273 v4l2_err(v4l2_dev, "Could not register controls\n");
274 goto err_hdl;
275 }
276 if (drv->max_volume)
277 v4l2_ctrl_cluster(2, &isa->mute);
278 v4l2_dev->ctrl_handler = &isa->hdl;
279
280 mutex_init(&isa->lock);
281 isa->vdev.lock = &isa->lock;
282 strlcpy(isa->vdev.name, v4l2_dev->name, sizeof(isa->vdev.name));
283 isa->vdev.v4l2_dev = v4l2_dev;
284 isa->vdev.fops = &radio_isa_fops;
285 isa->vdev.ioctl_ops = &radio_isa_ioctl_ops;
286 isa->vdev.release = video_device_release_empty;
287 set_bit(V4L2_FL_USE_FH_PRIO, &isa->vdev.flags);
288 video_set_drvdata(&isa->vdev, isa);
289 isa->freq = FREQ_LOW;
290 isa->stereo = drv->has_stereo;
291
292 if (ops->init)
293 res = ops->init(isa);
294 if (!res)
295 res = v4l2_ctrl_handler_setup(&isa->hdl);
296 if (!res)
297 res = ops->s_frequency(isa, isa->freq);
298 if (!res && ops->s_stereo)
299 res = ops->s_stereo(isa, isa->stereo);
300 if (res < 0) {
301 v4l2_err(v4l2_dev, "Could not setup card\n");
302 goto err_node_reg;
303 }
304 res = video_register_device(&isa->vdev, VFL_TYPE_RADIO,
305 drv->radio_nr_params[dev]);
306 if (res < 0) {
307 v4l2_err(v4l2_dev, "Could not register device node\n");
308 goto err_node_reg;
309 }
310
311 v4l2_info(v4l2_dev, "Initialized radio card %s on port 0x%03x\n",
312 drv->card, isa->io);
313 return 0;
314
315err_node_reg:
316 v4l2_ctrl_handler_free(&isa->hdl);
317err_hdl:
318 v4l2_device_unregister(&isa->v4l2_dev);
319err_dev_reg:
320 release_region(isa->io, drv->region_size);
321 kfree(isa);
322 return res;
323}
324EXPORT_SYMBOL_GPL(radio_isa_probe);
325
326int radio_isa_remove(struct device *pdev, unsigned int dev)
327{
328 struct radio_isa_card *isa = dev_get_drvdata(pdev);
329 const struct radio_isa_ops *ops = isa->drv->ops;
330
331 ops->s_mute_volume(isa, true, isa->volume ? isa->volume->cur.val : 0);
332 video_unregister_device(&isa->vdev);
333 v4l2_ctrl_handler_free(&isa->hdl);
334 v4l2_device_unregister(&isa->v4l2_dev);
335 release_region(isa->io, isa->drv->region_size);
336 v4l2_info(&isa->v4l2_dev, "Removed radio card %s\n", isa->drv->card);
337 kfree(isa);
338 return 0;
339}
340EXPORT_SYMBOL_GPL(radio_isa_remove);
diff --git a/drivers/media/radio/radio-isa.h b/drivers/media/radio/radio-isa.h
new file mode 100644
index 000000000000..8a0ea84d86de
--- /dev/null
+++ b/drivers/media/radio/radio-isa.h
@@ -0,0 +1,105 @@
1/*
2 * Framework for ISA radio drivers.
3 * This takes care of all the V4L2 scaffolding, allowing the ISA drivers
4 * to concentrate on the actual hardware operation.
5 *
6 * Copyright (C) 2012 Hans Verkuil <hans.verkuil@cisco.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 */
22
23#ifndef _RADIO_ISA_H_
24#define _RADIO_ISA_H_
25
26#include <linux/isa.h>
27#include <linux/videodev2.h>
28#include <media/v4l2-device.h>
29#include <media/v4l2-ctrls.h>
30
31struct radio_isa_driver;
32struct radio_isa_ops;
33
34/* Core structure for radio ISA cards */
35struct radio_isa_card {
36 const struct radio_isa_driver *drv;
37 struct v4l2_device v4l2_dev;
38 struct v4l2_ctrl_handler hdl;
39 struct video_device vdev;
40 struct mutex lock;
41 const struct radio_isa_ops *ops;
42 struct { /* mute/volume cluster */
43 struct v4l2_ctrl *mute;
44 struct v4l2_ctrl *volume;
45 };
46 /* I/O port */
47 int io;
48
49 /* Card is in stereo audio mode */
50 bool stereo;
51 /* Current frequency */
52 u32 freq;
53};
54
55struct radio_isa_ops {
56 /* Allocate and initialize a radio_isa_card struct */
57 struct radio_isa_card *(*alloc)(void);
58 /* Probe whether a card is present at the given port */
59 bool (*probe)(struct radio_isa_card *isa, int io);
60 /* Special card initialization can be done here, this is called after
61 * the standard controls are registered, but before they are setup,
62 * thus allowing drivers to add their own controls here. */
63 int (*init)(struct radio_isa_card *isa);
64 /* Set mute and volume. */
65 int (*s_mute_volume)(struct radio_isa_card *isa, bool mute, int volume);
66 /* Set frequency */
67 int (*s_frequency)(struct radio_isa_card *isa, u32 freq);
68 /* Set stereo/mono audio mode */
69 int (*s_stereo)(struct radio_isa_card *isa, bool stereo);
70 /* Get rxsubchans value for VIDIOC_G_TUNER */
71 u32 (*g_rxsubchans)(struct radio_isa_card *isa);
72 /* Get the signal strength for VIDIOC_G_TUNER */
73 u32 (*g_signal)(struct radio_isa_card *isa);
74};
75
76/* Top level structure needed to instantiate the cards */
77struct radio_isa_driver {
78 struct isa_driver driver;
79 const struct radio_isa_ops *ops;
80 /* The module_param_array with the specified I/O ports */
81 int *io_params;
82 /* The module_param_array with the radio_nr values */
83 int *radio_nr_params;
84 /* Whether we should probe for possible cards */
85 bool probe;
86 /* The list of possible I/O ports */
87 const int *io_ports;
88 /* The size of that list */
89 int num_of_io_ports;
90 /* The region size to request */
91 unsigned region_size;
92 /* The name of the card */
93 const char *card;
94 /* Card can capture stereo audio */
95 bool has_stereo;
96 /* The maximum volume for the volume control. If 0, then there
97 is no volume control possible. */
98 int max_volume;
99};
100
101int radio_isa_match(struct device *pdev, unsigned int dev);
102int radio_isa_probe(struct device *pdev, unsigned int dev);
103int radio_isa_remove(struct device *pdev, unsigned int dev);
104
105#endif
diff --git a/drivers/media/radio/radio-keene.c b/drivers/media/radio/radio-keene.c
new file mode 100644
index 000000000000..55bd1d2937c8
--- /dev/null
+++ b/drivers/media/radio/radio-keene.c
@@ -0,0 +1,427 @@
1/*
2 * Copyright (c) 2012 Hans Verkuil <hverkuil@xs4all.nl>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19/* kernel includes */
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <linux/input.h>
25#include <linux/videodev2.h>
26#include <media/v4l2-device.h>
27#include <media/v4l2-ioctl.h>
28#include <media/v4l2-ctrls.h>
29#include <media/v4l2-event.h>
30#include <linux/usb.h>
31#include <linux/version.h>
32#include <linux/mutex.h>
33
34/* driver and module definitions */
35MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
36MODULE_DESCRIPTION("Keene FM Transmitter driver");
37MODULE_LICENSE("GPL");
38
39/* Actually, it advertises itself as a Logitech */
40#define USB_KEENE_VENDOR 0x046d
41#define USB_KEENE_PRODUCT 0x0a0e
42
43/* Probably USB_TIMEOUT should be modified in module parameter */
44#define BUFFER_LENGTH 8
45#define USB_TIMEOUT 500
46
47/* Frequency limits in MHz */
48#define FREQ_MIN 76U
49#define FREQ_MAX 108U
50#define FREQ_MUL 16000U
51
52/* USB Device ID List */
53static struct usb_device_id usb_keene_device_table[] = {
54 {USB_DEVICE_AND_INTERFACE_INFO(USB_KEENE_VENDOR, USB_KEENE_PRODUCT,
55 USB_CLASS_HID, 0, 0) },
56 { } /* Terminating entry */
57};
58
59MODULE_DEVICE_TABLE(usb, usb_keene_device_table);
60
61struct keene_device {
62 struct usb_device *usbdev;
63 struct usb_interface *intf;
64 struct video_device vdev;
65 struct v4l2_device v4l2_dev;
66 struct v4l2_ctrl_handler hdl;
67 struct mutex lock;
68
69 u8 *buffer;
70 unsigned curfreq;
71 u8 tx;
72 u8 pa;
73 bool stereo;
74 bool muted;
75 bool preemph_75_us;
76};
77
78static inline struct keene_device *to_keene_dev(struct v4l2_device *v4l2_dev)
79{
80 return container_of(v4l2_dev, struct keene_device, v4l2_dev);
81}
82
83/* Set frequency (if non-0), PA, mute and turn on/off the FM transmitter. */
84static int keene_cmd_main(struct keene_device *radio, unsigned freq, bool play)
85{
86 unsigned short freq_send = freq ? (freq - 76 * 16000) / 800 : 0;
87 int ret;
88
89 radio->buffer[0] = 0x00;
90 radio->buffer[1] = 0x50;
91 radio->buffer[2] = (freq_send >> 8) & 0xff;
92 radio->buffer[3] = freq_send & 0xff;
93 radio->buffer[4] = radio->pa;
94 /* If bit 4 is set, then tune to the frequency.
95 If bit 3 is set, then unmute; if bit 2 is set, then mute.
96 If bit 1 is set, then enter idle mode; if bit 0 is set,
97 then enter transit mode.
98 */
99 radio->buffer[5] = (radio->muted ? 4 : 8) | (play ? 1 : 2) |
100 (freq ? 0x10 : 0);
101 radio->buffer[6] = 0x00;
102 radio->buffer[7] = 0x00;
103
104 ret = usb_control_msg(radio->usbdev, usb_sndctrlpipe(radio->usbdev, 0),
105 9, 0x21, 0x200, 2, radio->buffer, BUFFER_LENGTH, USB_TIMEOUT);
106
107 if (ret < 0) {
108 dev_warn(&radio->vdev.dev, "%s failed (%d)\n", __func__, ret);
109 return ret;
110 }
111 if (freq)
112 radio->curfreq = freq;
113 return 0;
114}
115
116/* Set TX, stereo and preemphasis mode (50 us vs 75 us). */
117static int keene_cmd_set(struct keene_device *radio)
118{
119 int ret;
120
121 radio->buffer[0] = 0x00;
122 radio->buffer[1] = 0x51;
123 radio->buffer[2] = radio->tx;
124 /* If bit 0 is set, then transmit mono, otherwise stereo.
125 If bit 2 is set, then enable 75 us preemphasis, otherwise
126 it is 50 us. */
127 radio->buffer[3] = (!radio->stereo) | (radio->preemph_75_us ? 4 : 0);
128 radio->buffer[4] = 0x00;
129 radio->buffer[5] = 0x00;
130 radio->buffer[6] = 0x00;
131 radio->buffer[7] = 0x00;
132
133 ret = usb_control_msg(radio->usbdev, usb_sndctrlpipe(radio->usbdev, 0),
134 9, 0x21, 0x200, 2, radio->buffer, BUFFER_LENGTH, USB_TIMEOUT);
135
136 if (ret < 0) {
137 dev_warn(&radio->vdev.dev, "%s failed (%d)\n", __func__, ret);
138 return ret;
139 }
140 return 0;
141}
142
143/* Handle unplugging the device.
144 * We call video_unregister_device in any case.
145 * The last function called in this procedure is
146 * usb_keene_device_release.
147 */
148static void usb_keene_disconnect(struct usb_interface *intf)
149{
150 struct keene_device *radio = to_keene_dev(usb_get_intfdata(intf));
151
152 v4l2_device_get(&radio->v4l2_dev);
153 mutex_lock(&radio->lock);
154 usb_set_intfdata(intf, NULL);
155 video_unregister_device(&radio->vdev);
156 v4l2_device_disconnect(&radio->v4l2_dev);
157 mutex_unlock(&radio->lock);
158 v4l2_device_put(&radio->v4l2_dev);
159}
160
161static int vidioc_querycap(struct file *file, void *priv,
162 struct v4l2_capability *v)
163{
164 struct keene_device *radio = video_drvdata(file);
165
166 strlcpy(v->driver, "radio-keene", sizeof(v->driver));
167 strlcpy(v->card, "Keene FM Transmitter", sizeof(v->card));
168 usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
169 v->device_caps = V4L2_CAP_RADIO | V4L2_CAP_MODULATOR;
170 v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
171 return 0;
172}
173
174static int vidioc_g_modulator(struct file *file, void *priv,
175 struct v4l2_modulator *v)
176{
177 struct keene_device *radio = video_drvdata(file);
178
179 if (v->index > 0)
180 return -EINVAL;
181
182 strlcpy(v->name, "FM", sizeof(v->name));
183 v->rangelow = FREQ_MIN * FREQ_MUL;
184 v->rangehigh = FREQ_MAX * FREQ_MUL;
185 v->txsubchans = radio->stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
186 v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
187 return 0;
188}
189
190static int vidioc_s_modulator(struct file *file, void *priv,
191 struct v4l2_modulator *v)
192{
193 struct keene_device *radio = video_drvdata(file);
194
195 if (v->index > 0)
196 return -EINVAL;
197
198 radio->stereo = (v->txsubchans == V4L2_TUNER_SUB_STEREO);
199 return keene_cmd_set(radio);
200}
201
202static int vidioc_s_frequency(struct file *file, void *priv,
203 struct v4l2_frequency *f)
204{
205 struct keene_device *radio = video_drvdata(file);
206
207 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
208 return -EINVAL;
209 f->frequency = clamp(f->frequency,
210 FREQ_MIN * FREQ_MUL, FREQ_MAX * FREQ_MUL);
211 return keene_cmd_main(radio, f->frequency, true);
212}
213
214static int vidioc_g_frequency(struct file *file, void *priv,
215 struct v4l2_frequency *f)
216{
217 struct keene_device *radio = video_drvdata(file);
218
219 if (f->tuner != 0)
220 return -EINVAL;
221 f->type = V4L2_TUNER_RADIO;
222 f->frequency = radio->curfreq;
223 return 0;
224}
225
226static int keene_s_ctrl(struct v4l2_ctrl *ctrl)
227{
228 static const u8 db2tx[] = {
229 /* -15, -12, -9, -6, -3, 0 dB */
230 0x03, 0x13, 0x02, 0x12, 0x22, 0x32,
231 /* 3, 6, 9, 12, 15, 18 dB */
232 0x21, 0x31, 0x20, 0x30, 0x40, 0x50
233 };
234 struct keene_device *radio =
235 container_of(ctrl->handler, struct keene_device, hdl);
236
237 switch (ctrl->id) {
238 case V4L2_CID_AUDIO_MUTE:
239 radio->muted = ctrl->val;
240 return keene_cmd_main(radio, 0, true);
241
242 case V4L2_CID_TUNE_POWER_LEVEL:
243 /* To go from dBuV to the register value we apply the
244 following formula: */
245 radio->pa = (ctrl->val - 71) * 100 / 62;
246 return keene_cmd_main(radio, 0, true);
247
248 case V4L2_CID_TUNE_PREEMPHASIS:
249 radio->preemph_75_us = ctrl->val == V4L2_PREEMPHASIS_75_uS;
250 return keene_cmd_set(radio);
251
252 case V4L2_CID_AUDIO_COMPRESSION_GAIN:
253 radio->tx = db2tx[(ctrl->val - ctrl->minimum) / ctrl->step];
254 return keene_cmd_set(radio);
255 }
256 return -EINVAL;
257}
258
259static int vidioc_subscribe_event(struct v4l2_fh *fh,
260 struct v4l2_event_subscription *sub)
261{
262 switch (sub->type) {
263 case V4L2_EVENT_CTRL:
264 return v4l2_event_subscribe(fh, sub, 0);
265 default:
266 return -EINVAL;
267 }
268}
269
270
271/* File system interface */
272static const struct v4l2_file_operations usb_keene_fops = {
273 .owner = THIS_MODULE,
274 .open = v4l2_fh_open,
275 .release = v4l2_fh_release,
276 .poll = v4l2_ctrl_poll,
277 .unlocked_ioctl = video_ioctl2,
278};
279
280static const struct v4l2_ctrl_ops keene_ctrl_ops = {
281 .s_ctrl = keene_s_ctrl,
282};
283
284static const struct v4l2_ioctl_ops usb_keene_ioctl_ops = {
285 .vidioc_querycap = vidioc_querycap,
286 .vidioc_g_modulator = vidioc_g_modulator,
287 .vidioc_s_modulator = vidioc_s_modulator,
288 .vidioc_g_frequency = vidioc_g_frequency,
289 .vidioc_s_frequency = vidioc_s_frequency,
290 .vidioc_log_status = v4l2_ctrl_log_status,
291 .vidioc_subscribe_event = vidioc_subscribe_event,
292 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
293};
294
295static void usb_keene_video_device_release(struct v4l2_device *v4l2_dev)
296{
297 struct keene_device *radio = to_keene_dev(v4l2_dev);
298
299 /* free rest memory */
300 v4l2_ctrl_handler_free(&radio->hdl);
301 kfree(radio->buffer);
302 kfree(radio);
303}
304
305/* check if the device is present and register with v4l and usb if it is */
306static int usb_keene_probe(struct usb_interface *intf,
307 const struct usb_device_id *id)
308{
309 struct usb_device *dev = interface_to_usbdev(intf);
310 struct keene_device *radio;
311 struct v4l2_ctrl_handler *hdl;
312 int retval = 0;
313
314 /*
315 * The Keene FM transmitter USB device has the same USB ID as
316 * the Logitech AudioHub Speaker, but it should ignore the hid.
317 * Check if the name is that of the Keene device.
318 * If not, then someone connected the AudioHub and we shouldn't
319 * attempt to handle this driver.
320 * For reference: the product name of the AudioHub is
321 * "AudioHub Speaker".
322 */
323 if (dev->product && strcmp(dev->product, "B-LINK USB Audio "))
324 return -ENODEV;
325
326 radio = kzalloc(sizeof(struct keene_device), GFP_KERNEL);
327 if (radio)
328 radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL);
329
330 if (!radio || !radio->buffer) {
331 dev_err(&intf->dev, "kmalloc for keene_device failed\n");
332 kfree(radio);
333 retval = -ENOMEM;
334 goto err;
335 }
336
337 hdl = &radio->hdl;
338 v4l2_ctrl_handler_init(hdl, 4);
339 v4l2_ctrl_new_std(hdl, &keene_ctrl_ops, V4L2_CID_AUDIO_MUTE,
340 0, 1, 1, 0);
341 v4l2_ctrl_new_std_menu(hdl, &keene_ctrl_ops, V4L2_CID_TUNE_PREEMPHASIS,
342 V4L2_PREEMPHASIS_75_uS, 1, V4L2_PREEMPHASIS_50_uS);
343 v4l2_ctrl_new_std(hdl, &keene_ctrl_ops, V4L2_CID_TUNE_POWER_LEVEL,
344 84, 118, 1, 118);
345 v4l2_ctrl_new_std(hdl, &keene_ctrl_ops, V4L2_CID_AUDIO_COMPRESSION_GAIN,
346 -15, 18, 3, 0);
347 radio->pa = 118;
348 radio->tx = 0x32;
349 radio->stereo = true;
350 radio->curfreq = 95.16 * FREQ_MUL;
351 if (hdl->error) {
352 retval = hdl->error;
353
354 v4l2_ctrl_handler_free(hdl);
355 goto err_v4l2;
356 }
357 retval = v4l2_device_register(&intf->dev, &radio->v4l2_dev);
358 if (retval < 0) {
359 dev_err(&intf->dev, "couldn't register v4l2_device\n");
360 goto err_v4l2;
361 }
362
363 mutex_init(&radio->lock);
364
365 radio->v4l2_dev.ctrl_handler = hdl;
366 radio->v4l2_dev.release = usb_keene_video_device_release;
367 strlcpy(radio->vdev.name, radio->v4l2_dev.name,
368 sizeof(radio->vdev.name));
369 radio->vdev.v4l2_dev = &radio->v4l2_dev;
370 radio->vdev.fops = &usb_keene_fops;
371 radio->vdev.ioctl_ops = &usb_keene_ioctl_ops;
372 radio->vdev.lock = &radio->lock;
373 radio->vdev.release = video_device_release_empty;
374
375 radio->usbdev = interface_to_usbdev(intf);
376 radio->intf = intf;
377 usb_set_intfdata(intf, &radio->v4l2_dev);
378
379 video_set_drvdata(&radio->vdev, radio);
380 set_bit(V4L2_FL_USE_FH_PRIO, &radio->vdev.flags);
381
382 retval = video_register_device(&radio->vdev, VFL_TYPE_RADIO, -1);
383 if (retval < 0) {
384 dev_err(&intf->dev, "could not register video device\n");
385 goto err_vdev;
386 }
387 v4l2_ctrl_handler_setup(hdl);
388 dev_info(&intf->dev, "V4L2 device registered as %s\n",
389 video_device_node_name(&radio->vdev));
390 return 0;
391
392err_vdev:
393 v4l2_device_unregister(&radio->v4l2_dev);
394err_v4l2:
395 kfree(radio->buffer);
396 kfree(radio);
397err:
398 return retval;
399}
400
401/* USB subsystem interface */
402static struct usb_driver usb_keene_driver = {
403 .name = "radio-keene",
404 .probe = usb_keene_probe,
405 .disconnect = usb_keene_disconnect,
406 .id_table = usb_keene_device_table,
407};
408
409static int __init keene_init(void)
410{
411 int retval = usb_register(&usb_keene_driver);
412
413 if (retval)
414 pr_err(KBUILD_MODNAME
415 ": usb_register failed. Error number %d\n", retval);
416
417 return retval;
418}
419
420static void __exit keene_exit(void)
421{
422 usb_deregister(&usb_keene_driver);
423}
424
425module_init(keene_init);
426module_exit(keene_exit);
427
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index f872a54cf3d9..740a3d5520c7 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -42,67 +42,37 @@
42#include <linux/videodev2.h> 42#include <linux/videodev2.h>
43#include <linux/io.h> 43#include <linux/io.h>
44#include <linux/slab.h> 44#include <linux/slab.h>
45#include <sound/tea575x-tuner.h>
45#include <media/v4l2-device.h> 46#include <media/v4l2-device.h>
46#include <media/v4l2-ioctl.h> 47#include <media/v4l2-ioctl.h>
47 48#include <media/v4l2-fh.h>
48#define DRIVER_VERSION "0.7.8" 49#include <media/v4l2-ctrls.h>
49 50#include <media/v4l2-event.h>
50 51
51MODULE_AUTHOR("Dimitromanolakis Apostolos, apdim@grecian.net"); 52MODULE_AUTHOR("Dimitromanolakis Apostolos, apdim@grecian.net");
52MODULE_DESCRIPTION("Radio driver for the Guillemot Maxi Radio FM2000 radio."); 53MODULE_DESCRIPTION("Radio driver for the Guillemot Maxi Radio FM2000.");
53MODULE_LICENSE("GPL"); 54MODULE_LICENSE("GPL");
54MODULE_VERSION(DRIVER_VERSION); 55MODULE_VERSION("1.0.0");
55 56
56static int radio_nr = -1; 57static int radio_nr = -1;
57module_param(radio_nr, int, 0); 58module_param(radio_nr, int, 0644);
58 59MODULE_PARM_DESC(radio_nr, "Radio device number");
59static int debug;
60
61module_param(debug, int, 0644);
62MODULE_PARM_DESC(debug, "activates debug info");
63
64#define dprintk(dev, num, fmt, arg...) \
65 v4l2_dbg(num, debug, &dev->v4l2_dev, fmt, ## arg)
66
67#ifndef PCI_VENDOR_ID_GUILLEMOT
68#define PCI_VENDOR_ID_GUILLEMOT 0x5046
69#endif
70
71#ifndef PCI_DEVICE_ID_GUILLEMOT
72#define PCI_DEVICE_ID_GUILLEMOT_MAXIRADIO 0x1001
73#endif
74
75 60
76/* TEA5757 pin mappings */ 61/* TEA5757 pin mappings */
77static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16; 62static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16;
78 63
79#define FREQ_LO (87 * 16000) 64static atomic_t maxiradio_instance = ATOMIC_INIT(0);
80#define FREQ_HI (108 * 16000)
81
82#define FREQ_IF 171200 /* 10.7*16000 */
83#define FREQ_STEP 200 /* 12.5*16 */
84
85/* (x==fmhz*16*1000) -> bits */
86#define FREQ2BITS(x) \
87 ((((unsigned int)(x) + FREQ_IF + (FREQ_STEP << 1)) / (FREQ_STEP << 2)) << 2)
88
89#define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF)
90 65
66#define PCI_VENDOR_ID_GUILLEMOT 0x5046
67#define PCI_DEVICE_ID_GUILLEMOT_MAXIRADIO 0x1001
91 68
92struct maxiradio 69struct maxiradio
93{ 70{
71 struct snd_tea575x tea;
94 struct v4l2_device v4l2_dev; 72 struct v4l2_device v4l2_dev;
95 struct video_device vdev;
96 struct pci_dev *pdev; 73 struct pci_dev *pdev;
97 74
98 u16 io; /* base of radio io */ 75 u16 io; /* base of radio io */
99 u16 muted; /* VIDEO_AUDIO_MUTE */
100 u16 stereo; /* VIDEO_TUNER_STEREO_ON */
101 u16 tuned; /* signal strength (0 or 0xffff) */
102
103 unsigned long freq;
104
105 struct mutex lock;
106}; 76};
107 77
108static inline struct maxiradio *to_maxiradio(struct v4l2_device *v4l2_dev) 78static inline struct maxiradio *to_maxiradio(struct v4l2_device *v4l2_dev)
@@ -110,259 +80,41 @@ static inline struct maxiradio *to_maxiradio(struct v4l2_device *v4l2_dev)
110 return container_of(v4l2_dev, struct maxiradio, v4l2_dev); 80 return container_of(v4l2_dev, struct maxiradio, v4l2_dev);
111} 81}
112 82
113static void outbit(unsigned long bit, u16 io) 83static void maxiradio_tea575x_set_pins(struct snd_tea575x *tea, u8 pins)
114{
115 int val = power | wren | (bit ? data : 0);
116
117 outb(val, io);
118 udelay(4);
119 outb(val | clk, io);
120 udelay(4);
121 outb(val, io);
122 udelay(4);
123}
124
125static void turn_power(struct maxiradio *dev, int p)
126{
127 if (p != 0) {
128 dprintk(dev, 1, "Radio powered on\n");
129 outb(power, dev->io);
130 } else {
131 dprintk(dev, 1, "Radio powered off\n");
132 outb(0, dev->io);
133 }
134}
135
136static void set_freq(struct maxiradio *dev, u32 freq)
137{
138 unsigned long int si;
139 int bl;
140 int io = dev->io;
141 int val = FREQ2BITS(freq);
142
143 /* TEA5757 shift register bits (see pdf) */
144
145 outbit(0, io); /* 24 search */
146 outbit(1, io); /* 23 search up/down */
147
148 outbit(0, io); /* 22 stereo/mono */
149
150 outbit(0, io); /* 21 band */
151 outbit(0, io); /* 20 band (only 00=FM works I think) */
152
153 outbit(0, io); /* 19 port ? */
154 outbit(0, io); /* 18 port ? */
155
156 outbit(0, io); /* 17 search level */
157 outbit(0, io); /* 16 search level */
158
159 si = 0x8000;
160 for (bl = 1; bl <= 16; bl++) {
161 outbit(val & si, io);
162 si >>= 1;
163 }
164
165 dprintk(dev, 1, "Radio freq set to %d.%02d MHz\n",
166 freq / 16000,
167 freq % 16000 * 100 / 16000);
168
169 turn_power(dev, 1);
170}
171
172static int get_stereo(u16 io)
173{ 84{
174 outb(power,io); 85 struct maxiradio *dev = tea->private_data;
175 udelay(4); 86 u8 bits = 0;
176 87
177 return !(inb(io) & mo_st); 88 bits |= (pins & TEA575X_DATA) ? data : 0;
178} 89 bits |= (pins & TEA575X_CLK) ? clk : 0;
90 bits |= (pins & TEA575X_WREN) ? wren : 0;
91 bits |= power;
179 92
180static int get_tune(u16 io) 93 outb(bits, dev->io);
181{
182 outb(power+clk,io);
183 udelay(4);
184
185 return !(inb(io) & mo_st);
186}
187
188
189static int vidioc_querycap(struct file *file, void *priv,
190 struct v4l2_capability *v)
191{
192 struct maxiradio *dev = video_drvdata(file);
193
194 strlcpy(v->driver, "radio-maxiradio", sizeof(v->driver));
195 strlcpy(v->card, "Maxi Radio FM2000 radio", sizeof(v->card));
196 snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(dev->pdev));
197 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
198 return 0;
199} 94}
200 95
201static int vidioc_g_tuner(struct file *file, void *priv, 96/* Note: this card cannot read out the data of the shift registers,
202 struct v4l2_tuner *v) 97 only the mono/stereo pin works. */
98static u8 maxiradio_tea575x_get_pins(struct snd_tea575x *tea)
203{ 99{
204 struct maxiradio *dev = video_drvdata(file); 100 struct maxiradio *dev = tea->private_data;
205 101 u8 bits = inb(dev->io);
206 if (v->index > 0)
207 return -EINVAL;
208
209 mutex_lock(&dev->lock);
210 strlcpy(v->name, "FM", sizeof(v->name));
211 v->type = V4L2_TUNER_RADIO;
212 v->rangelow = FREQ_LO;
213 v->rangehigh = FREQ_HI;
214 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
215 v->capability = V4L2_TUNER_CAP_LOW;
216 if (get_stereo(dev->io))
217 v->audmode = V4L2_TUNER_MODE_STEREO;
218 else
219 v->audmode = V4L2_TUNER_MODE_MONO;
220 v->signal = 0xffff * get_tune(dev->io);
221 mutex_unlock(&dev->lock);
222 102
223 return 0; 103 return ((bits & data) ? TEA575X_DATA : 0) |
104 ((bits & mo_st) ? TEA575X_MOST : 0);
224} 105}
225 106
226static int vidioc_s_tuner(struct file *file, void *priv, 107static void maxiradio_tea575x_set_direction(struct snd_tea575x *tea, bool output)
227 struct v4l2_tuner *v)
228{ 108{
229 return v->index ? -EINVAL : 0;
230} 109}
231 110
232static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) 111static struct snd_tea575x_ops maxiradio_tea_ops = {
233{ 112 .set_pins = maxiradio_tea575x_set_pins,
234 *i = 0; 113 .get_pins = maxiradio_tea575x_get_pins,
235 return 0; 114 .set_direction = maxiradio_tea575x_set_direction,
236}
237
238static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
239{
240 return i ? -EINVAL : 0;
241}
242
243static int vidioc_g_audio(struct file *file, void *priv,
244 struct v4l2_audio *a)
245{
246 a->index = 0;
247 strlcpy(a->name, "Radio", sizeof(a->name));
248 a->capability = V4L2_AUDCAP_STEREO;
249 return 0;
250}
251
252
253static int vidioc_s_audio(struct file *file, void *priv,
254 struct v4l2_audio *a)
255{
256 return a->index ? -EINVAL : 0;
257}
258
259static int vidioc_s_frequency(struct file *file, void *priv,
260 struct v4l2_frequency *f)
261{
262 struct maxiradio *dev = video_drvdata(file);
263
264 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
265 return -EINVAL;
266 if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) {
267 dprintk(dev, 1, "radio freq (%d.%02d MHz) out of range (%d-%d)\n",
268 f->frequency / 16000,
269 f->frequency % 16000 * 100 / 16000,
270 FREQ_LO / 16000, FREQ_HI / 16000);
271
272 return -EINVAL;
273 }
274
275 mutex_lock(&dev->lock);
276 dev->freq = f->frequency;
277 set_freq(dev, dev->freq);
278 msleep(125);
279 mutex_unlock(&dev->lock);
280
281 return 0;
282}
283
284static int vidioc_g_frequency(struct file *file, void *priv,
285 struct v4l2_frequency *f)
286{
287 struct maxiradio *dev = video_drvdata(file);
288
289 if (f->tuner != 0)
290 return -EINVAL;
291 f->type = V4L2_TUNER_RADIO;
292 f->frequency = dev->freq;
293
294 dprintk(dev, 4, "radio freq is %d.%02d MHz",
295 f->frequency / 16000,
296 f->frequency % 16000 * 100 / 16000);
297
298 return 0;
299}
300
301static int vidioc_queryctrl(struct file *file, void *priv,
302 struct v4l2_queryctrl *qc)
303{
304 switch (qc->id) {
305 case V4L2_CID_AUDIO_MUTE:
306 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
307 }
308 return -EINVAL;
309}
310
311static int vidioc_g_ctrl(struct file *file, void *priv,
312 struct v4l2_control *ctrl)
313{
314 struct maxiradio *dev = video_drvdata(file);
315
316 switch (ctrl->id) {
317 case V4L2_CID_AUDIO_MUTE:
318 ctrl->value = dev->muted;
319 return 0;
320 }
321
322 return -EINVAL;
323}
324
325static int vidioc_s_ctrl(struct file *file, void *priv,
326 struct v4l2_control *ctrl)
327{
328 struct maxiradio *dev = video_drvdata(file);
329
330 switch (ctrl->id) {
331 case V4L2_CID_AUDIO_MUTE:
332 mutex_lock(&dev->lock);
333 dev->muted = ctrl->value;
334 if (dev->muted)
335 turn_power(dev, 0);
336 else
337 set_freq(dev, dev->freq);
338 mutex_unlock(&dev->lock);
339 return 0;
340 }
341
342 return -EINVAL;
343}
344
345static const struct v4l2_file_operations maxiradio_fops = {
346 .owner = THIS_MODULE,
347 .unlocked_ioctl = video_ioctl2,
348}; 115};
349 116
350static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = { 117static int __devinit maxiradio_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
351 .vidioc_querycap = vidioc_querycap,
352 .vidioc_g_tuner = vidioc_g_tuner,
353 .vidioc_s_tuner = vidioc_s_tuner,
354 .vidioc_g_audio = vidioc_g_audio,
355 .vidioc_s_audio = vidioc_s_audio,
356 .vidioc_g_input = vidioc_g_input,
357 .vidioc_s_input = vidioc_s_input,
358 .vidioc_g_frequency = vidioc_g_frequency,
359 .vidioc_s_frequency = vidioc_s_frequency,
360 .vidioc_queryctrl = vidioc_queryctrl,
361 .vidioc_g_ctrl = vidioc_g_ctrl,
362 .vidioc_s_ctrl = vidioc_s_ctrl,
363};
364
365static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
366{ 118{
367 struct maxiradio *dev; 119 struct maxiradio *dev;
368 struct v4l2_device *v4l2_dev; 120 struct v4l2_device *v4l2_dev;
@@ -375,63 +127,60 @@ static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_d
375 } 127 }
376 128
377 v4l2_dev = &dev->v4l2_dev; 129 v4l2_dev = &dev->v4l2_dev;
378 mutex_init(&dev->lock); 130 v4l2_device_set_name(v4l2_dev, "maxiradio", &maxiradio_instance);
379 dev->pdev = pdev;
380 dev->muted = 1;
381 dev->freq = FREQ_LO;
382
383 strlcpy(v4l2_dev->name, "maxiradio", sizeof(v4l2_dev->name));
384 131
385 retval = v4l2_device_register(&pdev->dev, v4l2_dev); 132 retval = v4l2_device_register(&pdev->dev, v4l2_dev);
386 if (retval < 0) { 133 if (retval < 0) {
387 v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); 134 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
388 goto errfr; 135 goto errfr;
389 } 136 }
137 dev->tea.private_data = dev;
138 dev->tea.ops = &maxiradio_tea_ops;
139 /* The data pin cannot be read. This may be a hardware limitation, or
140 we just don't know how to read it. */
141 dev->tea.cannot_read_data = true;
142 dev->tea.v4l2_dev = v4l2_dev;
143 dev->tea.radio_nr = radio_nr;
144 strlcpy(dev->tea.card, "Maxi Radio FM2000", sizeof(dev->tea.card));
145 snprintf(dev->tea.bus_info, sizeof(dev->tea.bus_info),
146 "PCI:%s", pci_name(pdev));
147
148 retval = -ENODEV;
390 149
391 if (!request_region(pci_resource_start(pdev, 0), 150 if (!request_region(pci_resource_start(pdev, 0),
392 pci_resource_len(pdev, 0), "Maxi Radio FM 2000")) { 151 pci_resource_len(pdev, 0), v4l2_dev->name)) {
393 v4l2_err(v4l2_dev, "can't reserve I/O ports\n"); 152 dev_err(&pdev->dev, "can't reserve I/O ports\n");
394 goto err_out; 153 goto err_hdl;
395 } 154 }
396 155
397 if (pci_enable_device(pdev)) 156 if (pci_enable_device(pdev))
398 goto err_out_free_region; 157 goto err_out_free_region;
399 158
400 dev->io = pci_resource_start(pdev, 0); 159 dev->io = pci_resource_start(pdev, 0);
401 strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name)); 160 if (snd_tea575x_init(&dev->tea)) {
402 dev->vdev.v4l2_dev = v4l2_dev; 161 printk(KERN_ERR "radio-maxiradio: Unable to detect TEA575x tuner\n");
403 dev->vdev.fops = &maxiradio_fops;
404 dev->vdev.ioctl_ops = &maxiradio_ioctl_ops;
405 dev->vdev.release = video_device_release_empty;
406 video_set_drvdata(&dev->vdev, dev);
407
408 if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
409 v4l2_err(v4l2_dev, "can't register device!");
410 goto err_out_free_region; 162 goto err_out_free_region;
411 } 163 }
412
413 v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n");
414
415 v4l2_info(v4l2_dev, "found Guillemot MAXI Radio device (io = 0x%x)\n",
416 dev->io);
417 return 0; 164 return 0;
418 165
419err_out_free_region: 166err_out_free_region:
420 release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); 167 release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
421err_out: 168err_hdl:
422 v4l2_device_unregister(v4l2_dev); 169 v4l2_device_unregister(v4l2_dev);
423errfr: 170errfr:
424 kfree(dev); 171 kfree(dev);
425 return -ENODEV; 172 return retval;
426} 173}
427 174
428static void __devexit maxiradio_remove_one(struct pci_dev *pdev) 175static void __devexit maxiradio_remove(struct pci_dev *pdev)
429{ 176{
430 struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev); 177 struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
431 struct maxiradio *dev = to_maxiradio(v4l2_dev); 178 struct maxiradio *dev = to_maxiradio(v4l2_dev);
432 179
433 video_unregister_device(&dev->vdev); 180 snd_tea575x_exit(&dev->tea);
434 v4l2_device_unregister(&dev->v4l2_dev); 181 /* Turn off power */
182 outb(0, dev->io);
183 v4l2_device_unregister(v4l2_dev);
435 release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); 184 release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
436} 185}
437 186
@@ -446,19 +195,19 @@ MODULE_DEVICE_TABLE(pci, maxiradio_pci_tbl);
446static struct pci_driver maxiradio_driver = { 195static struct pci_driver maxiradio_driver = {
447 .name = "radio-maxiradio", 196 .name = "radio-maxiradio",
448 .id_table = maxiradio_pci_tbl, 197 .id_table = maxiradio_pci_tbl,
449 .probe = maxiradio_init_one, 198 .probe = maxiradio_probe,
450 .remove = __devexit_p(maxiradio_remove_one), 199 .remove = __devexit_p(maxiradio_remove),
451}; 200};
452 201
453static int __init maxiradio_radio_init(void) 202static int __init maxiradio_init(void)
454{ 203{
455 return pci_register_driver(&maxiradio_driver); 204 return pci_register_driver(&maxiradio_driver);
456} 205}
457 206
458static void __exit maxiradio_radio_exit(void) 207static void __exit maxiradio_exit(void)
459{ 208{
460 pci_unregister_driver(&maxiradio_driver); 209 pci_unregister_driver(&maxiradio_driver);
461} 210}
462 211
463module_init(maxiradio_radio_init); 212module_init(maxiradio_init);
464module_exit(maxiradio_radio_exit); 213module_exit(maxiradio_exit);
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index 3628be617ee9..b275c5d0fe9a 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -1,11 +1,12 @@
1/* RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff 1/*
2 * RadioTrack II driver
3 * Copyright 1998 Ben Pfaff
2 * 4 *
3 * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood 5 * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood
4 * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk> 6 * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk>
5 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> 7 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
6 * 8 *
7 * TODO: Allow for more than one of these foolish entities :-) 9 * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com>
8 *
9 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> 10 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
10 */ 11 */
11 12
@@ -18,323 +19,120 @@
18#include <linux/io.h> /* outb, outb_p */ 19#include <linux/io.h> /* outb, outb_p */
19#include <media/v4l2-device.h> 20#include <media/v4l2-device.h>
20#include <media/v4l2-ioctl.h> 21#include <media/v4l2-ioctl.h>
22#include "radio-isa.h"
21 23
22MODULE_AUTHOR("Ben Pfaff"); 24MODULE_AUTHOR("Ben Pfaff");
23MODULE_DESCRIPTION("A driver for the RadioTrack II radio card."); 25MODULE_DESCRIPTION("A driver for the RadioTrack II radio card.");
24MODULE_LICENSE("GPL"); 26MODULE_LICENSE("GPL");
25MODULE_VERSION("0.0.3"); 27MODULE_VERSION("0.1.99");
26 28
27#ifndef CONFIG_RADIO_RTRACK2_PORT 29#ifndef CONFIG_RADIO_RTRACK2_PORT
28#define CONFIG_RADIO_RTRACK2_PORT -1 30#define CONFIG_RADIO_RTRACK2_PORT -1
29#endif 31#endif
30 32
31static int io = CONFIG_RADIO_RTRACK2_PORT; 33#define RTRACK2_MAX 2
32static int radio_nr = -1;
33
34module_param(io, int, 0);
35MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20c or 0x30c)");
36module_param(radio_nr, int, 0);
37
38struct rtrack2
39{
40 struct v4l2_device v4l2_dev;
41 struct video_device vdev;
42 int io;
43 unsigned long curfreq;
44 int muted;
45 struct mutex lock;
46};
47 34
48static struct rtrack2 rtrack2_card; 35static int io[RTRACK2_MAX] = { [0] = CONFIG_RADIO_RTRACK2_PORT,
36 [1 ... (RTRACK2_MAX - 1)] = -1 };
37static int radio_nr[RTRACK2_MAX] = { [0 ... (RTRACK2_MAX - 1)] = -1 };
49 38
39module_param_array(io, int, NULL, 0444);
40MODULE_PARM_DESC(io, "I/O addresses of the RadioTrack card (0x20f or 0x30f)");
41module_param_array(radio_nr, int, NULL, 0444);
42MODULE_PARM_DESC(radio_nr, "Radio device numbers");
50 43
51/* local things */ 44static struct radio_isa_card *rtrack2_alloc(void)
52
53static void rt_mute(struct rtrack2 *dev)
54{
55 if (dev->muted)
56 return;
57 mutex_lock(&dev->lock);
58 outb(1, dev->io);
59 mutex_unlock(&dev->lock);
60 dev->muted = 1;
61}
62
63static void rt_unmute(struct rtrack2 *dev)
64{ 45{
65 if(dev->muted == 0) 46 return kzalloc(sizeof(struct radio_isa_card), GFP_KERNEL);
66 return;
67 mutex_lock(&dev->lock);
68 outb(0, dev->io);
69 mutex_unlock(&dev->lock);
70 dev->muted = 0;
71} 47}
72 48
73static void zero(struct rtrack2 *dev) 49static void zero(struct radio_isa_card *isa)
74{ 50{
75 outb_p(1, dev->io); 51 outb_p(1, isa->io);
76 outb_p(3, dev->io); 52 outb_p(3, isa->io);
77 outb_p(1, dev->io); 53 outb_p(1, isa->io);
78} 54}
79 55
80static void one(struct rtrack2 *dev) 56static void one(struct radio_isa_card *isa)
81{ 57{
82 outb_p(5, dev->io); 58 outb_p(5, isa->io);
83 outb_p(7, dev->io); 59 outb_p(7, isa->io);
84 outb_p(5, dev->io); 60 outb_p(5, isa->io);
85} 61}
86 62
87static int rt_setfreq(struct rtrack2 *dev, unsigned long freq) 63static int rtrack2_s_frequency(struct radio_isa_card *isa, u32 freq)
88{ 64{
89 int i; 65 int i;
90 66
91 mutex_lock(&dev->lock);
92 dev->curfreq = freq;
93 freq = freq / 200 + 856; 67 freq = freq / 200 + 856;
94 68
95 outb_p(0xc8, dev->io); 69 outb_p(0xc8, isa->io);
96 outb_p(0xc9, dev->io); 70 outb_p(0xc9, isa->io);
97 outb_p(0xc9, dev->io); 71 outb_p(0xc9, isa->io);
98 72
99 for (i = 0; i < 10; i++) 73 for (i = 0; i < 10; i++)
100 zero(dev); 74 zero(isa);
101 75
102 for (i = 14; i >= 0; i--) 76 for (i = 14; i >= 0; i--)
103 if (freq & (1 << i)) 77 if (freq & (1 << i))
104 one(dev); 78 one(isa);
105 else 79 else
106 zero(dev); 80 zero(isa);
107
108 outb_p(0xc8, dev->io);
109 if (!dev->muted)
110 outb_p(0, dev->io);
111
112 mutex_unlock(&dev->lock);
113 return 0;
114}
115
116static int vidioc_querycap(struct file *file, void *priv,
117 struct v4l2_capability *v)
118{
119 strlcpy(v->driver, "radio-rtrack2", sizeof(v->driver));
120 strlcpy(v->card, "RadioTrack II", sizeof(v->card));
121 strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
122 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
123 return 0;
124}
125 81
126static int vidioc_s_tuner(struct file *file, void *priv, 82 outb_p(0xc8, isa->io);
127 struct v4l2_tuner *v) 83 if (!v4l2_ctrl_g_ctrl(isa->mute))
128{ 84 outb_p(0, isa->io);
129 return v->index ? -EINVAL : 0;
130}
131
132static int rt_getsigstr(struct rtrack2 *dev)
133{
134 int sig = 1;
135
136 mutex_lock(&dev->lock);
137 if (inb(dev->io) & 2) /* bit set = no signal present */
138 sig = 0;
139 mutex_unlock(&dev->lock);
140 return sig;
141}
142
143static int vidioc_g_tuner(struct file *file, void *priv,
144 struct v4l2_tuner *v)
145{
146 struct rtrack2 *rt = video_drvdata(file);
147
148 if (v->index > 0)
149 return -EINVAL;
150
151 strlcpy(v->name, "FM", sizeof(v->name));
152 v->type = V4L2_TUNER_RADIO;
153 v->rangelow = 88 * 16000;
154 v->rangehigh = 108 * 16000;
155 v->rxsubchans = V4L2_TUNER_SUB_MONO;
156 v->capability = V4L2_TUNER_CAP_LOW;
157 v->audmode = V4L2_TUNER_MODE_MONO;
158 v->signal = 0xFFFF * rt_getsigstr(rt);
159 return 0; 85 return 0;
160} 86}
161 87
162static int vidioc_s_frequency(struct file *file, void *priv, 88static u32 rtrack2_g_signal(struct radio_isa_card *isa)
163 struct v4l2_frequency *f)
164{ 89{
165 struct rtrack2 *rt = video_drvdata(file); 90 /* bit set = no signal present */
166 91 return (inb(isa->io) & 2) ? 0 : 0xffff;
167 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
168 return -EINVAL;
169 rt_setfreq(rt, f->frequency);
170 return 0;
171} 92}
172 93
173static int vidioc_g_frequency(struct file *file, void *priv, 94static int rtrack2_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol)
174 struct v4l2_frequency *f)
175{ 95{
176 struct rtrack2 *rt = video_drvdata(file); 96 outb(mute, isa->io);
177
178 if (f->tuner != 0)
179 return -EINVAL;
180 f->type = V4L2_TUNER_RADIO;
181 f->frequency = rt->curfreq;
182 return 0; 97 return 0;
183} 98}
184 99
185static int vidioc_queryctrl(struct file *file, void *priv, 100static const struct radio_isa_ops rtrack2_ops = {
186 struct v4l2_queryctrl *qc) 101 .alloc = rtrack2_alloc,
187{ 102 .s_mute_volume = rtrack2_s_mute_volume,
188 switch (qc->id) { 103 .s_frequency = rtrack2_s_frequency,
189 case V4L2_CID_AUDIO_MUTE: 104 .g_signal = rtrack2_g_signal,
190 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
191 case V4L2_CID_AUDIO_VOLUME:
192 return v4l2_ctrl_query_fill(qc, 0, 65535, 65535, 65535);
193 }
194 return -EINVAL;
195}
196
197static int vidioc_g_ctrl(struct file *file, void *priv,
198 struct v4l2_control *ctrl)
199{
200 struct rtrack2 *rt = video_drvdata(file);
201
202 switch (ctrl->id) {
203 case V4L2_CID_AUDIO_MUTE:
204 ctrl->value = rt->muted;
205 return 0;
206 case V4L2_CID_AUDIO_VOLUME:
207 if (rt->muted)
208 ctrl->value = 0;
209 else
210 ctrl->value = 65535;
211 return 0;
212 }
213 return -EINVAL;
214}
215
216static int vidioc_s_ctrl(struct file *file, void *priv,
217 struct v4l2_control *ctrl)
218{
219 struct rtrack2 *rt = video_drvdata(file);
220
221 switch (ctrl->id) {
222 case V4L2_CID_AUDIO_MUTE:
223 if (ctrl->value)
224 rt_mute(rt);
225 else
226 rt_unmute(rt);
227 return 0;
228 case V4L2_CID_AUDIO_VOLUME:
229 if (ctrl->value)
230 rt_unmute(rt);
231 else
232 rt_mute(rt);
233 return 0;
234 }
235 return -EINVAL;
236}
237
238static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
239{
240 *i = 0;
241 return 0;
242}
243
244static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
245{
246 return i ? -EINVAL : 0;
247}
248
249static int vidioc_g_audio(struct file *file, void *priv,
250 struct v4l2_audio *a)
251{
252 a->index = 0;
253 strlcpy(a->name, "Radio", sizeof(a->name));
254 a->capability = V4L2_AUDCAP_STEREO;
255 return 0;
256}
257
258static int vidioc_s_audio(struct file *file, void *priv,
259 struct v4l2_audio *a)
260{
261 return a->index ? -EINVAL : 0;
262}
263
264static const struct v4l2_file_operations rtrack2_fops = {
265 .owner = THIS_MODULE,
266 .unlocked_ioctl = video_ioctl2,
267}; 105};
268 106
269static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = { 107static const int rtrack2_ioports[] = { 0x20f, 0x30f };
270 .vidioc_querycap = vidioc_querycap, 108
271 .vidioc_g_tuner = vidioc_g_tuner, 109static struct radio_isa_driver rtrack2_driver = {
272 .vidioc_s_tuner = vidioc_s_tuner, 110 .driver = {
273 .vidioc_g_frequency = vidioc_g_frequency, 111 .match = radio_isa_match,
274 .vidioc_s_frequency = vidioc_s_frequency, 112 .probe = radio_isa_probe,
275 .vidioc_queryctrl = vidioc_queryctrl, 113 .remove = radio_isa_remove,
276 .vidioc_g_ctrl = vidioc_g_ctrl, 114 .driver = {
277 .vidioc_s_ctrl = vidioc_s_ctrl, 115 .name = "radio-rtrack2",
278 .vidioc_g_audio = vidioc_g_audio, 116 },
279 .vidioc_s_audio = vidioc_s_audio, 117 },
280 .vidioc_g_input = vidioc_g_input, 118 .io_params = io,
281 .vidioc_s_input = vidioc_s_input, 119 .radio_nr_params = radio_nr,
120 .io_ports = rtrack2_ioports,
121 .num_of_io_ports = ARRAY_SIZE(rtrack2_ioports),
122 .region_size = 4,
123 .card = "AIMSlab RadioTrack II",
124 .ops = &rtrack2_ops,
125 .has_stereo = true,
282}; 126};
283 127
284static int __init rtrack2_init(void) 128static int __init rtrack2_init(void)
285{ 129{
286 struct rtrack2 *dev = &rtrack2_card; 130 return isa_register_driver(&rtrack2_driver.driver, RTRACK2_MAX);
287 struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
288 int res;
289
290 strlcpy(v4l2_dev->name, "rtrack2", sizeof(v4l2_dev->name));
291 dev->io = io;
292 if (dev->io == -1) {
293 v4l2_err(v4l2_dev, "You must set an I/O address with io=0x20c or io=0x30c\n");
294 return -EINVAL;
295 }
296 if (!request_region(dev->io, 4, "rtrack2")) {
297 v4l2_err(v4l2_dev, "port 0x%x already in use\n", dev->io);
298 return -EBUSY;
299 }
300
301 res = v4l2_device_register(NULL, v4l2_dev);
302 if (res < 0) {
303 release_region(dev->io, 4);
304 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
305 return res;
306 }
307
308 strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
309 dev->vdev.v4l2_dev = v4l2_dev;
310 dev->vdev.fops = &rtrack2_fops;
311 dev->vdev.ioctl_ops = &rtrack2_ioctl_ops;
312 dev->vdev.release = video_device_release_empty;
313 video_set_drvdata(&dev->vdev, dev);
314
315 /* mute card - prevents noisy bootups */
316 outb(1, dev->io);
317 dev->muted = 1;
318
319 mutex_init(&dev->lock);
320 if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
321 v4l2_device_unregister(v4l2_dev);
322 release_region(dev->io, 4);
323 return -EINVAL;
324 }
325
326 v4l2_info(v4l2_dev, "AIMSlab Radiotrack II card driver.\n");
327
328 return 0;
329} 131}
330 132
331static void __exit rtrack2_exit(void) 133static void __exit rtrack2_exit(void)
332{ 134{
333 struct rtrack2 *dev = &rtrack2_card; 135 isa_unregister_driver(&rtrack2_driver.driver);
334
335 video_unregister_device(&dev->vdev);
336 v4l2_device_unregister(&dev->v4l2_dev);
337 release_region(dev->io, 4);
338} 136}
339 137
340module_init(rtrack2_init); 138module_init(rtrack2_init);
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index 7ab9afadf29b..7c69214334bf 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -9,16 +9,23 @@
9#include <linux/delay.h> 9#include <linux/delay.h>
10#include <linux/module.h> /* Modules */ 10#include <linux/module.h> /* Modules */
11#include <linux/init.h> /* Initdata */ 11#include <linux/init.h> /* Initdata */
12#include <linux/slab.h>
12#include <linux/ioport.h> /* request_region */ 13#include <linux/ioport.h> /* request_region */
13#include <linux/io.h> /* outb, outb_p */ 14#include <linux/io.h> /* outb, outb_p */
15#include <linux/isa.h>
14#include <sound/tea575x-tuner.h> 16#include <sound/tea575x-tuner.h>
15 17
16MODULE_AUTHOR("Ondrej Zary"); 18MODULE_AUTHOR("Ondrej Zary");
17MODULE_DESCRIPTION("MediaForte SF16-FMR2 FM radio card driver"); 19MODULE_DESCRIPTION("MediaForte SF16-FMR2 FM radio card driver");
18MODULE_LICENSE("GPL"); 20MODULE_LICENSE("GPL");
19 21
22static int radio_nr = -1;
23module_param(radio_nr, int, 0444);
24MODULE_PARM_DESC(radio_nr, "Radio device number");
25
20struct fmr2 { 26struct fmr2 {
21 int io; 27 int io;
28 struct v4l2_device v4l2_dev;
22 struct snd_tea575x tea; 29 struct snd_tea575x tea;
23 struct v4l2_ctrl *volume; 30 struct v4l2_ctrl *volume;
24 struct v4l2_ctrl *balance; 31 struct v4l2_ctrl *balance;
@@ -26,7 +33,6 @@ struct fmr2 {
26 33
27/* the port is hardwired so no need to support multiple cards */ 34/* the port is hardwired so no need to support multiple cards */
28#define FMR2_PORT 0x384 35#define FMR2_PORT 0x384
29static struct fmr2 fmr2_card;
30 36
31/* TEA575x tuner pins */ 37/* TEA575x tuner pins */
32#define STR_DATA (1 << 0) 38#define STR_DATA (1 << 0)
@@ -180,26 +186,46 @@ static int fmr2_tea_ext_init(struct snd_tea575x *tea)
180 return 0; 186 return 0;
181} 187}
182 188
183static int __init fmr2_init(void) 189static int __devinit fmr2_probe(struct device *pdev, unsigned int dev)
184{ 190{
185 struct fmr2 *fmr2 = &fmr2_card; 191 struct fmr2 *fmr2;
192 int err;
193
194 fmr2 = kzalloc(sizeof(*fmr2), GFP_KERNEL);
195 if (fmr2 == NULL)
196 return -ENOMEM;
186 197
198 strlcpy(fmr2->v4l2_dev.name, dev_name(pdev),
199 sizeof(fmr2->v4l2_dev.name));
187 fmr2->io = FMR2_PORT; 200 fmr2->io = FMR2_PORT;
188 201
189 if (!request_region(fmr2->io, 2, "SF16-FMR2")) { 202 if (!request_region(fmr2->io, 2, fmr2->v4l2_dev.name)) {
190 printk(KERN_ERR "radio-sf16fmr2: I/O port 0x%x already in use\n", fmr2->io); 203 printk(KERN_ERR "radio-sf16fmr2: I/O port 0x%x already in use\n", fmr2->io);
204 kfree(fmr2);
191 return -EBUSY; 205 return -EBUSY;
192 } 206 }
193 207
208 dev_set_drvdata(pdev, fmr2);
209 err = v4l2_device_register(pdev, &fmr2->v4l2_dev);
210 if (err < 0) {
211 v4l2_err(&fmr2->v4l2_dev, "Could not register v4l2_device\n");
212 release_region(fmr2->io, 2);
213 kfree(fmr2);
214 return err;
215 }
216 fmr2->tea.v4l2_dev = &fmr2->v4l2_dev;
194 fmr2->tea.private_data = fmr2; 217 fmr2->tea.private_data = fmr2;
218 fmr2->tea.radio_nr = radio_nr;
195 fmr2->tea.ops = &fmr2_tea_ops; 219 fmr2->tea.ops = &fmr2_tea_ops;
196 fmr2->tea.ext_init = fmr2_tea_ext_init; 220 fmr2->tea.ext_init = fmr2_tea_ext_init;
197 strlcpy(fmr2->tea.card, "SF16-FMR2", sizeof(fmr2->tea.card)); 221 strlcpy(fmr2->tea.card, "SF16-FMR2", sizeof(fmr2->tea.card));
198 strcpy(fmr2->tea.bus_info, "ISA"); 222 snprintf(fmr2->tea.bus_info, sizeof(fmr2->tea.bus_info), "ISA:%s",
223 fmr2->v4l2_dev.name);
199 224
200 if (snd_tea575x_init(&fmr2->tea)) { 225 if (snd_tea575x_init(&fmr2->tea)) {
201 printk(KERN_ERR "radio-sf16fmr2: Unable to detect TEA575x tuner\n"); 226 printk(KERN_ERR "radio-sf16fmr2: Unable to detect TEA575x tuner\n");
202 release_region(fmr2->io, 2); 227 release_region(fmr2->io, 2);
228 kfree(fmr2);
203 return -ENODEV; 229 return -ENODEV;
204 } 230 }
205 231
@@ -207,12 +233,33 @@ static int __init fmr2_init(void)
207 return 0; 233 return 0;
208} 234}
209 235
210static void __exit fmr2_exit(void) 236static int __exit fmr2_remove(struct device *pdev, unsigned int dev)
211{ 237{
212 struct fmr2 *fmr2 = &fmr2_card; 238 struct fmr2 *fmr2 = dev_get_drvdata(pdev);
213 239
214 snd_tea575x_exit(&fmr2->tea); 240 snd_tea575x_exit(&fmr2->tea);
215 release_region(fmr2->io, 2); 241 release_region(fmr2->io, 2);
242 v4l2_device_unregister(&fmr2->v4l2_dev);
243 kfree(fmr2);
244 return 0;
245}
246
247struct isa_driver fmr2_driver = {
248 .probe = fmr2_probe,
249 .remove = fmr2_remove,
250 .driver = {
251 .name = "radio-sf16fmr2",
252 },
253};
254
255static int __init fmr2_init(void)
256{
257 return isa_register_driver(&fmr2_driver, 1);
258}
259
260static void __exit fmr2_exit(void)
261{
262 isa_unregister_driver(&fmr2_driver);
216} 263}
217 264
218module_init(fmr2_init); 265module_init(fmr2_init);
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c
index db20904d01f0..6b1fae32b483 100644
--- a/drivers/media/radio/radio-tea5764.c
+++ b/drivers/media/radio/radio-tea5764.c
@@ -575,21 +575,7 @@ static struct i2c_driver tea5764_i2c_driver = {
575 .id_table = tea5764_id, 575 .id_table = tea5764_id,
576}; 576};
577 577
578/* init the driver */ 578module_i2c_driver(tea5764_i2c_driver);
579static int __init tea5764_init(void)
580{
581 int ret = i2c_add_driver(&tea5764_i2c_driver);
582
583 printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ": "
584 DRIVER_DESC "\n");
585 return ret;
586}
587
588/* cleanup the driver */
589static void __exit tea5764_exit(void)
590{
591 i2c_del_driver(&tea5764_i2c_driver);
592}
593 579
594MODULE_AUTHOR(DRIVER_AUTHOR); 580MODULE_AUTHOR(DRIVER_AUTHOR);
595MODULE_DESCRIPTION(DRIVER_DESC); 581MODULE_DESCRIPTION(DRIVER_DESC);
@@ -600,6 +586,3 @@ module_param(use_xtal, int, 0);
600MODULE_PARM_DESC(use_xtal, "Chip have a xtal connected in board"); 586MODULE_PARM_DESC(use_xtal, "Chip have a xtal connected in board");
601module_param(radio_nr, int, 0); 587module_param(radio_nr, int, 0);
602MODULE_PARM_DESC(radio_nr, "video4linux device number to use"); 588MODULE_PARM_DESC(radio_nr, "video4linux device number to use");
603
604module_init(tea5764_init);
605module_exit(tea5764_exit);
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index f2ed9cc3cf3b..be10a802e3a9 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -16,11 +16,7 @@
16 * Frequency control is done digitally -- ie out(port,encodefreq(95.8)); 16 * Frequency control is done digitally -- ie out(port,encodefreq(95.8));
17 * Volume Control is done digitally 17 * Volume Control is done digitally
18 * 18 *
19 * there is a I2C controlled RDS decoder (SAA6588) onboard, which i would like to support someday 19 * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com>
20 * (as soon i have understand how to get started :)
21 * If you can help me out with that, please contact me!!
22 *
23 *
24 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> 20 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
25 */ 21 */
26 22
@@ -30,43 +26,24 @@
30#include <linux/videodev2.h> /* kernel radio structs */ 26#include <linux/videodev2.h> /* kernel radio structs */
31#include <linux/mutex.h> 27#include <linux/mutex.h>
32#include <linux/io.h> /* outb, outb_p */ 28#include <linux/io.h> /* outb, outb_p */
29#include <linux/slab.h>
33#include <media/v4l2-device.h> 30#include <media/v4l2-device.h>
34#include <media/v4l2-ioctl.h> 31#include <media/v4l2-ioctl.h>
32#include "radio-isa.h"
35 33
36MODULE_AUTHOR("R.OFFERMANNS & others"); 34MODULE_AUTHOR("R. Offermans & others");
37MODULE_DESCRIPTION("A driver for the TerraTec ActiveRadio Standalone radio card."); 35MODULE_DESCRIPTION("A driver for the TerraTec ActiveRadio Standalone radio card.");
38MODULE_LICENSE("GPL"); 36MODULE_LICENSE("GPL");
39MODULE_VERSION("0.0.3"); 37MODULE_VERSION("0.1.99");
40
41#ifndef CONFIG_RADIO_TERRATEC_PORT
42#define CONFIG_RADIO_TERRATEC_PORT 0x590
43#endif
44 38
45static int io = CONFIG_RADIO_TERRATEC_PORT; 39/* Note: there seems to be only one possible port (0x590), but without
40 hardware this is hard to verify. For now, this is the only one we will
41 support. */
42static int io = 0x590;
46static int radio_nr = -1; 43static int radio_nr = -1;
47 44
48module_param(io, int, 0); 45module_param(radio_nr, int, 0444);
49MODULE_PARM_DESC(io, "I/O address of the TerraTec ActiveRadio card (0x590 or 0x591)"); 46MODULE_PARM_DESC(radio_nr, "Radio device number");
50module_param(radio_nr, int, 0);
51
52static struct v4l2_queryctrl radio_qctrl[] = {
53 {
54 .id = V4L2_CID_AUDIO_MUTE,
55 .name = "Mute",
56 .minimum = 0,
57 .maximum = 1,
58 .default_value = 1,
59 .type = V4L2_CTRL_TYPE_BOOLEAN,
60 },{
61 .id = V4L2_CID_AUDIO_VOLUME,
62 .name = "Volume",
63 .minimum = 0,
64 .maximum = 0xff,
65 .step = 1,
66 .default_value = 0xff,
67 .type = V4L2_CTRL_TYPE_INTEGER,
68 }
69};
70 47
71#define WRT_DIS 0x00 48#define WRT_DIS 0x00
72#define CLK_OFF 0x00 49#define CLK_OFF 0x00
@@ -76,63 +53,24 @@ static struct v4l2_queryctrl radio_qctrl[] = {
76#define CLK_ON 0x08 53#define CLK_ON 0x08
77#define WRT_EN 0x10 54#define WRT_EN 0x10
78 55
79struct terratec 56static struct radio_isa_card *terratec_alloc(void)
80{ 57{
81 struct v4l2_device v4l2_dev; 58 return kzalloc(sizeof(struct radio_isa_card), GFP_KERNEL);
82 struct video_device vdev; 59}
83 int io;
84 int curvol;
85 unsigned long curfreq;
86 int muted;
87 struct mutex lock;
88};
89
90static struct terratec terratec_card;
91
92/* local things */
93 60
94static void tt_write_vol(struct terratec *tt, int volume) 61static int terratec_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol)
95{ 62{
96 int i; 63 int i;
97 64
98 volume = volume + (volume * 32); /* change both channels */ 65 if (mute)
99 mutex_lock(&tt->lock); 66 vol = 0;
67 vol = vol + (vol * 32); /* change both channels */
100 for (i = 0; i < 8; i++) { 68 for (i = 0; i < 8; i++) {
101 if (volume & (0x80 >> i)) 69 if (vol & (0x80 >> i))
102 outb(0x80, tt->io + 1); 70 outb(0x80, isa->io + 1);
103 else 71 else
104 outb(0x00, tt->io + 1); 72 outb(0x00, isa->io + 1);
105 }
106 mutex_unlock(&tt->lock);
107}
108
109
110
111static void tt_mute(struct terratec *tt)
112{
113 tt->muted = 1;
114 tt_write_vol(tt, 0);
115}
116
117static int tt_setvol(struct terratec *tt, int vol)
118{
119 if (vol == tt->curvol) { /* requested volume = current */
120 if (tt->muted) { /* user is unmuting the card */
121 tt->muted = 0;
122 tt_write_vol(tt, vol); /* enable card */
123 }
124 return 0;
125 }
126
127 if (vol == 0) { /* volume = 0 means mute the card */
128 tt_write_vol(tt, 0); /* "turn off card" by setting vol to 0 */
129 tt->curvol = vol; /* track the volume state! */
130 return 0;
131 } 73 }
132
133 tt->muted = 0;
134 tt_write_vol(tt, vol);
135 tt->curvol = vol;
136 return 0; 74 return 0;
137} 75}
138 76
@@ -140,20 +78,15 @@ static int tt_setvol(struct terratec *tt, int vol)
140/* this is the worst part in this driver */ 78/* this is the worst part in this driver */
141/* many more or less strange things are going on here, but hey, it works :) */ 79/* many more or less strange things are going on here, but hey, it works :) */
142 80
143static int tt_setfreq(struct terratec *tt, unsigned long freq1) 81static int terratec_s_frequency(struct radio_isa_card *isa, u32 freq)
144{ 82{
145 int freq;
146 int i; 83 int i;
147 int p; 84 int p;
148 int temp; 85 int temp;
149 long rest; 86 long rest;
150 unsigned char buffer[25]; /* we have to bit shift 25 registers */ 87 unsigned char buffer[25]; /* we have to bit shift 25 registers */
151 88
152 mutex_lock(&tt->lock); 89 freq = freq / 160; /* convert the freq. to a nice to handle value */
153
154 tt->curfreq = freq1;
155
156 freq = freq1 / 160; /* convert the freq. to a nice to handle value */
157 memset(buffer, 0, sizeof(buffer)); 90 memset(buffer, 0, sizeof(buffer));
158 91
159 rest = freq * 10 + 10700; /* I once had understood what is going on here */ 92 rest = freq * 10 + 10700; /* I once had understood what is going on here */
@@ -175,239 +108,61 @@ static int tt_setfreq(struct terratec *tt, unsigned long freq1)
175 108
176 for (i = 24; i > -1; i--) { /* bit shift the values to the radiocard */ 109 for (i = 24; i > -1; i--) { /* bit shift the values to the radiocard */
177 if (buffer[i] == 1) { 110 if (buffer[i] == 1) {
178 outb(WRT_EN | DATA, tt->io); 111 outb(WRT_EN | DATA, isa->io);
179 outb(WRT_EN | DATA | CLK_ON, tt->io); 112 outb(WRT_EN | DATA | CLK_ON, isa->io);
180 outb(WRT_EN | DATA, tt->io); 113 outb(WRT_EN | DATA, isa->io);
181 } else { 114 } else {
182 outb(WRT_EN | 0x00, tt->io); 115 outb(WRT_EN | 0x00, isa->io);
183 outb(WRT_EN | 0x00 | CLK_ON, tt->io); 116 outb(WRT_EN | 0x00 | CLK_ON, isa->io);
184 }
185 }
186 outb(0x00, tt->io);
187
188 mutex_unlock(&tt->lock);
189
190 return 0;
191}
192
193static int tt_getsigstr(struct terratec *tt)
194{
195 if (inb(tt->io) & 2) /* bit set = no signal present */
196 return 0;
197 return 1; /* signal present */
198}
199
200static int vidioc_querycap(struct file *file, void *priv,
201 struct v4l2_capability *v)
202{
203 strlcpy(v->driver, "radio-terratec", sizeof(v->driver));
204 strlcpy(v->card, "ActiveRadio", sizeof(v->card));
205 strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
206 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
207 return 0;
208}
209
210static int vidioc_g_tuner(struct file *file, void *priv,
211 struct v4l2_tuner *v)
212{
213 struct terratec *tt = video_drvdata(file);
214
215 if (v->index > 0)
216 return -EINVAL;
217
218 strlcpy(v->name, "FM", sizeof(v->name));
219 v->type = V4L2_TUNER_RADIO;
220 v->rangelow = 87 * 16000;
221 v->rangehigh = 108 * 16000;
222 v->rxsubchans = V4L2_TUNER_SUB_MONO;
223 v->capability = V4L2_TUNER_CAP_LOW;
224 v->audmode = V4L2_TUNER_MODE_MONO;
225 v->signal = 0xFFFF * tt_getsigstr(tt);
226 return 0;
227}
228
229static int vidioc_s_tuner(struct file *file, void *priv,
230 struct v4l2_tuner *v)
231{
232 return v->index ? -EINVAL : 0;
233}
234
235static int vidioc_s_frequency(struct file *file, void *priv,
236 struct v4l2_frequency *f)
237{
238 struct terratec *tt = video_drvdata(file);
239
240 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
241 return -EINVAL;
242 tt_setfreq(tt, f->frequency);
243 return 0;
244}
245
246static int vidioc_g_frequency(struct file *file, void *priv,
247 struct v4l2_frequency *f)
248{
249 struct terratec *tt = video_drvdata(file);
250
251 if (f->tuner != 0)
252 return -EINVAL;
253 f->type = V4L2_TUNER_RADIO;
254 f->frequency = tt->curfreq;
255 return 0;
256}
257
258static int vidioc_queryctrl(struct file *file, void *priv,
259 struct v4l2_queryctrl *qc)
260{
261 int i;
262
263 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
264 if (qc->id && qc->id == radio_qctrl[i].id) {
265 memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
266 return 0;
267 } 117 }
268 } 118 }
269 return -EINVAL; 119 outb(0x00, isa->io);
270}
271
272static int vidioc_g_ctrl(struct file *file, void *priv,
273 struct v4l2_control *ctrl)
274{
275 struct terratec *tt = video_drvdata(file);
276
277 switch (ctrl->id) {
278 case V4L2_CID_AUDIO_MUTE:
279 if (tt->muted)
280 ctrl->value = 1;
281 else
282 ctrl->value = 0;
283 return 0;
284 case V4L2_CID_AUDIO_VOLUME:
285 ctrl->value = tt->curvol * 6554;
286 return 0;
287 }
288 return -EINVAL;
289}
290
291static int vidioc_s_ctrl(struct file *file, void *priv,
292 struct v4l2_control *ctrl)
293{
294 struct terratec *tt = video_drvdata(file);
295
296 switch (ctrl->id) {
297 case V4L2_CID_AUDIO_MUTE:
298 if (ctrl->value)
299 tt_mute(tt);
300 else
301 tt_setvol(tt,tt->curvol);
302 return 0;
303 case V4L2_CID_AUDIO_VOLUME:
304 tt_setvol(tt,ctrl->value);
305 return 0;
306 }
307 return -EINVAL;
308}
309
310static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
311{
312 *i = 0;
313 return 0;
314}
315
316static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
317{
318 return i ? -EINVAL : 0;
319}
320
321static int vidioc_g_audio(struct file *file, void *priv,
322 struct v4l2_audio *a)
323{
324 a->index = 0;
325 strlcpy(a->name, "Radio", sizeof(a->name));
326 a->capability = V4L2_AUDCAP_STEREO;
327 return 0; 120 return 0;
328} 121}
329 122
330static int vidioc_s_audio(struct file *file, void *priv, 123static u32 terratec_g_signal(struct radio_isa_card *isa)
331 struct v4l2_audio *a)
332{ 124{
333 return a->index ? -EINVAL : 0; 125 /* bit set = no signal present */
126 return (inb(isa->io) & 2) ? 0 : 0xffff;
334} 127}
335 128
336static const struct v4l2_file_operations terratec_fops = { 129static const struct radio_isa_ops terratec_ops = {
337 .owner = THIS_MODULE, 130 .alloc = terratec_alloc,
338 .unlocked_ioctl = video_ioctl2, 131 .s_mute_volume = terratec_s_mute_volume,
132 .s_frequency = terratec_s_frequency,
133 .g_signal = terratec_g_signal,
339}; 134};
340 135
341static const struct v4l2_ioctl_ops terratec_ioctl_ops = { 136static const int terratec_ioports[] = { 0x590 };
342 .vidioc_querycap = vidioc_querycap, 137
343 .vidioc_g_tuner = vidioc_g_tuner, 138static struct radio_isa_driver terratec_driver = {
344 .vidioc_s_tuner = vidioc_s_tuner, 139 .driver = {
345 .vidioc_g_frequency = vidioc_g_frequency, 140 .match = radio_isa_match,
346 .vidioc_s_frequency = vidioc_s_frequency, 141 .probe = radio_isa_probe,
347 .vidioc_queryctrl = vidioc_queryctrl, 142 .remove = radio_isa_remove,
348 .vidioc_g_ctrl = vidioc_g_ctrl, 143 .driver = {
349 .vidioc_s_ctrl = vidioc_s_ctrl, 144 .name = "radio-terratec",
350 .vidioc_g_audio = vidioc_g_audio, 145 },
351 .vidioc_s_audio = vidioc_s_audio, 146 },
352 .vidioc_g_input = vidioc_g_input, 147 .io_params = &io,
353 .vidioc_s_input = vidioc_s_input, 148 .radio_nr_params = &radio_nr,
149 .io_ports = terratec_ioports,
150 .num_of_io_ports = ARRAY_SIZE(terratec_ioports),
151 .region_size = 2,
152 .card = "TerraTec ActiveRadio",
153 .ops = &terratec_ops,
154 .has_stereo = true,
155 .max_volume = 10,
354}; 156};
355 157
356static int __init terratec_init(void) 158static int __init terratec_init(void)
357{ 159{
358 struct terratec *tt = &terratec_card; 160 return isa_register_driver(&terratec_driver.driver, 1);
359 struct v4l2_device *v4l2_dev = &tt->v4l2_dev;
360 int res;
361
362 strlcpy(v4l2_dev->name, "terratec", sizeof(v4l2_dev->name));
363 tt->io = io;
364 if (tt->io == -1) {
365 v4l2_err(v4l2_dev, "you must set an I/O address with io=0x590 or 0x591\n");
366 return -EINVAL;
367 }
368 if (!request_region(tt->io, 2, "terratec")) {
369 v4l2_err(v4l2_dev, "port 0x%x already in use\n", io);
370 return -EBUSY;
371 }
372
373 res = v4l2_device_register(NULL, v4l2_dev);
374 if (res < 0) {
375 release_region(tt->io, 2);
376 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
377 return res;
378 }
379
380 strlcpy(tt->vdev.name, v4l2_dev->name, sizeof(tt->vdev.name));
381 tt->vdev.v4l2_dev = v4l2_dev;
382 tt->vdev.fops = &terratec_fops;
383 tt->vdev.ioctl_ops = &terratec_ioctl_ops;
384 tt->vdev.release = video_device_release_empty;
385 video_set_drvdata(&tt->vdev, tt);
386
387 mutex_init(&tt->lock);
388
389 /* mute card - prevents noisy bootups */
390 tt_write_vol(tt, 0);
391
392 if (video_register_device(&tt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
393 v4l2_device_unregister(&tt->v4l2_dev);
394 release_region(tt->io, 2);
395 return -EINVAL;
396 }
397
398 v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver.\n");
399 return 0;
400} 161}
401 162
402static void __exit terratec_exit(void) 163static void __exit terratec_exit(void)
403{ 164{
404 struct terratec *tt = &terratec_card; 165 isa_unregister_driver(&terratec_driver.driver);
405 struct v4l2_device *v4l2_dev = &tt->v4l2_dev;
406
407 video_unregister_device(&tt->vdev);
408 v4l2_device_unregister(&tt->v4l2_dev);
409 release_region(tt->io, 2);
410 v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver unloaded.\n");
411} 166}
412 167
413module_init(terratec_init); 168module_init(terratec_init);
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
index b3f45a019d82..26a8c6002121 100644
--- a/drivers/media/radio/radio-trust.c
+++ b/drivers/media/radio/radio-trust.c
@@ -21,13 +21,15 @@
21#include <linux/ioport.h> 21#include <linux/ioport.h>
22#include <linux/videodev2.h> 22#include <linux/videodev2.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/slab.h>
24#include <media/v4l2-device.h> 25#include <media/v4l2-device.h>
25#include <media/v4l2-ioctl.h> 26#include <media/v4l2-ioctl.h>
27#include "radio-isa.h"
26 28
27MODULE_AUTHOR("Eric Lammerts, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath"); 29MODULE_AUTHOR("Eric Lammerts, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
28MODULE_DESCRIPTION("A driver for the Trust FM Radio card."); 30MODULE_DESCRIPTION("A driver for the Trust FM Radio card.");
29MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
30MODULE_VERSION("0.0.3"); 32MODULE_VERSION("0.1.99");
31 33
32/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */ 34/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
33 35
@@ -35,39 +37,38 @@ MODULE_VERSION("0.0.3");
35#define CONFIG_RADIO_TRUST_PORT -1 37#define CONFIG_RADIO_TRUST_PORT -1
36#endif 38#endif
37 39
38static int io = CONFIG_RADIO_TRUST_PORT; 40#define TRUST_MAX 2
39static int radio_nr = -1;
40 41
41module_param(io, int, 0); 42static int io[TRUST_MAX] = { [0] = CONFIG_RADIO_TRUST_PORT,
42MODULE_PARM_DESC(io, "I/O address of the Trust FM Radio card (0x350 or 0x358)"); 43 [1 ... (TRUST_MAX - 1)] = -1 };
43module_param(radio_nr, int, 0); 44static int radio_nr[TRUST_MAX] = { [0 ... (TRUST_MAX - 1)] = -1 };
45
46module_param_array(io, int, NULL, 0444);
47MODULE_PARM_DESC(io, "I/O addresses of the Trust FM Radio card (0x350 or 0x358)");
48module_param_array(radio_nr, int, NULL, 0444);
49MODULE_PARM_DESC(radio_nr, "Radio device numbers");
44 50
45struct trust { 51struct trust {
46 struct v4l2_device v4l2_dev; 52 struct radio_isa_card isa;
47 struct video_device vdev;
48 int io;
49 int ioval; 53 int ioval;
50 __u16 curvol;
51 __u16 curbass;
52 __u16 curtreble;
53 int muted;
54 unsigned long curfreq;
55 int curstereo;
56 int curmute;
57 struct mutex lock;
58}; 54};
59 55
60static struct trust trust_card; 56static struct radio_isa_card *trust_alloc(void)
57{
58 struct trust *tr = kzalloc(sizeof(*tr), GFP_KERNEL);
59
60 return tr ? &tr->isa : NULL;
61}
61 62
62/* i2c addresses */ 63/* i2c addresses */
63#define TDA7318_ADDR 0x88 64#define TDA7318_ADDR 0x88
64#define TSA6060T_ADDR 0xc4 65#define TSA6060T_ADDR 0xc4
65 66
66#define TR_DELAY do { inb(tr->io); inb(tr->io); inb(tr->io); } while (0) 67#define TR_DELAY do { inb(tr->isa.io); inb(tr->isa.io); inb(tr->isa.io); } while (0)
67#define TR_SET_SCL outb(tr->ioval |= 2, tr->io) 68#define TR_SET_SCL outb(tr->ioval |= 2, tr->isa.io)
68#define TR_CLR_SCL outb(tr->ioval &= 0xfd, tr->io) 69#define TR_CLR_SCL outb(tr->ioval &= 0xfd, tr->isa.io)
69#define TR_SET_SDA outb(tr->ioval |= 1, tr->io) 70#define TR_SET_SDA outb(tr->ioval |= 1, tr->isa.io)
70#define TR_CLR_SDA outb(tr->ioval &= 0xfe, tr->io) 71#define TR_CLR_SDA outb(tr->ioval &= 0xfe, tr->isa.io)
71 72
72static void write_i2c(struct trust *tr, int n, ...) 73static void write_i2c(struct trust *tr, int n, ...)
73{ 74{
@@ -84,10 +85,10 @@ static void write_i2c(struct trust *tr, int n, ...)
84 TR_CLR_SCL; 85 TR_CLR_SCL;
85 TR_DELAY; 86 TR_DELAY;
86 87
87 for(; n; n--) { 88 for (; n; n--) {
88 val = va_arg(args, unsigned); 89 val = va_arg(args, unsigned);
89 for(mask = 0x80; mask; mask >>= 1) { 90 for (mask = 0x80; mask; mask >>= 1) {
90 if(val & mask) 91 if (val & mask)
91 TR_SET_SDA; 92 TR_SET_SDA;
92 else 93 else
93 TR_CLR_SDA; 94 TR_CLR_SDA;
@@ -115,317 +116,128 @@ static void write_i2c(struct trust *tr, int n, ...)
115 va_end(args); 116 va_end(args);
116} 117}
117 118
118static void tr_setvol(struct trust *tr, __u16 vol) 119static int trust_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol)
119{ 120{
120 mutex_lock(&tr->lock); 121 struct trust *tr = container_of(isa, struct trust, isa);
121 tr->curvol = vol / 2048;
122 write_i2c(tr, 2, TDA7318_ADDR, tr->curvol ^ 0x1f);
123 mutex_unlock(&tr->lock);
124}
125 122
126static int basstreble2chip[15] = { 123 tr->ioval = (tr->ioval & 0xf7) | (mute << 3);
127 0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8 124 outb(tr->ioval, isa->io);
128}; 125 write_i2c(tr, 2, TDA7318_ADDR, vol ^ 0x1f);
129 126 return 0;
130static void tr_setbass(struct trust *tr, __u16 bass)
131{
132 mutex_lock(&tr->lock);
133 tr->curbass = bass / 4370;
134 write_i2c(tr, 2, TDA7318_ADDR, 0x60 | basstreble2chip[tr->curbass]);
135 mutex_unlock(&tr->lock);
136}
137
138static void tr_settreble(struct trust *tr, __u16 treble)
139{
140 mutex_lock(&tr->lock);
141 tr->curtreble = treble / 4370;
142 write_i2c(tr, 2, TDA7318_ADDR, 0x70 | basstreble2chip[tr->curtreble]);
143 mutex_unlock(&tr->lock);
144} 127}
145 128
146static void tr_setstereo(struct trust *tr, int stereo) 129static int trust_s_stereo(struct radio_isa_card *isa, bool stereo)
147{ 130{
148 mutex_lock(&tr->lock); 131 struct trust *tr = container_of(isa, struct trust, isa);
149 tr->curstereo = !!stereo;
150 tr->ioval = (tr->ioval & 0xfb) | (!tr->curstereo << 2);
151 outb(tr->ioval, tr->io);
152 mutex_unlock(&tr->lock);
153}
154 132
155static void tr_setmute(struct trust *tr, int mute) 133 tr->ioval = (tr->ioval & 0xfb) | (!stereo << 2);
156{ 134 outb(tr->ioval, isa->io);
157 mutex_lock(&tr->lock); 135 return 0;
158 tr->curmute = !!mute;
159 tr->ioval = (tr->ioval & 0xf7) | (tr->curmute << 3);
160 outb(tr->ioval, tr->io);
161 mutex_unlock(&tr->lock);
162} 136}
163 137
164static int tr_getsigstr(struct trust *tr) 138static u32 trust_g_signal(struct radio_isa_card *isa)
165{ 139{
166 int i, v; 140 int i, v;
167 141
168 mutex_lock(&tr->lock);
169 for (i = 0, v = 0; i < 100; i++) 142 for (i = 0, v = 0; i < 100; i++)
170 v |= inb(tr->io); 143 v |= inb(isa->io);
171 mutex_unlock(&tr->lock);
172 return (v & 1) ? 0 : 0xffff; 144 return (v & 1) ? 0 : 0xffff;
173} 145}
174 146
175static int tr_getstereo(struct trust *tr) 147static int trust_s_frequency(struct radio_isa_card *isa, u32 freq)
176{
177 /* don't know how to determine it, just return the setting */
178 return tr->curstereo;
179}
180
181static void tr_setfreq(struct trust *tr, unsigned long f)
182{ 148{
183 mutex_lock(&tr->lock); 149 struct trust *tr = container_of(isa, struct trust, isa);
184 tr->curfreq = f;
185 f /= 160; /* Convert to 10 kHz units */
186 f += 1070; /* Add 10.7 MHz IF */
187 write_i2c(tr, 5, TSA6060T_ADDR, (f << 1) | 1, f >> 7, 0x60 | ((f >> 15) & 1), 0);
188 mutex_unlock(&tr->lock);
189}
190 150
191static int vidioc_querycap(struct file *file, void *priv, 151 freq /= 160; /* Convert to 10 kHz units */
192 struct v4l2_capability *v) 152 freq += 1070; /* Add 10.7 MHz IF */
193{ 153 write_i2c(tr, 5, TSA6060T_ADDR, (freq << 1) | 1,
194 strlcpy(v->driver, "radio-trust", sizeof(v->driver)); 154 freq >> 7, 0x60 | ((freq >> 15) & 1), 0);
195 strlcpy(v->card, "Trust FM Radio", sizeof(v->card));
196 strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
197 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
198 return 0; 155 return 0;
199} 156}
200 157
201static int vidioc_g_tuner(struct file *file, void *priv, 158static int basstreble2chip[15] = {
202 struct v4l2_tuner *v) 159 0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8
203{ 160};
204 struct trust *tr = video_drvdata(file);
205
206 if (v->index > 0)
207 return -EINVAL;
208
209 strlcpy(v->name, "FM", sizeof(v->name));
210 v->type = V4L2_TUNER_RADIO;
211 v->rangelow = 87.5 * 16000;
212 v->rangehigh = 108 * 16000;
213 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
214 v->capability = V4L2_TUNER_CAP_LOW;
215 if (tr_getstereo(tr))
216 v->audmode = V4L2_TUNER_MODE_STEREO;
217 else
218 v->audmode = V4L2_TUNER_MODE_MONO;
219 v->signal = tr_getsigstr(tr);
220 return 0;
221}
222
223static int vidioc_s_tuner(struct file *file, void *priv,
224 struct v4l2_tuner *v)
225{
226 struct trust *tr = video_drvdata(file);
227
228 if (v->index)
229 return -EINVAL;
230 tr_setstereo(tr, v->audmode == V4L2_TUNER_MODE_STEREO);
231 return 0;
232}
233
234static int vidioc_s_frequency(struct file *file, void *priv,
235 struct v4l2_frequency *f)
236{
237 struct trust *tr = video_drvdata(file);
238
239 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
240 return -EINVAL;
241 tr_setfreq(tr, f->frequency);
242 return 0;
243}
244
245static int vidioc_g_frequency(struct file *file, void *priv,
246 struct v4l2_frequency *f)
247{
248 struct trust *tr = video_drvdata(file);
249
250 if (f->tuner != 0)
251 return -EINVAL;
252 f->type = V4L2_TUNER_RADIO;
253 f->frequency = tr->curfreq;
254 return 0;
255}
256
257static int vidioc_queryctrl(struct file *file, void *priv,
258 struct v4l2_queryctrl *qc)
259{
260 switch (qc->id) {
261 case V4L2_CID_AUDIO_MUTE:
262 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
263 case V4L2_CID_AUDIO_VOLUME:
264 return v4l2_ctrl_query_fill(qc, 0, 65535, 2048, 65535);
265 case V4L2_CID_AUDIO_BASS:
266 case V4L2_CID_AUDIO_TREBLE:
267 return v4l2_ctrl_query_fill(qc, 0, 65535, 4370, 32768);
268 }
269 return -EINVAL;
270}
271
272static int vidioc_g_ctrl(struct file *file, void *priv,
273 struct v4l2_control *ctrl)
274{
275 struct trust *tr = video_drvdata(file);
276
277 switch (ctrl->id) {
278 case V4L2_CID_AUDIO_MUTE:
279 ctrl->value = tr->curmute;
280 return 0;
281 case V4L2_CID_AUDIO_VOLUME:
282 ctrl->value = tr->curvol * 2048;
283 return 0;
284 case V4L2_CID_AUDIO_BASS:
285 ctrl->value = tr->curbass * 4370;
286 return 0;
287 case V4L2_CID_AUDIO_TREBLE:
288 ctrl->value = tr->curtreble * 4370;
289 return 0;
290 }
291 return -EINVAL;
292}
293 161
294static int vidioc_s_ctrl(struct file *file, void *priv, 162static int trust_s_ctrl(struct v4l2_ctrl *ctrl)
295 struct v4l2_control *ctrl)
296{ 163{
297 struct trust *tr = video_drvdata(file); 164 struct radio_isa_card *isa =
165 container_of(ctrl->handler, struct radio_isa_card, hdl);
166 struct trust *tr = container_of(isa, struct trust, isa);
298 167
299 switch (ctrl->id) { 168 switch (ctrl->id) {
300 case V4L2_CID_AUDIO_MUTE:
301 tr_setmute(tr, ctrl->value);
302 return 0;
303 case V4L2_CID_AUDIO_VOLUME:
304 tr_setvol(tr, ctrl->value);
305 return 0;
306 case V4L2_CID_AUDIO_BASS: 169 case V4L2_CID_AUDIO_BASS:
307 tr_setbass(tr, ctrl->value); 170 write_i2c(tr, 2, TDA7318_ADDR, 0x60 | basstreble2chip[ctrl->val]);
308 return 0; 171 return 0;
309 case V4L2_CID_AUDIO_TREBLE: 172 case V4L2_CID_AUDIO_TREBLE:
310 tr_settreble(tr, ctrl->value); 173 write_i2c(tr, 2, TDA7318_ADDR, 0x70 | basstreble2chip[ctrl->val]);
311 return 0; 174 return 0;
312 } 175 }
313 return -EINVAL; 176 return -EINVAL;
314} 177}
315 178
316static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) 179static const struct v4l2_ctrl_ops trust_ctrl_ops = {
317{ 180 .s_ctrl = trust_s_ctrl,
318 *i = 0;
319 return 0;
320}
321
322static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
323{
324 return i ? -EINVAL : 0;
325}
326
327static int vidioc_g_audio(struct file *file, void *priv,
328 struct v4l2_audio *a)
329{
330 a->index = 0;
331 strlcpy(a->name, "Radio", sizeof(a->name));
332 a->capability = V4L2_AUDCAP_STEREO;
333 return 0;
334}
335
336static int vidioc_s_audio(struct file *file, void *priv,
337 struct v4l2_audio *a)
338{
339 return a->index ? -EINVAL : 0;
340}
341
342static const struct v4l2_file_operations trust_fops = {
343 .owner = THIS_MODULE,
344 .unlocked_ioctl = video_ioctl2,
345};
346
347static const struct v4l2_ioctl_ops trust_ioctl_ops = {
348 .vidioc_querycap = vidioc_querycap,
349 .vidioc_g_tuner = vidioc_g_tuner,
350 .vidioc_s_tuner = vidioc_s_tuner,
351 .vidioc_g_frequency = vidioc_g_frequency,
352 .vidioc_s_frequency = vidioc_s_frequency,
353 .vidioc_queryctrl = vidioc_queryctrl,
354 .vidioc_g_ctrl = vidioc_g_ctrl,
355 .vidioc_s_ctrl = vidioc_s_ctrl,
356 .vidioc_g_audio = vidioc_g_audio,
357 .vidioc_s_audio = vidioc_s_audio,
358 .vidioc_g_input = vidioc_g_input,
359 .vidioc_s_input = vidioc_s_input,
360}; 181};
361 182
362static int __init trust_init(void) 183static int trust_initialize(struct radio_isa_card *isa)
363{ 184{
364 struct trust *tr = &trust_card; 185 struct trust *tr = container_of(isa, struct trust, isa);
365 struct v4l2_device *v4l2_dev = &tr->v4l2_dev;
366 int res;
367 186
368 strlcpy(v4l2_dev->name, "trust", sizeof(v4l2_dev->name));
369 tr->io = io;
370 tr->ioval = 0xf; 187 tr->ioval = 0xf;
371 mutex_init(&tr->lock);
372
373 if (tr->io == -1) {
374 v4l2_err(v4l2_dev, "You must set an I/O address with io=0x0x350 or 0x358\n");
375 return -EINVAL;
376 }
377 if (!request_region(tr->io, 2, "Trust FM Radio")) {
378 v4l2_err(v4l2_dev, "port 0x%x already in use\n", tr->io);
379 return -EBUSY;
380 }
381
382 res = v4l2_device_register(NULL, v4l2_dev);
383 if (res < 0) {
384 release_region(tr->io, 2);
385 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
386 return res;
387 }
388
389 strlcpy(tr->vdev.name, v4l2_dev->name, sizeof(tr->vdev.name));
390 tr->vdev.v4l2_dev = v4l2_dev;
391 tr->vdev.fops = &trust_fops;
392 tr->vdev.ioctl_ops = &trust_ioctl_ops;
393 tr->vdev.release = video_device_release_empty;
394 video_set_drvdata(&tr->vdev, tr);
395
396 write_i2c(tr, 2, TDA7318_ADDR, 0x80); /* speaker att. LF = 0 dB */ 188 write_i2c(tr, 2, TDA7318_ADDR, 0x80); /* speaker att. LF = 0 dB */
397 write_i2c(tr, 2, TDA7318_ADDR, 0xa0); /* speaker att. RF = 0 dB */ 189 write_i2c(tr, 2, TDA7318_ADDR, 0xa0); /* speaker att. RF = 0 dB */
398 write_i2c(tr, 2, TDA7318_ADDR, 0xc0); /* speaker att. LR = 0 dB */ 190 write_i2c(tr, 2, TDA7318_ADDR, 0xc0); /* speaker att. LR = 0 dB */
399 write_i2c(tr, 2, TDA7318_ADDR, 0xe0); /* speaker att. RR = 0 dB */ 191 write_i2c(tr, 2, TDA7318_ADDR, 0xe0); /* speaker att. RR = 0 dB */
400 write_i2c(tr, 2, TDA7318_ADDR, 0x40); /* stereo 1 input, gain = 18.75 dB */ 192 write_i2c(tr, 2, TDA7318_ADDR, 0x40); /* stereo 1 input, gain = 18.75 dB */
401 193
402 tr_setvol(tr, 0xffff); 194 v4l2_ctrl_new_std(&isa->hdl, &trust_ctrl_ops,
403 tr_setbass(tr, 0x8000); 195 V4L2_CID_AUDIO_BASS, 0, 15, 1, 8);
404 tr_settreble(tr, 0x8000); 196 v4l2_ctrl_new_std(&isa->hdl, &trust_ctrl_ops,
405 tr_setstereo(tr, 1); 197 V4L2_CID_AUDIO_TREBLE, 0, 15, 1, 8);
406 198 return isa->hdl.error;
407 /* mute card - prevents noisy bootups */ 199}
408 tr_setmute(tr, 1);
409 200
410 if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { 201static const struct radio_isa_ops trust_ops = {
411 v4l2_device_unregister(v4l2_dev); 202 .init = trust_initialize,
412 release_region(tr->io, 2); 203 .alloc = trust_alloc,
413 return -EINVAL; 204 .s_mute_volume = trust_s_mute_volume,
414 } 205 .s_frequency = trust_s_frequency,
206 .s_stereo = trust_s_stereo,
207 .g_signal = trust_g_signal,
208};
415 209
416 v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n"); 210static const int trust_ioports[] = { 0x350, 0x358 };
211
212static struct radio_isa_driver trust_driver = {
213 .driver = {
214 .match = radio_isa_match,
215 .probe = radio_isa_probe,
216 .remove = radio_isa_remove,
217 .driver = {
218 .name = "radio-trust",
219 },
220 },
221 .io_params = io,
222 .radio_nr_params = radio_nr,
223 .io_ports = trust_ioports,
224 .num_of_io_ports = ARRAY_SIZE(trust_ioports),
225 .region_size = 2,
226 .card = "Trust FM Radio",
227 .ops = &trust_ops,
228 .has_stereo = true,
229 .max_volume = 31,
230};
417 231
418 return 0; 232static int __init trust_init(void)
233{
234 return isa_register_driver(&trust_driver.driver, TRUST_MAX);
419} 235}
420 236
421static void __exit cleanup_trust_module(void) 237static void __exit trust_exit(void)
422{ 238{
423 struct trust *tr = &trust_card; 239 isa_unregister_driver(&trust_driver.driver);
424
425 video_unregister_device(&tr->vdev);
426 v4l2_device_unregister(&tr->v4l2_dev);
427 release_region(tr->io, 2);
428} 240}
429 241
430module_init(trust_init); 242module_init(trust_init);
431module_exit(cleanup_trust_module); 243module_exit(trust_exit);
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
index 398726abc0c8..eb72a4d13758 100644
--- a/drivers/media/radio/radio-typhoon.c
+++ b/drivers/media/radio/radio-typhoon.c
@@ -33,63 +33,53 @@
33#include <linux/ioport.h> /* request_region */ 33#include <linux/ioport.h> /* request_region */
34#include <linux/videodev2.h> /* kernel radio structs */ 34#include <linux/videodev2.h> /* kernel radio structs */
35#include <linux/io.h> /* outb, outb_p */ 35#include <linux/io.h> /* outb, outb_p */
36#include <linux/slab.h>
36#include <media/v4l2-device.h> 37#include <media/v4l2-device.h>
37#include <media/v4l2-ioctl.h> 38#include <media/v4l2-ioctl.h>
39#include "radio-isa.h"
38 40
39#define DRIVER_VERSION "0.1.2" 41#define DRIVER_VERSION "0.1.2"
40 42
41MODULE_AUTHOR("Dr. Henrik Seidel"); 43MODULE_AUTHOR("Dr. Henrik Seidel");
42MODULE_DESCRIPTION("A driver for the Typhoon radio card (a.k.a. EcoRadio)."); 44MODULE_DESCRIPTION("A driver for the Typhoon radio card (a.k.a. EcoRadio).");
43MODULE_LICENSE("GPL"); 45MODULE_LICENSE("GPL");
44MODULE_VERSION(DRIVER_VERSION); 46MODULE_VERSION("0.1.99");
45 47
46#ifndef CONFIG_RADIO_TYPHOON_PORT 48#ifndef CONFIG_RADIO_TYPHOON_PORT
47#define CONFIG_RADIO_TYPHOON_PORT -1 49#define CONFIG_RADIO_TYPHOON_PORT -1
48#endif 50#endif
49 51
50#ifndef CONFIG_RADIO_TYPHOON_MUTEFREQ 52#ifndef CONFIG_RADIO_TYPHOON_MUTEFREQ
51#define CONFIG_RADIO_TYPHOON_MUTEFREQ 0 53#define CONFIG_RADIO_TYPHOON_MUTEFREQ 87000
52#endif 54#endif
53 55
54static int io = CONFIG_RADIO_TYPHOON_PORT; 56#define TYPHOON_MAX 2
55static int radio_nr = -1;
56
57module_param(io, int, 0);
58MODULE_PARM_DESC(io, "I/O address of the Typhoon card (0x316 or 0x336)");
59
60module_param(radio_nr, int, 0);
61 57
58static int io[TYPHOON_MAX] = { [0] = CONFIG_RADIO_TYPHOON_PORT,
59 [1 ... (TYPHOON_MAX - 1)] = -1 };
60static int radio_nr[TYPHOON_MAX] = { [0 ... (TYPHOON_MAX - 1)] = -1 };
62static unsigned long mutefreq = CONFIG_RADIO_TYPHOON_MUTEFREQ; 61static unsigned long mutefreq = CONFIG_RADIO_TYPHOON_MUTEFREQ;
62
63module_param_array(io, int, NULL, 0444);
64MODULE_PARM_DESC(io, "I/O addresses of the Typhoon card (0x316 or 0x336)");
65module_param_array(radio_nr, int, NULL, 0444);
66MODULE_PARM_DESC(radio_nr, "Radio device numbers");
63module_param(mutefreq, ulong, 0); 67module_param(mutefreq, ulong, 0);
64MODULE_PARM_DESC(mutefreq, "Frequency used when muting the card (in kHz)"); 68MODULE_PARM_DESC(mutefreq, "Frequency used when muting the card (in kHz)");
65 69
66#define BANNER "Typhoon Radio Card driver v" DRIVER_VERSION "\n"
67
68struct typhoon { 70struct typhoon {
69 struct v4l2_device v4l2_dev; 71 struct radio_isa_card isa;
70 struct video_device vdev;
71 int io;
72 int curvol;
73 int muted; 72 int muted;
74 unsigned long curfreq;
75 unsigned long mutefreq;
76 struct mutex lock;
77}; 73};
78 74
79static struct typhoon typhoon_card; 75static struct radio_isa_card *typhoon_alloc(void)
80
81static void typhoon_setvol_generic(struct typhoon *dev, int vol)
82{ 76{
83 mutex_lock(&dev->lock); 77 struct typhoon *ty = kzalloc(sizeof(*ty), GFP_KERNEL);
84 vol >>= 14; /* Map 16 bit to 2 bit */ 78
85 vol &= 3; 79 return ty ? &ty->isa : NULL;
86 outb_p(vol / 2, dev->io); /* Set the volume, high bit. */
87 outb_p(vol % 2, dev->io + 2); /* Set the volume, low bit. */
88 mutex_unlock(&dev->lock);
89} 80}
90 81
91static int typhoon_setfreq_generic(struct typhoon *dev, 82static int typhoon_s_frequency(struct radio_isa_card *isa, u32 freq)
92 unsigned long frequency)
93{ 83{
94 unsigned long outval; 84 unsigned long outval;
95 unsigned long x; 85 unsigned long x;
@@ -105,302 +95,86 @@ static int typhoon_setfreq_generic(struct typhoon *dev,
105 * 95 *
106 */ 96 */
107 97
108 mutex_lock(&dev->lock); 98 x = freq / 160;
109 x = frequency / 160;
110 outval = (x * x + 2500) / 5000; 99 outval = (x * x + 2500) / 5000;
111 outval = (outval * x + 5000) / 10000; 100 outval = (outval * x + 5000) / 10000;
112 outval -= (10 * x * x + 10433) / 20866; 101 outval -= (10 * x * x + 10433) / 20866;
113 outval += 4 * x - 11505; 102 outval += 4 * x - 11505;
114 103
115 outb_p((outval >> 8) & 0x01, dev->io + 4); 104 outb_p((outval >> 8) & 0x01, isa->io + 4);
116 outb_p(outval >> 9, dev->io + 6); 105 outb_p(outval >> 9, isa->io + 6);
117 outb_p(outval & 0xff, dev->io + 8); 106 outb_p(outval & 0xff, isa->io + 8);
118 mutex_unlock(&dev->lock);
119
120 return 0;
121}
122
123static int typhoon_setfreq(struct typhoon *dev, unsigned long frequency)
124{
125 typhoon_setfreq_generic(dev, frequency);
126 dev->curfreq = frequency;
127 return 0;
128}
129
130static void typhoon_mute(struct typhoon *dev)
131{
132 if (dev->muted == 1)
133 return;
134 typhoon_setvol_generic(dev, 0);
135 typhoon_setfreq_generic(dev, dev->mutefreq);
136 dev->muted = 1;
137}
138
139static void typhoon_unmute(struct typhoon *dev)
140{
141 if (dev->muted == 0)
142 return;
143 typhoon_setfreq_generic(dev, dev->curfreq);
144 typhoon_setvol_generic(dev, dev->curvol);
145 dev->muted = 0;
146}
147
148static int typhoon_setvol(struct typhoon *dev, int vol)
149{
150 if (dev->muted && vol != 0) { /* user is unmuting the card */
151 dev->curvol = vol;
152 typhoon_unmute(dev);
153 return 0;
154 }
155 if (vol == dev->curvol) /* requested volume == current */
156 return 0;
157
158 if (vol == 0) { /* volume == 0 means mute the card */
159 typhoon_mute(dev);
160 dev->curvol = vol;
161 return 0;
162 }
163 typhoon_setvol_generic(dev, vol);
164 dev->curvol = vol;
165 return 0;
166}
167
168static int vidioc_querycap(struct file *file, void *priv,
169 struct v4l2_capability *v)
170{
171 strlcpy(v->driver, "radio-typhoon", sizeof(v->driver));
172 strlcpy(v->card, "Typhoon Radio", sizeof(v->card));
173 strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
174 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
175 return 0;
176}
177
178static int vidioc_g_tuner(struct file *file, void *priv,
179 struct v4l2_tuner *v)
180{
181 if (v->index > 0)
182 return -EINVAL;
183
184 strlcpy(v->name, "FM", sizeof(v->name));
185 v->type = V4L2_TUNER_RADIO;
186 v->rangelow = 87.5 * 16000;
187 v->rangehigh = 108 * 16000;
188 v->rxsubchans = V4L2_TUNER_SUB_MONO;
189 v->capability = V4L2_TUNER_CAP_LOW;
190 v->audmode = V4L2_TUNER_MODE_MONO;
191 v->signal = 0xFFFF; /* We can't get the signal strength */
192 return 0;
193}
194
195static int vidioc_s_tuner(struct file *file, void *priv,
196 struct v4l2_tuner *v)
197{
198 return v->index ? -EINVAL : 0;
199}
200
201static int vidioc_g_frequency(struct file *file, void *priv,
202 struct v4l2_frequency *f)
203{
204 struct typhoon *dev = video_drvdata(file);
205
206 if (f->tuner != 0)
207 return -EINVAL;
208 f->type = V4L2_TUNER_RADIO;
209 f->frequency = dev->curfreq;
210 return 0;
211}
212
213static int vidioc_s_frequency(struct file *file, void *priv,
214 struct v4l2_frequency *f)
215{
216 struct typhoon *dev = video_drvdata(file);
217
218 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
219 return -EINVAL;
220 dev->curfreq = f->frequency;
221 typhoon_setfreq(dev, dev->curfreq);
222 return 0; 107 return 0;
223} 108}
224 109
225static int vidioc_queryctrl(struct file *file, void *priv, 110static int typhoon_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol)
226 struct v4l2_queryctrl *qc)
227{ 111{
228 switch (qc->id) { 112 struct typhoon *ty = container_of(isa, struct typhoon, isa);
229 case V4L2_CID_AUDIO_MUTE:
230 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
231 case V4L2_CID_AUDIO_VOLUME:
232 return v4l2_ctrl_query_fill(qc, 0, 65535, 16384, 65535);
233 }
234 return -EINVAL;
235}
236 113
237static int vidioc_g_ctrl(struct file *file, void *priv, 114 if (mute)
238 struct v4l2_control *ctrl) 115 vol = 0;
239{ 116 vol >>= 14; /* Map 16 bit to 2 bit */
240 struct typhoon *dev = video_drvdata(file); 117 vol &= 3;
118 outb_p(vol / 2, isa->io); /* Set the volume, high bit. */
119 outb_p(vol % 2, isa->io + 2); /* Set the volume, low bit. */
241 120
242 switch (ctrl->id) { 121 if (vol == 0 && !ty->muted) {
243 case V4L2_CID_AUDIO_MUTE: 122 ty->muted = true;
244 ctrl->value = dev->muted; 123 return typhoon_s_frequency(isa, mutefreq << 4);
245 return 0;
246 case V4L2_CID_AUDIO_VOLUME:
247 ctrl->value = dev->curvol;
248 return 0;
249 } 124 }
250 return -EINVAL; 125 if (vol && ty->muted) {
251} 126 ty->muted = false;
252 127 return typhoon_s_frequency(isa, isa->freq);
253static int vidioc_s_ctrl (struct file *file, void *priv,
254 struct v4l2_control *ctrl)
255{
256 struct typhoon *dev = video_drvdata(file);
257
258 switch (ctrl->id) {
259 case V4L2_CID_AUDIO_MUTE:
260 if (ctrl->value)
261 typhoon_mute(dev);
262 else
263 typhoon_unmute(dev);
264 return 0;
265 case V4L2_CID_AUDIO_VOLUME:
266 typhoon_setvol(dev, ctrl->value);
267 return 0;
268 } 128 }
269 return -EINVAL;
270}
271
272static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
273{
274 *i = 0;
275 return 0; 129 return 0;
276} 130}
277 131
278static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) 132static const struct radio_isa_ops typhoon_ops = {
279{ 133 .alloc = typhoon_alloc,
280 return i ? -EINVAL : 0; 134 .s_mute_volume = typhoon_s_mute_volume,
281} 135 .s_frequency = typhoon_s_frequency,
282
283static int vidioc_g_audio(struct file *file, void *priv,
284 struct v4l2_audio *a)
285{
286 a->index = 0;
287 strlcpy(a->name, "Radio", sizeof(a->name));
288 a->capability = V4L2_AUDCAP_STEREO;
289 return 0;
290}
291
292static int vidioc_s_audio(struct file *file, void *priv,
293 struct v4l2_audio *a)
294{
295 return a->index ? -EINVAL : 0;
296}
297
298static int vidioc_log_status(struct file *file, void *priv)
299{
300 struct typhoon *dev = video_drvdata(file);
301 struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
302
303 v4l2_info(v4l2_dev, BANNER);
304#ifdef MODULE
305 v4l2_info(v4l2_dev, "Load type: Driver loaded as a module\n\n");
306#else
307 v4l2_info(v4l2_dev, "Load type: Driver compiled into kernel\n\n");
308#endif
309 v4l2_info(v4l2_dev, "frequency = %lu kHz\n", dev->curfreq >> 4);
310 v4l2_info(v4l2_dev, "volume = %d\n", dev->curvol);
311 v4l2_info(v4l2_dev, "mute = %s\n", dev->muted ? "on" : "off");
312 v4l2_info(v4l2_dev, "io = 0x%x\n", dev->io);
313 v4l2_info(v4l2_dev, "mute frequency = %lu kHz\n", dev->mutefreq >> 4);
314 return 0;
315}
316
317static const struct v4l2_file_operations typhoon_fops = {
318 .owner = THIS_MODULE,
319 .unlocked_ioctl = video_ioctl2,
320}; 136};
321 137
322static const struct v4l2_ioctl_ops typhoon_ioctl_ops = { 138static const int typhoon_ioports[] = { 0x316, 0x336 };
323 .vidioc_log_status = vidioc_log_status, 139
324 .vidioc_querycap = vidioc_querycap, 140static struct radio_isa_driver typhoon_driver = {
325 .vidioc_g_tuner = vidioc_g_tuner, 141 .driver = {
326 .vidioc_s_tuner = vidioc_s_tuner, 142 .match = radio_isa_match,
327 .vidioc_g_audio = vidioc_g_audio, 143 .probe = radio_isa_probe,
328 .vidioc_s_audio = vidioc_s_audio, 144 .remove = radio_isa_remove,
329 .vidioc_g_input = vidioc_g_input, 145 .driver = {
330 .vidioc_s_input = vidioc_s_input, 146 .name = "radio-typhoon",
331 .vidioc_g_frequency = vidioc_g_frequency, 147 },
332 .vidioc_s_frequency = vidioc_s_frequency, 148 },
333 .vidioc_queryctrl = vidioc_queryctrl, 149 .io_params = io,
334 .vidioc_g_ctrl = vidioc_g_ctrl, 150 .radio_nr_params = radio_nr,
335 .vidioc_s_ctrl = vidioc_s_ctrl, 151 .io_ports = typhoon_ioports,
152 .num_of_io_ports = ARRAY_SIZE(typhoon_ioports),
153 .region_size = 8,
154 .card = "Typhoon Radio",
155 .ops = &typhoon_ops,
156 .has_stereo = true,
157 .max_volume = 3,
336}; 158};
337 159
338static int __init typhoon_init(void) 160static int __init typhoon_init(void)
339{ 161{
340 struct typhoon *dev = &typhoon_card; 162 if (mutefreq < 87000 || mutefreq > 108000) {
341 struct v4l2_device *v4l2_dev = &dev->v4l2_dev; 163 printk(KERN_ERR "%s: You must set a frequency (in kHz) used when muting the card,\n",
342 int res; 164 typhoon_driver.driver.driver.name);
343 165 printk(KERN_ERR "%s: e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108000)\n",
344 strlcpy(v4l2_dev->name, "typhoon", sizeof(v4l2_dev->name)); 166 typhoon_driver.driver.driver.name);
345 dev->io = io; 167 return -ENODEV;
346
347 if (dev->io == -1) {
348 v4l2_err(v4l2_dev, "You must set an I/O address with io=0x316 or io=0x336\n");
349 return -EINVAL;
350 }
351
352 if (mutefreq < 87000 || mutefreq > 108500) {
353 v4l2_err(v4l2_dev, "You must set a frequency (in kHz) used when muting the card,\n");
354 v4l2_err(v4l2_dev, "e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n");
355 return -EINVAL;
356 }
357 dev->curfreq = dev->mutefreq = mutefreq << 4;
358
359 mutex_init(&dev->lock);
360 if (!request_region(dev->io, 8, "typhoon")) {
361 v4l2_err(v4l2_dev, "port 0x%x already in use\n",
362 dev->io);
363 return -EBUSY;
364 }
365
366 res = v4l2_device_register(NULL, v4l2_dev);
367 if (res < 0) {
368 release_region(dev->io, 8);
369 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
370 return res;
371 } 168 }
372 v4l2_info(v4l2_dev, BANNER); 169 return isa_register_driver(&typhoon_driver.driver, TYPHOON_MAX);
373
374 strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
375 dev->vdev.v4l2_dev = v4l2_dev;
376 dev->vdev.fops = &typhoon_fops;
377 dev->vdev.ioctl_ops = &typhoon_ioctl_ops;
378 dev->vdev.release = video_device_release_empty;
379 video_set_drvdata(&dev->vdev, dev);
380
381 /* mute card - prevents noisy bootups */
382 typhoon_mute(dev);
383
384 if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
385 v4l2_device_unregister(&dev->v4l2_dev);
386 release_region(dev->io, 8);
387 return -EINVAL;
388 }
389 v4l2_info(v4l2_dev, "port 0x%x.\n", dev->io);
390 v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", mutefreq);
391
392 return 0;
393} 170}
394 171
395static void __exit typhoon_exit(void) 172static void __exit typhoon_exit(void)
396{ 173{
397 struct typhoon *dev = &typhoon_card; 174 isa_unregister_driver(&typhoon_driver.driver);
398
399 video_unregister_device(&dev->vdev);
400 v4l2_device_unregister(&dev->v4l2_dev);
401 release_region(dev->io, 8);
402} 175}
403 176
177
404module_init(typhoon_init); 178module_init(typhoon_init);
405module_exit(typhoon_exit); 179module_exit(typhoon_exit);
406 180
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index f5613b948203..026e88eef29c 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -1,5 +1,6 @@
1/* zoltrix radio plus driver for Linux radio support 1/*
2 * (c) 1998 C. van Schaik <carl@leg.uct.ac.za> 2 * Zoltrix Radio Plus driver
3 * Copyright 1998 C. van Schaik <carl@leg.uct.ac.za>
3 * 4 *
4 * BUGS 5 * BUGS
5 * Due to the inconsistency in reading from the signal flags 6 * Due to the inconsistency in reading from the signal flags
@@ -27,6 +28,14 @@
27 * 28 *
28 * 2006-07-24 - Converted to V4L2 API 29 * 2006-07-24 - Converted to V4L2 API
29 * by Mauro Carvalho Chehab <mchehab@infradead.org> 30 * by Mauro Carvalho Chehab <mchehab@infradead.org>
31 *
32 * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com>
33 *
34 * Note that this is the driver for the Zoltrix Radio Plus.
35 * This driver does not work for the Zoltrix Radio Plus 108 or the
36 * Zoltrix Radio Plus for Windows.
37 *
38 * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool.
30 */ 39 */
31 40
32#include <linux/module.h> /* Modules */ 41#include <linux/module.h> /* Modules */
@@ -36,82 +45,70 @@
36#include <linux/videodev2.h> /* kernel radio structs */ 45#include <linux/videodev2.h> /* kernel radio structs */
37#include <linux/mutex.h> 46#include <linux/mutex.h>
38#include <linux/io.h> /* outb, outb_p */ 47#include <linux/io.h> /* outb, outb_p */
48#include <linux/slab.h>
39#include <media/v4l2-device.h> 49#include <media/v4l2-device.h>
40#include <media/v4l2-ioctl.h> 50#include <media/v4l2-ioctl.h>
51#include "radio-isa.h"
41 52
42MODULE_AUTHOR("C.van Schaik"); 53MODULE_AUTHOR("C. van Schaik");
43MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus."); 54MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus.");
44MODULE_LICENSE("GPL"); 55MODULE_LICENSE("GPL");
45MODULE_VERSION("0.0.3"); 56MODULE_VERSION("0.1.99");
46 57
47#ifndef CONFIG_RADIO_ZOLTRIX_PORT 58#ifndef CONFIG_RADIO_ZOLTRIX_PORT
48#define CONFIG_RADIO_ZOLTRIX_PORT -1 59#define CONFIG_RADIO_ZOLTRIX_PORT -1
49#endif 60#endif
50 61
51static int io = CONFIG_RADIO_ZOLTRIX_PORT; 62#define ZOLTRIX_MAX 2
52static int radio_nr = -1; 63
64static int io[ZOLTRIX_MAX] = { [0] = CONFIG_RADIO_ZOLTRIX_PORT,
65 [1 ... (ZOLTRIX_MAX - 1)] = -1 };
66static int radio_nr[ZOLTRIX_MAX] = { [0 ... (ZOLTRIX_MAX - 1)] = -1 };
53 67
54module_param(io, int, 0); 68module_param_array(io, int, NULL, 0444);
55MODULE_PARM_DESC(io, "I/O address of the Zoltrix Radio Plus (0x20c or 0x30c)"); 69MODULE_PARM_DESC(io, "I/O addresses of the Zoltrix Radio Plus card (0x20c or 0x30c)");
56module_param(radio_nr, int, 0); 70module_param_array(radio_nr, int, NULL, 0444);
71MODULE_PARM_DESC(radio_nr, "Radio device numbers");
57 72
58struct zoltrix { 73struct zoltrix {
59 struct v4l2_device v4l2_dev; 74 struct radio_isa_card isa;
60 struct video_device vdev;
61 int io;
62 int curvol; 75 int curvol;
63 unsigned long curfreq; 76 bool muted;
64 int muted;
65 unsigned int stereo;
66 struct mutex lock;
67}; 77};
68 78
69static struct zoltrix zoltrix_card; 79static struct radio_isa_card *zoltrix_alloc(void)
80{
81 struct zoltrix *zol = kzalloc(sizeof(*zol), GFP_KERNEL);
82
83 return zol ? &zol->isa : NULL;
84}
70 85
71static int zol_setvol(struct zoltrix *zol, int vol) 86static int zoltrix_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol)
72{ 87{
73 zol->curvol = vol; 88 struct zoltrix *zol = container_of(isa, struct zoltrix, isa);
74 if (zol->muted)
75 return 0;
76 89
77 mutex_lock(&zol->lock); 90 zol->curvol = vol;
78 if (vol == 0) { 91 zol->muted = mute;
79 outb(0, zol->io); 92 if (mute || vol == 0) {
80 outb(0, zol->io); 93 outb(0, isa->io);
81 inb(zol->io + 3); /* Zoltrix needs to be read to confirm */ 94 outb(0, isa->io);
82 mutex_unlock(&zol->lock); 95 inb(isa->io + 3); /* Zoltrix needs to be read to confirm */
83 return 0; 96 return 0;
84 } 97 }
85 98
86 outb(zol->curvol-1, zol->io); 99 outb(vol - 1, isa->io);
87 msleep(10); 100 msleep(10);
88 inb(zol->io + 2); 101 inb(isa->io + 2);
89 mutex_unlock(&zol->lock);
90 return 0; 102 return 0;
91} 103}
92 104
93static void zol_mute(struct zoltrix *zol) 105/* tunes the radio to the desired frequency */
94{ 106static int zoltrix_s_frequency(struct radio_isa_card *isa, u32 freq)
95 zol->muted = 1;
96 mutex_lock(&zol->lock);
97 outb(0, zol->io);
98 outb(0, zol->io);
99 inb(zol->io + 3); /* Zoltrix needs to be read to confirm */
100 mutex_unlock(&zol->lock);
101}
102
103static void zol_unmute(struct zoltrix *zol)
104{
105 zol->muted = 0;
106 zol_setvol(zol, zol->curvol);
107}
108
109static int zol_setfreq(struct zoltrix *zol, unsigned long freq)
110{ 107{
111 /* tunes the radio to the desired frequency */ 108 struct zoltrix *zol = container_of(isa, struct zoltrix, isa);
112 struct v4l2_device *v4l2_dev = &zol->v4l2_dev; 109 struct v4l2_device *v4l2_dev = &isa->v4l2_dev;
113 unsigned long long bitmask, f, m; 110 unsigned long long bitmask, f, m;
114 unsigned int stereo = zol->stereo; 111 bool stereo = isa->stereo;
115 int i; 112 int i;
116 113
117 if (freq == 0) { 114 if (freq == 0) {
@@ -125,340 +122,125 @@ static int zol_setfreq(struct zoltrix *zol, unsigned long freq)
125 bitmask = 0xc480402c10080000ull; 122 bitmask = 0xc480402c10080000ull;
126 i = 45; 123 i = 45;
127 124
128 mutex_lock(&zol->lock); 125 outb(0, isa->io);
129 126 outb(0, isa->io);
130 zol->curfreq = freq; 127 inb(isa->io + 3); /* Zoltrix needs to be read to confirm */
131
132 outb(0, zol->io);
133 outb(0, zol->io);
134 inb(zol->io + 3); /* Zoltrix needs to be read to confirm */
135 128
136 outb(0x40, zol->io); 129 outb(0x40, isa->io);
137 outb(0xc0, zol->io); 130 outb(0xc0, isa->io);
138 131
139 bitmask = (bitmask ^ ((f & 0xff) << 47) ^ ((f & 0xff00) << 30) ^ (stereo << 31)); 132 bitmask = (bitmask ^ ((f & 0xff) << 47) ^ ((f & 0xff00) << 30) ^ (stereo << 31));
140 while (i--) { 133 while (i--) {
141 if ((bitmask & 0x8000000000000000ull) != 0) { 134 if ((bitmask & 0x8000000000000000ull) != 0) {
142 outb(0x80, zol->io); 135 outb(0x80, isa->io);
143 udelay(50); 136 udelay(50);
144 outb(0x00, zol->io); 137 outb(0x00, isa->io);
145 udelay(50); 138 udelay(50);
146 outb(0x80, zol->io); 139 outb(0x80, isa->io);
147 udelay(50); 140 udelay(50);
148 } else { 141 } else {
149 outb(0xc0, zol->io); 142 outb(0xc0, isa->io);
150 udelay(50); 143 udelay(50);
151 outb(0x40, zol->io); 144 outb(0x40, isa->io);
152 udelay(50); 145 udelay(50);
153 outb(0xc0, zol->io); 146 outb(0xc0, isa->io);
154 udelay(50); 147 udelay(50);
155 } 148 }
156 bitmask *= 2; 149 bitmask *= 2;
157 } 150 }
158 /* termination sequence */ 151 /* termination sequence */
159 outb(0x80, zol->io); 152 outb(0x80, isa->io);
160 outb(0xc0, zol->io); 153 outb(0xc0, isa->io);
161 outb(0x40, zol->io); 154 outb(0x40, isa->io);
162 udelay(1000); 155 udelay(1000);
163 inb(zol->io + 2); 156 inb(isa->io + 2);
164
165 udelay(1000); 157 udelay(1000);
166 158
167 if (zol->muted) { 159 return zoltrix_s_mute_volume(isa, zol->muted, zol->curvol);
168 outb(0, zol->io);
169 outb(0, zol->io);
170 inb(zol->io + 3);
171 udelay(1000);
172 }
173
174 mutex_unlock(&zol->lock);
175
176 if (!zol->muted)
177 zol_setvol(zol, zol->curvol);
178 return 0;
179} 160}
180 161
181/* Get signal strength */ 162/* Get signal strength */
182static int zol_getsigstr(struct zoltrix *zol) 163static u32 zoltrix_g_rxsubchans(struct radio_isa_card *isa)
183{ 164{
165 struct zoltrix *zol = container_of(isa, struct zoltrix, isa);
184 int a, b; 166 int a, b;
185 167
186 mutex_lock(&zol->lock); 168 outb(0x00, isa->io); /* This stuff I found to do nothing */
187 outb(0x00, zol->io); /* This stuff I found to do nothing */ 169 outb(zol->curvol, isa->io);
188 outb(zol->curvol, zol->io);
189 msleep(20); 170 msleep(20);
190 171
191 a = inb(zol->io); 172 a = inb(isa->io);
192 msleep(10); 173 msleep(10);
193 b = inb(zol->io); 174 b = inb(isa->io);
194 175
195 mutex_unlock(&zol->lock); 176 return (a == b && a == 0xcf) ?
196 177 V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
197 if (a != b)
198 return 0;
199
200 /* I found this out by playing with a binary scanner on the card io */
201 return a == 0xcf || a == 0xdf || a == 0xef;
202} 178}
203 179
204static int zol_is_stereo(struct zoltrix *zol) 180static u32 zoltrix_g_signal(struct radio_isa_card *isa)
205{ 181{
206 int x1, x2; 182 struct zoltrix *zol = container_of(isa, struct zoltrix, isa);
207 183 int a, b;
208 mutex_lock(&zol->lock);
209 184
210 outb(0x00, zol->io); 185 outb(0x00, isa->io); /* This stuff I found to do nothing */
211 outb(zol->curvol, zol->io); 186 outb(zol->curvol, isa->io);
212 msleep(20); 187 msleep(20);
213 188
214 x1 = inb(zol->io); 189 a = inb(isa->io);
215 msleep(10); 190 msleep(10);
216 x2 = inb(zol->io); 191 b = inb(isa->io);
217
218 mutex_unlock(&zol->lock);
219
220 return x1 == x2 && x1 == 0xcf;
221}
222
223static int vidioc_querycap(struct file *file, void *priv,
224 struct v4l2_capability *v)
225{
226 strlcpy(v->driver, "radio-zoltrix", sizeof(v->driver));
227 strlcpy(v->card, "Zoltrix Radio", sizeof(v->card));
228 strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
229 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
230 return 0;
231}
232
233static int vidioc_g_tuner(struct file *file, void *priv,
234 struct v4l2_tuner *v)
235{
236 struct zoltrix *zol = video_drvdata(file);
237
238 if (v->index > 0)
239 return -EINVAL;
240
241 strlcpy(v->name, "FM", sizeof(v->name));
242 v->type = V4L2_TUNER_RADIO;
243 v->rangelow = 88 * 16000;
244 v->rangehigh = 108 * 16000;
245 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
246 v->capability = V4L2_TUNER_CAP_LOW;
247 if (zol_is_stereo(zol))
248 v->audmode = V4L2_TUNER_MODE_STEREO;
249 else
250 v->audmode = V4L2_TUNER_MODE_MONO;
251 v->signal = 0xFFFF * zol_getsigstr(zol);
252 return 0;
253}
254
255static int vidioc_s_tuner(struct file *file, void *priv,
256 struct v4l2_tuner *v)
257{
258 return v->index ? -EINVAL : 0;
259}
260
261static int vidioc_s_frequency(struct file *file, void *priv,
262 struct v4l2_frequency *f)
263{
264 struct zoltrix *zol = video_drvdata(file);
265
266 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
267 return -EINVAL;
268 if (zol_setfreq(zol, f->frequency) != 0)
269 return -EINVAL;
270 return 0;
271}
272
273static int vidioc_g_frequency(struct file *file, void *priv,
274 struct v4l2_frequency *f)
275{
276 struct zoltrix *zol = video_drvdata(file);
277 192
278 if (f->tuner != 0) 193 if (a != b)
279 return -EINVAL;
280 f->type = V4L2_TUNER_RADIO;
281 f->frequency = zol->curfreq;
282 return 0;
283}
284
285static int vidioc_queryctrl(struct file *file, void *priv,
286 struct v4l2_queryctrl *qc)
287{
288 switch (qc->id) {
289 case V4L2_CID_AUDIO_MUTE:
290 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
291 case V4L2_CID_AUDIO_VOLUME:
292 return v4l2_ctrl_query_fill(qc, 0, 65535, 4096, 65535);
293 }
294 return -EINVAL;
295}
296
297static int vidioc_g_ctrl(struct file *file, void *priv,
298 struct v4l2_control *ctrl)
299{
300 struct zoltrix *zol = video_drvdata(file);
301
302 switch (ctrl->id) {
303 case V4L2_CID_AUDIO_MUTE:
304 ctrl->value = zol->muted;
305 return 0;
306 case V4L2_CID_AUDIO_VOLUME:
307 ctrl->value = zol->curvol * 4096;
308 return 0;
309 }
310 return -EINVAL;
311}
312
313static int vidioc_s_ctrl(struct file *file, void *priv,
314 struct v4l2_control *ctrl)
315{
316 struct zoltrix *zol = video_drvdata(file);
317
318 switch (ctrl->id) {
319 case V4L2_CID_AUDIO_MUTE:
320 if (ctrl->value)
321 zol_mute(zol);
322 else {
323 zol_unmute(zol);
324 zol_setvol(zol, zol->curvol);
325 }
326 return 0;
327 case V4L2_CID_AUDIO_VOLUME:
328 zol_setvol(zol, ctrl->value / 4096);
329 return 0; 194 return 0;
330 }
331 zol->stereo = 1;
332 if (zol_setfreq(zol, zol->curfreq) != 0)
333 return -EINVAL;
334#if 0
335/* FIXME: Implement stereo/mono switch on V4L2 */
336 if (v->mode & VIDEO_SOUND_STEREO) {
337 zol->stereo = 1;
338 zol_setfreq(zol, zol->curfreq);
339 }
340 if (v->mode & VIDEO_SOUND_MONO) {
341 zol->stereo = 0;
342 zol_setfreq(zol, zol->curfreq);
343 }
344#endif
345 return -EINVAL;
346}
347
348static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
349{
350 *i = 0;
351 return 0;
352}
353
354static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
355{
356 return i ? -EINVAL : 0;
357}
358 195
359static int vidioc_g_audio(struct file *file, void *priv, 196 /* I found this out by playing with a binary scanner on the card io */
360 struct v4l2_audio *a) 197 return (a == 0xcf || a == 0xdf || a == 0xef) ? 0xffff : 0;
361{
362 a->index = 0;
363 strlcpy(a->name, "Radio", sizeof(a->name));
364 a->capability = V4L2_AUDCAP_STEREO;
365 return 0;
366} 198}
367 199
368static int vidioc_s_audio(struct file *file, void *priv, 200static int zoltrix_s_stereo(struct radio_isa_card *isa, bool stereo)
369 struct v4l2_audio *a)
370{ 201{
371 return a->index ? -EINVAL : 0; 202 return zoltrix_s_frequency(isa, isa->freq);
372} 203}
373 204
374static const struct v4l2_file_operations zoltrix_fops = 205static const struct radio_isa_ops zoltrix_ops = {
375{ 206 .alloc = zoltrix_alloc,
376 .owner = THIS_MODULE, 207 .s_mute_volume = zoltrix_s_mute_volume,
377 .unlocked_ioctl = video_ioctl2, 208 .s_frequency = zoltrix_s_frequency,
209 .s_stereo = zoltrix_s_stereo,
210 .g_rxsubchans = zoltrix_g_rxsubchans,
211 .g_signal = zoltrix_g_signal,
378}; 212};
379 213
380static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = { 214static const int zoltrix_ioports[] = { 0x20c, 0x30c };
381 .vidioc_querycap = vidioc_querycap, 215
382 .vidioc_g_tuner = vidioc_g_tuner, 216static struct radio_isa_driver zoltrix_driver = {
383 .vidioc_s_tuner = vidioc_s_tuner, 217 .driver = {
384 .vidioc_g_audio = vidioc_g_audio, 218 .match = radio_isa_match,
385 .vidioc_s_audio = vidioc_s_audio, 219 .probe = radio_isa_probe,
386 .vidioc_g_input = vidioc_g_input, 220 .remove = radio_isa_remove,
387 .vidioc_s_input = vidioc_s_input, 221 .driver = {
388 .vidioc_g_frequency = vidioc_g_frequency, 222 .name = "radio-zoltrix",
389 .vidioc_s_frequency = vidioc_s_frequency, 223 },
390 .vidioc_queryctrl = vidioc_queryctrl, 224 },
391 .vidioc_g_ctrl = vidioc_g_ctrl, 225 .io_params = io,
392 .vidioc_s_ctrl = vidioc_s_ctrl, 226 .radio_nr_params = radio_nr,
227 .io_ports = zoltrix_ioports,
228 .num_of_io_ports = ARRAY_SIZE(zoltrix_ioports),
229 .region_size = 2,
230 .card = "Zoltrix Radio Plus",
231 .ops = &zoltrix_ops,
232 .has_stereo = true,
233 .max_volume = 15,
393}; 234};
394 235
395static int __init zoltrix_init(void) 236static int __init zoltrix_init(void)
396{ 237{
397 struct zoltrix *zol = &zoltrix_card; 238 return isa_register_driver(&zoltrix_driver.driver, ZOLTRIX_MAX);
398 struct v4l2_device *v4l2_dev = &zol->v4l2_dev;
399 int res;
400
401 strlcpy(v4l2_dev->name, "zoltrix", sizeof(v4l2_dev->name));
402 zol->io = io;
403 if (zol->io == -1) {
404 v4l2_err(v4l2_dev, "You must set an I/O address with io=0x20c or 0x30c\n");
405 return -EINVAL;
406 }
407 if (zol->io != 0x20c && zol->io != 0x30c) {
408 v4l2_err(v4l2_dev, "invalid port, try 0x20c or 0x30c\n");
409 return -ENXIO;
410 }
411
412 if (!request_region(zol->io, 2, "zoltrix")) {
413 v4l2_err(v4l2_dev, "port 0x%x already in use\n", zol->io);
414 return -EBUSY;
415 }
416
417 res = v4l2_device_register(NULL, v4l2_dev);
418 if (res < 0) {
419 release_region(zol->io, 2);
420 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
421 return res;
422 }
423
424 mutex_init(&zol->lock);
425
426 /* mute card - prevents noisy bootups */
427
428 /* this ensures that the volume is all the way down */
429
430 outb(0, zol->io);
431 outb(0, zol->io);
432 msleep(20);
433 inb(zol->io + 3);
434
435 zol->curvol = 0;
436 zol->stereo = 1;
437
438 strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name));
439 zol->vdev.v4l2_dev = v4l2_dev;
440 zol->vdev.fops = &zoltrix_fops;
441 zol->vdev.ioctl_ops = &zoltrix_ioctl_ops;
442 zol->vdev.release = video_device_release_empty;
443 video_set_drvdata(&zol->vdev, zol);
444
445 if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
446 v4l2_device_unregister(v4l2_dev);
447 release_region(zol->io, 2);
448 return -EINVAL;
449 }
450 v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n");
451
452 return 0;
453} 239}
454 240
455static void __exit zoltrix_exit(void) 241static void __exit zoltrix_exit(void)
456{ 242{
457 struct zoltrix *zol = &zoltrix_card; 243 isa_unregister_driver(&zoltrix_driver.driver);
458
459 video_unregister_device(&zol->vdev);
460 v4l2_device_unregister(&zol->v4l2_dev);
461 release_region(zol->io, 2);
462} 244}
463 245
464module_init(zoltrix_init); 246module_init(zoltrix_init);
diff --git a/drivers/media/radio/saa7706h.c b/drivers/media/radio/saa7706h.c
index b1193dfc5087..9474706350f8 100644
--- a/drivers/media/radio/saa7706h.c
+++ b/drivers/media/radio/saa7706h.c
@@ -434,18 +434,7 @@ static struct i2c_driver saa7706h_driver = {
434 .id_table = saa7706h_id, 434 .id_table = saa7706h_id,
435}; 435};
436 436
437static __init int saa7706h_init(void) 437module_i2c_driver(saa7706h_driver);
438{
439 return i2c_add_driver(&saa7706h_driver);
440}
441
442static __exit void saa7706h_exit(void)
443{
444 i2c_del_driver(&saa7706h_driver);
445}
446
447module_init(saa7706h_init);
448module_exit(saa7706h_exit);
449 438
450MODULE_DESCRIPTION("SAA7706H Car Radio DSP driver"); 439MODULE_DESCRIPTION("SAA7706H Car Radio DSP driver");
451MODULE_AUTHOR("Mocean Laboratories"); 440MODULE_AUTHOR("Mocean Laboratories");
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c
index fd3541b0e91c..9b546a5523f3 100644
--- a/drivers/media/radio/si470x/radio-si470x-i2c.c
+++ b/drivers/media/radio/si470x/radio-si470x-i2c.c
@@ -539,33 +539,7 @@ static struct i2c_driver si470x_i2c_driver = {
539 .id_table = si470x_i2c_id, 539 .id_table = si470x_i2c_id,
540}; 540};
541 541
542 542module_i2c_driver(si470x_i2c_driver);
543
544/**************************************************************************
545 * Module Interface
546 **************************************************************************/
547
548/*
549 * si470x_i2c_init - module init
550 */
551static int __init si470x_i2c_init(void)
552{
553 printk(KERN_INFO DRIVER_DESC ", Version " DRIVER_VERSION "\n");
554 return i2c_add_driver(&si470x_i2c_driver);
555}
556
557
558/*
559 * si470x_i2c_exit - module exit
560 */
561static void __exit si470x_i2c_exit(void)
562{
563 i2c_del_driver(&si470x_i2c_driver);
564}
565
566
567module_init(si470x_i2c_init);
568module_exit(si470x_i2c_exit);
569 543
570MODULE_LICENSE("GPL"); 544MODULE_LICENSE("GPL");
571MODULE_AUTHOR(DRIVER_AUTHOR); 545MODULE_AUTHOR(DRIVER_AUTHOR);
diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c
index 27aba936fb2b..b898c8925ab7 100644
--- a/drivers/media/radio/si4713-i2c.c
+++ b/drivers/media/radio/si4713-i2c.c
@@ -2106,17 +2106,4 @@ static struct i2c_driver si4713_i2c_driver = {
2106 .id_table = si4713_id, 2106 .id_table = si4713_id,
2107}; 2107};
2108 2108
2109/* Module Interface */ 2109module_i2c_driver(si4713_i2c_driver);
2110static int __init si4713_module_init(void)
2111{
2112 return i2c_add_driver(&si4713_i2c_driver);
2113}
2114
2115static void __exit si4713_module_exit(void)
2116{
2117 i2c_del_driver(&si4713_i2c_driver);
2118}
2119
2120module_init(si4713_module_init);
2121module_exit(si4713_module_exit);
2122
diff --git a/drivers/media/radio/tef6862.c b/drivers/media/radio/tef6862.c
index 3408685b690c..6418c4c9faf1 100644
--- a/drivers/media/radio/tef6862.c
+++ b/drivers/media/radio/tef6862.c
@@ -215,20 +215,8 @@ static struct i2c_driver tef6862_driver = {
215 .id_table = tef6862_id, 215 .id_table = tef6862_id,
216}; 216};
217 217
218static __init int tef6862_init(void) 218module_i2c_driver(tef6862_driver);
219{
220 return i2c_add_driver(&tef6862_driver);
221}
222
223static __exit void tef6862_exit(void)
224{
225 i2c_del_driver(&tef6862_driver);
226}
227
228module_init(tef6862_init);
229module_exit(tef6862_exit);
230 219
231MODULE_DESCRIPTION("TEF6862 Car Radio Enhanced Selectivity Tuner"); 220MODULE_DESCRIPTION("TEF6862 Car Radio Enhanced Selectivity Tuner");
232MODULE_AUTHOR("Mocean Laboratories"); 221MODULE_AUTHOR("Mocean Laboratories");
233MODULE_LICENSE("GPL v2"); 222MODULE_LICENSE("GPL v2");
234
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index 4df4affeea5f..a3fbb21350e9 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -266,4 +266,13 @@ config RC_LOOPBACK
266 To compile this driver as a module, choose M here: the module will 266 To compile this driver as a module, choose M here: the module will
267 be called rc_loopback. 267 be called rc_loopback.
268 268
269config IR_GPIO_CIR
270 tristate "GPIO IR remote control"
271 depends on RC_CORE
272 ---help---
273 Say Y if you want to use GPIO based IR Receiver.
274
275 To compile this driver as a module, choose M here: the module will
276 be called gpio-ir-recv.
277
269endif #RC_CORE 278endif #RC_CORE
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index fb3dee2dd845..29f364f88a94 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -26,3 +26,4 @@ obj-$(CONFIG_IR_REDRAT3) += redrat3.o
26obj-$(CONFIG_IR_STREAMZAP) += streamzap.o 26obj-$(CONFIG_IR_STREAMZAP) += streamzap.o
27obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o 27obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o
28obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o 28obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o
29obj-$(CONFIG_IR_GPIO_CIR) += gpio-ir-recv.o
diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c
index 7f7079b12f23..392d4be91f8f 100644
--- a/drivers/media/rc/fintek-cir.c
+++ b/drivers/media/rc/fintek-cir.c
@@ -117,7 +117,7 @@ static u8 fintek_cir_reg_read(struct fintek_dev *fintek, u8 offset)
117static void cir_dump_regs(struct fintek_dev *fintek) 117static void cir_dump_regs(struct fintek_dev *fintek)
118{ 118{
119 fintek_config_mode_enable(fintek); 119 fintek_config_mode_enable(fintek);
120 fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR); 120 fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
121 121
122 pr_reg("%s: Dump CIR logical device registers:\n", FINTEK_DRIVER_NAME); 122 pr_reg("%s: Dump CIR logical device registers:\n", FINTEK_DRIVER_NAME);
123 pr_reg(" * CR CIR BASE ADDR: 0x%x\n", 123 pr_reg(" * CR CIR BASE ADDR: 0x%x\n",
@@ -143,7 +143,7 @@ static int fintek_hw_detect(struct fintek_dev *fintek)
143 u8 chip_major, chip_minor; 143 u8 chip_major, chip_minor;
144 u8 vendor_major, vendor_minor; 144 u8 vendor_major, vendor_minor;
145 u8 portsel, ir_class; 145 u8 portsel, ir_class;
146 u16 vendor; 146 u16 vendor, chip;
147 int ret = 0; 147 int ret = 0;
148 148
149 fintek_config_mode_enable(fintek); 149 fintek_config_mode_enable(fintek);
@@ -176,6 +176,7 @@ static int fintek_hw_detect(struct fintek_dev *fintek)
176 176
177 chip_major = fintek_cr_read(fintek, GCR_CHIP_ID_HI); 177 chip_major = fintek_cr_read(fintek, GCR_CHIP_ID_HI);
178 chip_minor = fintek_cr_read(fintek, GCR_CHIP_ID_LO); 178 chip_minor = fintek_cr_read(fintek, GCR_CHIP_ID_LO);
179 chip = chip_major << 8 | chip_minor;
179 180
180 vendor_major = fintek_cr_read(fintek, GCR_VENDOR_ID_HI); 181 vendor_major = fintek_cr_read(fintek, GCR_VENDOR_ID_HI);
181 vendor_minor = fintek_cr_read(fintek, GCR_VENDOR_ID_LO); 182 vendor_minor = fintek_cr_read(fintek, GCR_VENDOR_ID_LO);
@@ -192,6 +193,15 @@ static int fintek_hw_detect(struct fintek_dev *fintek)
192 fintek->chip_major = chip_major; 193 fintek->chip_major = chip_major;
193 fintek->chip_minor = chip_minor; 194 fintek->chip_minor = chip_minor;
194 fintek->chip_vendor = vendor; 195 fintek->chip_vendor = vendor;
196
197 /*
198 * Newer reviews of this chipset uses port 8 instead of 5
199 */
200 if ((chip != 0x0408) || (chip != 0x0804))
201 fintek->logical_dev_cir = LOGICAL_DEV_CIR_REV2;
202 else
203 fintek->logical_dev_cir = LOGICAL_DEV_CIR_REV1;
204
195 spin_unlock_irqrestore(&fintek->fintek_lock, flags); 205 spin_unlock_irqrestore(&fintek->fintek_lock, flags);
196 206
197 return ret; 207 return ret;
@@ -200,7 +210,7 @@ static int fintek_hw_detect(struct fintek_dev *fintek)
200static void fintek_cir_ldev_init(struct fintek_dev *fintek) 210static void fintek_cir_ldev_init(struct fintek_dev *fintek)
201{ 211{
202 /* Select CIR logical device and enable */ 212 /* Select CIR logical device and enable */
203 fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR); 213 fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
204 fintek_cr_write(fintek, LOGICAL_DEV_ENABLE, CIR_CR_DEV_EN); 214 fintek_cr_write(fintek, LOGICAL_DEV_ENABLE, CIR_CR_DEV_EN);
205 215
206 /* Write allocated CIR address and IRQ information to hardware */ 216 /* Write allocated CIR address and IRQ information to hardware */
@@ -381,7 +391,7 @@ static irqreturn_t fintek_cir_isr(int irq, void *data)
381 fit_dbg_verbose("%s firing", __func__); 391 fit_dbg_verbose("%s firing", __func__);
382 392
383 fintek_config_mode_enable(fintek); 393 fintek_config_mode_enable(fintek);
384 fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR); 394 fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
385 fintek_config_mode_disable(fintek); 395 fintek_config_mode_disable(fintek);
386 396
387 /* 397 /*
@@ -422,7 +432,7 @@ static void fintek_enable_cir(struct fintek_dev *fintek)
422 fintek_config_mode_enable(fintek); 432 fintek_config_mode_enable(fintek);
423 433
424 /* enable the CIR logical device */ 434 /* enable the CIR logical device */
425 fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR); 435 fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
426 fintek_cr_write(fintek, LOGICAL_DEV_ENABLE, CIR_CR_DEV_EN); 436 fintek_cr_write(fintek, LOGICAL_DEV_ENABLE, CIR_CR_DEV_EN);
427 437
428 fintek_config_mode_disable(fintek); 438 fintek_config_mode_disable(fintek);
@@ -439,7 +449,7 @@ static void fintek_disable_cir(struct fintek_dev *fintek)
439 fintek_config_mode_enable(fintek); 449 fintek_config_mode_enable(fintek);
440 450
441 /* disable the CIR logical device */ 451 /* disable the CIR logical device */
442 fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR); 452 fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
443 fintek_cr_write(fintek, LOGICAL_DEV_DISABLE, CIR_CR_DEV_EN); 453 fintek_cr_write(fintek, LOGICAL_DEV_DISABLE, CIR_CR_DEV_EN);
444 454
445 fintek_config_mode_disable(fintek); 455 fintek_config_mode_disable(fintek);
@@ -611,7 +621,7 @@ static int fintek_suspend(struct pnp_dev *pdev, pm_message_t state)
611 fintek_config_mode_enable(fintek); 621 fintek_config_mode_enable(fintek);
612 622
613 /* disable cir logical dev */ 623 /* disable cir logical dev */
614 fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR); 624 fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
615 fintek_cr_write(fintek, LOGICAL_DEV_DISABLE, CIR_CR_DEV_EN); 625 fintek_cr_write(fintek, LOGICAL_DEV_DISABLE, CIR_CR_DEV_EN);
616 626
617 fintek_config_mode_disable(fintek); 627 fintek_config_mode_disable(fintek);
@@ -634,7 +644,7 @@ static int fintek_resume(struct pnp_dev *pdev)
634 644
635 /* Enable CIR logical device */ 645 /* Enable CIR logical device */
636 fintek_config_mode_enable(fintek); 646 fintek_config_mode_enable(fintek);
637 fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR); 647 fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
638 fintek_cr_write(fintek, LOGICAL_DEV_ENABLE, CIR_CR_DEV_EN); 648 fintek_cr_write(fintek, LOGICAL_DEV_ENABLE, CIR_CR_DEV_EN);
639 649
640 fintek_config_mode_disable(fintek); 650 fintek_config_mode_disable(fintek);
diff --git a/drivers/media/rc/fintek-cir.h b/drivers/media/rc/fintek-cir.h
index 1b10b2011f5e..82516a1d39b0 100644
--- a/drivers/media/rc/fintek-cir.h
+++ b/drivers/media/rc/fintek-cir.h
@@ -88,6 +88,7 @@ struct fintek_dev {
88 u8 chip_major; 88 u8 chip_major;
89 u8 chip_minor; 89 u8 chip_minor;
90 u16 chip_vendor; 90 u16 chip_vendor;
91 u8 logical_dev_cir;
91 92
92 /* hardware features */ 93 /* hardware features */
93 bool hw_learning_capable; 94 bool hw_learning_capable;
@@ -172,7 +173,8 @@ struct fintek_dev {
172#define LOGICAL_DEV_ENABLE 0x01 173#define LOGICAL_DEV_ENABLE 0x01
173 174
174/* Logical device number of the CIR function */ 175/* Logical device number of the CIR function */
175#define LOGICAL_DEV_CIR 0x05 176#define LOGICAL_DEV_CIR_REV1 0x05
177#define LOGICAL_DEV_CIR_REV2 0x08
176 178
177/* CIR Logical Device (LDN 0x08) config registers */ 179/* CIR Logical Device (LDN 0x08) config registers */
178#define CIR_CR_COMMAND_INDEX 0x04 180#define CIR_CR_COMMAND_INDEX 0x04
diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c
new file mode 100644
index 000000000000..0d875450c5ce
--- /dev/null
+++ b/drivers/media/rc/gpio-ir-recv.c
@@ -0,0 +1,205 @@
1/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/interrupt.h>
17#include <linux/gpio.h>
18#include <linux/slab.h>
19#include <linux/platform_device.h>
20#include <linux/irq.h>
21#include <media/rc-core.h>
22#include <media/gpio-ir-recv.h>
23
24#define GPIO_IR_DRIVER_NAME "gpio-rc-recv"
25#define GPIO_IR_DEVICE_NAME "gpio_ir_recv"
26
27struct gpio_rc_dev {
28 struct rc_dev *rcdev;
29 int gpio_nr;
30 bool active_low;
31};
32
33static irqreturn_t gpio_ir_recv_irq(int irq, void *dev_id)
34{
35 struct gpio_rc_dev *gpio_dev = dev_id;
36 int gval;
37 int rc = 0;
38 enum raw_event_type type = IR_SPACE;
39
40 gval = gpio_get_value_cansleep(gpio_dev->gpio_nr);
41
42 if (gval < 0)
43 goto err_get_value;
44
45 if (gpio_dev->active_low)
46 gval = !gval;
47
48 if (gval == 1)
49 type = IR_PULSE;
50
51 rc = ir_raw_event_store_edge(gpio_dev->rcdev, type);
52 if (rc < 0)
53 goto err_get_value;
54
55 ir_raw_event_handle(gpio_dev->rcdev);
56
57err_get_value:
58 return IRQ_HANDLED;
59}
60
61static int __devinit gpio_ir_recv_probe(struct platform_device *pdev)
62{
63 struct gpio_rc_dev *gpio_dev;
64 struct rc_dev *rcdev;
65 const struct gpio_ir_recv_platform_data *pdata =
66 pdev->dev.platform_data;
67 int rc;
68
69 if (!pdata)
70 return -EINVAL;
71
72 if (pdata->gpio_nr < 0)
73 return -EINVAL;
74
75 gpio_dev = kzalloc(sizeof(struct gpio_rc_dev), GFP_KERNEL);
76 if (!gpio_dev)
77 return -ENOMEM;
78
79 rcdev = rc_allocate_device();
80 if (!rcdev) {
81 rc = -ENOMEM;
82 goto err_allocate_device;
83 }
84
85 rcdev->driver_type = RC_DRIVER_IR_RAW;
86 rcdev->allowed_protos = RC_TYPE_ALL;
87 rcdev->input_name = GPIO_IR_DEVICE_NAME;
88 rcdev->input_id.bustype = BUS_HOST;
89 rcdev->driver_name = GPIO_IR_DRIVER_NAME;
90 rcdev->map_name = RC_MAP_EMPTY;
91
92 gpio_dev->rcdev = rcdev;
93 gpio_dev->gpio_nr = pdata->gpio_nr;
94 gpio_dev->active_low = pdata->active_low;
95
96 rc = gpio_request(pdata->gpio_nr, "gpio-ir-recv");
97 if (rc < 0)
98 goto err_gpio_request;
99 rc = gpio_direction_input(pdata->gpio_nr);
100 if (rc < 0)
101 goto err_gpio_direction_input;
102
103 rc = rc_register_device(rcdev);
104 if (rc < 0) {
105 dev_err(&pdev->dev, "failed to register rc device\n");
106 goto err_register_rc_device;
107 }
108
109 platform_set_drvdata(pdev, gpio_dev);
110
111 rc = request_any_context_irq(gpio_to_irq(pdata->gpio_nr),
112 gpio_ir_recv_irq,
113 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
114 "gpio-ir-recv-irq", gpio_dev);
115 if (rc < 0)
116 goto err_request_irq;
117
118 return 0;
119
120err_request_irq:
121 platform_set_drvdata(pdev, NULL);
122 rc_unregister_device(rcdev);
123err_register_rc_device:
124err_gpio_direction_input:
125 gpio_free(pdata->gpio_nr);
126err_gpio_request:
127 rc_free_device(rcdev);
128 rcdev = NULL;
129err_allocate_device:
130 kfree(gpio_dev);
131 return rc;
132}
133
134static int __devexit gpio_ir_recv_remove(struct platform_device *pdev)
135{
136 struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev);
137
138 free_irq(gpio_to_irq(gpio_dev->gpio_nr), gpio_dev);
139 platform_set_drvdata(pdev, NULL);
140 rc_unregister_device(gpio_dev->rcdev);
141 gpio_free(gpio_dev->gpio_nr);
142 rc_free_device(gpio_dev->rcdev);
143 kfree(gpio_dev);
144 return 0;
145}
146
147#ifdef CONFIG_PM
148static int gpio_ir_recv_suspend(struct device *dev)
149{
150 struct platform_device *pdev = to_platform_device(dev);
151 struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev);
152
153 if (device_may_wakeup(dev))
154 enable_irq_wake(gpio_to_irq(gpio_dev->gpio_nr));
155 else
156 disable_irq(gpio_to_irq(gpio_dev->gpio_nr));
157
158 return 0;
159}
160
161static int gpio_ir_recv_resume(struct device *dev)
162{
163 struct platform_device *pdev = to_platform_device(dev);
164 struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev);
165
166 if (device_may_wakeup(dev))
167 disable_irq_wake(gpio_to_irq(gpio_dev->gpio_nr));
168 else
169 enable_irq(gpio_to_irq(gpio_dev->gpio_nr));
170
171 return 0;
172}
173
174static const struct dev_pm_ops gpio_ir_recv_pm_ops = {
175 .suspend = gpio_ir_recv_suspend,
176 .resume = gpio_ir_recv_resume,
177};
178#endif
179
180static struct platform_driver gpio_ir_recv_driver = {
181 .probe = gpio_ir_recv_probe,
182 .remove = __devexit_p(gpio_ir_recv_remove),
183 .driver = {
184 .name = GPIO_IR_DRIVER_NAME,
185 .owner = THIS_MODULE,
186#ifdef CONFIG_PM
187 .pm = &gpio_ir_recv_pm_ops,
188#endif
189 },
190};
191
192static int __init gpio_ir_recv_init(void)
193{
194 return platform_driver_register(&gpio_ir_recv_driver);
195}
196module_init(gpio_ir_recv_init);
197
198static void __exit gpio_ir_recv_exit(void)
199{
200 platform_driver_unregister(&gpio_ir_recv_driver);
201}
202module_exit(gpio_ir_recv_exit);
203
204MODULE_DESCRIPTION("GPIO IR Receiver driver");
205MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/rc/ir-sony-decoder.c b/drivers/media/rc/ir-sony-decoder.c
index d5e2b50aff1f..dab98b37621a 100644
--- a/drivers/media/rc/ir-sony-decoder.c
+++ b/drivers/media/rc/ir-sony-decoder.c
@@ -130,7 +130,7 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev)
130 case 15: 130 case 15:
131 device = bitrev8((data->bits >> 0) & 0xFF); 131 device = bitrev8((data->bits >> 0) & 0xFF);
132 subdevice = 0; 132 subdevice = 0;
133 function = bitrev8((data->bits >> 7) & 0xFD); 133 function = bitrev8((data->bits >> 7) & 0xFE);
134 break; 134 break;
135 case 20: 135 case 20:
136 device = bitrev8((data->bits >> 5) & 0xF8); 136 device = bitrev8((data->bits >> 5) & 0xF8);
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index 36e4d5e8dd6a..49ce2662f56b 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -41,8 +41,11 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
41 rc-imon-mce.o \ 41 rc-imon-mce.o \
42 rc-imon-pad.o \ 42 rc-imon-pad.o \
43 rc-iodata-bctv7e.o \ 43 rc-iodata-bctv7e.o \
44 rc-it913x-v1.o \
45 rc-it913x-v2.o \
44 rc-kaiomy.o \ 46 rc-kaiomy.o \
45 rc-kworld-315u.o \ 47 rc-kworld-315u.o \
48 rc-kworld-pc150u.o \
46 rc-kworld-plus-tv-analog.o \ 49 rc-kworld-plus-tv-analog.o \
47 rc-leadtek-y04g0051.o \ 50 rc-leadtek-y04g0051.o \
48 rc-lirc.o \ 51 rc-lirc.o \
diff --git a/drivers/media/rc/keymaps/rc-it913x-v1.c b/drivers/media/rc/keymaps/rc-it913x-v1.c
new file mode 100644
index 000000000000..0ac775fd109d
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-it913x-v1.c
@@ -0,0 +1,95 @@
1/* ITE Generic remotes Version 1
2 *
3 * Copyright (C) 2012 Malcolm Priestley (tvboxspy@gmail.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 of the License, or
8 * (at your option) any later version.
9 */
10
11#include <media/rc-map.h>
12#include <linux/module.h>
13
14
15static struct rc_map_table it913x_v1_rc[] = {
16 /* Type 1 */
17 { 0x61d601, KEY_VIDEO }, /* Source */
18 { 0x61d602, KEY_3 },
19 { 0x61d603, KEY_POWER }, /* ShutDown */
20 { 0x61d604, KEY_1 },
21 { 0x61d605, KEY_5 },
22 { 0x61d606, KEY_6 },
23 { 0x61d607, KEY_CHANNELDOWN }, /* CH- */
24 { 0x61d608, KEY_2 },
25 { 0x61d609, KEY_CHANNELUP }, /* CH+ */
26 { 0x61d60a, KEY_9 },
27 { 0x61d60b, KEY_ZOOM }, /* Zoom */
28 { 0x61d60c, KEY_7 },
29 { 0x61d60d, KEY_8 },
30 { 0x61d60e, KEY_VOLUMEUP }, /* Vol+ */
31 { 0x61d60f, KEY_4 },
32 { 0x61d610, KEY_ESC }, /* [back up arrow] */
33 { 0x61d611, KEY_0 },
34 { 0x61d612, KEY_OK }, /* [enter arrow] */
35 { 0x61d613, KEY_VOLUMEDOWN }, /* Vol- */
36 { 0x61d614, KEY_RECORD }, /* Rec */
37 { 0x61d615, KEY_STOP }, /* Stop */
38 { 0x61d616, KEY_PLAY }, /* Play */
39 { 0x61d617, KEY_MUTE }, /* Mute */
40 { 0x61d618, KEY_UP },
41 { 0x61d619, KEY_DOWN },
42 { 0x61d61a, KEY_LEFT },
43 { 0x61d61b, KEY_RIGHT },
44 { 0x61d61c, KEY_RED },
45 { 0x61d61d, KEY_GREEN },
46 { 0x61d61e, KEY_YELLOW },
47 { 0x61d61f, KEY_BLUE },
48 { 0x61d643, KEY_POWER2 }, /* [red power button] */
49 /* Type 2 - 20 buttons */
50 { 0x807f0d, KEY_0 },
51 { 0x807f04, KEY_1 },
52 { 0x807f05, KEY_2 },
53 { 0x807f06, KEY_3 },
54 { 0x807f07, KEY_4 },
55 { 0x807f08, KEY_5 },
56 { 0x807f09, KEY_6 },
57 { 0x807f0a, KEY_7 },
58 { 0x807f1b, KEY_8 },
59 { 0x807f1f, KEY_9 },
60 { 0x807f12, KEY_POWER },
61 { 0x807f01, KEY_MEDIA_REPEAT}, /* Recall */
62 { 0x807f19, KEY_PAUSE }, /* Timeshift */
63 { 0x807f1e, KEY_VOLUMEUP }, /* 2 x -/+ Keys not marked */
64 { 0x807f03, KEY_VOLUMEDOWN }, /* Volume defined as right hand*/
65 { 0x807f1a, KEY_CHANNELUP },
66 { 0x807f02, KEY_CHANNELDOWN },
67 { 0x807f0c, KEY_ZOOM },
68 { 0x807f00, KEY_RECORD },
69 { 0x807f0e, KEY_STOP },
70};
71
72static struct rc_map_list it913x_v1_map = {
73 .map = {
74 .scan = it913x_v1_rc,
75 .size = ARRAY_SIZE(it913x_v1_rc),
76 .rc_type = RC_TYPE_NEC,
77 .name = RC_MAP_IT913X_V1,
78 }
79};
80
81static int __init init_rc_it913x_v1_map(void)
82{
83 return rc_map_register(&it913x_v1_map);
84}
85
86static void __exit exit_rc_it913x_v1_map(void)
87{
88 rc_map_unregister(&it913x_v1_map);
89}
90
91module_init(init_rc_it913x_v1_map)
92module_exit(exit_rc_it913x_v1_map)
93
94MODULE_LICENSE("GPL");
95MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
diff --git a/drivers/media/rc/keymaps/rc-it913x-v2.c b/drivers/media/rc/keymaps/rc-it913x-v2.c
new file mode 100644
index 000000000000..28e376e18b99
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-it913x-v2.c
@@ -0,0 +1,94 @@
1/* ITE Generic remotes Version 2
2 *
3 * Copyright (C) 2012 Malcolm Priestley (tvboxspy@gmail.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 of the License, or
8 * (at your option) any later version.
9 */
10
11#include <media/rc-map.h>
12#include <linux/module.h>
13
14
15static struct rc_map_table it913x_v2_rc[] = {
16 /* Type 1 */
17 /* 9005 remote */
18 { 0x807f12, KEY_POWER2 }, /* Power (RED POWER BUTTON)*/
19 { 0x807f1a, KEY_VIDEO }, /* Source */
20 { 0x807f1e, KEY_MUTE }, /* Mute */
21 { 0x807f01, KEY_RECORD }, /* Record */
22 { 0x807f02, KEY_CHANNELUP }, /* Channel+ */
23 { 0x807f03, KEY_TIME }, /* TimeShift */
24 { 0x807f04, KEY_VOLUMEUP }, /* Volume- */
25 { 0x807f05, KEY_SCREEN }, /* FullScreen */
26 { 0x807f06, KEY_VOLUMEDOWN }, /* Volume- */
27 { 0x807f07, KEY_0 }, /* 0 */
28 { 0x807f08, KEY_CHANNELDOWN }, /* Channel- */
29 { 0x807f09, KEY_PREVIOUS }, /* Recall */
30 { 0x807f0a, KEY_1 }, /* 1 */
31 { 0x807f1b, KEY_2 }, /* 2 */
32 { 0x807f1f, KEY_3 }, /* 3 */
33 { 0x807f0c, KEY_4 }, /* 4 */
34 { 0x807f0d, KEY_5 }, /* 5 */
35 { 0x807f0e, KEY_6 }, /* 6 */
36 { 0x807f00, KEY_7 }, /* 7 */
37 { 0x807f0f, KEY_8 }, /* 8 */
38 { 0x807f19, KEY_9 }, /* 9 */
39
40 /* Type 2 */
41 /* keys stereo, snapshot unassigned */
42 { 0x866b00, KEY_0 },
43 { 0x866b1b, KEY_1 },
44 { 0x866b02, KEY_2 },
45 { 0x866b03, KEY_3 },
46 { 0x866b04, KEY_4 },
47 { 0x866b05, KEY_5 },
48 { 0x866b06, KEY_6 },
49 { 0x866b07, KEY_7 },
50 { 0x866b08, KEY_8 },
51 { 0x866b09, KEY_9 },
52 { 0x866b12, KEY_POWER },
53 { 0x866b13, KEY_MUTE },
54 { 0x866b0a, KEY_PREVIOUS }, /* Recall */
55 { 0x866b1e, KEY_PAUSE },
56 { 0x866b0c, KEY_VOLUMEUP },
57 { 0x866b18, KEY_VOLUMEDOWN },
58 { 0x866b0b, KEY_CHANNELUP },
59 { 0x866b18, KEY_CHANNELDOWN },
60 { 0x866b10, KEY_ZOOM },
61 { 0x866b1d, KEY_RECORD },
62 { 0x866b0e, KEY_STOP },
63 { 0x866b11, KEY_EPG},
64 { 0x866b1a, KEY_FASTFORWARD },
65 { 0x866b0f, KEY_REWIND },
66 { 0x866b1c, KEY_TV },
67 { 0x866b1b, KEY_TEXT },
68
69};
70
71static struct rc_map_list it913x_v2_map = {
72 .map = {
73 .scan = it913x_v2_rc,
74 .size = ARRAY_SIZE(it913x_v2_rc),
75 .rc_type = RC_TYPE_NEC,
76 .name = RC_MAP_IT913X_V2,
77 }
78};
79
80static int __init init_rc_it913x_v2_map(void)
81{
82 return rc_map_register(&it913x_v2_map);
83}
84
85static void __exit exit_rc_it913x_v2_map(void)
86{
87 rc_map_unregister(&it913x_v2_map);
88}
89
90module_init(init_rc_it913x_v2_map)
91module_exit(exit_rc_it913x_v2_map)
92
93MODULE_LICENSE("GPL");
94MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
diff --git a/drivers/media/rc/keymaps/rc-kworld-pc150u.c b/drivers/media/rc/keymaps/rc-kworld-pc150u.c
new file mode 100644
index 000000000000..233bb5ee087f
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-kworld-pc150u.c
@@ -0,0 +1,102 @@
1/* kworld-pc150u.c - Keytable for kworld_pc150u Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Kyle Strickland
6 * (based on kworld-plus-tv-analog.c by
7 * Mauro Carvalho Chehab <mchehab@redhat.com>)
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 */
14
15#include <media/rc-map.h>
16#include <linux/module.h>
17
18/* Kworld PC150-U
19 Kyle Strickland <kyle@kyle.strickland.name>
20 */
21
22static struct rc_map_table kworld_pc150u[] = {
23 { 0x0c, KEY_MEDIA }, /* Kworld key */
24 { 0x16, KEY_EJECTCLOSECD }, /* -> ) */
25 { 0x1d, KEY_POWER2 },
26
27 { 0x00, KEY_1 },
28 { 0x01, KEY_2 },
29 { 0x02, KEY_3 },
30 { 0x03, KEY_4 },
31 { 0x04, KEY_5 },
32 { 0x05, KEY_6 },
33 { 0x06, KEY_7 },
34 { 0x07, KEY_8 },
35 { 0x08, KEY_9 },
36 { 0x0a, KEY_0 },
37
38 { 0x09, KEY_AGAIN },
39 { 0x14, KEY_MUTE },
40
41 { 0x1e, KEY_LAST },
42 { 0x17, KEY_ZOOM },
43 { 0x1f, KEY_HOMEPAGE },
44 { 0x0e, KEY_ESC },
45
46 { 0x20, KEY_UP },
47 { 0x21, KEY_DOWN },
48 { 0x42, KEY_LEFT },
49 { 0x43, KEY_RIGHT },
50 { 0x0b, KEY_ENTER },
51
52 { 0x10, KEY_CHANNELUP },
53 { 0x11, KEY_CHANNELDOWN },
54
55 { 0x13, KEY_VOLUMEUP },
56 { 0x12, KEY_VOLUMEDOWN },
57
58 { 0x19, KEY_TIME}, /* Timeshift */
59 { 0x1a, KEY_STOP},
60 { 0x1b, KEY_RECORD},
61 { 0x4b, KEY_EMAIL},
62
63 { 0x40, KEY_REWIND},
64 { 0x44, KEY_PLAYPAUSE},
65 { 0x41, KEY_FORWARD},
66 { 0x22, KEY_TEXT},
67
68 { 0x15, KEY_AUDIO}, /* ((*)) */
69 { 0x0f, KEY_MODE}, /* display ratio */
70 { 0x1c, KEY_SYSRQ}, /* snapshot */
71 { 0x4a, KEY_SLEEP}, /* sleep timer */
72
73 { 0x48, KEY_SOUND}, /* switch theater mode */
74 { 0x49, KEY_BLUE}, /* A */
75 { 0x18, KEY_RED}, /* B */
76 { 0x23, KEY_GREEN}, /* C */
77};
78
79static struct rc_map_list kworld_pc150u_map = {
80 .map = {
81 .scan = kworld_pc150u,
82 .size = ARRAY_SIZE(kworld_pc150u),
83 .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
84 .name = RC_MAP_KWORLD_PC150U,
85 }
86};
87
88static int __init init_rc_map_kworld_pc150u(void)
89{
90 return rc_map_register(&kworld_pc150u_map);
91}
92
93static void __exit exit_rc_map_kworld_pc150u(void)
94{
95 rc_map_unregister(&kworld_pc150u_map);
96}
97
98module_init(init_rc_map_kworld_pc150u)
99module_exit(exit_rc_map_kworld_pc150u)
100
101MODULE_LICENSE("GPL");
102MODULE_AUTHOR("Kyle Strickland <kyle@kyle.strickland.name>");
diff --git a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c
index f3b86c8db679..8d4dae2e2ece 100644
--- a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c
+++ b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c
@@ -18,6 +18,8 @@
18 */ 18 */
19 19
20static struct rc_map_table nec_terratec_cinergy_xs[] = { 20static struct rc_map_table nec_terratec_cinergy_xs[] = {
21
22 /* Terratec Grey IR, with most keys in orange */
21 { 0x1441, KEY_HOME}, 23 { 0x1441, KEY_HOME},
22 { 0x1401, KEY_POWER2}, 24 { 0x1401, KEY_POWER2},
23 25
@@ -78,6 +80,56 @@ static struct rc_map_table nec_terratec_cinergy_xs[] = {
78 { 0x144e, KEY_REWIND}, 80 { 0x144e, KEY_REWIND},
79 { 0x144f, KEY_FASTFORWARD}, 81 { 0x144f, KEY_FASTFORWARD},
80 { 0x145c, KEY_NEXT}, 82 { 0x145c, KEY_NEXT},
83
84 /* Terratec Black IR, with most keys in black */
85 { 0x04eb01, KEY_POWER2},
86
87 { 0x04eb02, KEY_1},
88 { 0x04eb03, KEY_2},
89 { 0x04eb04, KEY_3},
90 { 0x04eb05, KEY_4},
91 { 0x04eb06, KEY_5},
92 { 0x04eb07, KEY_6},
93 { 0x04eb08, KEY_7},
94 { 0x04eb09, KEY_8},
95 { 0x04eb0a, KEY_9},
96 { 0x04eb0c, KEY_0},
97
98 { 0x04eb0b, KEY_TEXT}, /* TXT */
99 { 0x04eb0d, KEY_REFRESH}, /* Refresh */
100
101 { 0x04eb0e, KEY_HOME},
102 { 0x04eb0f, KEY_EPG},
103
104 { 0x04eb10, KEY_UP},
105 { 0x04eb11, KEY_LEFT},
106 { 0x04eb12, KEY_OK},
107 { 0x04eb13, KEY_RIGHT},
108 { 0x04eb14, KEY_DOWN},
109
110 { 0x04eb15, KEY_BACKSPACE},
111 { 0x04eb16, KEY_INFO},
112
113 { 0x04eb17, KEY_RED},
114 { 0x04eb18, KEY_GREEN},
115 { 0x04eb19, KEY_YELLOW},
116 { 0x04eb1a, KEY_BLUE},
117
118 { 0x04eb1c, KEY_VOLUMEUP},
119 { 0x04eb1e, KEY_VOLUMEDOWN},
120
121 { 0x04eb1d, KEY_MUTE},
122
123 { 0x04eb1b, KEY_CHANNELUP},
124 { 0x04eb1f, KEY_CHANNELDOWN},
125
126 { 0x04eb40, KEY_RECORD},
127 { 0x04eb4c, KEY_PLAY},
128 { 0x04eb58, KEY_PAUSE},
129
130 { 0x04eb54, KEY_REWIND},
131 { 0x04eb48, KEY_STOP},
132 { 0x04eb5c, KEY_NEXT},
81}; 133};
82 134
83static struct rc_map_list nec_terratec_cinergy_xs_map = { 135static struct rc_map_list nec_terratec_cinergy_xs_map = {
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index 21105bf9594d..e150a2e29a4b 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -361,6 +361,8 @@ static struct usb_device_id mceusb_dev_table[] = {
361 { USB_DEVICE(VENDOR_FORMOSA, 0xe03c) }, 361 { USB_DEVICE(VENDOR_FORMOSA, 0xe03c) },
362 /* Formosa Industrial Computing */ 362 /* Formosa Industrial Computing */
363 { USB_DEVICE(VENDOR_FORMOSA, 0xe03e) }, 363 { USB_DEVICE(VENDOR_FORMOSA, 0xe03e) },
364 /* Formosa Industrial Computing */
365 { USB_DEVICE(VENDOR_FORMOSA, 0xe042) },
364 /* Fintek eHome Infrared Transceiver (HP branded) */ 366 /* Fintek eHome Infrared Transceiver (HP branded) */
365 { USB_DEVICE(VENDOR_FINTEK, 0x5168) }, 367 { USB_DEVICE(VENDOR_FINTEK, 0x5168) },
366 /* Fintek eHome Infrared Transceiver */ 368 /* Fintek eHome Infrared Transceiver */
diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index b72f8580e317..96f0a8bb39ea 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -35,7 +35,7 @@ struct ir_raw_event_ctrl {
35 struct list_head list; /* to keep track of raw clients */ 35 struct list_head list; /* to keep track of raw clients */
36 struct task_struct *thread; 36 struct task_struct *thread;
37 spinlock_t lock; 37 spinlock_t lock;
38 struct kfifo kfifo; /* fifo for the pulse/space durations */ 38 struct kfifo_rec_ptr_1 kfifo; /* fifo for the pulse/space durations */
39 ktime_t last_event; /* when last event occurred */ 39 ktime_t last_event; /* when last event occurred */
40 enum raw_event_type last_type; /* last event type */ 40 enum raw_event_type last_type; /* last event type */
41 struct rc_dev *dev; /* pointer to the parent rc_dev */ 41 struct rc_dev *dev; /* pointer to the parent rc_dev */
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index f6a930b70c69..6e16b09c24a9 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -1029,6 +1029,7 @@ EXPORT_SYMBOL_GPL(rc_free_device);
1029 1029
1030int rc_register_device(struct rc_dev *dev) 1030int rc_register_device(struct rc_dev *dev)
1031{ 1031{
1032 static bool raw_init = false; /* raw decoders loaded? */
1032 static atomic_t devno = ATOMIC_INIT(0); 1033 static atomic_t devno = ATOMIC_INIT(0);
1033 struct rc_map *rc_map; 1034 struct rc_map *rc_map;
1034 const char *path; 1035 const char *path;
@@ -1103,6 +1104,12 @@ int rc_register_device(struct rc_dev *dev)
1103 kfree(path); 1104 kfree(path);
1104 1105
1105 if (dev->driver_type == RC_DRIVER_IR_RAW) { 1106 if (dev->driver_type == RC_DRIVER_IR_RAW) {
1107 /* Load raw decoders, if they aren't already */
1108 if (!raw_init) {
1109 IR_dprintk(1, "Loading raw decoders\n");
1110 ir_raw_init();
1111 raw_init = true;
1112 }
1106 rc = ir_raw_event_register(dev); 1113 rc = ir_raw_event_register(dev);
1107 if (rc < 0) 1114 if (rc < 0)
1108 goto out_input; 1115 goto out_input;
@@ -1176,8 +1183,6 @@ static int __init rc_core_init(void)
1176 return rc; 1183 return rc;
1177 } 1184 }
1178 1185
1179 /* Initialize/load the decoders/keymap code that will be used */
1180 ir_raw_init();
1181 rc_map_register(&empty_map); 1186 rc_map_register(&empty_map);
1182 1187
1183 return 0; 1188 return 0;
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 9adada0d7447..f2479c5c0eb2 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -273,6 +273,16 @@ config VIDEO_ADV7180
273 To compile this driver as a module, choose M here: the 273 To compile this driver as a module, choose M here: the
274 module will be called adv7180. 274 module will be called adv7180.
275 275
276config VIDEO_ADV7183
277 tristate "Analog Devices ADV7183 decoder"
278 depends on VIDEO_V4L2 && I2C
279 ---help---
280 V4l2 subdevice driver for the Analog Devices
281 ADV7183 video decoder.
282
283 To compile this driver as a module, choose M here: the
284 module will be called adv7183.
285
276config VIDEO_BT819 286config VIDEO_BT819
277 tristate "BT819A VideoStream decoder" 287 tristate "BT819A VideoStream decoder"
278 depends on VIDEO_V4L2 && I2C 288 depends on VIDEO_V4L2 && I2C
@@ -459,6 +469,9 @@ config VIDEO_AK881X
459 469
460comment "Camera sensor devices" 470comment "Camera sensor devices"
461 471
472config VIDEO_APTINA_PLL
473 tristate
474
462config VIDEO_OV7670 475config VIDEO_OV7670
463 tristate "OmniVision OV7670 sensor support" 476 tristate "OmniVision OV7670 sensor support"
464 depends on I2C && VIDEO_V4L2 477 depends on I2C && VIDEO_V4L2
@@ -467,9 +480,28 @@ config VIDEO_OV7670
467 OV7670 VGA camera. It currently only works with the M88ALP01 480 OV7670 VGA camera. It currently only works with the M88ALP01
468 controller. 481 controller.
469 482
483config VIDEO_VS6624
484 tristate "ST VS6624 sensor support"
485 depends on VIDEO_V4L2 && I2C
486 ---help---
487 This is a Video4Linux2 sensor-level driver for the ST VS6624
488 camera.
489
490 To compile this driver as a module, choose M here: the
491 module will be called vs6624.
492
493config VIDEO_MT9M032
494 tristate "MT9M032 camera sensor support"
495 depends on I2C && VIDEO_V4L2
496 select VIDEO_APTINA_PLL
497 ---help---
498 This driver supports MT9M032 camera sensors from Aptina, monochrome
499 models only.
500
470config VIDEO_MT9P031 501config VIDEO_MT9P031
471 tristate "Aptina MT9P031 support" 502 tristate "Aptina MT9P031 support"
472 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API 503 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
504 select VIDEO_APTINA_PLL
473 ---help--- 505 ---help---
474 This is a Video4Linux2 sensor-level driver for the Aptina 506 This is a Video4Linux2 sensor-level driver for the Aptina
475 (Micron) mt9p031 5 Mpixel camera. 507 (Micron) mt9p031 5 Mpixel camera.
@@ -851,6 +883,8 @@ source "drivers/media/video/davinci/Kconfig"
851 883
852source "drivers/media/video/omap/Kconfig" 884source "drivers/media/video/omap/Kconfig"
853 885
886source "drivers/media/video/blackfin/Kconfig"
887
854config VIDEO_SH_VOU 888config VIDEO_SH_VOU
855 tristate "SuperH VOU video output driver" 889 tristate "SuperH VOU video output driver"
856 depends on VIDEO_DEV && ARCH_SHMOBILE 890 depends on VIDEO_DEV && ARCH_SHMOBILE
@@ -1087,7 +1121,7 @@ config VIDEO_MX2_HOSTSUPPORT
1087config VIDEO_MX2 1121config VIDEO_MX2
1088 tristate "i.MX27/i.MX25 Camera Sensor Interface driver" 1122 tristate "i.MX27/i.MX25 Camera Sensor Interface driver"
1089 depends on VIDEO_DEV && SOC_CAMERA && (MACH_MX27 || ARCH_MX25) 1123 depends on VIDEO_DEV && SOC_CAMERA && (MACH_MX27 || ARCH_MX25)
1090 select VIDEOBUF_DMA_CONTIG 1124 select VIDEOBUF2_DMA_CONTIG
1091 select VIDEO_MX2_HOSTSUPPORT 1125 select VIDEO_MX2_HOSTSUPPORT
1092 ---help--- 1126 ---help---
1093 This is a v4l2 driver for the i.MX27 and the i.MX25 Camera Sensor 1127 This is a v4l2 driver for the i.MX27 and the i.MX25 Camera Sensor
@@ -1116,7 +1150,8 @@ config VIDEO_ATMEL_ISI
1116 1150
1117config VIDEO_S5P_MIPI_CSIS 1151config VIDEO_S5P_MIPI_CSIS
1118 tristate "Samsung S5P and EXYNOS4 MIPI CSI receiver driver" 1152 tristate "Samsung S5P and EXYNOS4 MIPI CSI receiver driver"
1119 depends on VIDEO_V4L2 && PM_RUNTIME && PLAT_S5P && VIDEO_V4L2_SUBDEV_API 1153 depends on VIDEO_V4L2 && PM_RUNTIME && PLAT_S5P
1154 depends on VIDEO_V4L2_SUBDEV_API && REGULATOR
1120 ---help--- 1155 ---help---
1121 This is a v4l2 driver for Samsung S5P/EXYNOS4 MIPI-CSI receiver. 1156 This is a v4l2 driver for Samsung S5P/EXYNOS4 MIPI-CSI receiver.
1122 1157
@@ -1176,4 +1211,14 @@ config VIDEO_SAMSUNG_S5P_MFC
1176 help 1211 help
1177 MFC 5.1 driver for V4L2. 1212 MFC 5.1 driver for V4L2.
1178 1213
1214config VIDEO_MX2_EMMAPRP
1215 tristate "MX2 eMMa-PrP support"
1216 depends on VIDEO_DEV && VIDEO_V4L2 && SOC_IMX27
1217 select VIDEOBUF2_DMA_CONTIG
1218 select V4L2_MEM2MEM_DEV
1219 help
1220 MX2X chips have a PrP that can be used to process buffers from
1221 memory to memory. Operations include resizing and format
1222 conversion.
1223
1179endif # V4L_MEM2MEM_DRIVERS 1224endif # V4L_MEM2MEM_DRIVERS
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 354138804cda..a6282a3a6a82 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -12,16 +12,19 @@ omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o
12 12
13videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \ 13videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \
14 v4l2-event.o v4l2-ctrls.o v4l2-subdev.o 14 v4l2-event.o v4l2-ctrls.o v4l2-subdev.o
15ifeq ($(CONFIG_COMPAT),y)
16 videodev-objs += v4l2-compat-ioctl32.o
17endif
15 18
16# V4L2 core modules 19# V4L2 core modules
17 20
18obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o 21obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o
19ifeq ($(CONFIG_COMPAT),y)
20 obj-$(CONFIG_VIDEO_DEV) += v4l2-compat-ioctl32.o
21endif
22
23obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o 22obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o
24 23
24# Helper modules
25
26obj-$(CONFIG_VIDEO_APTINA_PLL) += aptina-pll.o
27
25# All i2c modules must come first: 28# All i2c modules must come first:
26 29
27obj-$(CONFIG_VIDEO_TUNER) += tuner.o 30obj-$(CONFIG_VIDEO_TUNER) += tuner.o
@@ -40,8 +43,10 @@ obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o
40obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o 43obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o
41obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o 44obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o
42obj-$(CONFIG_VIDEO_ADV7180) += adv7180.o 45obj-$(CONFIG_VIDEO_ADV7180) += adv7180.o
46obj-$(CONFIG_VIDEO_ADV7183) += adv7183.o
43obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o 47obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o
44obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o 48obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
49obj-$(CONFIG_VIDEO_VS6624) += vs6624.o
45obj-$(CONFIG_VIDEO_BT819) += bt819.o 50obj-$(CONFIG_VIDEO_BT819) += bt819.o
46obj-$(CONFIG_VIDEO_BT856) += bt856.o 51obj-$(CONFIG_VIDEO_BT856) += bt856.o
47obj-$(CONFIG_VIDEO_BT866) += bt866.o 52obj-$(CONFIG_VIDEO_BT866) += bt866.o
@@ -65,6 +70,7 @@ obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
65obj-$(CONFIG_VIDEO_OV7670) += ov7670.o 70obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
66obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o 71obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
67obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o 72obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
73obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o
68obj-$(CONFIG_VIDEO_MT9P031) += mt9p031.o 74obj-$(CONFIG_VIDEO_MT9P031) += mt9p031.o
69obj-$(CONFIG_VIDEO_MT9T001) += mt9t001.o 75obj-$(CONFIG_VIDEO_MT9T001) += mt9t001.o
70obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o 76obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o
@@ -177,6 +183,8 @@ obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
177obj-$(CONFIG_VIDEO_OMAP1) += omap1_camera.o 183obj-$(CONFIG_VIDEO_OMAP1) += omap1_camera.o
178obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o 184obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o
179 185
186obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o
187
180obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) += s5p-fimc/ 188obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) += s5p-fimc/
181obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg/ 189obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg/
182obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) += s5p-mfc/ 190obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) += s5p-mfc/
@@ -184,6 +192,8 @@ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_TV) += s5p-tv/
184 192
185obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D) += s5p-g2d/ 193obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D) += s5p-g2d/
186 194
195obj-$(CONFIG_BLACKFIN) += blackfin/
196
187obj-$(CONFIG_ARCH_DAVINCI) += davinci/ 197obj-$(CONFIG_ARCH_DAVINCI) += davinci/
188 198
189obj-$(CONFIG_VIDEO_SH_VOU) += sh_vou.o 199obj-$(CONFIG_VIDEO_SH_VOU) += sh_vou.o
@@ -199,6 +209,6 @@ obj-y += davinci/
199 209
200obj-$(CONFIG_ARCH_OMAP) += omap/ 210obj-$(CONFIG_ARCH_OMAP) += omap/
201 211
202ccflags-y += -Idrivers/media/dvb/dvb-core 212ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
203ccflags-y += -Idrivers/media/dvb/frontends 213ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
204ccflags-y += -Idrivers/media/common/tuners 214ccflags-y += -I$(srctree)/drivers/media/common/tuners
diff --git a/drivers/media/video/adp1653.c b/drivers/media/video/adp1653.c
index 12eedf4d515a..5b045b4a66fe 100644
--- a/drivers/media/video/adp1653.c
+++ b/drivers/media/video/adp1653.c
@@ -33,7 +33,6 @@
33#include <linux/delay.h> 33#include <linux/delay.h>
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/i2c.h> 35#include <linux/i2c.h>
36#include <linux/module.h>
37#include <linux/slab.h> 36#include <linux/slab.h>
38#include <linux/version.h> 37#include <linux/version.h>
39#include <media/adp1653.h> 38#include <media/adp1653.h>
@@ -482,24 +481,7 @@ static struct i2c_driver adp1653_i2c_driver = {
482 .id_table = adp1653_id_table, 481 .id_table = adp1653_id_table,
483}; 482};
484 483
485static int __init adp1653_init(void) 484module_i2c_driver(adp1653_i2c_driver);
486{
487 int rval;
488
489 rval = i2c_add_driver(&adp1653_i2c_driver);
490 if (rval)
491 printk(KERN_ALERT "%s: failed at i2c_add_driver\n", __func__);
492
493 return rval;
494}
495
496static void __exit adp1653_exit(void)
497{
498 i2c_del_driver(&adp1653_i2c_driver);
499}
500
501module_init(adp1653_init);
502module_exit(adp1653_exit);
503 485
504MODULE_AUTHOR("Sakari Ailus <sakari.ailus@nokia.com>"); 486MODULE_AUTHOR("Sakari Ailus <sakari.ailus@nokia.com>");
505MODULE_DESCRIPTION("Analog Devices ADP1653 LED flash driver"); 487MODULE_DESCRIPTION("Analog Devices ADP1653 LED flash driver");
diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c
index 879f1d839760..6bc01fb98ff8 100644
--- a/drivers/media/video/adv7170.c
+++ b/drivers/media/video/adv7170.c
@@ -407,15 +407,4 @@ static struct i2c_driver adv7170_driver = {
407 .id_table = adv7170_id, 407 .id_table = adv7170_id,
408}; 408};
409 409
410static __init int init_adv7170(void) 410module_i2c_driver(adv7170_driver);
411{
412 return i2c_add_driver(&adv7170_driver);
413}
414
415static __exit void exit_adv7170(void)
416{
417 i2c_del_driver(&adv7170_driver);
418}
419
420module_init(init_adv7170);
421module_exit(exit_adv7170);
diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c
index 206078eca853..c7640fab5730 100644
--- a/drivers/media/video/adv7175.c
+++ b/drivers/media/video/adv7175.c
@@ -457,15 +457,4 @@ static struct i2c_driver adv7175_driver = {
457 .id_table = adv7175_id, 457 .id_table = adv7175_id,
458}; 458};
459 459
460static __init int init_adv7175(void) 460module_i2c_driver(adv7175_driver);
461{
462 return i2c_add_driver(&adv7175_driver);
463}
464
465static __exit void exit_adv7175(void)
466{
467 i2c_del_driver(&adv7175_driver);
468}
469
470module_init(init_adv7175);
471module_exit(exit_adv7175);
diff --git a/drivers/media/video/adv7180.c b/drivers/media/video/adv7180.c
index d2138d06bcad..b8b6c4b0cad4 100644
--- a/drivers/media/video/adv7180.c
+++ b/drivers/media/video/adv7180.c
@@ -444,20 +444,8 @@ static struct i2c_driver adv7180_driver = {
444 .id_table = adv7180_id, 444 .id_table = adv7180_id,
445}; 445};
446 446
447static __init int adv7180_init(void) 447module_i2c_driver(adv7180_driver);
448{
449 return i2c_add_driver(&adv7180_driver);
450}
451
452static __exit void adv7180_exit(void)
453{
454 i2c_del_driver(&adv7180_driver);
455}
456
457module_init(adv7180_init);
458module_exit(adv7180_exit);
459 448
460MODULE_DESCRIPTION("Analog Devices ADV7180 video decoder driver"); 449MODULE_DESCRIPTION("Analog Devices ADV7180 video decoder driver");
461MODULE_AUTHOR("Mocean Laboratories"); 450MODULE_AUTHOR("Mocean Laboratories");
462MODULE_LICENSE("GPL v2"); 451MODULE_LICENSE("GPL v2");
463
diff --git a/drivers/media/video/adv7183.c b/drivers/media/video/adv7183.c
new file mode 100644
index 000000000000..e1d4c89d7140
--- /dev/null
+++ b/drivers/media/video/adv7183.c
@@ -0,0 +1,699 @@
1/*
2 * adv7183.c Analog Devices ADV7183 video decoder driver
3 *
4 * Copyright (c) 2011 Analog Devices Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * 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/delay.h>
21#include <linux/errno.h>
22#include <linux/gpio.h>
23#include <linux/i2c.h>
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/slab.h>
27#include <linux/types.h>
28#include <linux/videodev2.h>
29
30#include <media/adv7183.h>
31#include <media/v4l2-chip-ident.h>
32#include <media/v4l2-ctrls.h>
33#include <media/v4l2-device.h>
34
35#include "adv7183_regs.h"
36
37struct adv7183 {
38 struct v4l2_subdev sd;
39 struct v4l2_ctrl_handler hdl;
40
41 v4l2_std_id std; /* Current set standard */
42 u32 input;
43 u32 output;
44 unsigned reset_pin;
45 unsigned oe_pin;
46 struct v4l2_mbus_framefmt fmt;
47};
48
49/* EXAMPLES USING 27 MHz CLOCK
50 * Mode 1 CVBS Input (Composite Video on AIN5)
51 * All standards are supported through autodetect, 8-bit, 4:2:2, ITU-R BT.656 output on P15 to P8.
52 */
53static const unsigned char adv7183_init_regs[] = {
54 ADV7183_IN_CTRL, 0x04, /* CVBS input on AIN5 */
55 ADV7183_DIGI_CLAMP_CTRL_1, 0x00, /* Slow down digital clamps */
56 ADV7183_SHAP_FILT_CTRL, 0x41, /* Set CSFM to SH1 */
57 ADV7183_ADC_CTRL, 0x16, /* Power down ADC 1 and ADC 2 */
58 ADV7183_CTI_DNR_CTRL_4, 0x04, /* Set DNR threshold to 4 for flat response */
59 /* ADI recommended programming sequence */
60 ADV7183_ADI_CTRL, 0x80,
61 ADV7183_CTI_DNR_CTRL_4, 0x20,
62 0x52, 0x18,
63 0x58, 0xED,
64 0x77, 0xC5,
65 0x7C, 0x93,
66 0x7D, 0x00,
67 0xD0, 0x48,
68 0xD5, 0xA0,
69 0xD7, 0xEA,
70 ADV7183_SD_SATURATION_CR, 0x3E,
71 ADV7183_PAL_V_END, 0x3E,
72 ADV7183_PAL_F_TOGGLE, 0x0F,
73 ADV7183_ADI_CTRL, 0x00,
74};
75
76static inline struct adv7183 *to_adv7183(struct v4l2_subdev *sd)
77{
78 return container_of(sd, struct adv7183, sd);
79}
80static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
81{
82 return &container_of(ctrl->handler, struct adv7183, hdl)->sd;
83}
84
85static inline int adv7183_read(struct v4l2_subdev *sd, unsigned char reg)
86{
87 struct i2c_client *client = v4l2_get_subdevdata(sd);
88
89 return i2c_smbus_read_byte_data(client, reg);
90}
91
92static inline int adv7183_write(struct v4l2_subdev *sd, unsigned char reg,
93 unsigned char value)
94{
95 struct i2c_client *client = v4l2_get_subdevdata(sd);
96
97 return i2c_smbus_write_byte_data(client, reg, value);
98}
99
100static int adv7183_writeregs(struct v4l2_subdev *sd,
101 const unsigned char *regs, unsigned int num)
102{
103 unsigned char reg, data;
104 unsigned int cnt = 0;
105
106 if (num & 0x1) {
107 v4l2_err(sd, "invalid regs array\n");
108 return -1;
109 }
110
111 while (cnt < num) {
112 reg = *regs++;
113 data = *regs++;
114 cnt += 2;
115
116 adv7183_write(sd, reg, data);
117 }
118 return 0;
119}
120
121static int adv7183_log_status(struct v4l2_subdev *sd)
122{
123 struct adv7183 *decoder = to_adv7183(sd);
124
125 v4l2_info(sd, "adv7183: Input control = 0x%02x\n",
126 adv7183_read(sd, ADV7183_IN_CTRL));
127 v4l2_info(sd, "adv7183: Video selection = 0x%02x\n",
128 adv7183_read(sd, ADV7183_VD_SEL));
129 v4l2_info(sd, "adv7183: Output control = 0x%02x\n",
130 adv7183_read(sd, ADV7183_OUT_CTRL));
131 v4l2_info(sd, "adv7183: Extended output control = 0x%02x\n",
132 adv7183_read(sd, ADV7183_EXT_OUT_CTRL));
133 v4l2_info(sd, "adv7183: Autodetect enable = 0x%02x\n",
134 adv7183_read(sd, ADV7183_AUTO_DET_EN));
135 v4l2_info(sd, "adv7183: Contrast = 0x%02x\n",
136 adv7183_read(sd, ADV7183_CONTRAST));
137 v4l2_info(sd, "adv7183: Brightness = 0x%02x\n",
138 adv7183_read(sd, ADV7183_BRIGHTNESS));
139 v4l2_info(sd, "adv7183: Hue = 0x%02x\n",
140 adv7183_read(sd, ADV7183_HUE));
141 v4l2_info(sd, "adv7183: Default value Y = 0x%02x\n",
142 adv7183_read(sd, ADV7183_DEF_Y));
143 v4l2_info(sd, "adv7183: Default value C = 0x%02x\n",
144 adv7183_read(sd, ADV7183_DEF_C));
145 v4l2_info(sd, "adv7183: ADI control = 0x%02x\n",
146 adv7183_read(sd, ADV7183_ADI_CTRL));
147 v4l2_info(sd, "adv7183: Power Management = 0x%02x\n",
148 adv7183_read(sd, ADV7183_POW_MANAGE));
149 v4l2_info(sd, "adv7183: Status 1 2 and 3 = 0x%02x 0x%02x 0x%02x\n",
150 adv7183_read(sd, ADV7183_STATUS_1),
151 adv7183_read(sd, ADV7183_STATUS_2),
152 adv7183_read(sd, ADV7183_STATUS_3));
153 v4l2_info(sd, "adv7183: Ident = 0x%02x\n",
154 adv7183_read(sd, ADV7183_IDENT));
155 v4l2_info(sd, "adv7183: Analog clamp control = 0x%02x\n",
156 adv7183_read(sd, ADV7183_ANAL_CLAMP_CTRL));
157 v4l2_info(sd, "adv7183: Digital clamp control 1 = 0x%02x\n",
158 adv7183_read(sd, ADV7183_DIGI_CLAMP_CTRL_1));
159 v4l2_info(sd, "adv7183: Shaping filter control 1 and 2 = 0x%02x 0x%02x\n",
160 adv7183_read(sd, ADV7183_SHAP_FILT_CTRL),
161 adv7183_read(sd, ADV7183_SHAP_FILT_CTRL_2));
162 v4l2_info(sd, "adv7183: Comb filter control = 0x%02x\n",
163 adv7183_read(sd, ADV7183_COMB_FILT_CTRL));
164 v4l2_info(sd, "adv7183: ADI control 2 = 0x%02x\n",
165 adv7183_read(sd, ADV7183_ADI_CTRL_2));
166 v4l2_info(sd, "adv7183: Pixel delay control = 0x%02x\n",
167 adv7183_read(sd, ADV7183_PIX_DELAY_CTRL));
168 v4l2_info(sd, "adv7183: Misc gain control = 0x%02x\n",
169 adv7183_read(sd, ADV7183_MISC_GAIN_CTRL));
170 v4l2_info(sd, "adv7183: AGC mode control = 0x%02x\n",
171 adv7183_read(sd, ADV7183_AGC_MODE_CTRL));
172 v4l2_info(sd, "adv7183: Chroma gain control 1 and 2 = 0x%02x 0x%02x\n",
173 adv7183_read(sd, ADV7183_CHRO_GAIN_CTRL_1),
174 adv7183_read(sd, ADV7183_CHRO_GAIN_CTRL_2));
175 v4l2_info(sd, "adv7183: Luma gain control 1 and 2 = 0x%02x 0x%02x\n",
176 adv7183_read(sd, ADV7183_LUMA_GAIN_CTRL_1),
177 adv7183_read(sd, ADV7183_LUMA_GAIN_CTRL_2));
178 v4l2_info(sd, "adv7183: Vsync field control 1 2 and 3 = 0x%02x 0x%02x 0x%02x\n",
179 adv7183_read(sd, ADV7183_VS_FIELD_CTRL_1),
180 adv7183_read(sd, ADV7183_VS_FIELD_CTRL_2),
181 adv7183_read(sd, ADV7183_VS_FIELD_CTRL_3));
182 v4l2_info(sd, "adv7183: Hsync positon control 1 2 and 3 = 0x%02x 0x%02x 0x%02x\n",
183 adv7183_read(sd, ADV7183_HS_POS_CTRL_1),
184 adv7183_read(sd, ADV7183_HS_POS_CTRL_2),
185 adv7183_read(sd, ADV7183_HS_POS_CTRL_3));
186 v4l2_info(sd, "adv7183: Polarity = 0x%02x\n",
187 adv7183_read(sd, ADV7183_POLARITY));
188 v4l2_info(sd, "adv7183: ADC control = 0x%02x\n",
189 adv7183_read(sd, ADV7183_ADC_CTRL));
190 v4l2_info(sd, "adv7183: SD offset Cb and Cr = 0x%02x 0x%02x\n",
191 adv7183_read(sd, ADV7183_SD_OFFSET_CB),
192 adv7183_read(sd, ADV7183_SD_OFFSET_CR));
193 v4l2_info(sd, "adv7183: SD saturation Cb and Cr = 0x%02x 0x%02x\n",
194 adv7183_read(sd, ADV7183_SD_SATURATION_CB),
195 adv7183_read(sd, ADV7183_SD_SATURATION_CR));
196 v4l2_info(sd, "adv7183: Drive strength = 0x%02x\n",
197 adv7183_read(sd, ADV7183_DRIVE_STR));
198 v4l2_ctrl_handler_log_status(&decoder->hdl, sd->name);
199 return 0;
200}
201
202static int adv7183_g_std(struct v4l2_subdev *sd, v4l2_std_id *std)
203{
204 struct adv7183 *decoder = to_adv7183(sd);
205
206 *std = decoder->std;
207 return 0;
208}
209
210static int adv7183_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
211{
212 struct adv7183 *decoder = to_adv7183(sd);
213 int reg;
214
215 reg = adv7183_read(sd, ADV7183_IN_CTRL) & 0xF;
216 if (std == V4L2_STD_PAL_60)
217 reg |= 0x60;
218 else if (std == V4L2_STD_NTSC_443)
219 reg |= 0x70;
220 else if (std == V4L2_STD_PAL_N)
221 reg |= 0x90;
222 else if (std == V4L2_STD_PAL_M)
223 reg |= 0xA0;
224 else if (std == V4L2_STD_PAL_Nc)
225 reg |= 0xC0;
226 else if (std & V4L2_STD_PAL)
227 reg |= 0x80;
228 else if (std & V4L2_STD_NTSC)
229 reg |= 0x50;
230 else if (std & V4L2_STD_SECAM)
231 reg |= 0xE0;
232 else
233 return -EINVAL;
234 adv7183_write(sd, ADV7183_IN_CTRL, reg);
235
236 decoder->std = std;
237
238 return 0;
239}
240
241static int adv7183_reset(struct v4l2_subdev *sd, u32 val)
242{
243 int reg;
244
245 reg = adv7183_read(sd, ADV7183_POW_MANAGE) | 0x80;
246 adv7183_write(sd, ADV7183_POW_MANAGE, reg);
247 /* wait 5ms before any further i2c writes are performed */
248 usleep_range(5000, 10000);
249 return 0;
250}
251
252static int adv7183_s_routing(struct v4l2_subdev *sd,
253 u32 input, u32 output, u32 config)
254{
255 struct adv7183 *decoder = to_adv7183(sd);
256 int reg;
257
258 if ((input > ADV7183_COMPONENT1) || (output > ADV7183_16BIT_OUT))
259 return -EINVAL;
260
261 if (input != decoder->input) {
262 decoder->input = input;
263 reg = adv7183_read(sd, ADV7183_IN_CTRL) & 0xF0;
264 switch (input) {
265 case ADV7183_COMPOSITE1:
266 reg |= 0x1;
267 break;
268 case ADV7183_COMPOSITE2:
269 reg |= 0x2;
270 break;
271 case ADV7183_COMPOSITE3:
272 reg |= 0x3;
273 break;
274 case ADV7183_COMPOSITE4:
275 reg |= 0x4;
276 break;
277 case ADV7183_COMPOSITE5:
278 reg |= 0x5;
279 break;
280 case ADV7183_COMPOSITE6:
281 reg |= 0xB;
282 break;
283 case ADV7183_COMPOSITE7:
284 reg |= 0xC;
285 break;
286 case ADV7183_COMPOSITE8:
287 reg |= 0xD;
288 break;
289 case ADV7183_COMPOSITE9:
290 reg |= 0xE;
291 break;
292 case ADV7183_COMPOSITE10:
293 reg |= 0xF;
294 break;
295 case ADV7183_SVIDEO0:
296 reg |= 0x6;
297 break;
298 case ADV7183_SVIDEO1:
299 reg |= 0x7;
300 break;
301 case ADV7183_SVIDEO2:
302 reg |= 0x8;
303 break;
304 case ADV7183_COMPONENT0:
305 reg |= 0x9;
306 break;
307 case ADV7183_COMPONENT1:
308 reg |= 0xA;
309 break;
310 default:
311 break;
312 }
313 adv7183_write(sd, ADV7183_IN_CTRL, reg);
314 }
315
316 if (output != decoder->output) {
317 decoder->output = output;
318 reg = adv7183_read(sd, ADV7183_OUT_CTRL) & 0xC0;
319 switch (output) {
320 case ADV7183_16BIT_OUT:
321 reg |= 0x9;
322 break;
323 default:
324 reg |= 0xC;
325 break;
326 }
327 adv7183_write(sd, ADV7183_OUT_CTRL, reg);
328 }
329
330 return 0;
331}
332
333static int adv7183_s_ctrl(struct v4l2_ctrl *ctrl)
334{
335 struct v4l2_subdev *sd = to_sd(ctrl);
336 int val = ctrl->val;
337
338 switch (ctrl->id) {
339 case V4L2_CID_BRIGHTNESS:
340 if (val < 0)
341 val = 127 - val;
342 adv7183_write(sd, ADV7183_BRIGHTNESS, val);
343 break;
344 case V4L2_CID_CONTRAST:
345 adv7183_write(sd, ADV7183_CONTRAST, val);
346 break;
347 case V4L2_CID_SATURATION:
348 adv7183_write(sd, ADV7183_SD_SATURATION_CB, val >> 8);
349 adv7183_write(sd, ADV7183_SD_SATURATION_CR, (val & 0xFF));
350 break;
351 case V4L2_CID_HUE:
352 adv7183_write(sd, ADV7183_SD_OFFSET_CB, val >> 8);
353 adv7183_write(sd, ADV7183_SD_OFFSET_CR, (val & 0xFF));
354 break;
355 default:
356 return -EINVAL;
357 }
358
359 return 0;
360}
361
362static int adv7183_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
363{
364 struct adv7183 *decoder = to_adv7183(sd);
365 int reg;
366
367 /* enable autodetection block */
368 reg = adv7183_read(sd, ADV7183_IN_CTRL) & 0xF;
369 adv7183_write(sd, ADV7183_IN_CTRL, reg);
370
371 /* wait autodetection switch */
372 mdelay(10);
373
374 /* get autodetection result */
375 reg = adv7183_read(sd, ADV7183_STATUS_1);
376 switch ((reg >> 0x4) & 0x7) {
377 case 0:
378 *std = V4L2_STD_NTSC;
379 break;
380 case 1:
381 *std = V4L2_STD_NTSC_443;
382 break;
383 case 2:
384 *std = V4L2_STD_PAL_M;
385 break;
386 case 3:
387 *std = V4L2_STD_PAL_60;
388 break;
389 case 4:
390 *std = V4L2_STD_PAL;
391 break;
392 case 5:
393 *std = V4L2_STD_SECAM;
394 break;
395 case 6:
396 *std = V4L2_STD_PAL_Nc;
397 break;
398 case 7:
399 *std = V4L2_STD_SECAM;
400 break;
401 default:
402 *std = V4L2_STD_UNKNOWN;
403 break;
404 }
405
406 /* after std detection, write back user set std */
407 adv7183_s_std(sd, decoder->std);
408 return 0;
409}
410
411static int adv7183_g_input_status(struct v4l2_subdev *sd, u32 *status)
412{
413 int reg;
414
415 *status = V4L2_IN_ST_NO_SIGNAL;
416 reg = adv7183_read(sd, ADV7183_STATUS_1);
417 if (reg < 0)
418 return reg;
419 if (reg & 0x1)
420 *status = 0;
421 return 0;
422}
423
424static int adv7183_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
425 enum v4l2_mbus_pixelcode *code)
426{
427 if (index > 0)
428 return -EINVAL;
429
430 *code = V4L2_MBUS_FMT_UYVY8_2X8;
431 return 0;
432}
433
434static int adv7183_try_mbus_fmt(struct v4l2_subdev *sd,
435 struct v4l2_mbus_framefmt *fmt)
436{
437 struct adv7183 *decoder = to_adv7183(sd);
438
439 fmt->code = V4L2_MBUS_FMT_UYVY8_2X8;
440 fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
441 if (decoder->std & V4L2_STD_525_60) {
442 fmt->field = V4L2_FIELD_SEQ_TB;
443 fmt->width = 720;
444 fmt->height = 480;
445 } else {
446 fmt->field = V4L2_FIELD_SEQ_BT;
447 fmt->width = 720;
448 fmt->height = 576;
449 }
450 return 0;
451}
452
453static int adv7183_s_mbus_fmt(struct v4l2_subdev *sd,
454 struct v4l2_mbus_framefmt *fmt)
455{
456 struct adv7183 *decoder = to_adv7183(sd);
457
458 adv7183_try_mbus_fmt(sd, fmt);
459 decoder->fmt = *fmt;
460 return 0;
461}
462
463static int adv7183_g_mbus_fmt(struct v4l2_subdev *sd,
464 struct v4l2_mbus_framefmt *fmt)
465{
466 struct adv7183 *decoder = to_adv7183(sd);
467
468 *fmt = decoder->fmt;
469 return 0;
470}
471
472static int adv7183_s_stream(struct v4l2_subdev *sd, int enable)
473{
474 struct adv7183 *decoder = to_adv7183(sd);
475
476 if (enable)
477 gpio_direction_output(decoder->oe_pin, 0);
478 else
479 gpio_direction_output(decoder->oe_pin, 1);
480 udelay(1);
481 return 0;
482}
483
484static int adv7183_g_chip_ident(struct v4l2_subdev *sd,
485 struct v4l2_dbg_chip_ident *chip)
486{
487 int rev;
488 struct i2c_client *client = v4l2_get_subdevdata(sd);
489
490 /* 0x11 for adv7183, 0x13 for adv7183b */
491 rev = adv7183_read(sd, ADV7183_IDENT);
492
493 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7183, rev);
494}
495
496#ifdef CONFIG_VIDEO_ADV_DEBUG
497static int adv7183_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
498{
499 struct i2c_client *client = v4l2_get_subdevdata(sd);
500
501 if (!v4l2_chip_match_i2c_client(client, &reg->match))
502 return -EINVAL;
503 if (!capable(CAP_SYS_ADMIN))
504 return -EPERM;
505 reg->val = adv7183_read(sd, reg->reg & 0xff);
506 reg->size = 1;
507 return 0;
508}
509
510static int adv7183_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
511{
512 struct i2c_client *client = v4l2_get_subdevdata(sd);
513
514 if (!v4l2_chip_match_i2c_client(client, &reg->match))
515 return -EINVAL;
516 if (!capable(CAP_SYS_ADMIN))
517 return -EPERM;
518 adv7183_write(sd, reg->reg & 0xff, reg->val & 0xff);
519 return 0;
520}
521#endif
522
523static const struct v4l2_ctrl_ops adv7183_ctrl_ops = {
524 .s_ctrl = adv7183_s_ctrl,
525};
526
527static const struct v4l2_subdev_core_ops adv7183_core_ops = {
528 .log_status = adv7183_log_status,
529 .g_std = adv7183_g_std,
530 .s_std = adv7183_s_std,
531 .reset = adv7183_reset,
532 .g_chip_ident = adv7183_g_chip_ident,
533#ifdef CONFIG_VIDEO_ADV_DEBUG
534 .g_register = adv7183_g_register,
535 .s_register = adv7183_s_register,
536#endif
537};
538
539static const struct v4l2_subdev_video_ops adv7183_video_ops = {
540 .s_routing = adv7183_s_routing,
541 .querystd = adv7183_querystd,
542 .g_input_status = adv7183_g_input_status,
543 .enum_mbus_fmt = adv7183_enum_mbus_fmt,
544 .try_mbus_fmt = adv7183_try_mbus_fmt,
545 .s_mbus_fmt = adv7183_s_mbus_fmt,
546 .g_mbus_fmt = adv7183_g_mbus_fmt,
547 .s_stream = adv7183_s_stream,
548};
549
550static const struct v4l2_subdev_ops adv7183_ops = {
551 .core = &adv7183_core_ops,
552 .video = &adv7183_video_ops,
553};
554
555static int adv7183_probe(struct i2c_client *client,
556 const struct i2c_device_id *id)
557{
558 struct adv7183 *decoder;
559 struct v4l2_subdev *sd;
560 struct v4l2_ctrl_handler *hdl;
561 int ret;
562 struct v4l2_mbus_framefmt fmt;
563 const unsigned *pin_array;
564
565 /* Check if the adapter supports the needed features */
566 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
567 return -EIO;
568
569 v4l_info(client, "chip found @ 0x%02x (%s)\n",
570 client->addr << 1, client->adapter->name);
571
572 pin_array = client->dev.platform_data;
573 if (pin_array == NULL)
574 return -EINVAL;
575
576 decoder = kzalloc(sizeof(struct adv7183), GFP_KERNEL);
577 if (decoder == NULL)
578 return -ENOMEM;
579
580 decoder->reset_pin = pin_array[0];
581 decoder->oe_pin = pin_array[1];
582
583 if (gpio_request(decoder->reset_pin, "ADV7183 Reset")) {
584 v4l_err(client, "failed to request GPIO %d\n", decoder->reset_pin);
585 ret = -EBUSY;
586 goto err_free_decoder;
587 }
588
589 if (gpio_request(decoder->oe_pin, "ADV7183 Output Enable")) {
590 v4l_err(client, "failed to request GPIO %d\n", decoder->oe_pin);
591 ret = -EBUSY;
592 goto err_free_reset;
593 }
594
595 sd = &decoder->sd;
596 v4l2_i2c_subdev_init(sd, client, &adv7183_ops);
597
598 hdl = &decoder->hdl;
599 v4l2_ctrl_handler_init(hdl, 4);
600 v4l2_ctrl_new_std(hdl, &adv7183_ctrl_ops,
601 V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
602 v4l2_ctrl_new_std(hdl, &adv7183_ctrl_ops,
603 V4L2_CID_CONTRAST, 0, 0xFF, 1, 0x80);
604 v4l2_ctrl_new_std(hdl, &adv7183_ctrl_ops,
605 V4L2_CID_SATURATION, 0, 0xFFFF, 1, 0x8080);
606 v4l2_ctrl_new_std(hdl, &adv7183_ctrl_ops,
607 V4L2_CID_HUE, 0, 0xFFFF, 1, 0x8080);
608 /* hook the control handler into the driver */
609 sd->ctrl_handler = hdl;
610 if (hdl->error) {
611 ret = hdl->error;
612
613 v4l2_ctrl_handler_free(hdl);
614 goto err_free_oe;
615 }
616
617 /* v4l2 doesn't support an autodetect standard, pick PAL as default */
618 decoder->std = V4L2_STD_PAL;
619 decoder->input = ADV7183_COMPOSITE4;
620 decoder->output = ADV7183_8BIT_OUT;
621
622 gpio_direction_output(decoder->oe_pin, 1);
623 /* reset chip */
624 gpio_direction_output(decoder->reset_pin, 0);
625 /* reset pulse width at least 5ms */
626 mdelay(10);
627 gpio_direction_output(decoder->reset_pin, 1);
628 /* wait 5ms before any further i2c writes are performed */
629 mdelay(5);
630
631 adv7183_writeregs(sd, adv7183_init_regs, ARRAY_SIZE(adv7183_init_regs));
632 adv7183_s_std(sd, decoder->std);
633 fmt.width = 720;
634 fmt.height = 576;
635 adv7183_s_mbus_fmt(sd, &fmt);
636
637 /* initialize the hardware to the default control values */
638 ret = v4l2_ctrl_handler_setup(hdl);
639 if (ret) {
640 v4l2_ctrl_handler_free(hdl);
641 goto err_free_oe;
642 }
643
644 return 0;
645err_free_oe:
646 gpio_free(decoder->oe_pin);
647err_free_reset:
648 gpio_free(decoder->reset_pin);
649err_free_decoder:
650 kfree(decoder);
651 return ret;
652}
653
654static int adv7183_remove(struct i2c_client *client)
655{
656 struct v4l2_subdev *sd = i2c_get_clientdata(client);
657 struct adv7183 *decoder = to_adv7183(sd);
658
659 v4l2_device_unregister_subdev(sd);
660 v4l2_ctrl_handler_free(sd->ctrl_handler);
661 gpio_free(decoder->oe_pin);
662 gpio_free(decoder->reset_pin);
663 kfree(decoder);
664 return 0;
665}
666
667static const struct i2c_device_id adv7183_id[] = {
668 {"adv7183", 0},
669 {},
670};
671
672MODULE_DEVICE_TABLE(i2c, adv7183_id);
673
674static struct i2c_driver adv7183_driver = {
675 .driver = {
676 .owner = THIS_MODULE,
677 .name = "adv7183",
678 },
679 .probe = adv7183_probe,
680 .remove = __devexit_p(adv7183_remove),
681 .id_table = adv7183_id,
682};
683
684static __init int adv7183_init(void)
685{
686 return i2c_add_driver(&adv7183_driver);
687}
688
689static __exit void adv7183_exit(void)
690{
691 i2c_del_driver(&adv7183_driver);
692}
693
694module_init(adv7183_init);
695module_exit(adv7183_exit);
696
697MODULE_DESCRIPTION("Analog Devices ADV7183 video decoder driver");
698MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>");
699MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/adv7183_regs.h b/drivers/media/video/adv7183_regs.h
new file mode 100644
index 000000000000..4a5b7d211d2f
--- /dev/null
+++ b/drivers/media/video/adv7183_regs.h
@@ -0,0 +1,107 @@
1/*
2 * adv7183 - Analog Devices ADV7183 video decoder registers
3 *
4 * Copyright (c) 2011 Analog Devices Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * 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#ifndef _ADV7183_REGS_H_
21#define _ADV7183_REGS_H_
22
23#define ADV7183_IN_CTRL 0x00 /* Input control */
24#define ADV7183_VD_SEL 0x01 /* Video selection */
25#define ADV7183_OUT_CTRL 0x03 /* Output control */
26#define ADV7183_EXT_OUT_CTRL 0x04 /* Extended output control */
27#define ADV7183_AUTO_DET_EN 0x07 /* Autodetect enable */
28#define ADV7183_CONTRAST 0x08 /* Contrast */
29#define ADV7183_BRIGHTNESS 0x0A /* Brightness */
30#define ADV7183_HUE 0x0B /* Hue */
31#define ADV7183_DEF_Y 0x0C /* Default value Y */
32#define ADV7183_DEF_C 0x0D /* Default value C */
33#define ADV7183_ADI_CTRL 0x0E /* ADI control */
34#define ADV7183_POW_MANAGE 0x0F /* Power Management */
35#define ADV7183_STATUS_1 0x10 /* Status 1 */
36#define ADV7183_IDENT 0x11 /* Ident */
37#define ADV7183_STATUS_2 0x12 /* Status 2 */
38#define ADV7183_STATUS_3 0x13 /* Status 3 */
39#define ADV7183_ANAL_CLAMP_CTRL 0x14 /* Analog clamp control */
40#define ADV7183_DIGI_CLAMP_CTRL_1 0x15 /* Digital clamp control 1 */
41#define ADV7183_SHAP_FILT_CTRL 0x17 /* Shaping filter control */
42#define ADV7183_SHAP_FILT_CTRL_2 0x18 /* Shaping filter control 2 */
43#define ADV7183_COMB_FILT_CTRL 0x19 /* Comb filter control */
44#define ADV7183_ADI_CTRL_2 0x1D /* ADI control 2 */
45#define ADV7183_PIX_DELAY_CTRL 0x27 /* Pixel delay control */
46#define ADV7183_MISC_GAIN_CTRL 0x2B /* Misc gain control */
47#define ADV7183_AGC_MODE_CTRL 0x2C /* AGC mode control */
48#define ADV7183_CHRO_GAIN_CTRL_1 0x2D /* Chroma gain control 1 */
49#define ADV7183_CHRO_GAIN_CTRL_2 0x2E /* Chroma gain control 2 */
50#define ADV7183_LUMA_GAIN_CTRL_1 0x2F /* Luma gain control 1 */
51#define ADV7183_LUMA_GAIN_CTRL_2 0x30 /* Luma gain control 2 */
52#define ADV7183_VS_FIELD_CTRL_1 0x31 /* Vsync field control 1 */
53#define ADV7183_VS_FIELD_CTRL_2 0x32 /* Vsync field control 2 */
54#define ADV7183_VS_FIELD_CTRL_3 0x33 /* Vsync field control 3 */
55#define ADV7183_HS_POS_CTRL_1 0x34 /* Hsync positon control 1 */
56#define ADV7183_HS_POS_CTRL_2 0x35 /* Hsync positon control 2 */
57#define ADV7183_HS_POS_CTRL_3 0x36 /* Hsync positon control 3 */
58#define ADV7183_POLARITY 0x37 /* Polarity */
59#define ADV7183_NTSC_COMB_CTRL 0x38 /* NTSC comb control */
60#define ADV7183_PAL_COMB_CTRL 0x39 /* PAL comb control */
61#define ADV7183_ADC_CTRL 0x3A /* ADC control */
62#define ADV7183_MAN_WIN_CTRL 0x3D /* Manual window control */
63#define ADV7183_RESAMPLE_CTRL 0x41 /* Resample control */
64#define ADV7183_GEMSTAR_CTRL_1 0x48 /* Gemstar ctrl 1 */
65#define ADV7183_GEMSTAR_CTRL_2 0x49 /* Gemstar ctrl 2 */
66#define ADV7183_GEMSTAR_CTRL_3 0x4A /* Gemstar ctrl 3 */
67#define ADV7183_GEMSTAR_CTRL_4 0x4B /* Gemstar ctrl 4 */
68#define ADV7183_GEMSTAR_CTRL_5 0x4C /* Gemstar ctrl 5 */
69#define ADV7183_CTI_DNR_CTRL_1 0x4D /* CTI DNR ctrl 1 */
70#define ADV7183_CTI_DNR_CTRL_2 0x4E /* CTI DNR ctrl 2 */
71#define ADV7183_CTI_DNR_CTRL_4 0x50 /* CTI DNR ctrl 4 */
72#define ADV7183_LOCK_CNT 0x51 /* Lock count */
73#define ADV7183_FREE_LINE_LEN 0x8F /* Free-Run line length 1 */
74#define ADV7183_VBI_INFO 0x90 /* VBI info */
75#define ADV7183_WSS_1 0x91 /* WSS 1 */
76#define ADV7183_WSS_2 0x92 /* WSS 2 */
77#define ADV7183_EDTV_1 0x93 /* EDTV 1 */
78#define ADV7183_EDTV_2 0x94 /* EDTV 2 */
79#define ADV7183_EDTV_3 0x95 /* EDTV 3 */
80#define ADV7183_CGMS_1 0x96 /* CGMS 1 */
81#define ADV7183_CGMS_2 0x97 /* CGMS 2 */
82#define ADV7183_CGMS_3 0x98 /* CGMS 3 */
83#define ADV7183_CCAP_1 0x99 /* CCAP 1 */
84#define ADV7183_CCAP_2 0x9A /* CCAP 2 */
85#define ADV7183_LETTERBOX_1 0x9B /* Letterbox 1 */
86#define ADV7183_LETTERBOX_2 0x9C /* Letterbox 2 */
87#define ADV7183_LETTERBOX_3 0x9D /* Letterbox 3 */
88#define ADV7183_CRC_EN 0xB2 /* CRC enable */
89#define ADV7183_ADC_SWITCH_1 0xC3 /* ADC switch 1 */
90#define ADV7183_ADC_SWITCH_2 0xC4 /* ADC swithc 2 */
91#define ADV7183_LETTERBOX_CTRL_1 0xDC /* Letterbox control 1 */
92#define ADV7183_LETTERBOX_CTRL_2 0xDD /* Letterbox control 2 */
93#define ADV7183_SD_OFFSET_CB 0xE1 /* SD offset Cb */
94#define ADV7183_SD_OFFSET_CR 0xE2 /* SD offset Cr */
95#define ADV7183_SD_SATURATION_CB 0xE3 /* SD saturation Cb */
96#define ADV7183_SD_SATURATION_CR 0xE4 /* SD saturation Cr */
97#define ADV7183_NTSC_V_BEGIN 0xE5 /* NTSC V bit begin */
98#define ADV7183_NTSC_V_END 0xE6 /* NTSC V bit end */
99#define ADV7183_NTSC_F_TOGGLE 0xE7 /* NTSC F bit toggle */
100#define ADV7183_PAL_V_BEGIN 0xE8 /* PAL V bit begin */
101#define ADV7183_PAL_V_END 0xE9 /* PAL V bit end */
102#define ADV7183_PAL_F_TOGGLE 0xEA /* PAL F bit toggle */
103#define ADV7183_DRIVE_STR 0xF4 /* Drive strength */
104#define ADV7183_IF_COMP_CTRL 0xF8 /* IF comp control */
105#define ADV7183_VS_MODE_CTRL 0xF9 /* VS mode control */
106
107#endif
diff --git a/drivers/media/video/adv7343.c b/drivers/media/video/adv7343.c
index 021fab23070d..119b60401bf3 100644
--- a/drivers/media/video/adv7343.c
+++ b/drivers/media/video/adv7343.c
@@ -475,15 +475,4 @@ static struct i2c_driver adv7343_driver = {
475 .id_table = adv7343_id, 475 .id_table = adv7343_id,
476}; 476};
477 477
478static __init int init_adv7343(void) 478module_i2c_driver(adv7343_driver);
479{
480 return i2c_add_driver(&adv7343_driver);
481}
482
483static __exit void exit_adv7343(void)
484{
485 i2c_del_driver(&adv7343_driver);
486}
487
488module_init(init_adv7343);
489module_exit(exit_adv7343);
diff --git a/drivers/media/video/ak881x.c b/drivers/media/video/ak881x.c
index 53c496c00fb6..ba674656b10d 100644
--- a/drivers/media/video/ak881x.c
+++ b/drivers/media/video/ak881x.c
@@ -352,18 +352,7 @@ static struct i2c_driver ak881x_i2c_driver = {
352 .id_table = ak881x_id, 352 .id_table = ak881x_id,
353}; 353};
354 354
355static int __init ak881x_module_init(void) 355module_i2c_driver(ak881x_i2c_driver);
356{
357 return i2c_add_driver(&ak881x_i2c_driver);
358}
359
360static void __exit ak881x_module_exit(void)
361{
362 i2c_del_driver(&ak881x_i2c_driver);
363}
364
365module_init(ak881x_module_init);
366module_exit(ak881x_module_exit);
367 356
368MODULE_DESCRIPTION("TV-output driver for ak8813/ak8814"); 357MODULE_DESCRIPTION("TV-output driver for ak8813/ak8814");
369MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); 358MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
diff --git a/drivers/media/video/aptina-pll.c b/drivers/media/video/aptina-pll.c
new file mode 100644
index 000000000000..0bd3813bb59d
--- /dev/null
+++ b/drivers/media/video/aptina-pll.c
@@ -0,0 +1,174 @@
1/*
2 * Aptina Sensor PLL Configuration
3 *
4 * Copyright (C) 2012 Laurent Pinchart <laurent.pinchart@ideasonboard.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * 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., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 */
20
21#include <linux/device.h>
22#include <linux/gcd.h>
23#include <linux/kernel.h>
24#include <linux/lcm.h>
25#include <linux/module.h>
26
27#include "aptina-pll.h"
28
29int aptina_pll_calculate(struct device *dev,
30 const struct aptina_pll_limits *limits,
31 struct aptina_pll *pll)
32{
33 unsigned int mf_min;
34 unsigned int mf_max;
35 unsigned int p1_min;
36 unsigned int p1_max;
37 unsigned int p1;
38 unsigned int div;
39
40 dev_dbg(dev, "PLL: ext clock %u pix clock %u\n",
41 pll->ext_clock, pll->pix_clock);
42
43 if (pll->ext_clock < limits->ext_clock_min ||
44 pll->ext_clock > limits->ext_clock_max) {
45 dev_err(dev, "pll: invalid external clock frequency.\n");
46 return -EINVAL;
47 }
48
49 if (pll->pix_clock == 0 || pll->pix_clock > limits->pix_clock_max) {
50 dev_err(dev, "pll: invalid pixel clock frequency.\n");
51 return -EINVAL;
52 }
53
54 /* Compute the multiplier M and combined N*P1 divisor. */
55 div = gcd(pll->pix_clock, pll->ext_clock);
56 pll->m = pll->pix_clock / div;
57 div = pll->ext_clock / div;
58
59 /* We now have the smallest M and N*P1 values that will result in the
60 * desired pixel clock frequency, but they might be out of the valid
61 * range. Compute the factor by which we should multiply them given the
62 * following constraints:
63 *
64 * - minimum/maximum multiplier
65 * - minimum/maximum multiplier output clock frequency assuming the
66 * minimum/maximum N value
67 * - minimum/maximum combined N*P1 divisor
68 */
69 mf_min = DIV_ROUND_UP(limits->m_min, pll->m);
70 mf_min = max(mf_min, limits->out_clock_min /
71 (pll->ext_clock / limits->n_min * pll->m));
72 mf_min = max(mf_min, limits->n_min * limits->p1_min / div);
73 mf_max = limits->m_max / pll->m;
74 mf_max = min(mf_max, limits->out_clock_max /
75 (pll->ext_clock / limits->n_max * pll->m));
76 mf_max = min(mf_max, DIV_ROUND_UP(limits->n_max * limits->p1_max, div));
77
78 dev_dbg(dev, "pll: mf min %u max %u\n", mf_min, mf_max);
79 if (mf_min > mf_max) {
80 dev_err(dev, "pll: no valid combined N*P1 divisor.\n");
81 return -EINVAL;
82 }
83
84 /*
85 * We're looking for the highest acceptable P1 value for which a
86 * multiplier factor MF exists that fulfills the following conditions:
87 *
88 * 1. p1 is in the [p1_min, p1_max] range given by the limits and is
89 * even
90 * 2. mf is in the [mf_min, mf_max] range computed above
91 * 3. div * mf is a multiple of p1, in order to compute
92 * n = div * mf / p1
93 * m = pll->m * mf
94 * 4. the internal clock frequency, given by ext_clock / n, is in the
95 * [int_clock_min, int_clock_max] range given by the limits
96 * 5. the output clock frequency, given by ext_clock / n * m, is in the
97 * [out_clock_min, out_clock_max] range given by the limits
98 *
99 * The first naive approach is to iterate over all p1 values acceptable
100 * according to (1) and all mf values acceptable according to (2), and
101 * stop at the first combination that fulfills (3), (4) and (5). This
102 * has a O(n^2) complexity.
103 *
104 * Instead of iterating over all mf values in the [mf_min, mf_max] range
105 * we can compute the mf increment between two acceptable values
106 * according to (3) with
107 *
108 * mf_inc = p1 / gcd(div, p1) (6)
109 *
110 * and round the minimum up to the nearest multiple of mf_inc. This will
111 * restrict the number of mf values to be checked.
112 *
113 * Furthermore, conditions (4) and (5) only restrict the range of
114 * acceptable p1 and mf values by modifying the minimum and maximum
115 * limits. (5) can be expressed as
116 *
117 * ext_clock / (div * mf / p1) * m * mf >= out_clock_min
118 * ext_clock / (div * mf / p1) * m * mf <= out_clock_max
119 *
120 * or
121 *
122 * p1 >= out_clock_min * div / (ext_clock * m) (7)
123 * p1 <= out_clock_max * div / (ext_clock * m)
124 *
125 * Similarly, (4) can be expressed as
126 *
127 * mf >= ext_clock * p1 / (int_clock_max * div) (8)
128 * mf <= ext_clock * p1 / (int_clock_min * div)
129 *
130 * We can thus iterate over the restricted p1 range defined by the
131 * combination of (1) and (7), and then compute the restricted mf range
132 * defined by the combination of (2), (6) and (8). If the resulting mf
133 * range is not empty, any value in the mf range is acceptable. We thus
134 * select the mf lwoer bound and the corresponding p1 value.
135 */
136 if (limits->p1_min == 0) {
137 dev_err(dev, "pll: P1 minimum value must be >0.\n");
138 return -EINVAL;
139 }
140
141 p1_min = max(limits->p1_min, DIV_ROUND_UP(limits->out_clock_min * div,
142 pll->ext_clock * pll->m));
143 p1_max = min(limits->p1_max, limits->out_clock_max * div /
144 (pll->ext_clock * pll->m));
145
146 for (p1 = p1_max & ~1; p1 >= p1_min; p1 -= 2) {
147 unsigned int mf_inc = p1 / gcd(div, p1);
148 unsigned int mf_high;
149 unsigned int mf_low;
150
151 mf_low = max(roundup(mf_min, mf_inc),
152 DIV_ROUND_UP(pll->ext_clock * p1,
153 limits->int_clock_max * div));
154 mf_high = min(mf_max, pll->ext_clock * p1 /
155 (limits->int_clock_min * div));
156
157 if (mf_low > mf_high)
158 continue;
159
160 pll->n = div * mf_low / p1;
161 pll->m *= mf_low;
162 pll->p1 = p1;
163 dev_dbg(dev, "PLL: N %u M %u P1 %u\n", pll->n, pll->m, pll->p1);
164 return 0;
165 }
166
167 dev_err(dev, "pll: no valid N and P1 divisors found.\n");
168 return -EINVAL;
169}
170EXPORT_SYMBOL_GPL(aptina_pll_calculate);
171
172MODULE_DESCRIPTION("Aptina PLL Helpers");
173MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
174MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/aptina-pll.h b/drivers/media/video/aptina-pll.h
new file mode 100644
index 000000000000..b370e341e75d
--- /dev/null
+++ b/drivers/media/video/aptina-pll.h
@@ -0,0 +1,56 @@
1/*
2 * Aptina Sensor PLL Configuration
3 *
4 * Copyright (C) 2012 Laurent Pinchart <laurent.pinchart@ideasonboard.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * 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., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 */
20
21#ifndef __APTINA_PLL_H
22#define __APTINA_PLL_H
23
24struct aptina_pll {
25 unsigned int ext_clock;
26 unsigned int pix_clock;
27
28 unsigned int n;
29 unsigned int m;
30 unsigned int p1;
31};
32
33struct aptina_pll_limits {
34 unsigned int ext_clock_min;
35 unsigned int ext_clock_max;
36 unsigned int int_clock_min;
37 unsigned int int_clock_max;
38 unsigned int out_clock_min;
39 unsigned int out_clock_max;
40 unsigned int pix_clock_max;
41
42 unsigned int n_min;
43 unsigned int n_max;
44 unsigned int m_min;
45 unsigned int m_max;
46 unsigned int p1_min;
47 unsigned int p1_max;
48};
49
50struct device;
51
52int aptina_pll_calculate(struct device *dev,
53 const struct aptina_pll_limits *limits,
54 struct aptina_pll *pll);
55
56#endif /* __APTINA_PLL_H */
diff --git a/drivers/media/video/as3645a.c b/drivers/media/video/as3645a.c
index f241702a0f36..7a3371f044fc 100644
--- a/drivers/media/video/as3645a.c
+++ b/drivers/media/video/as3645a.c
@@ -881,24 +881,7 @@ static struct i2c_driver as3645a_i2c_driver = {
881 .id_table = as3645a_id_table, 881 .id_table = as3645a_id_table,
882}; 882};
883 883
884static int __init as3645a_init(void) 884module_i2c_driver(as3645a_i2c_driver);
885{
886 int rval;
887
888 rval = i2c_add_driver(&as3645a_i2c_driver);
889 if (rval)
890 pr_err("%s: Failed to register the driver\n", AS3645A_NAME);
891
892 return rval;
893}
894
895static void __exit as3645a_exit(void)
896{
897 i2c_del_driver(&as3645a_i2c_driver);
898}
899
900module_init(as3645a_init);
901module_exit(as3645a_exit);
902 885
903MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); 886MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
904MODULE_DESCRIPTION("LED flash driver for AS3645A, LM3555 and their clones"); 887MODULE_DESCRIPTION("LED flash driver for AS3645A, LM3555 and their clones");
diff --git a/drivers/media/video/blackfin/Kconfig b/drivers/media/video/blackfin/Kconfig
new file mode 100644
index 000000000000..ecd5323768b7
--- /dev/null
+++ b/drivers/media/video/blackfin/Kconfig
@@ -0,0 +1,10 @@
1config VIDEO_BLACKFIN_CAPTURE
2 tristate "Blackfin Video Capture Driver"
3 depends on VIDEO_V4L2 && BLACKFIN && I2C
4 select VIDEOBUF2_DMA_CONTIG
5 help
6 V4L2 bridge driver for Blackfin video capture device.
7 Choose PPI or EPPI as its interface.
8
9 To compile this driver as a module, choose M here: the
10 module will be called bfin_video_capture.
diff --git a/drivers/media/video/blackfin/Makefile b/drivers/media/video/blackfin/Makefile
new file mode 100644
index 000000000000..aa3a0a216387
--- /dev/null
+++ b/drivers/media/video/blackfin/Makefile
@@ -0,0 +1,2 @@
1bfin_video_capture-objs := bfin_capture.o ppi.o
2obj-$(CONFIG_VIDEO_BLACKFIN_CAPTURE) += bfin_video_capture.o
diff --git a/drivers/media/video/blackfin/bfin_capture.c b/drivers/media/video/blackfin/bfin_capture.c
new file mode 100644
index 000000000000..514fcf742f5a
--- /dev/null
+++ b/drivers/media/video/blackfin/bfin_capture.c
@@ -0,0 +1,1059 @@
1/*
2 * Analog Devices video capture driver
3 *
4 * Copyright (c) 2011 Analog Devices Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * 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/completion.h>
21#include <linux/delay.h>
22#include <linux/errno.h>
23#include <linux/fs.h>
24#include <linux/i2c.h>
25#include <linux/init.h>
26#include <linux/interrupt.h>
27#include <linux/io.h>
28#include <linux/mm.h>
29#include <linux/module.h>
30#include <linux/platform_device.h>
31#include <linux/slab.h>
32#include <linux/time.h>
33#include <linux/types.h>
34
35#include <media/v4l2-chip-ident.h>
36#include <media/v4l2-common.h>
37#include <media/v4l2-ctrls.h>
38#include <media/v4l2-device.h>
39#include <media/v4l2-ioctl.h>
40#include <media/videobuf2-dma-contig.h>
41
42#include <asm/dma.h>
43
44#include <media/blackfin/bfin_capture.h>
45#include <media/blackfin/ppi.h>
46
47#define CAPTURE_DRV_NAME "bfin_capture"
48#define BCAP_MIN_NUM_BUF 2
49
50struct bcap_format {
51 char *desc;
52 u32 pixelformat;
53 enum v4l2_mbus_pixelcode mbus_code;
54 int bpp; /* bits per pixel */
55};
56
57struct bcap_buffer {
58 struct vb2_buffer vb;
59 struct list_head list;
60};
61
62struct bcap_device {
63 /* capture device instance */
64 struct v4l2_device v4l2_dev;
65 /* v4l2 control handler */
66 struct v4l2_ctrl_handler ctrl_handler;
67 /* device node data */
68 struct video_device *video_dev;
69 /* sub device instance */
70 struct v4l2_subdev *sd;
71 /* capture config */
72 struct bfin_capture_config *cfg;
73 /* ppi interface */
74 struct ppi_if *ppi;
75 /* current input */
76 unsigned int cur_input;
77 /* current selected standard */
78 v4l2_std_id std;
79 /* used to store pixel format */
80 struct v4l2_pix_format fmt;
81 /* bits per pixel*/
82 int bpp;
83 /* used to store sensor supported format */
84 struct bcap_format *sensor_formats;
85 /* number of sensor formats array */
86 int num_sensor_formats;
87 /* pointing to current video buffer */
88 struct bcap_buffer *cur_frm;
89 /* pointing to next video buffer */
90 struct bcap_buffer *next_frm;
91 /* buffer queue used in videobuf2 */
92 struct vb2_queue buffer_queue;
93 /* allocator-specific contexts for each plane */
94 struct vb2_alloc_ctx *alloc_ctx;
95 /* queue of filled frames */
96 struct list_head dma_queue;
97 /* used in videobuf2 callback */
98 spinlock_t lock;
99 /* used to access capture device */
100 struct mutex mutex;
101 /* used to wait ppi to complete one transfer */
102 struct completion comp;
103 /* prepare to stop */
104 bool stop;
105};
106
107struct bcap_fh {
108 struct v4l2_fh fh;
109 /* indicates whether this file handle is doing IO */
110 bool io_allowed;
111};
112
113static const struct bcap_format bcap_formats[] = {
114 {
115 .desc = "YCbCr 4:2:2 Interleaved UYVY",
116 .pixelformat = V4L2_PIX_FMT_UYVY,
117 .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8,
118 .bpp = 16,
119 },
120 {
121 .desc = "YCbCr 4:2:2 Interleaved YUYV",
122 .pixelformat = V4L2_PIX_FMT_YUYV,
123 .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
124 .bpp = 16,
125 },
126 {
127 .desc = "RGB 565",
128 .pixelformat = V4L2_PIX_FMT_RGB565,
129 .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE,
130 .bpp = 16,
131 },
132 {
133 .desc = "RGB 444",
134 .pixelformat = V4L2_PIX_FMT_RGB444,
135 .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE,
136 .bpp = 16,
137 },
138
139};
140#define BCAP_MAX_FMTS ARRAY_SIZE(bcap_formats)
141
142static irqreturn_t bcap_isr(int irq, void *dev_id);
143
144static struct bcap_buffer *to_bcap_vb(struct vb2_buffer *vb)
145{
146 return container_of(vb, struct bcap_buffer, vb);
147}
148
149static int bcap_init_sensor_formats(struct bcap_device *bcap_dev)
150{
151 enum v4l2_mbus_pixelcode code;
152 struct bcap_format *sf;
153 unsigned int num_formats = 0;
154 int i, j;
155
156 while (!v4l2_subdev_call(bcap_dev->sd, video,
157 enum_mbus_fmt, num_formats, &code))
158 num_formats++;
159 if (!num_formats)
160 return -ENXIO;
161
162 sf = kzalloc(num_formats * sizeof(*sf), GFP_KERNEL);
163 if (!sf)
164 return -ENOMEM;
165
166 for (i = 0; i < num_formats; i++) {
167 v4l2_subdev_call(bcap_dev->sd, video,
168 enum_mbus_fmt, i, &code);
169 for (j = 0; j < BCAP_MAX_FMTS; j++)
170 if (code == bcap_formats[j].mbus_code)
171 break;
172 if (j == BCAP_MAX_FMTS) {
173 /* we don't allow this sensor working with our bridge */
174 kfree(sf);
175 return -EINVAL;
176 }
177 sf[i] = bcap_formats[j];
178 }
179 bcap_dev->sensor_formats = sf;
180 bcap_dev->num_sensor_formats = num_formats;
181 return 0;
182}
183
184static void bcap_free_sensor_formats(struct bcap_device *bcap_dev)
185{
186 bcap_dev->num_sensor_formats = 0;
187 kfree(bcap_dev->sensor_formats);
188 bcap_dev->sensor_formats = NULL;
189}
190
191static int bcap_open(struct file *file)
192{
193 struct bcap_device *bcap_dev = video_drvdata(file);
194 struct video_device *vfd = bcap_dev->video_dev;
195 struct bcap_fh *bcap_fh;
196
197 if (!bcap_dev->sd) {
198 v4l2_err(&bcap_dev->v4l2_dev, "No sub device registered\n");
199 return -ENODEV;
200 }
201
202 bcap_fh = kzalloc(sizeof(*bcap_fh), GFP_KERNEL);
203 if (!bcap_fh) {
204 v4l2_err(&bcap_dev->v4l2_dev,
205 "unable to allocate memory for file handle object\n");
206 return -ENOMEM;
207 }
208
209 v4l2_fh_init(&bcap_fh->fh, vfd);
210
211 /* store pointer to v4l2_fh in private_data member of file */
212 file->private_data = &bcap_fh->fh;
213 v4l2_fh_add(&bcap_fh->fh);
214 bcap_fh->io_allowed = false;
215 return 0;
216}
217
218static int bcap_release(struct file *file)
219{
220 struct bcap_device *bcap_dev = video_drvdata(file);
221 struct v4l2_fh *fh = file->private_data;
222 struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh);
223
224 /* if this instance is doing IO */
225 if (bcap_fh->io_allowed)
226 vb2_queue_release(&bcap_dev->buffer_queue);
227
228 file->private_data = NULL;
229 v4l2_fh_del(&bcap_fh->fh);
230 v4l2_fh_exit(&bcap_fh->fh);
231 kfree(bcap_fh);
232 return 0;
233}
234
235static int bcap_mmap(struct file *file, struct vm_area_struct *vma)
236{
237 struct bcap_device *bcap_dev = video_drvdata(file);
238
239 return vb2_mmap(&bcap_dev->buffer_queue, vma);
240}
241
242#ifndef CONFIG_MMU
243static unsigned long bcap_get_unmapped_area(struct file *file,
244 unsigned long addr,
245 unsigned long len,
246 unsigned long pgoff,
247 unsigned long flags)
248{
249 struct bcap_device *bcap_dev = video_drvdata(file);
250
251 return vb2_get_unmapped_area(&bcap_dev->buffer_queue,
252 addr,
253 len,
254 pgoff,
255 flags);
256}
257#endif
258
259static unsigned int bcap_poll(struct file *file, poll_table *wait)
260{
261 struct bcap_device *bcap_dev = video_drvdata(file);
262
263 return vb2_poll(&bcap_dev->buffer_queue, file, wait);
264}
265
266static int bcap_queue_setup(struct vb2_queue *vq,
267 const struct v4l2_format *fmt,
268 unsigned int *nbuffers, unsigned int *nplanes,
269 unsigned int sizes[], void *alloc_ctxs[])
270{
271 struct bcap_device *bcap_dev = vb2_get_drv_priv(vq);
272
273 if (*nbuffers < BCAP_MIN_NUM_BUF)
274 *nbuffers = BCAP_MIN_NUM_BUF;
275
276 *nplanes = 1;
277 sizes[0] = bcap_dev->fmt.sizeimage;
278 alloc_ctxs[0] = bcap_dev->alloc_ctx;
279
280 return 0;
281}
282
283static int bcap_buffer_init(struct vb2_buffer *vb)
284{
285 struct bcap_buffer *buf = to_bcap_vb(vb);
286
287 INIT_LIST_HEAD(&buf->list);
288 return 0;
289}
290
291static int bcap_buffer_prepare(struct vb2_buffer *vb)
292{
293 struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue);
294 struct bcap_buffer *buf = to_bcap_vb(vb);
295 unsigned long size;
296
297 size = bcap_dev->fmt.sizeimage;
298 if (vb2_plane_size(vb, 0) < size) {
299 v4l2_err(&bcap_dev->v4l2_dev, "buffer too small (%lu < %lu)\n",
300 vb2_plane_size(vb, 0), size);
301 return -EINVAL;
302 }
303 vb2_set_plane_payload(&buf->vb, 0, size);
304
305 return 0;
306}
307
308static void bcap_buffer_queue(struct vb2_buffer *vb)
309{
310 struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue);
311 struct bcap_buffer *buf = to_bcap_vb(vb);
312 unsigned long flags;
313
314 spin_lock_irqsave(&bcap_dev->lock, flags);
315 list_add_tail(&buf->list, &bcap_dev->dma_queue);
316 spin_unlock_irqrestore(&bcap_dev->lock, flags);
317}
318
319static void bcap_buffer_cleanup(struct vb2_buffer *vb)
320{
321 struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue);
322 struct bcap_buffer *buf = to_bcap_vb(vb);
323 unsigned long flags;
324
325 spin_lock_irqsave(&bcap_dev->lock, flags);
326 list_del_init(&buf->list);
327 spin_unlock_irqrestore(&bcap_dev->lock, flags);
328}
329
330static void bcap_lock(struct vb2_queue *vq)
331{
332 struct bcap_device *bcap_dev = vb2_get_drv_priv(vq);
333 mutex_lock(&bcap_dev->mutex);
334}
335
336static void bcap_unlock(struct vb2_queue *vq)
337{
338 struct bcap_device *bcap_dev = vb2_get_drv_priv(vq);
339 mutex_unlock(&bcap_dev->mutex);
340}
341
342static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count)
343{
344 struct bcap_device *bcap_dev = vb2_get_drv_priv(vq);
345 struct ppi_if *ppi = bcap_dev->ppi;
346 struct ppi_params params;
347 int ret;
348
349 /* enable streamon on the sub device */
350 ret = v4l2_subdev_call(bcap_dev->sd, video, s_stream, 1);
351 if (ret && (ret != -ENOIOCTLCMD)) {
352 v4l2_err(&bcap_dev->v4l2_dev, "stream on failed in subdev\n");
353 return ret;
354 }
355
356 /* set ppi params */
357 params.width = bcap_dev->fmt.width;
358 params.height = bcap_dev->fmt.height;
359 params.bpp = bcap_dev->bpp;
360 params.ppi_control = bcap_dev->cfg->ppi_control;
361 params.int_mask = bcap_dev->cfg->int_mask;
362 params.blank_clocks = bcap_dev->cfg->blank_clocks;
363 ret = ppi->ops->set_params(ppi, &params);
364 if (ret < 0) {
365 v4l2_err(&bcap_dev->v4l2_dev,
366 "Error in setting ppi params\n");
367 return ret;
368 }
369
370 /* attach ppi DMA irq handler */
371 ret = ppi->ops->attach_irq(ppi, bcap_isr);
372 if (ret < 0) {
373 v4l2_err(&bcap_dev->v4l2_dev,
374 "Error in attaching interrupt handler\n");
375 return ret;
376 }
377
378 INIT_COMPLETION(bcap_dev->comp);
379 bcap_dev->stop = false;
380 return 0;
381}
382
383static int bcap_stop_streaming(struct vb2_queue *vq)
384{
385 struct bcap_device *bcap_dev = vb2_get_drv_priv(vq);
386 struct ppi_if *ppi = bcap_dev->ppi;
387 int ret;
388
389 if (!vb2_is_streaming(vq))
390 return 0;
391
392 bcap_dev->stop = true;
393 wait_for_completion(&bcap_dev->comp);
394 ppi->ops->stop(ppi);
395 ppi->ops->detach_irq(ppi);
396 ret = v4l2_subdev_call(bcap_dev->sd, video, s_stream, 0);
397 if (ret && (ret != -ENOIOCTLCMD))
398 v4l2_err(&bcap_dev->v4l2_dev,
399 "stream off failed in subdev\n");
400
401 /* release all active buffers */
402 while (!list_empty(&bcap_dev->dma_queue)) {
403 bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next,
404 struct bcap_buffer, list);
405 list_del(&bcap_dev->next_frm->list);
406 vb2_buffer_done(&bcap_dev->next_frm->vb, VB2_BUF_STATE_ERROR);
407 }
408 return 0;
409}
410
411static struct vb2_ops bcap_video_qops = {
412 .queue_setup = bcap_queue_setup,
413 .buf_init = bcap_buffer_init,
414 .buf_prepare = bcap_buffer_prepare,
415 .buf_cleanup = bcap_buffer_cleanup,
416 .buf_queue = bcap_buffer_queue,
417 .wait_prepare = bcap_unlock,
418 .wait_finish = bcap_lock,
419 .start_streaming = bcap_start_streaming,
420 .stop_streaming = bcap_stop_streaming,
421};
422
423static int bcap_reqbufs(struct file *file, void *priv,
424 struct v4l2_requestbuffers *req_buf)
425{
426 struct bcap_device *bcap_dev = video_drvdata(file);
427 struct vb2_queue *vq = &bcap_dev->buffer_queue;
428 struct v4l2_fh *fh = file->private_data;
429 struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh);
430
431 if (vb2_is_busy(vq))
432 return -EBUSY;
433
434 bcap_fh->io_allowed = true;
435
436 return vb2_reqbufs(vq, req_buf);
437}
438
439static int bcap_querybuf(struct file *file, void *priv,
440 struct v4l2_buffer *buf)
441{
442 struct bcap_device *bcap_dev = video_drvdata(file);
443
444 return vb2_querybuf(&bcap_dev->buffer_queue, buf);
445}
446
447static int bcap_qbuf(struct file *file, void *priv,
448 struct v4l2_buffer *buf)
449{
450 struct bcap_device *bcap_dev = video_drvdata(file);
451 struct v4l2_fh *fh = file->private_data;
452 struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh);
453
454 if (!bcap_fh->io_allowed)
455 return -EBUSY;
456
457 return vb2_qbuf(&bcap_dev->buffer_queue, buf);
458}
459
460static int bcap_dqbuf(struct file *file, void *priv,
461 struct v4l2_buffer *buf)
462{
463 struct bcap_device *bcap_dev = video_drvdata(file);
464 struct v4l2_fh *fh = file->private_data;
465 struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh);
466
467 if (!bcap_fh->io_allowed)
468 return -EBUSY;
469
470 return vb2_dqbuf(&bcap_dev->buffer_queue,
471 buf, file->f_flags & O_NONBLOCK);
472}
473
474static irqreturn_t bcap_isr(int irq, void *dev_id)
475{
476 struct ppi_if *ppi = dev_id;
477 struct bcap_device *bcap_dev = ppi->priv;
478 struct timeval timevalue;
479 struct vb2_buffer *vb = &bcap_dev->cur_frm->vb;
480 dma_addr_t addr;
481
482 spin_lock(&bcap_dev->lock);
483
484 if (bcap_dev->cur_frm != bcap_dev->next_frm) {
485 do_gettimeofday(&timevalue);
486 vb->v4l2_buf.timestamp = timevalue;
487 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
488 bcap_dev->cur_frm = bcap_dev->next_frm;
489 }
490
491 ppi->ops->stop(ppi);
492
493 if (bcap_dev->stop) {
494 complete(&bcap_dev->comp);
495 } else {
496 if (!list_empty(&bcap_dev->dma_queue)) {
497 bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next,
498 struct bcap_buffer, list);
499 list_del(&bcap_dev->next_frm->list);
500 addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->next_frm->vb, 0);
501 ppi->ops->update_addr(ppi, (unsigned long)addr);
502 }
503 ppi->ops->start(ppi);
504 }
505
506 spin_unlock(&bcap_dev->lock);
507
508 return IRQ_HANDLED;
509}
510
511static int bcap_streamon(struct file *file, void *priv,
512 enum v4l2_buf_type buf_type)
513{
514 struct bcap_device *bcap_dev = video_drvdata(file);
515 struct bcap_fh *fh = file->private_data;
516 struct ppi_if *ppi = bcap_dev->ppi;
517 dma_addr_t addr;
518 int ret;
519
520 if (!fh->io_allowed)
521 return -EBUSY;
522
523 /* call streamon to start streaming in videobuf */
524 ret = vb2_streamon(&bcap_dev->buffer_queue, buf_type);
525 if (ret)
526 return ret;
527
528 /* if dma queue is empty, return error */
529 if (list_empty(&bcap_dev->dma_queue)) {
530 v4l2_err(&bcap_dev->v4l2_dev, "dma queue is empty\n");
531 ret = -EINVAL;
532 goto err;
533 }
534
535 /* get the next frame from the dma queue */
536 bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next,
537 struct bcap_buffer, list);
538 bcap_dev->cur_frm = bcap_dev->next_frm;
539 /* remove buffer from the dma queue */
540 list_del(&bcap_dev->cur_frm->list);
541 addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0);
542 /* update DMA address */
543 ppi->ops->update_addr(ppi, (unsigned long)addr);
544 /* enable ppi */
545 ppi->ops->start(ppi);
546
547 return 0;
548err:
549 vb2_streamoff(&bcap_dev->buffer_queue, buf_type);
550 return ret;
551}
552
553static int bcap_streamoff(struct file *file, void *priv,
554 enum v4l2_buf_type buf_type)
555{
556 struct bcap_device *bcap_dev = video_drvdata(file);
557 struct bcap_fh *fh = file->private_data;
558
559 if (!fh->io_allowed)
560 return -EBUSY;
561
562 return vb2_streamoff(&bcap_dev->buffer_queue, buf_type);
563}
564
565static int bcap_querystd(struct file *file, void *priv, v4l2_std_id *std)
566{
567 struct bcap_device *bcap_dev = video_drvdata(file);
568
569 return v4l2_subdev_call(bcap_dev->sd, video, querystd, std);
570}
571
572static int bcap_g_std(struct file *file, void *priv, v4l2_std_id *std)
573{
574 struct bcap_device *bcap_dev = video_drvdata(file);
575
576 *std = bcap_dev->std;
577 return 0;
578}
579
580static int bcap_s_std(struct file *file, void *priv, v4l2_std_id *std)
581{
582 struct bcap_device *bcap_dev = video_drvdata(file);
583 int ret;
584
585 if (vb2_is_busy(&bcap_dev->buffer_queue))
586 return -EBUSY;
587
588 ret = v4l2_subdev_call(bcap_dev->sd, core, s_std, *std);
589 if (ret < 0)
590 return ret;
591
592 bcap_dev->std = *std;
593 return 0;
594}
595
596static int bcap_enum_input(struct file *file, void *priv,
597 struct v4l2_input *input)
598{
599 struct bcap_device *bcap_dev = video_drvdata(file);
600 struct bfin_capture_config *config = bcap_dev->cfg;
601 int ret;
602 u32 status;
603
604 if (input->index >= config->num_inputs)
605 return -EINVAL;
606
607 *input = config->inputs[input->index];
608 /* get input status */
609 ret = v4l2_subdev_call(bcap_dev->sd, video, g_input_status, &status);
610 if (!ret)
611 input->status = status;
612 return 0;
613}
614
615static int bcap_g_input(struct file *file, void *priv, unsigned int *index)
616{
617 struct bcap_device *bcap_dev = video_drvdata(file);
618
619 *index = bcap_dev->cur_input;
620 return 0;
621}
622
623static int bcap_s_input(struct file *file, void *priv, unsigned int index)
624{
625 struct bcap_device *bcap_dev = video_drvdata(file);
626 struct bfin_capture_config *config = bcap_dev->cfg;
627 struct bcap_route *route;
628 int ret;
629
630 if (vb2_is_busy(&bcap_dev->buffer_queue))
631 return -EBUSY;
632
633 if (index >= config->num_inputs)
634 return -EINVAL;
635
636 route = &config->routes[index];
637 ret = v4l2_subdev_call(bcap_dev->sd, video, s_routing,
638 route->input, route->output, 0);
639 if ((ret < 0) && (ret != -ENOIOCTLCMD)) {
640 v4l2_err(&bcap_dev->v4l2_dev, "Failed to set input\n");
641 return ret;
642 }
643 bcap_dev->cur_input = index;
644 return 0;
645}
646
647static int bcap_try_format(struct bcap_device *bcap,
648 struct v4l2_pix_format *pixfmt,
649 enum v4l2_mbus_pixelcode *mbus_code,
650 int *bpp)
651{
652 struct bcap_format *sf = bcap->sensor_formats;
653 struct bcap_format *fmt = NULL;
654 struct v4l2_mbus_framefmt mbus_fmt;
655 int ret, i;
656
657 for (i = 0; i < bcap->num_sensor_formats; i++) {
658 fmt = &sf[i];
659 if (pixfmt->pixelformat == fmt->pixelformat)
660 break;
661 }
662 if (i == bcap->num_sensor_formats)
663 fmt = &sf[0];
664
665 if (mbus_code)
666 *mbus_code = fmt->mbus_code;
667 if (bpp)
668 *bpp = fmt->bpp;
669 v4l2_fill_mbus_format(&mbus_fmt, pixfmt, fmt->mbus_code);
670 ret = v4l2_subdev_call(bcap->sd, video,
671 try_mbus_fmt, &mbus_fmt);
672 if (ret < 0)
673 return ret;
674 v4l2_fill_pix_format(pixfmt, &mbus_fmt);
675 pixfmt->bytesperline = pixfmt->width * fmt->bpp / 8;
676 pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
677 return 0;
678}
679
680static int bcap_enum_fmt_vid_cap(struct file *file, void *priv,
681 struct v4l2_fmtdesc *fmt)
682{
683 struct bcap_device *bcap_dev = video_drvdata(file);
684 struct bcap_format *sf = bcap_dev->sensor_formats;
685
686 if (fmt->index >= bcap_dev->num_sensor_formats)
687 return -EINVAL;
688
689 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
690 strlcpy(fmt->description,
691 sf[fmt->index].desc,
692 sizeof(fmt->description));
693 fmt->pixelformat = sf[fmt->index].pixelformat;
694 return 0;
695}
696
697static int bcap_try_fmt_vid_cap(struct file *file, void *priv,
698 struct v4l2_format *fmt)
699{
700 struct bcap_device *bcap_dev = video_drvdata(file);
701 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
702
703 return bcap_try_format(bcap_dev, pixfmt, NULL, NULL);
704}
705
706static int bcap_g_fmt_vid_cap(struct file *file, void *priv,
707 struct v4l2_format *fmt)
708{
709 struct bcap_device *bcap_dev = video_drvdata(file);
710
711 fmt->fmt.pix = bcap_dev->fmt;
712 return 0;
713}
714
715static int bcap_s_fmt_vid_cap(struct file *file, void *priv,
716 struct v4l2_format *fmt)
717{
718 struct bcap_device *bcap_dev = video_drvdata(file);
719 struct v4l2_mbus_framefmt mbus_fmt;
720 enum v4l2_mbus_pixelcode mbus_code;
721 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
722 int ret, bpp;
723
724 if (vb2_is_busy(&bcap_dev->buffer_queue))
725 return -EBUSY;
726
727 /* see if format works */
728 ret = bcap_try_format(bcap_dev, pixfmt, &mbus_code, &bpp);
729 if (ret < 0)
730 return ret;
731
732 v4l2_fill_mbus_format(&mbus_fmt, pixfmt, mbus_code);
733 ret = v4l2_subdev_call(bcap_dev->sd, video, s_mbus_fmt, &mbus_fmt);
734 if (ret < 0)
735 return ret;
736 bcap_dev->fmt = *pixfmt;
737 bcap_dev->bpp = bpp;
738 return 0;
739}
740
741static int bcap_querycap(struct file *file, void *priv,
742 struct v4l2_capability *cap)
743{
744 struct bcap_device *bcap_dev = video_drvdata(file);
745
746 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
747 strlcpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver));
748 strlcpy(cap->bus_info, "Blackfin Platform", sizeof(cap->bus_info));
749 strlcpy(cap->card, bcap_dev->cfg->card_name, sizeof(cap->card));
750 return 0;
751}
752
753static int bcap_g_parm(struct file *file, void *fh,
754 struct v4l2_streamparm *a)
755{
756 struct bcap_device *bcap_dev = video_drvdata(file);
757
758 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
759 return -EINVAL;
760 return v4l2_subdev_call(bcap_dev->sd, video, g_parm, a);
761}
762
763static int bcap_s_parm(struct file *file, void *fh,
764 struct v4l2_streamparm *a)
765{
766 struct bcap_device *bcap_dev = video_drvdata(file);
767
768 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
769 return -EINVAL;
770 return v4l2_subdev_call(bcap_dev->sd, video, s_parm, a);
771}
772
773static int bcap_g_chip_ident(struct file *file, void *priv,
774 struct v4l2_dbg_chip_ident *chip)
775{
776 struct bcap_device *bcap_dev = video_drvdata(file);
777
778 chip->ident = V4L2_IDENT_NONE;
779 chip->revision = 0;
780 if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
781 chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
782 return -EINVAL;
783
784 return v4l2_subdev_call(bcap_dev->sd, core,
785 g_chip_ident, chip);
786}
787
788#ifdef CONFIG_VIDEO_ADV_DEBUG
789static int bcap_dbg_g_register(struct file *file, void *priv,
790 struct v4l2_dbg_register *reg)
791{
792 struct bcap_device *bcap_dev = video_drvdata(file);
793
794 return v4l2_subdev_call(bcap_dev->sd, core,
795 g_register, reg);
796}
797
798static int bcap_dbg_s_register(struct file *file, void *priv,
799 struct v4l2_dbg_register *reg)
800{
801 struct bcap_device *bcap_dev = video_drvdata(file);
802
803 return v4l2_subdev_call(bcap_dev->sd, core,
804 s_register, reg);
805}
806#endif
807
808static int bcap_log_status(struct file *file, void *priv)
809{
810 struct bcap_device *bcap_dev = video_drvdata(file);
811 /* status for sub devices */
812 v4l2_device_call_all(&bcap_dev->v4l2_dev, 0, core, log_status);
813 return 0;
814}
815
816static const struct v4l2_ioctl_ops bcap_ioctl_ops = {
817 .vidioc_querycap = bcap_querycap,
818 .vidioc_g_fmt_vid_cap = bcap_g_fmt_vid_cap,
819 .vidioc_enum_fmt_vid_cap = bcap_enum_fmt_vid_cap,
820 .vidioc_s_fmt_vid_cap = bcap_s_fmt_vid_cap,
821 .vidioc_try_fmt_vid_cap = bcap_try_fmt_vid_cap,
822 .vidioc_enum_input = bcap_enum_input,
823 .vidioc_g_input = bcap_g_input,
824 .vidioc_s_input = bcap_s_input,
825 .vidioc_querystd = bcap_querystd,
826 .vidioc_s_std = bcap_s_std,
827 .vidioc_g_std = bcap_g_std,
828 .vidioc_reqbufs = bcap_reqbufs,
829 .vidioc_querybuf = bcap_querybuf,
830 .vidioc_qbuf = bcap_qbuf,
831 .vidioc_dqbuf = bcap_dqbuf,
832 .vidioc_streamon = bcap_streamon,
833 .vidioc_streamoff = bcap_streamoff,
834 .vidioc_g_parm = bcap_g_parm,
835 .vidioc_s_parm = bcap_s_parm,
836 .vidioc_g_chip_ident = bcap_g_chip_ident,
837#ifdef CONFIG_VIDEO_ADV_DEBUG
838 .vidioc_g_register = bcap_dbg_g_register,
839 .vidioc_s_register = bcap_dbg_s_register,
840#endif
841 .vidioc_log_status = bcap_log_status,
842};
843
844static struct v4l2_file_operations bcap_fops = {
845 .owner = THIS_MODULE,
846 .open = bcap_open,
847 .release = bcap_release,
848 .unlocked_ioctl = video_ioctl2,
849 .mmap = bcap_mmap,
850#ifndef CONFIG_MMU
851 .get_unmapped_area = bcap_get_unmapped_area,
852#endif
853 .poll = bcap_poll
854};
855
856static int __devinit bcap_probe(struct platform_device *pdev)
857{
858 struct bcap_device *bcap_dev;
859 struct video_device *vfd;
860 struct i2c_adapter *i2c_adap;
861 struct bfin_capture_config *config;
862 struct vb2_queue *q;
863 int ret;
864
865 config = pdev->dev.platform_data;
866 if (!config) {
867 v4l2_err(pdev->dev.driver, "Unable to get board config\n");
868 return -ENODEV;
869 }
870
871 bcap_dev = kzalloc(sizeof(*bcap_dev), GFP_KERNEL);
872 if (!bcap_dev) {
873 v4l2_err(pdev->dev.driver, "Unable to alloc bcap_dev\n");
874 return -ENOMEM;
875 }
876
877 bcap_dev->cfg = config;
878
879 bcap_dev->ppi = ppi_create_instance(config->ppi_info);
880 if (!bcap_dev->ppi) {
881 v4l2_err(pdev->dev.driver, "Unable to create ppi\n");
882 ret = -ENODEV;
883 goto err_free_dev;
884 }
885 bcap_dev->ppi->priv = bcap_dev;
886
887 bcap_dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
888 if (IS_ERR(bcap_dev->alloc_ctx)) {
889 ret = PTR_ERR(bcap_dev->alloc_ctx);
890 goto err_free_ppi;
891 }
892
893 vfd = video_device_alloc();
894 if (!vfd) {
895 ret = -ENOMEM;
896 v4l2_err(pdev->dev.driver, "Unable to alloc video device\n");
897 goto err_cleanup_ctx;
898 }
899
900 /* initialize field of video device */
901 vfd->release = video_device_release;
902 vfd->fops = &bcap_fops;
903 vfd->ioctl_ops = &bcap_ioctl_ops;
904 vfd->tvnorms = 0;
905 vfd->v4l2_dev = &bcap_dev->v4l2_dev;
906 set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
907 strncpy(vfd->name, CAPTURE_DRV_NAME, sizeof(vfd->name));
908 bcap_dev->video_dev = vfd;
909
910 ret = v4l2_device_register(&pdev->dev, &bcap_dev->v4l2_dev);
911 if (ret) {
912 v4l2_err(pdev->dev.driver,
913 "Unable to register v4l2 device\n");
914 goto err_release_vdev;
915 }
916 v4l2_info(&bcap_dev->v4l2_dev, "v4l2 device registered\n");
917
918 bcap_dev->v4l2_dev.ctrl_handler = &bcap_dev->ctrl_handler;
919 ret = v4l2_ctrl_handler_init(&bcap_dev->ctrl_handler, 0);
920 if (ret) {
921 v4l2_err(&bcap_dev->v4l2_dev,
922 "Unable to init control handler\n");
923 goto err_unreg_v4l2;
924 }
925
926 spin_lock_init(&bcap_dev->lock);
927 /* initialize queue */
928 q = &bcap_dev->buffer_queue;
929 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
930 q->io_modes = VB2_MMAP;
931 q->drv_priv = bcap_dev;
932 q->buf_struct_size = sizeof(struct bcap_buffer);
933 q->ops = &bcap_video_qops;
934 q->mem_ops = &vb2_dma_contig_memops;
935
936 vb2_queue_init(q);
937
938 mutex_init(&bcap_dev->mutex);
939 init_completion(&bcap_dev->comp);
940
941 /* init video dma queues */
942 INIT_LIST_HEAD(&bcap_dev->dma_queue);
943
944 vfd->lock = &bcap_dev->mutex;
945
946 /* register video device */
947 ret = video_register_device(bcap_dev->video_dev, VFL_TYPE_GRABBER, -1);
948 if (ret) {
949 v4l2_err(&bcap_dev->v4l2_dev,
950 "Unable to register video device\n");
951 goto err_free_handler;
952 }
953 video_set_drvdata(bcap_dev->video_dev, bcap_dev);
954 v4l2_info(&bcap_dev->v4l2_dev, "video device registered as: %s\n",
955 video_device_node_name(vfd));
956
957 /* load up the subdevice */
958 i2c_adap = i2c_get_adapter(config->i2c_adapter_id);
959 if (!i2c_adap) {
960 v4l2_err(&bcap_dev->v4l2_dev,
961 "Unable to find i2c adapter\n");
962 goto err_unreg_vdev;
963
964 }
965 bcap_dev->sd = v4l2_i2c_new_subdev_board(&bcap_dev->v4l2_dev,
966 i2c_adap,
967 &config->board_info,
968 NULL);
969 if (bcap_dev->sd) {
970 int i;
971 /* update tvnorms from the sub devices */
972 for (i = 0; i < config->num_inputs; i++)
973 vfd->tvnorms |= config->inputs[i].std;
974 } else {
975 v4l2_err(&bcap_dev->v4l2_dev,
976 "Unable to register sub device\n");
977 goto err_unreg_vdev;
978 }
979
980 v4l2_info(&bcap_dev->v4l2_dev, "v4l2 sub device registered\n");
981
982 /* now we can probe the default state */
983 if (vfd->tvnorms) {
984 v4l2_std_id std;
985 ret = v4l2_subdev_call(bcap_dev->sd, core, g_std, &std);
986 if (ret) {
987 v4l2_err(&bcap_dev->v4l2_dev,
988 "Unable to get std\n");
989 goto err_unreg_vdev;
990 }
991 bcap_dev->std = std;
992 }
993 ret = bcap_init_sensor_formats(bcap_dev);
994 if (ret) {
995 v4l2_err(&bcap_dev->v4l2_dev,
996 "Unable to create sensor formats table\n");
997 goto err_unreg_vdev;
998 }
999 return 0;
1000err_unreg_vdev:
1001 video_unregister_device(bcap_dev->video_dev);
1002 bcap_dev->video_dev = NULL;
1003err_free_handler:
1004 v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler);
1005err_unreg_v4l2:
1006 v4l2_device_unregister(&bcap_dev->v4l2_dev);
1007err_release_vdev:
1008 if (bcap_dev->video_dev)
1009 video_device_release(bcap_dev->video_dev);
1010err_cleanup_ctx:
1011 vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx);
1012err_free_ppi:
1013 ppi_delete_instance(bcap_dev->ppi);
1014err_free_dev:
1015 kfree(bcap_dev);
1016 return ret;
1017}
1018
1019static int __devexit bcap_remove(struct platform_device *pdev)
1020{
1021 struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
1022 struct bcap_device *bcap_dev = container_of(v4l2_dev,
1023 struct bcap_device, v4l2_dev);
1024
1025 bcap_free_sensor_formats(bcap_dev);
1026 video_unregister_device(bcap_dev->video_dev);
1027 v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler);
1028 v4l2_device_unregister(v4l2_dev);
1029 vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx);
1030 ppi_delete_instance(bcap_dev->ppi);
1031 kfree(bcap_dev);
1032 return 0;
1033}
1034
1035static struct platform_driver bcap_driver = {
1036 .driver = {
1037 .name = CAPTURE_DRV_NAME,
1038 .owner = THIS_MODULE,
1039 },
1040 .probe = bcap_probe,
1041 .remove = __devexit_p(bcap_remove),
1042};
1043
1044static __init int bcap_init(void)
1045{
1046 return platform_driver_register(&bcap_driver);
1047}
1048
1049static __exit void bcap_exit(void)
1050{
1051 platform_driver_unregister(&bcap_driver);
1052}
1053
1054module_init(bcap_init);
1055module_exit(bcap_exit);
1056
1057MODULE_DESCRIPTION("Analog Devices blackfin video capture driver");
1058MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>");
1059MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/blackfin/ppi.c b/drivers/media/video/blackfin/ppi.c
new file mode 100644
index 000000000000..d29592186b02
--- /dev/null
+++ b/drivers/media/video/blackfin/ppi.c
@@ -0,0 +1,271 @@
1/*
2 * ppi.c Analog Devices Parallel Peripheral Interface driver
3 *
4 * Copyright (c) 2011 Analog Devices Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * 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/slab.h>
21
22#include <asm/bfin_ppi.h>
23#include <asm/blackfin.h>
24#include <asm/cacheflush.h>
25#include <asm/dma.h>
26#include <asm/portmux.h>
27
28#include <media/blackfin/ppi.h>
29
30static int ppi_attach_irq(struct ppi_if *ppi, irq_handler_t handler);
31static void ppi_detach_irq(struct ppi_if *ppi);
32static int ppi_start(struct ppi_if *ppi);
33static int ppi_stop(struct ppi_if *ppi);
34static int ppi_set_params(struct ppi_if *ppi, struct ppi_params *params);
35static void ppi_update_addr(struct ppi_if *ppi, unsigned long addr);
36
37static const struct ppi_ops ppi_ops = {
38 .attach_irq = ppi_attach_irq,
39 .detach_irq = ppi_detach_irq,
40 .start = ppi_start,
41 .stop = ppi_stop,
42 .set_params = ppi_set_params,
43 .update_addr = ppi_update_addr,
44};
45
46static irqreturn_t ppi_irq_err(int irq, void *dev_id)
47{
48 struct ppi_if *ppi = dev_id;
49 const struct ppi_info *info = ppi->info;
50
51 switch (info->type) {
52 case PPI_TYPE_PPI:
53 {
54 struct bfin_ppi_regs *reg = info->base;
55 unsigned short status;
56
57 /* register on bf561 is cleared when read
58 * others are W1C
59 */
60 status = bfin_read16(&reg->status);
61 bfin_write16(&reg->status, 0xff00);
62 break;
63 }
64 case PPI_TYPE_EPPI:
65 {
66 struct bfin_eppi_regs *reg = info->base;
67 bfin_write16(&reg->status, 0xffff);
68 break;
69 }
70 default:
71 break;
72 }
73
74 return IRQ_HANDLED;
75}
76
77static int ppi_attach_irq(struct ppi_if *ppi, irq_handler_t handler)
78{
79 const struct ppi_info *info = ppi->info;
80 int ret;
81
82 ret = request_dma(info->dma_ch, "PPI_DMA");
83
84 if (ret) {
85 pr_err("Unable to allocate DMA channel for PPI\n");
86 return ret;
87 }
88 set_dma_callback(info->dma_ch, handler, ppi);
89
90 if (ppi->err_int) {
91 ret = request_irq(info->irq_err, ppi_irq_err, 0, "PPI ERROR", ppi);
92 if (ret) {
93 pr_err("Unable to allocate IRQ for PPI\n");
94 free_dma(info->dma_ch);
95 }
96 }
97 return ret;
98}
99
100static void ppi_detach_irq(struct ppi_if *ppi)
101{
102 const struct ppi_info *info = ppi->info;
103
104 if (ppi->err_int)
105 free_irq(info->irq_err, ppi);
106 free_dma(info->dma_ch);
107}
108
109static int ppi_start(struct ppi_if *ppi)
110{
111 const struct ppi_info *info = ppi->info;
112
113 /* enable DMA */
114 enable_dma(info->dma_ch);
115
116 /* enable PPI */
117 ppi->ppi_control |= PORT_EN;
118 switch (info->type) {
119 case PPI_TYPE_PPI:
120 {
121 struct bfin_ppi_regs *reg = info->base;
122 bfin_write16(&reg->control, ppi->ppi_control);
123 break;
124 }
125 case PPI_TYPE_EPPI:
126 {
127 struct bfin_eppi_regs *reg = info->base;
128 bfin_write32(&reg->control, ppi->ppi_control);
129 break;
130 }
131 default:
132 return -EINVAL;
133 }
134
135 SSYNC();
136 return 0;
137}
138
139static int ppi_stop(struct ppi_if *ppi)
140{
141 const struct ppi_info *info = ppi->info;
142
143 /* disable PPI */
144 ppi->ppi_control &= ~PORT_EN;
145 switch (info->type) {
146 case PPI_TYPE_PPI:
147 {
148 struct bfin_ppi_regs *reg = info->base;
149 bfin_write16(&reg->control, ppi->ppi_control);
150 break;
151 }
152 case PPI_TYPE_EPPI:
153 {
154 struct bfin_eppi_regs *reg = info->base;
155 bfin_write32(&reg->control, ppi->ppi_control);
156 break;
157 }
158 default:
159 return -EINVAL;
160 }
161
162 /* disable DMA */
163 clear_dma_irqstat(info->dma_ch);
164 disable_dma(info->dma_ch);
165
166 SSYNC();
167 return 0;
168}
169
170static int ppi_set_params(struct ppi_if *ppi, struct ppi_params *params)
171{
172 const struct ppi_info *info = ppi->info;
173 int dma32 = 0;
174 int dma_config, bytes_per_line, lines_per_frame;
175
176 bytes_per_line = params->width * params->bpp / 8;
177 lines_per_frame = params->height;
178 if (params->int_mask == 0xFFFFFFFF)
179 ppi->err_int = false;
180 else
181 ppi->err_int = true;
182
183 dma_config = (DMA_FLOW_STOP | WNR | RESTART | DMA2D | DI_EN);
184 ppi->ppi_control = params->ppi_control & ~PORT_EN;
185 switch (info->type) {
186 case PPI_TYPE_PPI:
187 {
188 struct bfin_ppi_regs *reg = info->base;
189
190 if (params->ppi_control & DMA32)
191 dma32 = 1;
192
193 bfin_write16(&reg->control, ppi->ppi_control);
194 bfin_write16(&reg->count, bytes_per_line - 1);
195 bfin_write16(&reg->frame, lines_per_frame);
196 break;
197 }
198 case PPI_TYPE_EPPI:
199 {
200 struct bfin_eppi_regs *reg = info->base;
201
202 if ((params->ppi_control & PACK_EN)
203 || (params->ppi_control & 0x38000) > DLEN_16)
204 dma32 = 1;
205
206 bfin_write32(&reg->control, ppi->ppi_control);
207 bfin_write16(&reg->line, bytes_per_line + params->blank_clocks);
208 bfin_write16(&reg->frame, lines_per_frame);
209 bfin_write16(&reg->hdelay, 0);
210 bfin_write16(&reg->vdelay, 0);
211 bfin_write16(&reg->hcount, bytes_per_line);
212 bfin_write16(&reg->vcount, lines_per_frame);
213 break;
214 }
215 default:
216 return -EINVAL;
217 }
218
219 if (dma32) {
220 dma_config |= WDSIZE_32;
221 set_dma_x_count(info->dma_ch, bytes_per_line >> 2);
222 set_dma_x_modify(info->dma_ch, 4);
223 set_dma_y_modify(info->dma_ch, 4);
224 } else {
225 dma_config |= WDSIZE_16;
226 set_dma_x_count(info->dma_ch, bytes_per_line >> 1);
227 set_dma_x_modify(info->dma_ch, 2);
228 set_dma_y_modify(info->dma_ch, 2);
229 }
230 set_dma_y_count(info->dma_ch, lines_per_frame);
231 set_dma_config(info->dma_ch, dma_config);
232
233 SSYNC();
234 return 0;
235}
236
237static void ppi_update_addr(struct ppi_if *ppi, unsigned long addr)
238{
239 set_dma_start_addr(ppi->info->dma_ch, addr);
240}
241
242struct ppi_if *ppi_create_instance(const struct ppi_info *info)
243{
244 struct ppi_if *ppi;
245
246 if (!info || !info->pin_req)
247 return NULL;
248
249 if (peripheral_request_list(info->pin_req, KBUILD_MODNAME)) {
250 pr_err("request peripheral failed\n");
251 return NULL;
252 }
253
254 ppi = kzalloc(sizeof(*ppi), GFP_KERNEL);
255 if (!ppi) {
256 peripheral_free_list(info->pin_req);
257 pr_err("unable to allocate memory for ppi handle\n");
258 return NULL;
259 }
260 ppi->ops = &ppi_ops;
261 ppi->info = info;
262
263 pr_info("ppi probe success\n");
264 return ppi;
265}
266
267void ppi_delete_instance(struct ppi_if *ppi)
268{
269 peripheral_free_list(ppi->info->pin_req);
270 kfree(ppi);
271}
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
index 859eabf57978..377bf05b1efd 100644
--- a/drivers/media/video/bt819.c
+++ b/drivers/media/video/bt819.c
@@ -514,15 +514,4 @@ static struct i2c_driver bt819_driver = {
514 .id_table = bt819_id, 514 .id_table = bt819_id,
515}; 515};
516 516
517static __init int init_bt819(void) 517module_i2c_driver(bt819_driver);
518{
519 return i2c_add_driver(&bt819_driver);
520}
521
522static __exit void exit_bt819(void)
523{
524 i2c_del_driver(&bt819_driver);
525}
526
527module_init(init_bt819);
528module_exit(exit_bt819);
diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c
index a43059d4c799..7e5bd365c239 100644
--- a/drivers/media/video/bt856.c
+++ b/drivers/media/video/bt856.c
@@ -270,15 +270,4 @@ static struct i2c_driver bt856_driver = {
270 .id_table = bt856_id, 270 .id_table = bt856_id,
271}; 271};
272 272
273static __init int init_bt856(void) 273module_i2c_driver(bt856_driver);
274{
275 return i2c_add_driver(&bt856_driver);
276}
277
278static __exit void exit_bt856(void)
279{
280 i2c_del_driver(&bt856_driver);
281}
282
283module_init(init_bt856);
284module_exit(exit_bt856);
diff --git a/drivers/media/video/bt866.c b/drivers/media/video/bt866.c
index 4e5dcea0501d..905320b67a1c 100644
--- a/drivers/media/video/bt866.c
+++ b/drivers/media/video/bt866.c
@@ -240,15 +240,4 @@ static struct i2c_driver bt866_driver = {
240 .id_table = bt866_id, 240 .id_table = bt866_id,
241}; 241};
242 242
243static __init int init_bt866(void) 243module_i2c_driver(bt866_driver);
244{
245 return i2c_add_driver(&bt866_driver);
246}
247
248static __exit void exit_bt866(void)
249{
250 i2c_del_driver(&bt866_driver);
251}
252
253module_init(init_bt866);
254module_exit(exit_bt866);
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 76c301f05095..e581b37be789 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -2035,11 +2035,7 @@ static int bttv_log_status(struct file *file, void *f)
2035 struct bttv_fh *fh = f; 2035 struct bttv_fh *fh = f;
2036 struct bttv *btv = fh->btv; 2036 struct bttv *btv = fh->btv;
2037 2037
2038 pr_info("%d: ======== START STATUS CARD #%d ========\n",
2039 btv->c.nr, btv->c.nr);
2040 bttv_call_all(btv, core, log_status); 2038 bttv_call_all(btv, core, log_status);
2041 pr_info("%d: ======== END STATUS CARD #%d ========\n",
2042 btv->c.nr, btv->c.nr);
2043 return 0; 2039 return 0;
2044} 2040}
2045 2041
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
index 1d64af9adf71..c8581e26fa9c 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/video/cs5345.c
@@ -249,15 +249,4 @@ static struct i2c_driver cs5345_driver = {
249 .id_table = cs5345_id, 249 .id_table = cs5345_id,
250}; 250};
251 251
252static __init int init_cs5345(void) 252module_i2c_driver(cs5345_driver);
253{
254 return i2c_add_driver(&cs5345_driver);
255}
256
257static __exit void exit_cs5345(void)
258{
259 i2c_del_driver(&cs5345_driver);
260}
261
262module_init(init_cs5345);
263module_exit(exit_cs5345);
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
index 51c5b9ad67d8..b293912206eb 100644
--- a/drivers/media/video/cs53l32a.c
+++ b/drivers/media/video/cs53l32a.c
@@ -248,15 +248,4 @@ static struct i2c_driver cs53l32a_driver = {
248 .id_table = cs53l32a_id, 248 .id_table = cs53l32a_id,
249}; 249};
250 250
251static __init int init_cs53l32a(void) 251module_i2c_driver(cs53l32a_driver);
252{
253 return i2c_add_driver(&cs53l32a_driver);
254}
255
256static __exit void exit_cs53l32a(void)
257{
258 i2c_del_driver(&cs53l32a_driver);
259}
260
261module_init(init_cs53l32a);
262module_exit(exit_cs53l32a);
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 349bd9c2aff5..b55d57cc1a1c 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -38,7 +38,7 @@
38#include "cx18-ioctl.h" 38#include "cx18-ioctl.h"
39#include "cx18-controls.h" 39#include "cx18-controls.h"
40#include "tuner-xc2028.h" 40#include "tuner-xc2028.h"
41 41#include <linux/dma-mapping.h>
42#include <media/tveeprom.h> 42#include <media/tveeprom.h>
43 43
44/* If you have already X v4l cards, then set this to X. This way 44/* If you have already X v4l cards, then set this to X. This way
@@ -75,7 +75,7 @@ static int radio[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
75 -1, -1, -1, -1, -1, -1, -1, -1 }; 75 -1, -1, -1, -1, -1, -1, -1, -1 };
76static unsigned cardtype_c = 1; 76static unsigned cardtype_c = 1;
77static unsigned tuner_c = 1; 77static unsigned tuner_c = 1;
78static bool radio_c = 1; 78static unsigned radio_c = 1;
79static char pal[] = "--"; 79static char pal[] = "--";
80static char secam[] = "--"; 80static char secam[] = "--";
81static char ntsc[] = "-"; 81static char ntsc[] = "-";
@@ -110,7 +110,7 @@ static int retry_mmio = 1;
110int cx18_debug; 110int cx18_debug;
111 111
112module_param_array(tuner, int, &tuner_c, 0644); 112module_param_array(tuner, int, &tuner_c, 0644);
113module_param_array(radio, bool, &radio_c, 0644); 113module_param_array(radio, int, &radio_c, 0644);
114module_param_array(cardtype, int, &cardtype_c, 0644); 114module_param_array(cardtype, int, &cardtype_c, 0644);
115module_param_string(pal, pal, sizeof(pal), 0644); 115module_param_string(pal, pal, sizeof(pal), 0644);
116module_param_string(secam, secam, sizeof(secam), 0644); 116module_param_string(secam, secam, sizeof(secam), 0644);
@@ -812,7 +812,7 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev,
812 CX18_ERR("Can't enable device %d!\n", cx->instance); 812 CX18_ERR("Can't enable device %d!\n", cx->instance);
813 return -EIO; 813 return -EIO;
814 } 814 }
815 if (pci_set_dma_mask(pci_dev, 0xffffffff)) { 815 if (pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32))) {
816 CX18_ERR("No suitable DMA available, card %d\n", cx->instance); 816 CX18_ERR("No suitable DMA available, card %d\n", cx->instance);
817 return -EIO; 817 return -EIO;
818 } 818 }
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index b9a94fc5146d..7a37e0ee136f 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -44,8 +44,6 @@
44#include <linux/slab.h> 44#include <linux/slab.h>
45#include <asm/byteorder.h> 45#include <asm/byteorder.h>
46 46
47#include <linux/dvb/video.h>
48#include <linux/dvb/audio.h>
49#include <media/v4l2-common.h> 47#include <media/v4l2-common.h>
50#include <media/v4l2-ioctl.h> 48#include <media/v4l2-ioctl.h>
51#include <media/v4l2-device.h> 49#include <media/v4l2-device.h>
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index 66b1c15c3541..be49f68ddf37 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -1085,8 +1085,6 @@ static int cx18_log_status(struct file *file, void *fh)
1085 struct v4l2_audio audin; 1085 struct v4l2_audio audin;
1086 int i; 1086 int i;
1087 1087
1088 CX18_INFO("================= START STATUS CARD #%d "
1089 "=================\n", cx->instance);
1090 CX18_INFO("Version: %s Card: %s\n", CX18_VERSION, cx->card_name); 1088 CX18_INFO("Version: %s Card: %s\n", CX18_VERSION, cx->card_name);
1091 if (cx->hw_flags & CX18_HW_TVEEPROM) { 1089 if (cx->hw_flags & CX18_HW_TVEEPROM) {
1092 struct tveeprom tv; 1090 struct tveeprom tv;
@@ -1120,8 +1118,6 @@ static int cx18_log_status(struct file *file, void *fh)
1120 CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n", 1118 CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
1121 (long long)cx->mpg_data_received, 1119 (long long)cx->mpg_data_received,
1122 (long long)cx->vbi_data_inserted); 1120 (long long)cx->vbi_data_inserted);
1123 CX18_INFO("================== END STATUS CARD #%d "
1124 "==================\n", cx->instance);
1125 return 0; 1121 return 0;
1126} 1122}
1127 1123
diff --git a/drivers/media/video/cx231xx/cx231xx-417.c b/drivers/media/video/cx231xx/cx231xx-417.c
index f8f0e59cd583..d4327dab5a36 100644
--- a/drivers/media/video/cx231xx/cx231xx-417.c
+++ b/drivers/media/video/cx231xx/cx231xx-417.c
@@ -1686,7 +1686,6 @@ static struct v4l2_capability pvr_capability = {
1686 .capabilities = (V4L2_CAP_VIDEO_CAPTURE | 1686 .capabilities = (V4L2_CAP_VIDEO_CAPTURE |
1687 V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | 1687 V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
1688 V4L2_CAP_STREAMING | V4L2_CAP_READWRITE), 1688 V4L2_CAP_STREAMING | V4L2_CAP_READWRITE),
1689 .reserved = {0, 0, 0, 0}
1690}; 1689};
1691static int vidioc_querycap(struct file *file, void *priv, 1690static int vidioc_querycap(struct file *file, void *priv,
1692 struct v4l2_capability *cap) 1691 struct v4l2_capability *cap)
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
index 875a7ce94736..8ed460d692e0 100644
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -861,7 +861,6 @@ void cx231xx_release_resources(struct cx231xx *dev)
861 kfree(dev->sliced_cc_mode.alt_max_pkt_size); 861 kfree(dev->sliced_cc_mode.alt_max_pkt_size);
862 kfree(dev->ts1_mode.alt_max_pkt_size); 862 kfree(dev->ts1_mode.alt_max_pkt_size);
863 kfree(dev); 863 kfree(dev);
864 dev = NULL;
865} 864}
866 865
867/* 866/*
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c
index 829a41b0c9ef..7f916f0685e9 100644
--- a/drivers/media/video/cx231xx/cx231xx-video.c
+++ b/drivers/media/video/cx231xx/cx231xx-video.c
@@ -2319,8 +2319,7 @@ static int cx231xx_v4l2_close(struct file *filp)
2319 if (dev->state & DEV_DISCONNECTED) { 2319 if (dev->state & DEV_DISCONNECTED) {
2320 if (atomic_read(&dev->devlist_count) > 0) { 2320 if (atomic_read(&dev->devlist_count) > 0) {
2321 cx231xx_release_resources(dev); 2321 cx231xx_release_resources(dev);
2322 kfree(dev); 2322 fh->dev = NULL;
2323 dev = NULL;
2324 return 0; 2323 return 0;
2325 } 2324 }
2326 return 0; 2325 return 0;
@@ -2350,8 +2349,7 @@ static int cx231xx_v4l2_close(struct file *filp)
2350 free the remaining resources */ 2349 free the remaining resources */
2351 if (dev->state & DEV_DISCONNECTED) { 2350 if (dev->state & DEV_DISCONNECTED) {
2352 cx231xx_release_resources(dev); 2351 cx231xx_release_resources(dev);
2353 kfree(dev); 2352 fh->dev = NULL;
2354 dev = NULL;
2355 return 0; 2353 return 0;
2356 } 2354 }
2357 2355
diff --git a/drivers/media/video/cx25821/cx25821-core.c b/drivers/media/video/cx25821/cx25821-core.c
index f617474f9073..7930ca58349f 100644
--- a/drivers/media/video/cx25821/cx25821-core.c
+++ b/drivers/media/video/cx25821/cx25821-core.c
@@ -1474,8 +1474,13 @@ static DEFINE_PCI_DEVICE_TABLE(cx25821_pci_tbl) = {
1474 .device = 0x8210, 1474 .device = 0x8210,
1475 .subvendor = 0x14f1, 1475 .subvendor = 0x14f1,
1476 .subdevice = 0x0920, 1476 .subdevice = 0x0920,
1477 }, 1477 }, {
1478 { 1478 /* CX25821 No Brand */
1479 .vendor = 0x14f1,
1480 .device = 0x8210,
1481 .subvendor = 0x0000,
1482 .subdevice = 0x0000,
1483 }, {
1479 /* --- end of list --- */ 1484 /* --- end of list --- */
1480 } 1485 }
1481}; 1486};
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 05247d4c340a..fc1ff69cffd0 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -5301,15 +5301,4 @@ static struct i2c_driver cx25840_driver = {
5301 .id_table = cx25840_id, 5301 .id_table = cx25840_id,
5302}; 5302};
5303 5303
5304static __init int init_cx25840(void) 5304module_i2c_driver(cx25840_driver);
5305{
5306 return i2c_add_driver(&cx25840_driver);
5307}
5308
5309static __exit void exit_cx25840(void)
5310{
5311 i2c_del_driver(&cx25840_driver);
5312}
5313
5314module_init(init_cx25840);
5315module_exit(exit_cx25840);
diff --git a/drivers/media/video/davinci/vpif.h b/drivers/media/video/davinci/vpif.h
index 25036cb11bea..8bcac65f9294 100644
--- a/drivers/media/video/davinci/vpif.h
+++ b/drivers/media/video/davinci/vpif.h
@@ -18,8 +18,6 @@
18 18
19#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/videodev2.h> 20#include <linux/videodev2.h>
21#include <mach/hardware.h>
22#include <mach/dm646x.h>
23#include <media/davinci/vpif_types.h> 21#include <media/davinci/vpif_types.h>
24 22
25/* Maximum channel allowed */ 23/* Maximum channel allowed */
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c
index 286f02910044..7fa34b4fae26 100644
--- a/drivers/media/video/davinci/vpif_display.c
+++ b/drivers/media/video/davinci/vpif_display.c
@@ -39,8 +39,6 @@
39#include <media/v4l2-ioctl.h> 39#include <media/v4l2-ioctl.h>
40#include <media/v4l2-chip-ident.h> 40#include <media/v4l2-chip-ident.h>
41 41
42#include <mach/dm646x.h>
43
44#include "vpif_display.h" 42#include "vpif_display.h"
45#include "vpif.h" 43#include "vpif.h"
46 44
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 4561cd89938d..9fd8cc7dbb23 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -353,6 +353,44 @@ static struct em28xx_reg_seq hauppauge_930c_digital[] = {
353}; 353};
354#endif 354#endif
355 355
356/* 1b80:e425 MaxMedia UB425-TC
357 * GPIO_6 - demod reset, 0=active
358 * GPIO_7 - LED, 0=active
359 */
360static struct em28xx_reg_seq maxmedia_ub425_tc[] = {
361 {EM2874_R80_GPIO, 0x83, 0xff, 100},
362 {EM2874_R80_GPIO, 0xc3, 0xff, 100}, /* GPIO_6 = 1 */
363 {EM2874_R80_GPIO, 0x43, 0xff, 000}, /* GPIO_7 = 0 */
364 {-1, -1, -1, -1},
365};
366
367/* 2304:0242 PCTV QuatroStick (510e)
368 * GPIO_2: decoder reset, 0=active
369 * GPIO_4: decoder suspend, 0=active
370 * GPIO_6: demod reset, 0=active
371 * GPIO_7: LED, 1=active
372 */
373static struct em28xx_reg_seq pctv_510e[] = {
374 {EM2874_R80_GPIO, 0x10, 0xff, 100},
375 {EM2874_R80_GPIO, 0x14, 0xff, 100}, /* GPIO_2 = 1 */
376 {EM2874_R80_GPIO, 0x54, 0xff, 050}, /* GPIO_6 = 1 */
377 { -1, -1, -1, -1},
378};
379
380/* 2013:0251 PCTV QuatroStick nano (520e)
381 * GPIO_2: decoder reset, 0=active
382 * GPIO_4: decoder suspend, 0=active
383 * GPIO_6: demod reset, 0=active
384 * GPIO_7: LED, 1=active
385 */
386static struct em28xx_reg_seq pctv_520e[] = {
387 {EM2874_R80_GPIO, 0x10, 0xff, 100},
388 {EM2874_R80_GPIO, 0x14, 0xff, 100}, /* GPIO_2 = 1 */
389 {EM2874_R80_GPIO, 0x54, 0xff, 050}, /* GPIO_6 = 1 */
390 {EM2874_R80_GPIO, 0xd4, 0xff, 000}, /* GPIO_7 = 1 */
391 { -1, -1, -1, -1},
392};
393
356/* 394/*
357 * Board definitions 395 * Board definitions
358 */ 396 */
@@ -1908,6 +1946,41 @@ struct em28xx_board em28xx_boards[] = {
1908 .amux = EM28XX_AMUX_LINE_IN, 1946 .amux = EM28XX_AMUX_LINE_IN,
1909 } }, 1947 } },
1910 }, 1948 },
1949 /* 1b80:e425 MaxMedia UB425-TC
1950 * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2 */
1951 [EM2874_BOARD_MAXMEDIA_UB425_TC] = {
1952 .name = "MaxMedia UB425-TC",
1953 .tuner_type = TUNER_ABSENT,
1954 .tuner_gpio = maxmedia_ub425_tc,
1955 .has_dvb = 1,
1956 .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT |
1957 EM28XX_I2C_CLK_WAIT_ENABLE |
1958 EM28XX_I2C_FREQ_400_KHZ,
1959 },
1960 /* 2304:0242 PCTV QuatroStick (510e)
1961 * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2 */
1962 [EM2884_BOARD_PCTV_510E] = {
1963 .name = "PCTV QuatroStick (510e)",
1964 .tuner_type = TUNER_ABSENT,
1965 .tuner_gpio = pctv_510e,
1966 .has_dvb = 1,
1967 .ir_codes = RC_MAP_PINNACLE_PCTV_HD,
1968 .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT |
1969 EM28XX_I2C_CLK_WAIT_ENABLE |
1970 EM28XX_I2C_FREQ_400_KHZ,
1971 },
1972 /* 2013:0251 PCTV QuatroStick nano (520e)
1973 * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2 */
1974 [EM2884_BOARD_PCTV_520E] = {
1975 .name = "PCTV QuatroStick nano (520e)",
1976 .tuner_type = TUNER_ABSENT,
1977 .tuner_gpio = pctv_520e,
1978 .has_dvb = 1,
1979 .ir_codes = RC_MAP_PINNACLE_PCTV_HD,
1980 .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT |
1981 EM28XX_I2C_CLK_WAIT_ENABLE |
1982 EM28XX_I2C_FREQ_400_KHZ,
1983 },
1911}; 1984};
1912const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); 1985const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
1913 1986
@@ -2059,6 +2132,12 @@ struct usb_device_id em28xx_id_table[] = {
2059 .driver_info = EM2860_BOARD_HT_VIDBOX_NW03 }, 2132 .driver_info = EM2860_BOARD_HT_VIDBOX_NW03 },
2060 { USB_DEVICE(0x1b80, 0xe309), /* Sveon STV40 */ 2133 { USB_DEVICE(0x1b80, 0xe309), /* Sveon STV40 */
2061 .driver_info = EM2860_BOARD_EASYCAP }, 2134 .driver_info = EM2860_BOARD_EASYCAP },
2135 { USB_DEVICE(0x1b80, 0xe425),
2136 .driver_info = EM2874_BOARD_MAXMEDIA_UB425_TC },
2137 { USB_DEVICE(0x2304, 0x0242),
2138 .driver_info = EM2884_BOARD_PCTV_510E },
2139 { USB_DEVICE(0x2013, 0x0251),
2140 .driver_info = EM2884_BOARD_PCTV_520E },
2062 { }, 2141 { },
2063}; 2142};
2064MODULE_DEVICE_TABLE(usb, em28xx_id_table); 2143MODULE_DEVICE_TABLE(usb, em28xx_id_table);
@@ -3122,7 +3201,6 @@ static int em28xx_usb_probe(struct usb_interface *interface,
3122 int i, nr; 3201 int i, nr;
3123 const int ifnum = interface->altsetting[0].desc.bInterfaceNumber; 3202 const int ifnum = interface->altsetting[0].desc.bInterfaceNumber;
3124 char *speed; 3203 char *speed;
3125 char descr[255] = "";
3126 3204
3127 udev = usb_get_dev(interface_to_usbdev(interface)); 3205 udev = usb_get_dev(interface_to_usbdev(interface));
3128 3206
@@ -3227,21 +3305,11 @@ static int em28xx_usb_probe(struct usb_interface *interface,
3227 speed = "unknown"; 3305 speed = "unknown";
3228 } 3306 }
3229 3307
3230 if (udev->manufacturer)
3231 strlcpy(descr, udev->manufacturer, sizeof(descr));
3232
3233 if (udev->product) {
3234 if (*descr)
3235 strlcat(descr, " ", sizeof(descr));
3236 strlcat(descr, udev->product, sizeof(descr));
3237 }
3238
3239 if (*descr)
3240 strlcat(descr, " ", sizeof(descr));
3241
3242 printk(KERN_INFO DRIVER_NAME 3308 printk(KERN_INFO DRIVER_NAME
3243 ": New device %s@ %s Mbps (%04x:%04x, interface %d, class %d)\n", 3309 ": New device %s %s @ %s Mbps "
3244 descr, 3310 "(%04x:%04x, interface %d, class %d)\n",
3311 udev->manufacturer ? udev->manufacturer : "",
3312 udev->product ? udev->product : "",
3245 speed, 3313 speed,
3246 le16_to_cpu(udev->descriptor.idVendor), 3314 le16_to_cpu(udev->descriptor.idVendor),
3247 le16_to_cpu(udev->descriptor.idProduct), 3315 le16_to_cpu(udev->descriptor.idProduct),
@@ -3307,6 +3375,17 @@ static int em28xx_usb_probe(struct usb_interface *interface,
3307 goto unlock_and_free; 3375 goto unlock_and_free;
3308 } 3376 }
3309 3377
3378 if (has_dvb) {
3379 /* pre-allocate DVB isoc transfer buffers */
3380 retval = em28xx_alloc_isoc(dev, EM28XX_DIGITAL_MODE,
3381 EM28XX_DVB_MAX_PACKETS,
3382 EM28XX_DVB_NUM_BUFS,
3383 dev->dvb_max_pkt_size);
3384 if (retval) {
3385 goto unlock_and_free;
3386 }
3387 }
3388
3310 request_modules(dev); 3389 request_modules(dev);
3311 3390
3312 /* Should be the last thing to do, to avoid newer udev's to 3391 /* Should be the last thing to do, to avoid newer udev's to
@@ -3379,7 +3458,7 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
3379 video_device_node_name(dev->vdev)); 3458 video_device_node_name(dev->vdev));
3380 3459
3381 dev->state |= DEV_MISCONFIGURED; 3460 dev->state |= DEV_MISCONFIGURED;
3382 em28xx_uninit_isoc(dev); 3461 em28xx_uninit_isoc(dev, dev->mode);
3383 dev->state |= DEV_DISCONNECTED; 3462 dev->state |= DEV_DISCONNECTED;
3384 wake_up_interruptible(&dev->wait_frame); 3463 wake_up_interruptible(&dev->wait_frame);
3385 wake_up_interruptible(&dev->wait_stream); 3464 wake_up_interruptible(&dev->wait_stream);
@@ -3388,6 +3467,9 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
3388 em28xx_release_resources(dev); 3467 em28xx_release_resources(dev);
3389 } 3468 }
3390 3469
3470 /* free DVB isoc buffers */
3471 em28xx_uninit_isoc(dev, EM28XX_DIGITAL_MODE);
3472
3391 mutex_unlock(&dev->lock); 3473 mutex_unlock(&dev->lock);
3392 3474
3393 em28xx_close_extension(dev); 3475 em28xx_close_extension(dev);
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 0aacc96f9a23..53a9fb91e97e 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -666,6 +666,7 @@ int em28xx_capture_start(struct em28xx *dev, int start)
666 666
667 return rc; 667 return rc;
668} 668}
669EXPORT_SYMBOL_GPL(em28xx_capture_start);
669 670
670int em28xx_vbi_supported(struct em28xx *dev) 671int em28xx_vbi_supported(struct em28xx *dev)
671{ 672{
@@ -961,146 +962,192 @@ static void em28xx_irq_callback(struct urb *urb)
961/* 962/*
962 * Stop and Deallocate URBs 963 * Stop and Deallocate URBs
963 */ 964 */
964void em28xx_uninit_isoc(struct em28xx *dev) 965void em28xx_uninit_isoc(struct em28xx *dev, enum em28xx_mode mode)
965{ 966{
966 struct urb *urb; 967 struct urb *urb;
968 struct em28xx_usb_isoc_bufs *isoc_bufs;
967 int i; 969 int i;
968 970
969 em28xx_isocdbg("em28xx: called em28xx_uninit_isoc\n"); 971 em28xx_isocdbg("em28xx: called em28xx_uninit_isoc in mode %d\n", mode);
972
973 if (mode == EM28XX_DIGITAL_MODE)
974 isoc_bufs = &dev->isoc_ctl.digital_bufs;
975 else
976 isoc_bufs = &dev->isoc_ctl.analog_bufs;
970 977
971 dev->isoc_ctl.nfields = -1; 978 dev->isoc_ctl.nfields = -1;
972 for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { 979 for (i = 0; i < isoc_bufs->num_bufs; i++) {
973 urb = dev->isoc_ctl.urb[i]; 980 urb = isoc_bufs->urb[i];
974 if (urb) { 981 if (urb) {
975 if (!irqs_disabled()) 982 if (!irqs_disabled())
976 usb_kill_urb(urb); 983 usb_kill_urb(urb);
977 else 984 else
978 usb_unlink_urb(urb); 985 usb_unlink_urb(urb);
979 986
980 if (dev->isoc_ctl.transfer_buffer[i]) { 987 if (isoc_bufs->transfer_buffer[i]) {
981 usb_free_coherent(dev->udev, 988 usb_free_coherent(dev->udev,
982 urb->transfer_buffer_length, 989 urb->transfer_buffer_length,
983 dev->isoc_ctl.transfer_buffer[i], 990 isoc_bufs->transfer_buffer[i],
984 urb->transfer_dma); 991 urb->transfer_dma);
985 } 992 }
986 usb_free_urb(urb); 993 usb_free_urb(urb);
987 dev->isoc_ctl.urb[i] = NULL; 994 isoc_bufs->urb[i] = NULL;
988 } 995 }
989 dev->isoc_ctl.transfer_buffer[i] = NULL; 996 isoc_bufs->transfer_buffer[i] = NULL;
990 } 997 }
991 998
992 kfree(dev->isoc_ctl.urb); 999 kfree(isoc_bufs->urb);
993 kfree(dev->isoc_ctl.transfer_buffer); 1000 kfree(isoc_bufs->transfer_buffer);
994 1001
995 dev->isoc_ctl.urb = NULL; 1002 isoc_bufs->urb = NULL;
996 dev->isoc_ctl.transfer_buffer = NULL; 1003 isoc_bufs->transfer_buffer = NULL;
997 dev->isoc_ctl.num_bufs = 0; 1004 isoc_bufs->num_bufs = 0;
998 1005
999 em28xx_capture_start(dev, 0); 1006 em28xx_capture_start(dev, 0);
1000} 1007}
1001EXPORT_SYMBOL_GPL(em28xx_uninit_isoc); 1008EXPORT_SYMBOL_GPL(em28xx_uninit_isoc);
1002 1009
1003/* 1010/*
1004 * Allocate URBs and start IRQ 1011 * Allocate URBs
1005 */ 1012 */
1006int em28xx_init_isoc(struct em28xx *dev, int max_packets, 1013int em28xx_alloc_isoc(struct em28xx *dev, enum em28xx_mode mode,
1007 int num_bufs, int max_pkt_size, 1014 int max_packets, int num_bufs, int max_pkt_size)
1008 int (*isoc_copy) (struct em28xx *dev, struct urb *urb))
1009{ 1015{
1010 struct em28xx_dmaqueue *dma_q = &dev->vidq; 1016 struct em28xx_usb_isoc_bufs *isoc_bufs;
1011 struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq;
1012 int i; 1017 int i;
1013 int sb_size, pipe; 1018 int sb_size, pipe;
1014 struct urb *urb; 1019 struct urb *urb;
1015 int j, k; 1020 int j, k;
1016 int rc;
1017 1021
1018 em28xx_isocdbg("em28xx: called em28xx_prepare_isoc\n"); 1022 em28xx_isocdbg("em28xx: called em28xx_alloc_isoc in mode %d\n", mode);
1023
1024 if (mode == EM28XX_DIGITAL_MODE)
1025 isoc_bufs = &dev->isoc_ctl.digital_bufs;
1026 else
1027 isoc_bufs = &dev->isoc_ctl.analog_bufs;
1019 1028
1020 /* De-allocates all pending stuff */ 1029 /* De-allocates all pending stuff */
1021 em28xx_uninit_isoc(dev); 1030 em28xx_uninit_isoc(dev, mode);
1022 1031
1023 dev->isoc_ctl.isoc_copy = isoc_copy; 1032 isoc_bufs->num_bufs = num_bufs;
1024 dev->isoc_ctl.num_bufs = num_bufs;
1025 1033
1026 dev->isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL); 1034 isoc_bufs->urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL);
1027 if (!dev->isoc_ctl.urb) { 1035 if (!isoc_bufs->urb) {
1028 em28xx_errdev("cannot alloc memory for usb buffers\n"); 1036 em28xx_errdev("cannot alloc memory for usb buffers\n");
1029 return -ENOMEM; 1037 return -ENOMEM;
1030 } 1038 }
1031 1039
1032 dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs, 1040 isoc_bufs->transfer_buffer = kzalloc(sizeof(void *)*num_bufs,
1033 GFP_KERNEL); 1041 GFP_KERNEL);
1034 if (!dev->isoc_ctl.transfer_buffer) { 1042 if (!isoc_bufs->transfer_buffer) {
1035 em28xx_errdev("cannot allocate memory for usb transfer\n"); 1043 em28xx_errdev("cannot allocate memory for usb transfer\n");
1036 kfree(dev->isoc_ctl.urb); 1044 kfree(isoc_bufs->urb);
1037 return -ENOMEM; 1045 return -ENOMEM;
1038 } 1046 }
1039 1047
1040 dev->isoc_ctl.max_pkt_size = max_pkt_size; 1048 isoc_bufs->max_pkt_size = max_pkt_size;
1049 isoc_bufs->num_packets = max_packets;
1041 dev->isoc_ctl.vid_buf = NULL; 1050 dev->isoc_ctl.vid_buf = NULL;
1042 dev->isoc_ctl.vbi_buf = NULL; 1051 dev->isoc_ctl.vbi_buf = NULL;
1043 1052
1044 sb_size = max_packets * dev->isoc_ctl.max_pkt_size; 1053 sb_size = isoc_bufs->num_packets * isoc_bufs->max_pkt_size;
1045 1054
1046 /* allocate urbs and transfer buffers */ 1055 /* allocate urbs and transfer buffers */
1047 for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { 1056 for (i = 0; i < isoc_bufs->num_bufs; i++) {
1048 urb = usb_alloc_urb(max_packets, GFP_KERNEL); 1057 urb = usb_alloc_urb(isoc_bufs->num_packets, GFP_KERNEL);
1049 if (!urb) { 1058 if (!urb) {
1050 em28xx_err("cannot alloc isoc_ctl.urb %i\n", i); 1059 em28xx_err("cannot alloc isoc_ctl.urb %i\n", i);
1051 em28xx_uninit_isoc(dev); 1060 em28xx_uninit_isoc(dev, mode);
1052 return -ENOMEM; 1061 return -ENOMEM;
1053 } 1062 }
1054 dev->isoc_ctl.urb[i] = urb; 1063 isoc_bufs->urb[i] = urb;
1055 1064
1056 dev->isoc_ctl.transfer_buffer[i] = usb_alloc_coherent(dev->udev, 1065 isoc_bufs->transfer_buffer[i] = usb_alloc_coherent(dev->udev,
1057 sb_size, GFP_KERNEL, &urb->transfer_dma); 1066 sb_size, GFP_KERNEL, &urb->transfer_dma);
1058 if (!dev->isoc_ctl.transfer_buffer[i]) { 1067 if (!isoc_bufs->transfer_buffer[i]) {
1059 em28xx_err("unable to allocate %i bytes for transfer" 1068 em28xx_err("unable to allocate %i bytes for transfer"
1060 " buffer %i%s\n", 1069 " buffer %i%s\n",
1061 sb_size, i, 1070 sb_size, i,
1062 in_interrupt() ? " while in int" : ""); 1071 in_interrupt() ? " while in int" : "");
1063 em28xx_uninit_isoc(dev); 1072 em28xx_uninit_isoc(dev, mode);
1064 return -ENOMEM; 1073 return -ENOMEM;
1065 } 1074 }
1066 memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size); 1075 memset(isoc_bufs->transfer_buffer[i], 0, sb_size);
1067 1076
1068 /* FIXME: this is a hack - should be 1077 /* FIXME: this is a hack - should be
1069 'desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK' 1078 'desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK'
1070 should also be using 'desc.bInterval' 1079 should also be using 'desc.bInterval'
1071 */ 1080 */
1072 pipe = usb_rcvisocpipe(dev->udev, 1081 pipe = usb_rcvisocpipe(dev->udev,
1073 dev->mode == EM28XX_ANALOG_MODE ? 1082 mode == EM28XX_ANALOG_MODE ?
1074 EM28XX_EP_ANALOG : EM28XX_EP_DIGITAL); 1083 EM28XX_EP_ANALOG : EM28XX_EP_DIGITAL);
1075 1084
1076 usb_fill_int_urb(urb, dev->udev, pipe, 1085 usb_fill_int_urb(urb, dev->udev, pipe,
1077 dev->isoc_ctl.transfer_buffer[i], sb_size, 1086 isoc_bufs->transfer_buffer[i], sb_size,
1078 em28xx_irq_callback, dev, 1); 1087 em28xx_irq_callback, dev, 1);
1079 1088
1080 urb->number_of_packets = max_packets; 1089 urb->number_of_packets = isoc_bufs->num_packets;
1081 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; 1090 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
1082 1091
1083 k = 0; 1092 k = 0;
1084 for (j = 0; j < max_packets; j++) { 1093 for (j = 0; j < isoc_bufs->num_packets; j++) {
1085 urb->iso_frame_desc[j].offset = k; 1094 urb->iso_frame_desc[j].offset = k;
1086 urb->iso_frame_desc[j].length = 1095 urb->iso_frame_desc[j].length =
1087 dev->isoc_ctl.max_pkt_size; 1096 isoc_bufs->max_pkt_size;
1088 k += dev->isoc_ctl.max_pkt_size; 1097 k += isoc_bufs->max_pkt_size;
1089 } 1098 }
1090 } 1099 }
1091 1100
1101 return 0;
1102}
1103EXPORT_SYMBOL_GPL(em28xx_alloc_isoc);
1104
1105/*
1106 * Allocate URBs and start IRQ
1107 */
1108int em28xx_init_isoc(struct em28xx *dev, enum em28xx_mode mode,
1109 int max_packets, int num_bufs, int max_pkt_size,
1110 int (*isoc_copy) (struct em28xx *dev, struct urb *urb))
1111{
1112 struct em28xx_dmaqueue *dma_q = &dev->vidq;
1113 struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq;
1114 struct em28xx_usb_isoc_bufs *isoc_bufs;
1115 int i;
1116 int rc;
1117 int alloc;
1118
1119 em28xx_isocdbg("em28xx: called em28xx_init_isoc in mode %d\n", mode);
1120
1121 dev->isoc_ctl.isoc_copy = isoc_copy;
1122
1123 if (mode == EM28XX_DIGITAL_MODE) {
1124 isoc_bufs = &dev->isoc_ctl.digital_bufs;
1125 /* no need to free/alloc isoc buffers in digital mode */
1126 alloc = 0;
1127 } else {
1128 isoc_bufs = &dev->isoc_ctl.analog_bufs;
1129 alloc = 1;
1130 }
1131
1132 if (alloc) {
1133 rc = em28xx_alloc_isoc(dev, mode, max_packets,
1134 num_bufs, max_pkt_size);
1135 if (rc)
1136 return rc;
1137 }
1138
1092 init_waitqueue_head(&dma_q->wq); 1139 init_waitqueue_head(&dma_q->wq);
1093 init_waitqueue_head(&vbi_dma_q->wq); 1140 init_waitqueue_head(&vbi_dma_q->wq);
1094 1141
1095 em28xx_capture_start(dev, 1); 1142 em28xx_capture_start(dev, 1);
1096 1143
1097 /* submit urbs and enables IRQ */ 1144 /* submit urbs and enables IRQ */
1098 for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { 1145 for (i = 0; i < isoc_bufs->num_bufs; i++) {
1099 rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC); 1146 rc = usb_submit_urb(isoc_bufs->urb[i], GFP_ATOMIC);
1100 if (rc) { 1147 if (rc) {
1101 em28xx_err("submit of urb %i failed (error=%i)\n", i, 1148 em28xx_err("submit of urb %i failed (error=%i)\n", i,
1102 rc); 1149 rc);
1103 em28xx_uninit_isoc(dev); 1150 em28xx_uninit_isoc(dev, mode);
1104 return rc; 1151 return rc;
1105 } 1152 }
1106 } 1153 }
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index aabbf4854f66..503a8d5b5382 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -61,9 +61,6 @@ if (debug >= level) \
61 printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->name, ## arg); \ 61 printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->name, ## arg); \
62} while (0) 62} while (0)
63 63
64#define EM28XX_DVB_NUM_BUFS 5
65#define EM28XX_DVB_MAX_PACKETS 64
66
67struct em28xx_dvb { 64struct em28xx_dvb {
68 struct dvb_frontend *fe[2]; 65 struct dvb_frontend *fe[2];
69 66
@@ -172,20 +169,21 @@ static int em28xx_start_streaming(struct em28xx_dvb *dvb)
172 max_dvb_packet_size = dev->dvb_max_pkt_size; 169 max_dvb_packet_size = dev->dvb_max_pkt_size;
173 if (max_dvb_packet_size < 0) 170 if (max_dvb_packet_size < 0)
174 return max_dvb_packet_size; 171 return max_dvb_packet_size;
175 dprintk(1, "Using %d buffers each with %d bytes\n", 172 dprintk(1, "Using %d buffers each with %d x %d bytes\n",
176 EM28XX_DVB_NUM_BUFS, 173 EM28XX_DVB_NUM_BUFS,
174 EM28XX_DVB_MAX_PACKETS,
177 max_dvb_packet_size); 175 max_dvb_packet_size);
178 176
179 return em28xx_init_isoc(dev, EM28XX_DVB_MAX_PACKETS, 177 return em28xx_init_isoc(dev, EM28XX_DIGITAL_MODE,
180 EM28XX_DVB_NUM_BUFS, max_dvb_packet_size, 178 EM28XX_DVB_MAX_PACKETS, EM28XX_DVB_NUM_BUFS,
181 em28xx_dvb_isoc_copy); 179 max_dvb_packet_size, em28xx_dvb_isoc_copy);
182} 180}
183 181
184static int em28xx_stop_streaming(struct em28xx_dvb *dvb) 182static int em28xx_stop_streaming(struct em28xx_dvb *dvb)
185{ 183{
186 struct em28xx *dev = dvb->adapter.priv; 184 struct em28xx *dev = dvb->adapter.priv;
187 185
188 em28xx_uninit_isoc(dev); 186 em28xx_capture_start(dev, 0);
189 187
190 em28xx_set_mode(dev, EM28XX_SUSPEND); 188 em28xx_set_mode(dev, EM28XX_SUSPEND);
191 189
@@ -327,6 +325,19 @@ struct drxk_config hauppauge_930c_drxk = {
327 .chunk_size = 56, 325 .chunk_size = 56,
328}; 326};
329 327
328struct drxk_config maxmedia_ub425_tc_drxk = {
329 .adr = 0x29,
330 .single_master = 1,
331 .no_i2c_bridge = 1,
332};
333
334struct drxk_config pctv_520e_drxk = {
335 .adr = 0x29,
336 .single_master = 1,
337 .microcode_name = "dvb-demod-drxk-pctv.fw",
338 .chunk_size = 58,
339};
340
330static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) 341static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
331{ 342{
332 struct em28xx_dvb *dvb = fe->sec_priv; 343 struct em28xx_dvb *dvb = fe->sec_priv;
@@ -460,6 +471,33 @@ static void terratec_h5_init(struct em28xx *dev)
460 em28xx_gpio_set(dev, terratec_h5_end); 471 em28xx_gpio_set(dev, terratec_h5_end);
461}; 472};
462 473
474static void pctv_520e_init(struct em28xx *dev)
475{
476 /*
477 * Init TDA8295(?) analog demodulator. Looks like I2C traffic to
478 * digital demodulator and tuner are routed via TDA8295.
479 */
480 int i;
481 struct {
482 unsigned char r[4];
483 int len;
484 } regs[] = {
485 {{ 0x06, 0x02, 0x00, 0x31 }, 4},
486 {{ 0x01, 0x02 }, 2},
487 {{ 0x01, 0x02, 0x00, 0xc6 }, 4},
488 {{ 0x01, 0x00 }, 2},
489 {{ 0x01, 0x00, 0xff, 0xaf }, 4},
490 {{ 0x01, 0x00, 0x03, 0xa0 }, 4},
491 {{ 0x01, 0x00 }, 2},
492 {{ 0x01, 0x00, 0x73, 0xaf }, 4},
493 };
494
495 dev->i2c_client.addr = 0x82 >> 1; /* 0x41 */
496
497 for (i = 0; i < ARRAY_SIZE(regs); i++)
498 i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len);
499};
500
463static int em28xx_mt352_terratec_xs_init(struct dvb_frontend *fe) 501static int em28xx_mt352_terratec_xs_init(struct dvb_frontend *fe)
464{ 502{
465 /* Values extracted from a USB trace of the Terratec Windows driver */ 503 /* Values extracted from a USB trace of the Terratec Windows driver */
@@ -938,6 +976,48 @@ static int em28xx_dvb_init(struct em28xx *dev)
938 dvb_attach(a8293_attach, dvb->fe[0], &dev->i2c_adap, 976 dvb_attach(a8293_attach, dvb->fe[0], &dev->i2c_adap,
939 &em28xx_a8293_config); 977 &em28xx_a8293_config);
940 break; 978 break;
979 case EM2874_BOARD_MAXMEDIA_UB425_TC:
980 /* attach demodulator */
981 dvb->fe[0] = dvb_attach(drxk_attach, &maxmedia_ub425_tc_drxk,
982 &dev->i2c_adap);
983
984 if (dvb->fe[0]) {
985 /* disable I2C-gate */
986 dvb->fe[0]->ops.i2c_gate_ctrl = NULL;
987
988 /* attach tuner */
989 if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0],
990 &dev->i2c_adap, 0x60)) {
991 dvb_frontend_detach(dvb->fe[0]);
992 result = -EINVAL;
993 goto out_free;
994 }
995 }
996
997 /* TODO: we need drx-3913k firmware in order to support DVB-T */
998 em28xx_info("MaxMedia UB425-TC: only DVB-C supported by that " \
999 "driver version\n");
1000
1001 break;
1002 case EM2884_BOARD_PCTV_510E:
1003 case EM2884_BOARD_PCTV_520E:
1004 pctv_520e_init(dev);
1005
1006 /* attach demodulator */
1007 dvb->fe[0] = dvb_attach(drxk_attach, &pctv_520e_drxk,
1008 &dev->i2c_adap);
1009
1010 if (dvb->fe[0]) {
1011 /* attach tuner */
1012 if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
1013 &dev->i2c_adap,
1014 &em28xx_cxd2820r_tda18271_config)) {
1015 dvb_frontend_detach(dvb->fe[0]);
1016 result = -EINVAL;
1017 goto out_free;
1018 }
1019 }
1020 break;
941 default: 1021 default:
942 em28xx_errdev("/2: The frontend of your DVB/ATSC card" 1022 em28xx_errdev("/2: The frontend of your DVB/ATSC card"
943 " isn't supported yet\n"); 1023 " isn't supported yet\n");
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index 36f5a9bc8b76..a88e169dba23 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -41,14 +41,6 @@ static unsigned int i2c_debug;
41module_param(i2c_debug, int, 0644); 41module_param(i2c_debug, int, 0644);
42MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); 42MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
43 43
44
45#define dprintk1(lvl, fmt, args...) \
46do { \
47 if (i2c_debug >= lvl) { \
48 printk(fmt, ##args); \
49 } \
50} while (0)
51
52#define dprintk2(lvl, fmt, args...) \ 44#define dprintk2(lvl, fmt, args...) \
53do { \ 45do { \
54 if (i2c_debug >= lvl) { \ 46 if (i2c_debug >= lvl) { \
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 613300b51a9e..324b695c0724 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -760,17 +760,19 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
760 goto fail; 760 goto fail;
761 } 761 }
762 762
763 if (!dev->isoc_ctl.num_bufs) 763 if (!dev->isoc_ctl.analog_bufs.num_bufs)
764 urb_init = 1; 764 urb_init = 1;
765 765
766 if (urb_init) { 766 if (urb_init) {
767 if (em28xx_vbi_supported(dev) == 1) 767 if (em28xx_vbi_supported(dev) == 1)
768 rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS, 768 rc = em28xx_init_isoc(dev, EM28XX_ANALOG_MODE,
769 EM28XX_NUM_PACKETS,
769 EM28XX_NUM_BUFS, 770 EM28XX_NUM_BUFS,
770 dev->max_pkt_size, 771 dev->max_pkt_size,
771 em28xx_isoc_copy_vbi); 772 em28xx_isoc_copy_vbi);
772 else 773 else
773 rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS, 774 rc = em28xx_init_isoc(dev, EM28XX_ANALOG_MODE,
775 EM28XX_NUM_PACKETS,
774 EM28XX_NUM_BUFS, 776 EM28XX_NUM_BUFS,
775 dev->max_pkt_size, 777 dev->max_pkt_size,
776 em28xx_isoc_copy); 778 em28xx_isoc_copy);
@@ -2267,7 +2269,7 @@ static int em28xx_v4l2_close(struct file *filp)
2267 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0); 2269 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
2268 2270
2269 /* do this before setting alternate! */ 2271 /* do this before setting alternate! */
2270 em28xx_uninit_isoc(dev); 2272 em28xx_uninit_isoc(dev, EM28XX_ANALOG_MODE);
2271 em28xx_set_mode(dev, EM28XX_SUSPEND); 2273 em28xx_set_mode(dev, EM28XX_SUSPEND);
2272 2274
2273 /* set alternate 0 */ 2275 /* set alternate 0 */
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 22e252bcc41e..2868b19f8b54 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -125,6 +125,9 @@
125#define EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C 81 125#define EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C 81
126#define EM2884_BOARD_CINERGY_HTC_STICK 82 126#define EM2884_BOARD_CINERGY_HTC_STICK 82
127#define EM2860_BOARD_HT_VIDBOX_NW03 83 127#define EM2860_BOARD_HT_VIDBOX_NW03 83
128#define EM2874_BOARD_MAXMEDIA_UB425_TC 84
129#define EM2884_BOARD_PCTV_510E 85
130#define EM2884_BOARD_PCTV_520E 86
128 131
129/* Limits minimum and default number of buffers */ 132/* Limits minimum and default number of buffers */
130#define EM28XX_MIN_BUF 4 133#define EM28XX_MIN_BUF 4
@@ -151,12 +154,14 @@
151 154
152/* number of buffers for isoc transfers */ 155/* number of buffers for isoc transfers */
153#define EM28XX_NUM_BUFS 5 156#define EM28XX_NUM_BUFS 5
157#define EM28XX_DVB_NUM_BUFS 5
154 158
155/* number of packets for each buffer 159/* number of packets for each buffer
156 windows requests only 64 packets .. so we better do the same 160 windows requests only 64 packets .. so we better do the same
157 this is what I found out for all alternate numbers there! 161 this is what I found out for all alternate numbers there!
158 */ 162 */
159#define EM28XX_NUM_PACKETS 64 163#define EM28XX_NUM_PACKETS 64
164#define EM28XX_DVB_MAX_PACKETS 64
160 165
161#define EM28XX_INTERLACED_DEFAULT 1 166#define EM28XX_INTERLACED_DEFAULT 1
162 167
@@ -197,10 +202,13 @@ enum em28xx_mode {
197 202
198struct em28xx; 203struct em28xx;
199 204
200struct em28xx_usb_isoc_ctl { 205struct em28xx_usb_isoc_bufs {
201 /* max packet size of isoc transaction */ 206 /* max packet size of isoc transaction */
202 int max_pkt_size; 207 int max_pkt_size;
203 208
209 /* number of packets in each buffer */
210 int num_packets;
211
204 /* number of allocated urbs */ 212 /* number of allocated urbs */
205 int num_bufs; 213 int num_bufs;
206 214
@@ -209,6 +217,14 @@ struct em28xx_usb_isoc_ctl {
209 217
210 /* transfer buffers for isoc transfer */ 218 /* transfer buffers for isoc transfer */
211 char **transfer_buffer; 219 char **transfer_buffer;
220};
221
222struct em28xx_usb_isoc_ctl {
223 /* isoc transfer buffers for analog mode */
224 struct em28xx_usb_isoc_bufs analog_bufs;
225
226 /* isoc transfer buffers for digital mode */
227 struct em28xx_usb_isoc_bufs digital_bufs;
212 228
213 /* Last buffer command and region */ 229 /* Last buffer command and region */
214 u8 cmd; 230 u8 cmd;
@@ -600,9 +616,6 @@ struct em28xx {
600 unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */ 616 unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
601 int dvb_alt; /* alternate for DVB */ 617 int dvb_alt; /* alternate for DVB */
602 unsigned int dvb_max_pkt_size; /* wMaxPacketSize for DVB */ 618 unsigned int dvb_max_pkt_size; /* wMaxPacketSize for DVB */
603 struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */
604 char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc
605 transfer */
606 char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */ 619 char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */
607 620
608 /* helper funcs that call usb_control_msg */ 621 /* helper funcs that call usb_control_msg */
@@ -676,10 +689,12 @@ int em28xx_vbi_supported(struct em28xx *dev);
676int em28xx_set_outfmt(struct em28xx *dev); 689int em28xx_set_outfmt(struct em28xx *dev);
677int em28xx_resolution_set(struct em28xx *dev); 690int em28xx_resolution_set(struct em28xx *dev);
678int em28xx_set_alternate(struct em28xx *dev); 691int em28xx_set_alternate(struct em28xx *dev);
679int em28xx_init_isoc(struct em28xx *dev, int max_packets, 692int em28xx_alloc_isoc(struct em28xx *dev, enum em28xx_mode mode,
680 int num_bufs, int max_pkt_size, 693 int max_packets, int num_bufs, int max_pkt_size);
694int em28xx_init_isoc(struct em28xx *dev, enum em28xx_mode mode,
695 int max_packets, int num_bufs, int max_pkt_size,
681 int (*isoc_copy) (struct em28xx *dev, struct urb *urb)); 696 int (*isoc_copy) (struct em28xx *dev, struct urb *urb));
682void em28xx_uninit_isoc(struct em28xx *dev); 697void em28xx_uninit_isoc(struct em28xx *dev, enum em28xx_mode mode);
683int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev); 698int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev);
684int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); 699int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode);
685int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); 700int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio);
diff --git a/drivers/media/video/gspca/gl860/Makefile b/drivers/media/video/gspca/gl860/Makefile
index f511eccdfd9c..773ea3426561 100644
--- a/drivers/media/video/gspca/gl860/Makefile
+++ b/drivers/media/video/gspca/gl860/Makefile
@@ -6,5 +6,5 @@ gspca_gl860-objs := gl860.o \
6 gl860-ov9655.o \ 6 gl860-ov9655.o \
7 gl860-mi2020.o 7 gl860-mi2020.o
8 8
9ccflags-y += -Idrivers/media/video/gspca 9ccflags-y += -I$(srctree)/drivers/media/video/gspca
10 10
diff --git a/drivers/media/video/gspca/m5602/Makefile b/drivers/media/video/gspca/m5602/Makefile
index 7f52961f439c..575b75bacb62 100644
--- a/drivers/media/video/gspca/m5602/Makefile
+++ b/drivers/media/video/gspca/m5602/Makefile
@@ -8,4 +8,4 @@ gspca_m5602-objs := m5602_core.o \
8 m5602_s5k83a.o \ 8 m5602_s5k83a.o \
9 m5602_s5k4aa.o 9 m5602_s5k4aa.o
10 10
11ccflags-y += -Idrivers/media/video/gspca 11ccflags-y += -I$(srctree)/drivers/media/video/gspca
diff --git a/drivers/media/video/gspca/ov534_9.c b/drivers/media/video/gspca/ov534_9.c
index fbfa02affa13..e6601b886032 100644
--- a/drivers/media/video/gspca/ov534_9.c
+++ b/drivers/media/video/gspca/ov534_9.c
@@ -1107,16 +1107,34 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1107{ 1107{
1108 struct sd *sd = (struct sd *) gspca_dev; 1108 struct sd *sd = (struct sd *) gspca_dev;
1109 u8 val; 1109 u8 val;
1110 s8 sval;
1110 1111
1111 if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS)) 1112 if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS))
1112 return; 1113 return;
1113 val = sd->ctrls[BRIGHTNESS].val; 1114 if (sd->sensor == SENSOR_OV562x) {
1114 if (val < 8) 1115 sval = sd->ctrls[BRIGHTNESS].val;
1115 val = 15 - val; /* f .. 8 */ 1116 val = 0x76;
1116 else 1117 val += sval;
1117 val = val - 8; /* 0 .. 7 */ 1118 sccb_write(gspca_dev, 0x24, val);
1118 sccb_write(gspca_dev, 0x55, /* brtn - brightness adjustment */ 1119 val = 0x6a;
1119 0x0f | (val << 4)); 1120 val += sval;
1121 sccb_write(gspca_dev, 0x25, val);
1122 if (sval < -40)
1123 val = 0x71;
1124 else if (sval < 20)
1125 val = 0x94;
1126 else
1127 val = 0xe6;
1128 sccb_write(gspca_dev, 0x26, val);
1129 } else {
1130 val = sd->ctrls[BRIGHTNESS].val;
1131 if (val < 8)
1132 val = 15 - val; /* f .. 8 */
1133 else
1134 val = val - 8; /* 0 .. 7 */
1135 sccb_write(gspca_dev, 0x55, /* brtn - brightness adjustment */
1136 0x0f | (val << 4));
1137 }
1120} 1138}
1121 1139
1122static void setcontrast(struct gspca_dev *gspca_dev) 1140static void setcontrast(struct gspca_dev *gspca_dev)
@@ -1339,7 +1357,16 @@ static int sd_init(struct gspca_dev *gspca_dev)
1339 reg_w(gspca_dev, 0x56, 0x17); 1357 reg_w(gspca_dev, 0x56, 0x17);
1340 } else if ((sensor_id & 0xfff0) == 0x5620) { 1358 } else if ((sensor_id & 0xfff0) == 0x5620) {
1341 sd->sensor = SENSOR_OV562x; 1359 sd->sensor = SENSOR_OV562x;
1342 1360 gspca_dev->ctrl_dis = (1 << CONTRAST) |
1361 (1 << AUTOGAIN) |
1362 (1 << EXPOSURE) |
1363 (1 << SHARPNESS) |
1364 (1 << SATUR) |
1365 (1 << LIGHTFREQ);
1366
1367 sd->ctrls[BRIGHTNESS].min = -90;
1368 sd->ctrls[BRIGHTNESS].max = 90;
1369 sd->ctrls[BRIGHTNESS].def = 0;
1343 gspca_dev->cam.cam_mode = ov562x_mode; 1370 gspca_dev->cam.cam_mode = ov562x_mode;
1344 gspca_dev->cam.nmodes = ARRAY_SIZE(ov562x_mode); 1371 gspca_dev->cam.nmodes = ARRAY_SIZE(ov562x_mode);
1345 1372
@@ -1360,8 +1387,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
1360{ 1387{
1361 struct sd *sd = (struct sd *) gspca_dev; 1388 struct sd *sd = (struct sd *) gspca_dev;
1362 1389
1363 if (sd->sensor == SENSOR_OV971x || sd->sensor == SENSOR_OV562x) 1390 if (sd->sensor == SENSOR_OV971x)
1364 return gspca_dev->usb_err; 1391 return gspca_dev->usb_err;
1392 else if (sd->sensor == SENSOR_OV562x) {
1393 setbrightness(gspca_dev);
1394 return gspca_dev->usb_err;
1395 }
1365 switch (gspca_dev->curr_mode) { 1396 switch (gspca_dev->curr_mode) {
1366 case QVGA_MODE: /* 320x240 */ 1397 case QVGA_MODE: /* 320x240 */
1367 sccb_w_array(gspca_dev, ov965x_start_1_vga, 1398 sccb_w_array(gspca_dev, ov965x_start_1_vga,
diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c
index 9db2b34d172c..30662fccb0cf 100644
--- a/drivers/media/video/gspca/pac7302.c
+++ b/drivers/media/video/gspca/pac7302.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * Pixart PAC7302 library 2 * Pixart PAC7302 driver
3 * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
4 * 3 *
5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> 4 * Copyright (C) 2008-2012 Jean-Francois Moine <http://moinejf.free.fr>
5 * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
6 * 6 *
7 * Separated from Pixart PAC7311 library by Márton Németh 7 * Separated from Pixart PAC7311 library by Márton Németh
8 * Camera button input handling by Márton Németh <nm127@freemail.hu> 8 * Camera button input handling by Márton Németh <nm127@freemail.hu>
@@ -63,67 +63,61 @@
63 63
64#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 64#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
65 65
66#define MODULE_NAME "pac7302"
67
68#include <linux/input.h> 66#include <linux/input.h>
69#include <media/v4l2-chip-ident.h> 67#include <media/v4l2-chip-ident.h>
70#include "gspca.h" 68#include "gspca.h"
69/* Include pac common sof detection functions */
70#include "pac_common.h"
71 71
72MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); 72MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>, "
73 "Thomas Kaiser thomas@kaiser-linux.li");
73MODULE_DESCRIPTION("Pixart PAC7302"); 74MODULE_DESCRIPTION("Pixart PAC7302");
74MODULE_LICENSE("GPL"); 75MODULE_LICENSE("GPL");
75 76
77enum e_ctrl {
78 BRIGHTNESS,
79 CONTRAST,
80 COLORS,
81 WHITE_BALANCE,
82 RED_BALANCE,
83 BLUE_BALANCE,
84 GAIN,
85 AUTOGAIN,
86 EXPOSURE,
87 VFLIP,
88 HFLIP,
89 NCTRLS /* number of controls */
90};
91
76/* specific webcam descriptor for pac7302 */ 92/* specific webcam descriptor for pac7302 */
77struct sd { 93struct sd {
78 struct gspca_dev gspca_dev; /* !! must be the first item */ 94 struct gspca_dev gspca_dev; /* !! must be the first item */
79 95
80 unsigned char brightness; 96 struct gspca_ctrl ctrls[NCTRLS];
81 unsigned char contrast; 97
82 unsigned char colors;
83 unsigned char white_balance;
84 unsigned char red_balance;
85 unsigned char blue_balance;
86 unsigned char gain;
87 unsigned char autogain;
88 unsigned short exposure;
89 __u8 hflip;
90 __u8 vflip;
91 u8 flags; 98 u8 flags;
92#define FL_HFLIP 0x01 /* mirrored by default */ 99#define FL_HFLIP 0x01 /* mirrored by default */
93#define FL_VFLIP 0x02 /* vertical flipped by default */ 100#define FL_VFLIP 0x02 /* vertical flipped by default */
94 101
95 u8 sof_read; 102 u8 sof_read;
96 u8 autogain_ignore_frames; 103 s8 autogain_ignore_frames;
97 104
98 atomic_t avg_lum; 105 atomic_t avg_lum;
99}; 106};
100 107
101/* V4L2 controls supported by the driver */ 108/* V4L2 controls supported by the driver */
102static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 109static void setbrightcont(struct gspca_dev *gspca_dev);
103static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 110static void setcolors(struct gspca_dev *gspca_dev);
104static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); 111static void setwhitebalance(struct gspca_dev *gspca_dev);
105static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 112static void setredbalance(struct gspca_dev *gspca_dev);
106static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); 113static void setbluebalance(struct gspca_dev *gspca_dev);
107static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 114static void setgain(struct gspca_dev *gspca_dev);
108static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val); 115static void setexposure(struct gspca_dev *gspca_dev);
109static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val); 116static void setautogain(struct gspca_dev *gspca_dev);
110static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val); 117static void sethvflip(struct gspca_dev *gspca_dev);
111static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val);
112static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val);
113static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val);
114static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
115static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
116static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
117static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
118static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
119static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
120static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
121static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
122static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
123static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
124 118
125static const struct ctrl sd_ctrls[] = { 119static const struct ctrl sd_ctrls[] = {
126 { 120[BRIGHTNESS] = {
127 { 121 {
128 .id = V4L2_CID_BRIGHTNESS, 122 .id = V4L2_CID_BRIGHTNESS,
129 .type = V4L2_CTRL_TYPE_INTEGER, 123 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -132,13 +126,11 @@ static const struct ctrl sd_ctrls[] = {
132#define BRIGHTNESS_MAX 0x20 126#define BRIGHTNESS_MAX 0x20
133 .maximum = BRIGHTNESS_MAX, 127 .maximum = BRIGHTNESS_MAX,
134 .step = 1, 128 .step = 1,
135#define BRIGHTNESS_DEF 0x10 129 .default_value = 0x10,
136 .default_value = BRIGHTNESS_DEF,
137 }, 130 },
138 .set = sd_setbrightness, 131 .set_control = setbrightcont
139 .get = sd_getbrightness,
140 }, 132 },
141 { 133[CONTRAST] = {
142 { 134 {
143 .id = V4L2_CID_CONTRAST, 135 .id = V4L2_CID_CONTRAST,
144 .type = V4L2_CTRL_TYPE_INTEGER, 136 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -147,13 +139,11 @@ static const struct ctrl sd_ctrls[] = {
147#define CONTRAST_MAX 255 139#define CONTRAST_MAX 255
148 .maximum = CONTRAST_MAX, 140 .maximum = CONTRAST_MAX,
149 .step = 1, 141 .step = 1,
150#define CONTRAST_DEF 127 142 .default_value = 127,
151 .default_value = CONTRAST_DEF,
152 }, 143 },
153 .set = sd_setcontrast, 144 .set_control = setbrightcont
154 .get = sd_getcontrast,
155 }, 145 },
156 { 146[COLORS] = {
157 { 147 {
158 .id = V4L2_CID_SATURATION, 148 .id = V4L2_CID_SATURATION,
159 .type = V4L2_CTRL_TYPE_INTEGER, 149 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -162,13 +152,11 @@ static const struct ctrl sd_ctrls[] = {
162#define COLOR_MAX 255 152#define COLOR_MAX 255
163 .maximum = COLOR_MAX, 153 .maximum = COLOR_MAX,
164 .step = 1, 154 .step = 1,
165#define COLOR_DEF 127 155 .default_value = 127
166 .default_value = COLOR_DEF,
167 }, 156 },
168 .set = sd_setcolors, 157 .set_control = setcolors
169 .get = sd_getcolors,
170 }, 158 },
171 { 159[WHITE_BALANCE] = {
172 { 160 {
173 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE, 161 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
174 .type = V4L2_CTRL_TYPE_INTEGER, 162 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -176,13 +164,11 @@ static const struct ctrl sd_ctrls[] = {
176 .minimum = 0, 164 .minimum = 0,
177 .maximum = 255, 165 .maximum = 255,
178 .step = 1, 166 .step = 1,
179#define WHITEBALANCE_DEF 4 167 .default_value = 4,
180 .default_value = WHITEBALANCE_DEF,
181 }, 168 },
182 .set = sd_setwhitebalance, 169 .set_control = setwhitebalance
183 .get = sd_getwhitebalance,
184 }, 170 },
185 { 171[RED_BALANCE] = {
186 { 172 {
187 .id = V4L2_CID_RED_BALANCE, 173 .id = V4L2_CID_RED_BALANCE,
188 .type = V4L2_CTRL_TYPE_INTEGER, 174 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -190,13 +176,11 @@ static const struct ctrl sd_ctrls[] = {
190 .minimum = 0, 176 .minimum = 0,
191 .maximum = 3, 177 .maximum = 3,
192 .step = 1, 178 .step = 1,
193#define REDBALANCE_DEF 1 179 .default_value = 1,
194 .default_value = REDBALANCE_DEF,
195 }, 180 },
196 .set = sd_setredbalance, 181 .set_control = setredbalance
197 .get = sd_getredbalance,
198 }, 182 },
199 { 183[BLUE_BALANCE] = {
200 { 184 {
201 .id = V4L2_CID_BLUE_BALANCE, 185 .id = V4L2_CID_BLUE_BALANCE,
202 .type = V4L2_CTRL_TYPE_INTEGER, 186 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -204,29 +188,25 @@ static const struct ctrl sd_ctrls[] = {
204 .minimum = 0, 188 .minimum = 0,
205 .maximum = 3, 189 .maximum = 3,
206 .step = 1, 190 .step = 1,
207#define BLUEBALANCE_DEF 1 191 .default_value = 1,
208 .default_value = BLUEBALANCE_DEF,
209 }, 192 },
210 .set = sd_setbluebalance, 193 .set_control = setbluebalance
211 .get = sd_getbluebalance,
212 }, 194 },
213 { 195[GAIN] = {
214 { 196 {
215 .id = V4L2_CID_GAIN, 197 .id = V4L2_CID_GAIN,
216 .type = V4L2_CTRL_TYPE_INTEGER, 198 .type = V4L2_CTRL_TYPE_INTEGER,
217 .name = "Gain", 199 .name = "Gain",
218 .minimum = 0, 200 .minimum = 0,
219#define GAIN_MAX 255 201 .maximum = 255,
220 .maximum = GAIN_MAX,
221 .step = 1, 202 .step = 1,
222#define GAIN_DEF 127 203#define GAIN_DEF 127
223#define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */ 204#define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
224 .default_value = GAIN_DEF, 205 .default_value = GAIN_DEF,
225 }, 206 },
226 .set = sd_setgain, 207 .set_control = setgain
227 .get = sd_getgain,
228 }, 208 },
229 { 209[EXPOSURE] = {
230 { 210 {
231 .id = V4L2_CID_EXPOSURE, 211 .id = V4L2_CID_EXPOSURE,
232 .type = V4L2_CTRL_TYPE_INTEGER, 212 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -238,10 +218,9 @@ static const struct ctrl sd_ctrls[] = {
238#define EXPOSURE_KNEE 133 /* 66 ms / 15 fps */ 218#define EXPOSURE_KNEE 133 /* 66 ms / 15 fps */
239 .default_value = EXPOSURE_DEF, 219 .default_value = EXPOSURE_DEF,
240 }, 220 },
241 .set = sd_setexposure, 221 .set_control = setexposure
242 .get = sd_getexposure,
243 }, 222 },
244 { 223[AUTOGAIN] = {
245 { 224 {
246 .id = V4L2_CID_AUTOGAIN, 225 .id = V4L2_CID_AUTOGAIN,
247 .type = V4L2_CTRL_TYPE_BOOLEAN, 226 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -252,10 +231,9 @@ static const struct ctrl sd_ctrls[] = {
252#define AUTOGAIN_DEF 1 231#define AUTOGAIN_DEF 1
253 .default_value = AUTOGAIN_DEF, 232 .default_value = AUTOGAIN_DEF,
254 }, 233 },
255 .set = sd_setautogain, 234 .set_control = setautogain,
256 .get = sd_getautogain,
257 }, 235 },
258 { 236[HFLIP] = {
259 { 237 {
260 .id = V4L2_CID_HFLIP, 238 .id = V4L2_CID_HFLIP,
261 .type = V4L2_CTRL_TYPE_BOOLEAN, 239 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -263,13 +241,11 @@ static const struct ctrl sd_ctrls[] = {
263 .minimum = 0, 241 .minimum = 0,
264 .maximum = 1, 242 .maximum = 1,
265 .step = 1, 243 .step = 1,
266#define HFLIP_DEF 0 244 .default_value = 0,
267 .default_value = HFLIP_DEF,
268 }, 245 },
269 .set = sd_sethflip, 246 .set_control = sethvflip,
270 .get = sd_gethflip,
271 }, 247 },
272 { 248[VFLIP] = {
273 { 249 {
274 .id = V4L2_CID_VFLIP, 250 .id = V4L2_CID_VFLIP,
275 .type = V4L2_CTRL_TYPE_BOOLEAN, 251 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -277,11 +253,9 @@ static const struct ctrl sd_ctrls[] = {
277 .minimum = 0, 253 .minimum = 0,
278 .maximum = 1, 254 .maximum = 1,
279 .step = 1, 255 .step = 1,
280#define VFLIP_DEF 0 256 .default_value = 0,
281 .default_value = VFLIP_DEF,
282 }, 257 },
283 .set = sd_setvflip, 258 .set_control = sethvflip
284 .get = sd_getvflip,
285 }, 259 },
286}; 260};
287 261
@@ -290,21 +264,21 @@ static const struct v4l2_pix_format vga_mode[] = {
290 .bytesperline = 640, 264 .bytesperline = 640,
291 .sizeimage = 640 * 480 * 3 / 8 + 590, 265 .sizeimage = 640 * 480 * 3 / 8 + 590,
292 .colorspace = V4L2_COLORSPACE_JPEG, 266 .colorspace = V4L2_COLORSPACE_JPEG,
293 .priv = 0}, 267 },
294}; 268};
295 269
296#define LOAD_PAGE3 255 270#define LOAD_PAGE3 255
297#define END_OF_SEQUENCE 0 271#define END_OF_SEQUENCE 0
298 272
299/* pac 7302 */ 273/* pac 7302 */
300static const __u8 init_7302[] = { 274static const u8 init_7302[] = {
301/* index,value */ 275/* index,value */
302 0xff, 0x01, /* page 1 */ 276 0xff, 0x01, /* page 1 */
303 0x78, 0x00, /* deactivate */ 277 0x78, 0x00, /* deactivate */
304 0xff, 0x01, 278 0xff, 0x01,
305 0x78, 0x40, /* led off */ 279 0x78, 0x40, /* led off */
306}; 280};
307static const __u8 start_7302[] = { 281static const u8 start_7302[] = {
308/* index, len, [value]* */ 282/* index, len, [value]* */
309 0xff, 1, 0x00, /* page 0 */ 283 0xff, 1, 0x00, /* page 0 */
310 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80, 284 0x00, 12, 0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
@@ -319,7 +293,7 @@ static const __u8 start_7302[] = {
319 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11, 293 0x43, 11, 0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
320 0x00, 0x54, 0x11, 294 0x00, 0x54, 0x11,
321 0x55, 1, 0x00, 295 0x55, 1, 0x00,
322 0x62, 4, 0x10, 0x1e, 0x1e, 0x18, 296 0x62, 4, 0x10, 0x1e, 0x1e, 0x18,
323 0x6b, 1, 0x00, 297 0x6b, 1, 0x00,
324 0x6e, 3, 0x08, 0x06, 0x00, 298 0x6e, 3, 0x08, 0x06, 0x00,
325 0x72, 3, 0x00, 0xff, 0x00, 299 0x72, 3, 0x00, 0xff, 0x00,
@@ -370,7 +344,7 @@ static const __u8 start_7302[] = {
370 344
371#define SKIP 0xaa 345#define SKIP 0xaa
372/* page 3 - the value SKIP says skip the index - see reg_w_page() */ 346/* page 3 - the value SKIP says skip the index - see reg_w_page() */
373static const __u8 page3_7302[] = { 347static const u8 page3_7302[] = {
374 0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16, 348 0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
375 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00, 349 0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
376 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 350 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -394,7 +368,7 @@ static const __u8 page3_7302[] = {
394}; 368};
395 369
396static void reg_w_buf(struct gspca_dev *gspca_dev, 370static void reg_w_buf(struct gspca_dev *gspca_dev,
397 __u8 index, 371 u8 index,
398 const u8 *buffer, int len) 372 const u8 *buffer, int len)
399{ 373{
400 int ret; 374 int ret;
@@ -410,7 +384,7 @@ static void reg_w_buf(struct gspca_dev *gspca_dev,
410 index, gspca_dev->usb_buf, len, 384 index, gspca_dev->usb_buf, len,
411 500); 385 500);
412 if (ret < 0) { 386 if (ret < 0) {
413 pr_err("reg_w_buf failed index 0x%02x, error %d\n", 387 pr_err("reg_w_buf failed i: %02x error %d\n",
414 index, ret); 388 index, ret);
415 gspca_dev->usb_err = ret; 389 gspca_dev->usb_err = ret;
416 } 390 }
@@ -418,8 +392,8 @@ static void reg_w_buf(struct gspca_dev *gspca_dev,
418 392
419 393
420static void reg_w(struct gspca_dev *gspca_dev, 394static void reg_w(struct gspca_dev *gspca_dev,
421 __u8 index, 395 u8 index,
422 __u8 value) 396 u8 value)
423{ 397{
424 int ret; 398 int ret;
425 399
@@ -433,14 +407,14 @@ static void reg_w(struct gspca_dev *gspca_dev,
433 0, index, gspca_dev->usb_buf, 1, 407 0, index, gspca_dev->usb_buf, 1,
434 500); 408 500);
435 if (ret < 0) { 409 if (ret < 0) {
436 pr_err("reg_w() failed index 0x%02x, value 0x%02x, error %d\n", 410 pr_err("reg_w() failed i: %02x v: %02x error %d\n",
437 index, value, ret); 411 index, value, ret);
438 gspca_dev->usb_err = ret; 412 gspca_dev->usb_err = ret;
439 } 413 }
440} 414}
441 415
442static void reg_w_seq(struct gspca_dev *gspca_dev, 416static void reg_w_seq(struct gspca_dev *gspca_dev,
443 const __u8 *seq, int len) 417 const u8 *seq, int len)
444{ 418{
445 while (--len >= 0) { 419 while (--len >= 0) {
446 reg_w(gspca_dev, seq[0], seq[1]); 420 reg_w(gspca_dev, seq[0], seq[1]);
@@ -450,7 +424,7 @@ static void reg_w_seq(struct gspca_dev *gspca_dev,
450 424
451/* load the beginning of a page */ 425/* load the beginning of a page */
452static void reg_w_page(struct gspca_dev *gspca_dev, 426static void reg_w_page(struct gspca_dev *gspca_dev,
453 const __u8 *page, int len) 427 const u8 *page, int len)
454{ 428{
455 int index; 429 int index;
456 int ret = 0; 430 int ret = 0;
@@ -468,7 +442,7 @@ static void reg_w_page(struct gspca_dev *gspca_dev,
468 0, index, gspca_dev->usb_buf, 1, 442 0, index, gspca_dev->usb_buf, 1,
469 500); 443 500);
470 if (ret < 0) { 444 if (ret < 0) {
471 pr_err("reg_w_page() failed index 0x%02x, value 0x%02x, error %d\n", 445 pr_err("reg_w_page() failed i: %02x v: %02x error %d\n",
472 index, page[index], ret); 446 index, page[index], ret);
473 gspca_dev->usb_err = ret; 447 gspca_dev->usb_err = ret;
474 break; 448 break;
@@ -478,8 +452,8 @@ static void reg_w_page(struct gspca_dev *gspca_dev,
478 452
479/* output a variable sequence */ 453/* output a variable sequence */
480static void reg_w_var(struct gspca_dev *gspca_dev, 454static void reg_w_var(struct gspca_dev *gspca_dev,
481 const __u8 *seq, 455 const u8 *seq,
482 const __u8 *page3, unsigned int page3_len) 456 const u8 *page3, unsigned int page3_len)
483{ 457{
484 int index, len; 458 int index, len;
485 459
@@ -493,11 +467,13 @@ static void reg_w_var(struct gspca_dev *gspca_dev,
493 reg_w_page(gspca_dev, page3, page3_len); 467 reg_w_page(gspca_dev, page3, page3_len);
494 break; 468 break;
495 default: 469 default:
470#ifdef GSPCA_DEBUG
496 if (len > USB_BUF_SZ) { 471 if (len > USB_BUF_SZ) {
497 PDEBUG(D_ERR|D_STREAM, 472 PDEBUG(D_ERR|D_STREAM,
498 "Incorrect variable sequence"); 473 "Incorrect variable sequence");
499 return; 474 return;
500 } 475 }
476#endif
501 while (len > 0) { 477 while (len > 0) {
502 if (len < 8) { 478 if (len < 8) {
503 reg_w_buf(gspca_dev, 479 reg_w_buf(gspca_dev,
@@ -524,21 +500,11 @@ static int sd_config(struct gspca_dev *gspca_dev,
524 500
525 cam = &gspca_dev->cam; 501 cam = &gspca_dev->cam;
526 502
527 PDEBUG(D_CONF, "Find Sensor PAC7302");
528 cam->cam_mode = vga_mode; /* only 640x480 */ 503 cam->cam_mode = vga_mode; /* only 640x480 */
529 cam->nmodes = ARRAY_SIZE(vga_mode); 504 cam->nmodes = ARRAY_SIZE(vga_mode);
530 505
531 sd->brightness = BRIGHTNESS_DEF; 506 gspca_dev->cam.ctrls = sd->ctrls;
532 sd->contrast = CONTRAST_DEF; 507
533 sd->colors = COLOR_DEF;
534 sd->white_balance = WHITEBALANCE_DEF;
535 sd->red_balance = REDBALANCE_DEF;
536 sd->blue_balance = BLUEBALANCE_DEF;
537 sd->gain = GAIN_DEF;
538 sd->exposure = EXPOSURE_DEF;
539 sd->autogain = AUTOGAIN_DEF;
540 sd->hflip = HFLIP_DEF;
541 sd->vflip = VFLIP_DEF;
542 sd->flags = id->driver_info; 508 sd->flags = id->driver_info;
543 return 0; 509 return 0;
544} 510}
@@ -548,19 +514,19 @@ static void setbrightcont(struct gspca_dev *gspca_dev)
548{ 514{
549 struct sd *sd = (struct sd *) gspca_dev; 515 struct sd *sd = (struct sd *) gspca_dev;
550 int i, v; 516 int i, v;
551 static const __u8 max[10] = 517 static const u8 max[10] =
552 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb, 518 {0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
553 0xd4, 0xec}; 519 0xd4, 0xec};
554 static const __u8 delta[10] = 520 static const u8 delta[10] =
555 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17, 521 {0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
556 0x11, 0x0b}; 522 0x11, 0x0b};
557 523
558 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 524 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
559 for (i = 0; i < 10; i++) { 525 for (i = 0; i < 10; i++) {
560 v = max[i]; 526 v = max[i];
561 v += (sd->brightness - BRIGHTNESS_MAX) 527 v += (sd->ctrls[BRIGHTNESS].val - BRIGHTNESS_MAX)
562 * 150 / BRIGHTNESS_MAX; /* 200 ? */ 528 * 150 / BRIGHTNESS_MAX; /* 200 ? */
563 v -= delta[i] * sd->contrast / CONTRAST_MAX; 529 v -= delta[i] * sd->ctrls[CONTRAST].val / CONTRAST_MAX;
564 if (v < 0) 530 if (v < 0)
565 v = 0; 531 v = 0;
566 else if (v > 0xff) 532 else if (v > 0xff)
@@ -584,12 +550,11 @@ static void setcolors(struct gspca_dev *gspca_dev)
584 reg_w(gspca_dev, 0x11, 0x01); 550 reg_w(gspca_dev, 0x11, 0x01);
585 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 551 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
586 for (i = 0; i < 9; i++) { 552 for (i = 0; i < 9; i++) {
587 v = a[i] * sd->colors / COLOR_MAX + b[i]; 553 v = a[i] * sd->ctrls[COLORS].val / COLOR_MAX + b[i];
588 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07); 554 reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
589 reg_w(gspca_dev, 0x0f + 2 * i + 1, v); 555 reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
590 } 556 }
591 reg_w(gspca_dev, 0xdc, 0x01); 557 reg_w(gspca_dev, 0xdc, 0x01);
592 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
593} 558}
594 559
595static void setwhitebalance(struct gspca_dev *gspca_dev) 560static void setwhitebalance(struct gspca_dev *gspca_dev)
@@ -597,10 +562,9 @@ static void setwhitebalance(struct gspca_dev *gspca_dev)
597 struct sd *sd = (struct sd *) gspca_dev; 562 struct sd *sd = (struct sd *) gspca_dev;
598 563
599 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 564 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
600 reg_w(gspca_dev, 0xc6, sd->white_balance); 565 reg_w(gspca_dev, 0xc6, sd->ctrls[WHITE_BALANCE].val);
601 566
602 reg_w(gspca_dev, 0xdc, 0x01); 567 reg_w(gspca_dev, 0xdc, 0x01);
603 PDEBUG(D_CONF|D_STREAM, "white_balance: %i", sd->white_balance);
604} 568}
605 569
606static void setredbalance(struct gspca_dev *gspca_dev) 570static void setredbalance(struct gspca_dev *gspca_dev)
@@ -608,10 +572,9 @@ static void setredbalance(struct gspca_dev *gspca_dev)
608 struct sd *sd = (struct sd *) gspca_dev; 572 struct sd *sd = (struct sd *) gspca_dev;
609 573
610 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 574 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
611 reg_w(gspca_dev, 0xc5, sd->red_balance); 575 reg_w(gspca_dev, 0xc5, sd->ctrls[RED_BALANCE].val);
612 576
613 reg_w(gspca_dev, 0xdc, 0x01); 577 reg_w(gspca_dev, 0xdc, 0x01);
614 PDEBUG(D_CONF|D_STREAM, "red_balance: %i", sd->red_balance);
615} 578}
616 579
617static void setbluebalance(struct gspca_dev *gspca_dev) 580static void setbluebalance(struct gspca_dev *gspca_dev)
@@ -619,10 +582,9 @@ static void setbluebalance(struct gspca_dev *gspca_dev)
619 struct sd *sd = (struct sd *) gspca_dev; 582 struct sd *sd = (struct sd *) gspca_dev;
620 583
621 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */ 584 reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
622 reg_w(gspca_dev, 0xc7, sd->blue_balance); 585 reg_w(gspca_dev, 0xc7, sd->ctrls[BLUE_BALANCE].val);
623 586
624 reg_w(gspca_dev, 0xdc, 0x01); 587 reg_w(gspca_dev, 0xdc, 0x01);
625 PDEBUG(D_CONF|D_STREAM, "blue_balance: %i", sd->blue_balance);
626} 588}
627 589
628static void setgain(struct gspca_dev *gspca_dev) 590static void setgain(struct gspca_dev *gspca_dev)
@@ -630,7 +592,7 @@ static void setgain(struct gspca_dev *gspca_dev)
630 struct sd *sd = (struct sd *) gspca_dev; 592 struct sd *sd = (struct sd *) gspca_dev;
631 593
632 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */ 594 reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
633 reg_w(gspca_dev, 0x10, sd->gain >> 3); 595 reg_w(gspca_dev, 0x10, sd->ctrls[GAIN].val >> 3);
634 596
635 /* load registers to sensor (Bit 0, auto clear) */ 597 /* load registers to sensor (Bit 0, auto clear) */
636 reg_w(gspca_dev, 0x11, 0x01); 598 reg_w(gspca_dev, 0x11, 0x01);
@@ -639,13 +601,13 @@ static void setgain(struct gspca_dev *gspca_dev)
639static void setexposure(struct gspca_dev *gspca_dev) 601static void setexposure(struct gspca_dev *gspca_dev)
640{ 602{
641 struct sd *sd = (struct sd *) gspca_dev; 603 struct sd *sd = (struct sd *) gspca_dev;
642 __u8 clockdiv; 604 u8 clockdiv;
643 __u16 exposure; 605 u16 exposure;
644 606
645 /* register 2 of frame 3 contains the clock divider configuring the 607 /* register 2 of frame 3 contains the clock divider configuring the
646 no fps according to the formula: 90 / reg. sd->exposure is the 608 no fps according to the formula: 90 / reg. sd->exposure is the
647 desired exposure time in 0.5 ms. */ 609 desired exposure time in 0.5 ms. */
648 clockdiv = (90 * sd->exposure + 1999) / 2000; 610 clockdiv = (90 * sd->ctrls[EXPOSURE].val + 1999) / 2000;
649 611
650 /* Note clockdiv = 3 also works, but when running at 30 fps, depending 612 /* Note clockdiv = 3 also works, but when running at 30 fps, depending
651 on the scene being recorded, the camera switches to another 613 on the scene being recorded, the camera switches to another
@@ -664,7 +626,7 @@ static void setexposure(struct gspca_dev *gspca_dev)
664 626
665 /* frame exposure time in ms = 1000 * clockdiv / 90 -> 627 /* frame exposure time in ms = 1000 * clockdiv / 90 ->
666 exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90) */ 628 exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90) */
667 exposure = (sd->exposure * 45 * 448) / (1000 * clockdiv); 629 exposure = (sd->ctrls[EXPOSURE].val * 45 * 448) / (1000 * clockdiv);
668 /* 0 = use full frametime, 448 = no exposure, reverse it */ 630 /* 0 = use full frametime, 448 = no exposure, reverse it */
669 exposure = 448 - exposure; 631 exposure = 448 - exposure;
670 632
@@ -677,15 +639,35 @@ static void setexposure(struct gspca_dev *gspca_dev)
677 reg_w(gspca_dev, 0x11, 0x01); 639 reg_w(gspca_dev, 0x11, 0x01);
678} 640}
679 641
642static void setautogain(struct gspca_dev *gspca_dev)
643{
644 struct sd *sd = (struct sd *) gspca_dev;
645
646 /* when switching to autogain set defaults to make sure
647 we are on a valid point of the autogain gain /
648 exposure knee graph, and give this change time to
649 take effect before doing autogain. */
650 if (sd->ctrls[AUTOGAIN].val) {
651 sd->ctrls[EXPOSURE].val = EXPOSURE_DEF;
652 sd->ctrls[GAIN].val = GAIN_DEF;
653 sd->autogain_ignore_frames =
654 PAC_AUTOGAIN_IGNORE_FRAMES;
655 } else {
656 sd->autogain_ignore_frames = -1;
657 }
658 setexposure(gspca_dev);
659 setgain(gspca_dev);
660}
661
680static void sethvflip(struct gspca_dev *gspca_dev) 662static void sethvflip(struct gspca_dev *gspca_dev)
681{ 663{
682 struct sd *sd = (struct sd *) gspca_dev; 664 struct sd *sd = (struct sd *) gspca_dev;
683 u8 data, hflip, vflip; 665 u8 data, hflip, vflip;
684 666
685 hflip = sd->hflip; 667 hflip = sd->ctrls[HFLIP].val;
686 if (sd->flags & FL_HFLIP) 668 if (sd->flags & FL_HFLIP)
687 hflip = !hflip; 669 hflip = !hflip;
688 vflip = sd->vflip; 670 vflip = sd->ctrls[VFLIP].val;
689 if (sd->flags & FL_VFLIP) 671 if (sd->flags & FL_VFLIP)
690 vflip = !vflip; 672 vflip = !vflip;
691 673
@@ -708,8 +690,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
708{ 690{
709 struct sd *sd = (struct sd *) gspca_dev; 691 struct sd *sd = (struct sd *) gspca_dev;
710 692
711 sd->sof_read = 0;
712
713 reg_w_var(gspca_dev, start_7302, 693 reg_w_var(gspca_dev, start_7302,
714 page3_7302, sizeof(page3_7302)); 694 page3_7302, sizeof(page3_7302));
715 setbrightcont(gspca_dev); 695 setbrightcont(gspca_dev);
@@ -717,15 +697,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
717 setwhitebalance(gspca_dev); 697 setwhitebalance(gspca_dev);
718 setredbalance(gspca_dev); 698 setredbalance(gspca_dev);
719 setbluebalance(gspca_dev); 699 setbluebalance(gspca_dev);
720 setgain(gspca_dev); 700 setautogain(gspca_dev);
721 setexposure(gspca_dev);
722 sethvflip(gspca_dev); 701 sethvflip(gspca_dev);
723 702
724 /* only resolution 640x480 is supported for pac7302 */ 703 /* only resolution 640x480 is supported for pac7302 */
725 704
726 sd->sof_read = 0; 705 sd->sof_read = 0;
727 sd->autogain_ignore_frames = 0; 706 atomic_set(&sd->avg_lum, 270 + sd->ctrls[BRIGHTNESS].val);
728 atomic_set(&sd->avg_lum, -1);
729 707
730 /* start stream */ 708 /* start stream */
731 reg_w(gspca_dev, 0xff, 0x01); 709 reg_w(gspca_dev, 0xff, 0x01);
@@ -751,8 +729,10 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
751 reg_w(gspca_dev, 0x78, 0x40); 729 reg_w(gspca_dev, 0x78, 0x40);
752} 730}
753 731
754/* Include pac common sof detection functions */ 732/* !! coarse_grained_expo_autogain is not used !! */
755#include "pac_common.h" 733#define exp_too_low_cnt flags
734#define exp_too_high_cnt sof_read
735#include "autogain_functions.h"
756 736
757static void do_autogain(struct gspca_dev *gspca_dev) 737static void do_autogain(struct gspca_dev *gspca_dev)
758{ 738{
@@ -761,65 +741,44 @@ static void do_autogain(struct gspca_dev *gspca_dev)
761 int desired_lum; 741 int desired_lum;
762 const int deadzone = 30; 742 const int deadzone = 30;
763 743
764 if (avg_lum == -1) 744 if (sd->autogain_ignore_frames < 0)
765 return; 745 return;
766 746
767 desired_lum = 270 + sd->brightness; 747 if (sd->autogain_ignore_frames > 0) {
768
769 if (sd->autogain_ignore_frames > 0)
770 sd->autogain_ignore_frames--; 748 sd->autogain_ignore_frames--;
771 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum, 749 } else {
772 deadzone, GAIN_KNEE, EXPOSURE_KNEE)) 750 desired_lum = 270 + sd->ctrls[BRIGHTNESS].val;
751
752 auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum,
753 deadzone, GAIN_KNEE, EXPOSURE_KNEE);
773 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; 754 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
755 }
774} 756}
775 757
776/* JPEG header, part 1 */ 758/* JPEG header */
777static const unsigned char pac_jpeg_header1[] = { 759static const u8 jpeg_header[] = {
778 0xff, 0xd8, /* SOI: Start of Image */ 760 0xff, 0xd8, /* SOI: Start of Image */
779 761
780 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */ 762 0xff, 0xc0, /* SOF0: Start of Frame (Baseline DCT) */
781 0x00, 0x11, /* length = 17 bytes (including this length field) */ 763 0x00, 0x11, /* length = 17 bytes (including this length field) */
782 0x08 /* Precision: 8 */ 764 0x08, /* Precision: 8 */
783 /* 2 bytes is placed here: number of image lines */ 765 0x02, 0x80, /* height = 640 (image rotated) */
784 /* 2 bytes is placed here: samples per line */ 766 0x01, 0xe0, /* width = 480 */
785}; 767 0x03, /* Number of image components: 3 */
786 768 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */
787/* JPEG header, continued */ 769 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */
788static const unsigned char pac_jpeg_header2[] = { 770 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */
789 0x03, /* Number of image components: 3 */ 771
790 0x01, 0x21, 0x00, /* ID=1, Subsampling 1x1, Quantization table: 0 */ 772 0xff, 0xda, /* SOS: Start Of Scan */
791 0x02, 0x11, 0x01, /* ID=2, Subsampling 2x1, Quantization table: 1 */ 773 0x00, 0x0c, /* length = 12 bytes (including this length field) */
792 0x03, 0x11, 0x01, /* ID=3, Subsampling 2x1, Quantization table: 1 */ 774 0x03, /* number of components: 3 */
793 775 0x01, 0x00, /* selector 1, table 0x00 */
794 0xff, 0xda, /* SOS: Start Of Scan */ 776 0x02, 0x11, /* selector 2, table 0x11 */
795 0x00, 0x0c, /* length = 12 bytes (including this length field) */ 777 0x03, 0x11, /* selector 3, table 0x11 */
796 0x03, /* number of components: 3 */ 778 0x00, 0x3f, /* Spectral selection: 0 .. 63 */
797 0x01, 0x00, /* selector 1, table 0x00 */ 779 0x00 /* Successive approximation: 0 */
798 0x02, 0x11, /* selector 2, table 0x11 */
799 0x03, 0x11, /* selector 3, table 0x11 */
800 0x00, 0x3f, /* Spectral selection: 0 .. 63 */
801 0x00 /* Successive approximation: 0 */
802}; 780};
803 781
804static void pac_start_frame(struct gspca_dev *gspca_dev,
805 __u16 lines, __u16 samples_per_line)
806{
807 unsigned char tmpbuf[4];
808
809 gspca_frame_add(gspca_dev, FIRST_PACKET,
810 pac_jpeg_header1, sizeof(pac_jpeg_header1));
811
812 tmpbuf[0] = lines >> 8;
813 tmpbuf[1] = lines & 0xff;
814 tmpbuf[2] = samples_per_line >> 8;
815 tmpbuf[3] = samples_per_line & 0xff;
816
817 gspca_frame_add(gspca_dev, INTER_PACKET,
818 tmpbuf, sizeof(tmpbuf));
819 gspca_frame_add(gspca_dev, INTER_PACKET,
820 pac_jpeg_header2, sizeof(pac_jpeg_header2));
821}
822
823/* this function is run at interrupt level */ 782/* this function is run at interrupt level */
824static void sd_pkt_scan(struct gspca_dev *gspca_dev, 783static void sd_pkt_scan(struct gspca_dev *gspca_dev,
825 u8 *data, /* isoc packet */ 784 u8 *data, /* isoc packet */
@@ -827,7 +786,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
827{ 786{
828 struct sd *sd = (struct sd *) gspca_dev; 787 struct sd *sd = (struct sd *) gspca_dev;
829 u8 *image; 788 u8 *image;
830 unsigned char *sof; 789 u8 *sof;
831 790
832 sof = pac_find_sof(&sd->sof_read, data, len); 791 sof = pac_find_sof(&sd->sof_read, data, len);
833 if (sof) { 792 if (sof) {
@@ -864,234 +823,21 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
864 n >= lum_offset) 823 n >= lum_offset)
865 atomic_set(&sd->avg_lum, data[-lum_offset] + 824 atomic_set(&sd->avg_lum, data[-lum_offset] +
866 data[-lum_offset + 1]); 825 data[-lum_offset + 1]);
867 else
868 atomic_set(&sd->avg_lum, -1);
869 826
870 /* Start the new frame with the jpeg header */ 827 /* Start the new frame with the jpeg header */
871 /* The PAC7302 has the image rotated 90 degrees */ 828 /* The PAC7302 has the image rotated 90 degrees */
872 pac_start_frame(gspca_dev, 829 gspca_frame_add(gspca_dev, FIRST_PACKET,
873 gspca_dev->width, gspca_dev->height); 830 jpeg_header, sizeof jpeg_header);
874 } 831 }
875 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 832 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
876} 833}
877 834
878static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
879{
880 struct sd *sd = (struct sd *) gspca_dev;
881
882 sd->brightness = val;
883 if (gspca_dev->streaming)
884 setbrightcont(gspca_dev);
885 return gspca_dev->usb_err;
886}
887
888static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
889{
890 struct sd *sd = (struct sd *) gspca_dev;
891
892 *val = sd->brightness;
893 return 0;
894}
895
896static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
897{
898 struct sd *sd = (struct sd *) gspca_dev;
899
900 sd->contrast = val;
901 if (gspca_dev->streaming)
902 setbrightcont(gspca_dev);
903 return gspca_dev->usb_err;
904}
905
906static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
907{
908 struct sd *sd = (struct sd *) gspca_dev;
909
910 *val = sd->contrast;
911 return 0;
912}
913
914static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
915{
916 struct sd *sd = (struct sd *) gspca_dev;
917
918 sd->colors = val;
919 if (gspca_dev->streaming)
920 setcolors(gspca_dev);
921 return gspca_dev->usb_err;
922}
923
924static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
925{
926 struct sd *sd = (struct sd *) gspca_dev;
927
928 *val = sd->colors;
929 return 0;
930}
931
932static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
933{
934 struct sd *sd = (struct sd *) gspca_dev;
935
936 sd->white_balance = val;
937 if (gspca_dev->streaming)
938 setwhitebalance(gspca_dev);
939 return gspca_dev->usb_err;
940}
941
942static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
943{
944 struct sd *sd = (struct sd *) gspca_dev;
945
946 *val = sd->white_balance;
947 return 0;
948}
949
950static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val)
951{
952 struct sd *sd = (struct sd *) gspca_dev;
953
954 sd->red_balance = val;
955 if (gspca_dev->streaming)
956 setredbalance(gspca_dev);
957 return gspca_dev->usb_err;
958}
959
960static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val)
961{
962 struct sd *sd = (struct sd *) gspca_dev;
963
964 *val = sd->red_balance;
965 return 0;
966}
967
968static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val)
969{
970 struct sd *sd = (struct sd *) gspca_dev;
971
972 sd->blue_balance = val;
973 if (gspca_dev->streaming)
974 setbluebalance(gspca_dev);
975 return gspca_dev->usb_err;
976}
977
978static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val)
979{
980 struct sd *sd = (struct sd *) gspca_dev;
981
982 *val = sd->blue_balance;
983 return 0;
984}
985
986static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
987{
988 struct sd *sd = (struct sd *) gspca_dev;
989
990 sd->gain = val;
991 if (gspca_dev->streaming)
992 setgain(gspca_dev);
993 return gspca_dev->usb_err;
994}
995
996static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
997{
998 struct sd *sd = (struct sd *) gspca_dev;
999
1000 *val = sd->gain;
1001 return 0;
1002}
1003
1004static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1005{
1006 struct sd *sd = (struct sd *) gspca_dev;
1007
1008 sd->exposure = val;
1009 if (gspca_dev->streaming)
1010 setexposure(gspca_dev);
1011 return gspca_dev->usb_err;
1012}
1013
1014static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1015{
1016 struct sd *sd = (struct sd *) gspca_dev;
1017
1018 *val = sd->exposure;
1019 return 0;
1020}
1021
1022static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1023{
1024 struct sd *sd = (struct sd *) gspca_dev;
1025
1026 sd->autogain = val;
1027 /* when switching to autogain set defaults to make sure
1028 we are on a valid point of the autogain gain /
1029 exposure knee graph, and give this change time to
1030 take effect before doing autogain. */
1031 if (sd->autogain) {
1032 sd->exposure = EXPOSURE_DEF;
1033 sd->gain = GAIN_DEF;
1034 if (gspca_dev->streaming) {
1035 sd->autogain_ignore_frames =
1036 PAC_AUTOGAIN_IGNORE_FRAMES;
1037 setexposure(gspca_dev);
1038 setgain(gspca_dev);
1039 }
1040 }
1041
1042 return gspca_dev->usb_err;
1043}
1044
1045static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1046{
1047 struct sd *sd = (struct sd *) gspca_dev;
1048
1049 *val = sd->autogain;
1050 return 0;
1051}
1052
1053static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
1054{
1055 struct sd *sd = (struct sd *) gspca_dev;
1056
1057 sd->hflip = val;
1058 if (gspca_dev->streaming)
1059 sethvflip(gspca_dev);
1060 return gspca_dev->usb_err;
1061}
1062
1063static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
1064{
1065 struct sd *sd = (struct sd *) gspca_dev;
1066
1067 *val = sd->hflip;
1068 return 0;
1069}
1070
1071static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1072{
1073 struct sd *sd = (struct sd *) gspca_dev;
1074
1075 sd->vflip = val;
1076 if (gspca_dev->streaming)
1077 sethvflip(gspca_dev);
1078 return gspca_dev->usb_err;
1079}
1080
1081static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1082{
1083 struct sd *sd = (struct sd *) gspca_dev;
1084
1085 *val = sd->vflip;
1086 return 0;
1087}
1088
1089#ifdef CONFIG_VIDEO_ADV_DEBUG 835#ifdef CONFIG_VIDEO_ADV_DEBUG
1090static int sd_dbg_s_register(struct gspca_dev *gspca_dev, 836static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1091 struct v4l2_dbg_register *reg) 837 struct v4l2_dbg_register *reg)
1092{ 838{
1093 __u8 index; 839 u8 index;
1094 __u8 value; 840 u8 value;
1095 841
1096 /* reg->reg: bit0..15: reserved for register index (wIndex is 16bit 842 /* reg->reg: bit0..15: reserved for register index (wIndex is 16bit
1097 long on the USB bus) 843 long on the USB bus)
@@ -1103,8 +849,8 @@ static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1103 ) { 849 ) {
1104 /* Currently writing to page 0 is only supported. */ 850 /* Currently writing to page 0 is only supported. */
1105 /* reg_w() only supports 8bit index */ 851 /* reg_w() only supports 8bit index */
1106 index = reg->reg & 0x000000ff; 852 index = reg->reg;
1107 value = reg->val & 0x000000ff; 853 value = reg->val;
1108 854
1109 /* Note that there shall be no access to other page 855 /* Note that there shall be no access to other page
1110 by any other function between the page swith and 856 by any other function between the page swith and
@@ -1165,7 +911,7 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
1165 911
1166/* sub-driver description for pac7302 */ 912/* sub-driver description for pac7302 */
1167static const struct sd_desc sd_desc = { 913static const struct sd_desc sd_desc = {
1168 .name = MODULE_NAME, 914 .name = KBUILD_MODNAME,
1169 .ctrls = sd_ctrls, 915 .ctrls = sd_ctrls,
1170 .nctrls = ARRAY_SIZE(sd_ctrls), 916 .nctrls = ARRAY_SIZE(sd_ctrls),
1171 .config = sd_config, 917 .config = sd_config,
@@ -1187,6 +933,7 @@ static const struct sd_desc sd_desc = {
1187/* -- module initialisation -- */ 933/* -- module initialisation -- */
1188static const struct usb_device_id device_table[] = { 934static const struct usb_device_id device_table[] = {
1189 {USB_DEVICE(0x06f8, 0x3009)}, 935 {USB_DEVICE(0x06f8, 0x3009)},
936 {USB_DEVICE(0x06f8, 0x301b)},
1190 {USB_DEVICE(0x093a, 0x2620)}, 937 {USB_DEVICE(0x093a, 0x2620)},
1191 {USB_DEVICE(0x093a, 0x2621)}, 938 {USB_DEVICE(0x093a, 0x2621)},
1192 {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP}, 939 {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
@@ -1211,7 +958,7 @@ static int sd_probe(struct usb_interface *intf,
1211} 958}
1212 959
1213static struct usb_driver sd_driver = { 960static struct usb_driver sd_driver = {
1214 .name = MODULE_NAME, 961 .name = KBUILD_MODNAME,
1215 .id_table = device_table, 962 .id_table = device_table,
1216 .probe = sd_probe, 963 .probe = sd_probe,
1217 .disconnect = gspca_disconnect, 964 .disconnect = gspca_disconnect,
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
index 9e198b45c3c8..7e71aa2d2522 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -1,5 +1,7 @@
1/* 1/*
2 * Sonix sn9c201 sn9c202 library 2 * Sonix sn9c201 sn9c202 library
3 *
4 * Copyright (C) 2012 Jean-Francois Moine <http://moinejf.free.fr>
3 * Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com> 5 * Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com>
4 * Copyright (C) 2009 Brian Johnson <brijohn@gmail.com> 6 * Copyright (C) 2009 Brian Johnson <brijohn@gmail.com>
5 * 7 *
@@ -33,8 +35,6 @@ MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
33MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver"); 35MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
34MODULE_LICENSE("GPL"); 36MODULE_LICENSE("GPL");
35 37
36#define MODULE_NAME "sn9c20x"
37
38/* 38/*
39 * Pixel format private data 39 * Pixel format private data
40 */ 40 */
@@ -66,10 +66,37 @@ MODULE_LICENSE("GPL");
66#define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */ 66#define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
67#define FLIP_DETECT 0x4 67#define FLIP_DETECT 0x4
68 68
69enum e_ctrl {
70 BRIGHTNESS,
71 CONTRAST,
72 SATURATION,
73 HUE,
74 GAMMA,
75 BLUE,
76 RED,
77 VFLIP,
78 HFLIP,
79 EXPOSURE,
80 GAIN,
81 AUTOGAIN,
82 QUALITY,
83 NCTRLS /* number of controls */
84};
85
69/* specific webcam descriptor */ 86/* specific webcam descriptor */
70struct sd { 87struct sd {
71 struct gspca_dev gspca_dev; 88 struct gspca_dev gspca_dev;
72 89
90 struct gspca_ctrl ctrls[NCTRLS];
91
92 struct work_struct work;
93 struct workqueue_struct *work_thread;
94
95 u32 pktsz; /* (used by pkt_scan) */
96 u16 npkt;
97 s8 nchg;
98 u8 fmt; /* (used for JPEG QTAB update */
99
73#define MIN_AVG_LUM 80 100#define MIN_AVG_LUM 80
74#define MAX_AVG_LUM 130 101#define MAX_AVG_LUM 130
75 atomic_t avg_lum; 102 atomic_t avg_lum;
@@ -77,31 +104,18 @@ struct sd {
77 u8 older_step; 104 u8 older_step;
78 u8 exposure_step; 105 u8 exposure_step;
79 106
80 u8 brightness;
81 u8 contrast;
82 u8 saturation;
83 s16 hue;
84 u8 gamma;
85 u8 red;
86 u8 blue;
87
88 u8 hflip;
89 u8 vflip;
90 u8 gain;
91 u16 exposure;
92 u8 auto_exposure;
93
94 u8 i2c_addr; 107 u8 i2c_addr;
95 u8 sensor; 108 u8 sensor;
96 u8 hstart; 109 u8 hstart;
97 u8 vstart; 110 u8 vstart;
98 111
99 u8 jpeg_hdr[JPEG_HDR_SZ]; 112 u8 jpeg_hdr[JPEG_HDR_SZ];
100 u8 quality;
101 113
102 u8 flags; 114 u8 flags;
103}; 115};
104 116
117static void qual_upd(struct work_struct *work);
118
105struct i2c_reg_u8 { 119struct i2c_reg_u8 {
106 u8 reg; 120 u8 reg;
107 u8 val; 121 u8 val;
@@ -112,31 +126,6 @@ struct i2c_reg_u16 {
112 u16 val; 126 u16 val;
113}; 127};
114 128
115static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val);
116static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val);
117static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val);
118static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val);
119static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val);
120static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val);
121static int sd_sethue(struct gspca_dev *gspca_dev, s32 val);
122static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val);
123static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val);
124static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val);
125static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val);
126static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val);
127static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val);
128static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val);
129static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val);
130static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val);
131static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val);
132static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val);
133static int sd_setgain(struct gspca_dev *gspca_dev, s32 val);
134static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val);
135static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val);
136static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val);
137static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val);
138static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val);
139
140static const struct dmi_system_id flip_dmi_table[] = { 129static const struct dmi_system_id flip_dmi_table[] = {
141 { 130 {
142 .ident = "MSI MS-1034", 131 .ident = "MSI MS-1034",
@@ -177,9 +166,16 @@ static const struct dmi_system_id flip_dmi_table[] = {
177 {} 166 {}
178}; 167};
179 168
180static const struct ctrl sd_ctrls[] = { 169static void set_cmatrix(struct gspca_dev *gspca_dev);
181 { 170static void set_gamma(struct gspca_dev *gspca_dev);
182#define BRIGHTNESS_IDX 0 171static void set_redblue(struct gspca_dev *gspca_dev);
172static void set_hvflip(struct gspca_dev *gspca_dev);
173static void set_exposure(struct gspca_dev *gspca_dev);
174static void set_gain(struct gspca_dev *gspca_dev);
175static void set_quality(struct gspca_dev *gspca_dev);
176
177static const struct ctrl sd_ctrls[NCTRLS] = {
178[BRIGHTNESS] = {
183 { 179 {
184 .id = V4L2_CID_BRIGHTNESS, 180 .id = V4L2_CID_BRIGHTNESS,
185 .type = V4L2_CTRL_TYPE_INTEGER, 181 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -187,14 +183,11 @@ static const struct ctrl sd_ctrls[] = {
187 .minimum = 0, 183 .minimum = 0,
188 .maximum = 0xff, 184 .maximum = 0xff,
189 .step = 1, 185 .step = 1,
190#define BRIGHTNESS_DEFAULT 0x7f 186 .default_value = 0x7f
191 .default_value = BRIGHTNESS_DEFAULT,
192 }, 187 },
193 .set = sd_setbrightness, 188 .set_control = set_cmatrix
194 .get = sd_getbrightness,
195 }, 189 },
196 { 190[CONTRAST] = {
197#define CONTRAST_IDX 1
198 { 191 {
199 .id = V4L2_CID_CONTRAST, 192 .id = V4L2_CID_CONTRAST,
200 .type = V4L2_CTRL_TYPE_INTEGER, 193 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -202,14 +195,11 @@ static const struct ctrl sd_ctrls[] = {
202 .minimum = 0, 195 .minimum = 0,
203 .maximum = 0xff, 196 .maximum = 0xff,
204 .step = 1, 197 .step = 1,
205#define CONTRAST_DEFAULT 0x7f 198 .default_value = 0x7f
206 .default_value = CONTRAST_DEFAULT,
207 }, 199 },
208 .set = sd_setcontrast, 200 .set_control = set_cmatrix
209 .get = sd_getcontrast,
210 }, 201 },
211 { 202[SATURATION] = {
212#define SATURATION_IDX 2
213 { 203 {
214 .id = V4L2_CID_SATURATION, 204 .id = V4L2_CID_SATURATION,
215 .type = V4L2_CTRL_TYPE_INTEGER, 205 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -217,14 +207,11 @@ static const struct ctrl sd_ctrls[] = {
217 .minimum = 0, 207 .minimum = 0,
218 .maximum = 0xff, 208 .maximum = 0xff,
219 .step = 1, 209 .step = 1,
220#define SATURATION_DEFAULT 0x7f 210 .default_value = 0x7f
221 .default_value = SATURATION_DEFAULT,
222 }, 211 },
223 .set = sd_setsaturation, 212 .set_control = set_cmatrix
224 .get = sd_getsaturation,
225 }, 213 },
226 { 214[HUE] = {
227#define HUE_IDX 3
228 { 215 {
229 .id = V4L2_CID_HUE, 216 .id = V4L2_CID_HUE,
230 .type = V4L2_CTRL_TYPE_INTEGER, 217 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -232,14 +219,11 @@ static const struct ctrl sd_ctrls[] = {
232 .minimum = -180, 219 .minimum = -180,
233 .maximum = 180, 220 .maximum = 180,
234 .step = 1, 221 .step = 1,
235#define HUE_DEFAULT 0 222 .default_value = 0
236 .default_value = HUE_DEFAULT,
237 }, 223 },
238 .set = sd_sethue, 224 .set_control = set_cmatrix
239 .get = sd_gethue,
240 }, 225 },
241 { 226[GAMMA] = {
242#define GAMMA_IDX 4
243 { 227 {
244 .id = V4L2_CID_GAMMA, 228 .id = V4L2_CID_GAMMA,
245 .type = V4L2_CTRL_TYPE_INTEGER, 229 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -247,14 +231,11 @@ static const struct ctrl sd_ctrls[] = {
247 .minimum = 0, 231 .minimum = 0,
248 .maximum = 0xff, 232 .maximum = 0xff,
249 .step = 1, 233 .step = 1,
250#define GAMMA_DEFAULT 0x10 234 .default_value = 0x10
251 .default_value = GAMMA_DEFAULT,
252 }, 235 },
253 .set = sd_setgamma, 236 .set_control = set_gamma
254 .get = sd_getgamma,
255 }, 237 },
256 { 238[BLUE] = {
257#define BLUE_IDX 5
258 { 239 {
259 .id = V4L2_CID_BLUE_BALANCE, 240 .id = V4L2_CID_BLUE_BALANCE,
260 .type = V4L2_CTRL_TYPE_INTEGER, 241 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -262,14 +243,11 @@ static const struct ctrl sd_ctrls[] = {
262 .minimum = 0, 243 .minimum = 0,
263 .maximum = 0x7f, 244 .maximum = 0x7f,
264 .step = 1, 245 .step = 1,
265#define BLUE_DEFAULT 0x28 246 .default_value = 0x28
266 .default_value = BLUE_DEFAULT,
267 }, 247 },
268 .set = sd_setbluebalance, 248 .set_control = set_redblue
269 .get = sd_getbluebalance,
270 }, 249 },
271 { 250[RED] = {
272#define RED_IDX 6
273 { 251 {
274 .id = V4L2_CID_RED_BALANCE, 252 .id = V4L2_CID_RED_BALANCE,
275 .type = V4L2_CTRL_TYPE_INTEGER, 253 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -277,14 +255,11 @@ static const struct ctrl sd_ctrls[] = {
277 .minimum = 0, 255 .minimum = 0,
278 .maximum = 0x7f, 256 .maximum = 0x7f,
279 .step = 1, 257 .step = 1,
280#define RED_DEFAULT 0x28 258 .default_value = 0x28
281 .default_value = RED_DEFAULT,
282 }, 259 },
283 .set = sd_setredbalance, 260 .set_control = set_redblue
284 .get = sd_getredbalance,
285 }, 261 },
286 { 262[HFLIP] = {
287#define HFLIP_IDX 7
288 { 263 {
289 .id = V4L2_CID_HFLIP, 264 .id = V4L2_CID_HFLIP,
290 .type = V4L2_CTRL_TYPE_BOOLEAN, 265 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -292,14 +267,11 @@ static const struct ctrl sd_ctrls[] = {
292 .minimum = 0, 267 .minimum = 0,
293 .maximum = 1, 268 .maximum = 1,
294 .step = 1, 269 .step = 1,
295#define HFLIP_DEFAULT 0 270 .default_value = 0,
296 .default_value = HFLIP_DEFAULT,
297 }, 271 },
298 .set = sd_sethflip, 272 .set_control = set_hvflip
299 .get = sd_gethflip,
300 }, 273 },
301 { 274[VFLIP] = {
302#define VFLIP_IDX 8
303 { 275 {
304 .id = V4L2_CID_VFLIP, 276 .id = V4L2_CID_VFLIP,
305 .type = V4L2_CTRL_TYPE_BOOLEAN, 277 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -307,14 +279,11 @@ static const struct ctrl sd_ctrls[] = {
307 .minimum = 0, 279 .minimum = 0,
308 .maximum = 1, 280 .maximum = 1,
309 .step = 1, 281 .step = 1,
310#define VFLIP_DEFAULT 0 282 .default_value = 0,
311 .default_value = VFLIP_DEFAULT,
312 }, 283 },
313 .set = sd_setvflip, 284 .set_control = set_hvflip
314 .get = sd_getvflip,
315 }, 285 },
316 { 286[EXPOSURE] = {
317#define EXPOSURE_IDX 9
318 { 287 {
319 .id = V4L2_CID_EXPOSURE, 288 .id = V4L2_CID_EXPOSURE,
320 .type = V4L2_CTRL_TYPE_INTEGER, 289 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -322,14 +291,11 @@ static const struct ctrl sd_ctrls[] = {
322 .minimum = 0, 291 .minimum = 0,
323 .maximum = 0x1780, 292 .maximum = 0x1780,
324 .step = 1, 293 .step = 1,
325#define EXPOSURE_DEFAULT 0x33 294 .default_value = 0x33,
326 .default_value = EXPOSURE_DEFAULT,
327 }, 295 },
328 .set = sd_setexposure, 296 .set_control = set_exposure
329 .get = sd_getexposure,
330 }, 297 },
331 { 298[GAIN] = {
332#define GAIN_IDX 10
333 { 299 {
334 .id = V4L2_CID_GAIN, 300 .id = V4L2_CID_GAIN,
335 .type = V4L2_CTRL_TYPE_INTEGER, 301 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -337,14 +303,11 @@ static const struct ctrl sd_ctrls[] = {
337 .minimum = 0, 303 .minimum = 0,
338 .maximum = 28, 304 .maximum = 28,
339 .step = 1, 305 .step = 1,
340#define GAIN_DEFAULT 0x00 306 .default_value = 0,
341 .default_value = GAIN_DEFAULT,
342 }, 307 },
343 .set = sd_setgain, 308 .set_control = set_gain
344 .get = sd_getgain,
345 }, 309 },
346 { 310[AUTOGAIN] = {
347#define AUTOGAIN_IDX 11
348 { 311 {
349 .id = V4L2_CID_AUTOGAIN, 312 .id = V4L2_CID_AUTOGAIN,
350 .type = V4L2_CTRL_TYPE_BOOLEAN, 313 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -352,11 +315,23 @@ static const struct ctrl sd_ctrls[] = {
352 .minimum = 0, 315 .minimum = 0,
353 .maximum = 1, 316 .maximum = 1,
354 .step = 1, 317 .step = 1,
355#define AUTO_EXPOSURE_DEFAULT 1 318 .default_value = 1,
356 .default_value = AUTO_EXPOSURE_DEFAULT, 319 },
320 },
321[QUALITY] = {
322 {
323 .id = V4L2_CID_JPEG_COMPRESSION_QUALITY,
324 .type = V4L2_CTRL_TYPE_INTEGER,
325 .name = "Compression Quality",
326#define QUALITY_MIN 50
327#define QUALITY_MAX 90
328#define QUALITY_DEF 80
329 .minimum = QUALITY_MIN,
330 .maximum = QUALITY_MAX,
331 .step = 1,
332 .default_value = QUALITY_DEF,
357 }, 333 },
358 .set = sd_setautoexposure, 334 .set_control = set_quality
359 .get = sd_getautoexposure,
360 }, 335 },
361}; 336};
362 337
@@ -876,7 +851,7 @@ static u8 hv7131r_gain[] = {
876}; 851};
877 852
878static struct i2c_reg_u8 soi968_init[] = { 853static struct i2c_reg_u8 soi968_init[] = {
879 {0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f}, 854 {0x0c, 0x00}, {0x0f, 0x1f},
880 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00}, 855 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
881 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c}, 856 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
882 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff}, 857 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
@@ -902,7 +877,7 @@ static struct i2c_reg_u8 ov7660_init[] = {
902}; 877};
903 878
904static struct i2c_reg_u8 ov7670_init[] = { 879static struct i2c_reg_u8 ov7670_init[] = {
905 {0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01}, 880 {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
906 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00}, 881 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
907 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0}, 882 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
908 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00}, 883 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
@@ -959,7 +934,7 @@ static struct i2c_reg_u8 ov7670_init[] = {
959}; 934};
960 935
961static struct i2c_reg_u8 ov9650_init[] = { 936static struct i2c_reg_u8 ov9650_init[] = {
962 {0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78}, 937 {0x00, 0x00}, {0x01, 0x78},
963 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03}, 938 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
964 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00}, 939 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
965 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00}, 940 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
@@ -989,7 +964,7 @@ static struct i2c_reg_u8 ov9650_init[] = {
989}; 964};
990 965
991static struct i2c_reg_u8 ov9655_init[] = { 966static struct i2c_reg_u8 ov9655_init[] = {
992 {0x12, 0x80}, {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba}, 967 {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
993 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08}, 968 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
994 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d}, 969 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
995 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57}, 970 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
@@ -1112,10 +1087,13 @@ static struct i2c_reg_u8 hv7131r_init[] = {
1112 {0x23, 0x09}, {0x01, 0x08}, 1087 {0x23, 0x09}, {0x01, 0x08},
1113}; 1088};
1114 1089
1115static int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length) 1090static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
1116{ 1091{
1117 struct usb_device *dev = gspca_dev->dev; 1092 struct usb_device *dev = gspca_dev->dev;
1118 int result; 1093 int result;
1094
1095 if (gspca_dev->usb_err < 0)
1096 return;
1119 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 1097 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
1120 0x00, 1098 0x00,
1121 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 1099 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
@@ -1125,17 +1103,19 @@ static int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
1125 length, 1103 length,
1126 500); 1104 500);
1127 if (unlikely(result < 0 || result != length)) { 1105 if (unlikely(result < 0 || result != length)) {
1128 pr_err("Read register failed 0x%02X\n", reg); 1106 pr_err("Read register %02x failed %d\n", reg, result);
1129 return -EIO; 1107 gspca_dev->usb_err = result;
1130 } 1108 }
1131 return 0;
1132} 1109}
1133 1110
1134static int reg_w(struct gspca_dev *gspca_dev, u16 reg, 1111static void reg_w(struct gspca_dev *gspca_dev, u16 reg,
1135 const u8 *buffer, int length) 1112 const u8 *buffer, int length)
1136{ 1113{
1137 struct usb_device *dev = gspca_dev->dev; 1114 struct usb_device *dev = gspca_dev->dev;
1138 int result; 1115 int result;
1116
1117 if (gspca_dev->usb_err < 0)
1118 return;
1139 memcpy(gspca_dev->usb_buf, buffer, length); 1119 memcpy(gspca_dev->usb_buf, buffer, length);
1140 result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 1120 result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1141 0x08, 1121 0x08,
@@ -1146,38 +1126,41 @@ static int reg_w(struct gspca_dev *gspca_dev, u16 reg,
1146 length, 1126 length,
1147 500); 1127 500);
1148 if (unlikely(result < 0 || result != length)) { 1128 if (unlikely(result < 0 || result != length)) {
1149 pr_err("Write register failed index 0x%02X\n", reg); 1129 pr_err("Write register %02x failed %d\n", reg, result);
1150 return -EIO; 1130 gspca_dev->usb_err = result;
1151 } 1131 }
1152 return 0;
1153} 1132}
1154 1133
1155static int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value) 1134static void reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
1156{ 1135{
1157 u8 data[1] = {value}; 1136 reg_w(gspca_dev, reg, &value, 1);
1158 return reg_w(gspca_dev, reg, data, 1);
1159} 1137}
1160 1138
1161static int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer) 1139static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
1162{ 1140{
1163 int i; 1141 int i;
1142
1164 reg_w(gspca_dev, 0x10c0, buffer, 8); 1143 reg_w(gspca_dev, 0x10c0, buffer, 8);
1165 for (i = 0; i < 5; i++) { 1144 for (i = 0; i < 5; i++) {
1166 reg_r(gspca_dev, 0x10c0, 1); 1145 reg_r(gspca_dev, 0x10c0, 1);
1146 if (gspca_dev->usb_err < 0)
1147 return;
1167 if (gspca_dev->usb_buf[0] & 0x04) { 1148 if (gspca_dev->usb_buf[0] & 0x04) {
1168 if (gspca_dev->usb_buf[0] & 0x08) 1149 if (gspca_dev->usb_buf[0] & 0x08) {
1169 return -EIO; 1150 pr_err("i2c_w error\n");
1170 return 0; 1151 gspca_dev->usb_err = -EIO;
1152 }
1153 return;
1171 } 1154 }
1172 msleep(1); 1155 msleep(10);
1173 } 1156 }
1174 return -EIO; 1157 pr_err("i2c_w reg %02x no response\n", buffer[2]);
1158/* gspca_dev->usb_err = -EIO; fixme: may occur */
1175} 1159}
1176 1160
1177static int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) 1161static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1178{ 1162{
1179 struct sd *sd = (struct sd *) gspca_dev; 1163 struct sd *sd = (struct sd *) gspca_dev;
1180
1181 u8 row[8]; 1164 u8 row[8];
1182 1165
1183 /* 1166 /*
@@ -1193,10 +1176,19 @@ static int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1193 row[6] = 0x00; 1176 row[6] = 0x00;
1194 row[7] = 0x10; 1177 row[7] = 0x10;
1195 1178
1196 return i2c_w(gspca_dev, row); 1179 i2c_w(gspca_dev, row);
1180}
1181
1182static void i2c_w1_buf(struct gspca_dev *gspca_dev,
1183 struct i2c_reg_u8 *buf, int sz)
1184{
1185 while (--sz >= 0) {
1186 i2c_w1(gspca_dev, buf->reg, buf->val);
1187 buf++;
1188 }
1197} 1189}
1198 1190
1199static int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val) 1191static void i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1200{ 1192{
1201 struct sd *sd = (struct sd *) gspca_dev; 1193 struct sd *sd = (struct sd *) gspca_dev;
1202 u8 row[8]; 1194 u8 row[8];
@@ -1208,16 +1200,25 @@ static int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1208 row[0] = 0x81 | (3 << 4); 1200 row[0] = 0x81 | (3 << 4);
1209 row[1] = sd->i2c_addr; 1201 row[1] = sd->i2c_addr;
1210 row[2] = reg; 1202 row[2] = reg;
1211 row[3] = (val >> 8) & 0xff; 1203 row[3] = val >> 8;
1212 row[4] = val & 0xff; 1204 row[4] = val;
1213 row[5] = 0x00; 1205 row[5] = 0x00;
1214 row[6] = 0x00; 1206 row[6] = 0x00;
1215 row[7] = 0x10; 1207 row[7] = 0x10;
1216 1208
1217 return i2c_w(gspca_dev, row); 1209 i2c_w(gspca_dev, row);
1210}
1211
1212static void i2c_w2_buf(struct gspca_dev *gspca_dev,
1213 struct i2c_reg_u16 *buf, int sz)
1214{
1215 while (--sz >= 0) {
1216 i2c_w2(gspca_dev, buf->reg, buf->val);
1217 buf++;
1218 }
1218} 1219}
1219 1220
1220static int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val) 1221static void i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1221{ 1222{
1222 struct sd *sd = (struct sd *) gspca_dev; 1223 struct sd *sd = (struct sd *) gspca_dev;
1223 u8 row[8]; 1224 u8 row[8];
@@ -1230,19 +1231,15 @@ static int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1230 row[5] = 0; 1231 row[5] = 0;
1231 row[6] = 0; 1232 row[6] = 0;
1232 row[7] = 0x10; 1233 row[7] = 0x10;
1233 if (i2c_w(gspca_dev, row) < 0) 1234 i2c_w(gspca_dev, row);
1234 return -EIO;
1235 row[0] = 0x81 | (1 << 4) | 0x02; 1235 row[0] = 0x81 | (1 << 4) | 0x02;
1236 row[2] = 0; 1236 row[2] = 0;
1237 if (i2c_w(gspca_dev, row) < 0) 1237 i2c_w(gspca_dev, row);
1238 return -EIO; 1238 reg_r(gspca_dev, 0x10c2, 5);
1239 if (reg_r(gspca_dev, 0x10c2, 5) < 0)
1240 return -EIO;
1241 *val = gspca_dev->usb_buf[4]; 1239 *val = gspca_dev->usb_buf[4];
1242 return 0;
1243} 1240}
1244 1241
1245static int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val) 1242static void i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1246{ 1243{
1247 struct sd *sd = (struct sd *) gspca_dev; 1244 struct sd *sd = (struct sd *) gspca_dev;
1248 u8 row[8]; 1245 u8 row[8];
@@ -1255,233 +1252,204 @@ static int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1255 row[5] = 0; 1252 row[5] = 0;
1256 row[6] = 0; 1253 row[6] = 0;
1257 row[7] = 0x10; 1254 row[7] = 0x10;
1258 if (i2c_w(gspca_dev, row) < 0) 1255 i2c_w(gspca_dev, row);
1259 return -EIO;
1260 row[0] = 0x81 | (2 << 4) | 0x02; 1256 row[0] = 0x81 | (2 << 4) | 0x02;
1261 row[2] = 0; 1257 row[2] = 0;
1262 if (i2c_w(gspca_dev, row) < 0) 1258 i2c_w(gspca_dev, row);
1263 return -EIO; 1259 reg_r(gspca_dev, 0x10c2, 5);
1264 if (reg_r(gspca_dev, 0x10c2, 5) < 0)
1265 return -EIO;
1266 *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; 1260 *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1267 return 0;
1268} 1261}
1269 1262
1270static int ov9650_init_sensor(struct gspca_dev *gspca_dev) 1263static void ov9650_init_sensor(struct gspca_dev *gspca_dev)
1271{ 1264{
1272 int i;
1273 u16 id; 1265 u16 id;
1274 struct sd *sd = (struct sd *) gspca_dev; 1266 struct sd *sd = (struct sd *) gspca_dev;
1275 1267
1276 if (i2c_r2(gspca_dev, 0x1c, &id) < 0) 1268 i2c_r2(gspca_dev, 0x1c, &id);
1277 return -EINVAL; 1269 if (gspca_dev->usb_err < 0)
1270 return;
1278 1271
1279 if (id != 0x7fa2) { 1272 if (id != 0x7fa2) {
1280 pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id); 1273 pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id);
1281 return -ENODEV; 1274 gspca_dev->usb_err = -ENODEV;
1275 return;
1282 } 1276 }
1283 1277
1284 for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) { 1278 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1285 if (i2c_w1(gspca_dev, ov9650_init[i].reg, 1279 msleep(200);
1286 ov9650_init[i].val) < 0) { 1280 i2c_w1_buf(gspca_dev, ov9650_init, ARRAY_SIZE(ov9650_init));
1287 pr_err("OV9650 sensor initialization failed\n"); 1281 if (gspca_dev->usb_err < 0)
1288 return -ENODEV; 1282 pr_err("OV9650 sensor initialization failed\n");
1289 }
1290 }
1291 sd->hstart = 1; 1283 sd->hstart = 1;
1292 sd->vstart = 7; 1284 sd->vstart = 7;
1293 return 0;
1294} 1285}
1295 1286
1296static int ov9655_init_sensor(struct gspca_dev *gspca_dev) 1287static void ov9655_init_sensor(struct gspca_dev *gspca_dev)
1297{ 1288{
1298 int i;
1299 struct sd *sd = (struct sd *) gspca_dev; 1289 struct sd *sd = (struct sd *) gspca_dev;
1300 1290
1301 for (i = 0; i < ARRAY_SIZE(ov9655_init); i++) { 1291 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1302 if (i2c_w1(gspca_dev, ov9655_init[i].reg, 1292 msleep(200);
1303 ov9655_init[i].val) < 0) { 1293 i2c_w1_buf(gspca_dev, ov9655_init, ARRAY_SIZE(ov9655_init));
1304 pr_err("OV9655 sensor initialization failed\n"); 1294 if (gspca_dev->usb_err < 0)
1305 return -ENODEV; 1295 pr_err("OV9655 sensor initialization failed\n");
1306 } 1296
1307 }
1308 /* disable hflip and vflip */ 1297 /* disable hflip and vflip */
1309 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); 1298 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
1310 sd->hstart = 1; 1299 sd->hstart = 1;
1311 sd->vstart = 2; 1300 sd->vstart = 2;
1312 return 0;
1313} 1301}
1314 1302
1315static int soi968_init_sensor(struct gspca_dev *gspca_dev) 1303static void soi968_init_sensor(struct gspca_dev *gspca_dev)
1316{ 1304{
1317 int i;
1318 struct sd *sd = (struct sd *) gspca_dev; 1305 struct sd *sd = (struct sd *) gspca_dev;
1319 1306
1320 for (i = 0; i < ARRAY_SIZE(soi968_init); i++) { 1307 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1321 if (i2c_w1(gspca_dev, soi968_init[i].reg, 1308 msleep(200);
1322 soi968_init[i].val) < 0) { 1309 i2c_w1_buf(gspca_dev, soi968_init, ARRAY_SIZE(soi968_init));
1323 pr_err("SOI968 sensor initialization failed\n"); 1310 if (gspca_dev->usb_err < 0)
1324 return -ENODEV; 1311 pr_err("SOI968 sensor initialization failed\n");
1325 } 1312
1326 }
1327 /* disable hflip and vflip */ 1313 /* disable hflip and vflip */
1328 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) 1314 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP)
1329 | (1 << EXPOSURE_IDX); 1315 | (1 << EXPOSURE);
1330 sd->hstart = 60; 1316 sd->hstart = 60;
1331 sd->vstart = 11; 1317 sd->vstart = 11;
1332 return 0;
1333} 1318}
1334 1319
1335static int ov7660_init_sensor(struct gspca_dev *gspca_dev) 1320static void ov7660_init_sensor(struct gspca_dev *gspca_dev)
1336{ 1321{
1337 int i;
1338 struct sd *sd = (struct sd *) gspca_dev; 1322 struct sd *sd = (struct sd *) gspca_dev;
1339 1323
1340 for (i = 0; i < ARRAY_SIZE(ov7660_init); i++) { 1324 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1341 if (i2c_w1(gspca_dev, ov7660_init[i].reg, 1325 msleep(200);
1342 ov7660_init[i].val) < 0) { 1326 i2c_w1_buf(gspca_dev, ov7660_init, ARRAY_SIZE(ov7660_init));
1343 pr_err("OV7660 sensor initialization failed\n"); 1327 if (gspca_dev->usb_err < 0)
1344 return -ENODEV; 1328 pr_err("OV7660 sensor initialization failed\n");
1345 }
1346 }
1347 sd->hstart = 3; 1329 sd->hstart = 3;
1348 sd->vstart = 3; 1330 sd->vstart = 3;
1349 return 0;
1350} 1331}
1351 1332
1352static int ov7670_init_sensor(struct gspca_dev *gspca_dev) 1333static void ov7670_init_sensor(struct gspca_dev *gspca_dev)
1353{ 1334{
1354 int i;
1355 struct sd *sd = (struct sd *) gspca_dev; 1335 struct sd *sd = (struct sd *) gspca_dev;
1356 1336
1357 for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) { 1337 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1358 if (i2c_w1(gspca_dev, ov7670_init[i].reg, 1338 msleep(200);
1359 ov7670_init[i].val) < 0) { 1339 i2c_w1_buf(gspca_dev, ov7670_init, ARRAY_SIZE(ov7670_init));
1360 pr_err("OV7670 sensor initialization failed\n"); 1340 if (gspca_dev->usb_err < 0)
1361 return -ENODEV; 1341 pr_err("OV7670 sensor initialization failed\n");
1362 } 1342
1363 }
1364 /* disable hflip and vflip */ 1343 /* disable hflip and vflip */
1365 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); 1344 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
1366 sd->hstart = 0; 1345 sd->hstart = 0;
1367 sd->vstart = 1; 1346 sd->vstart = 1;
1368 return 0;
1369} 1347}
1370 1348
1371static int mt9v_init_sensor(struct gspca_dev *gspca_dev) 1349static void mt9v_init_sensor(struct gspca_dev *gspca_dev)
1372{ 1350{
1373 struct sd *sd = (struct sd *) gspca_dev; 1351 struct sd *sd = (struct sd *) gspca_dev;
1374 int i;
1375 u16 value; 1352 u16 value;
1376 int ret;
1377 1353
1378 sd->i2c_addr = 0x5d; 1354 sd->i2c_addr = 0x5d;
1379 ret = i2c_r2(gspca_dev, 0xff, &value); 1355 i2c_r2(gspca_dev, 0xff, &value);
1380 if ((ret == 0) && (value == 0x8243)) { 1356 if (gspca_dev->usb_err >= 0
1381 for (i = 0; i < ARRAY_SIZE(mt9v011_init); i++) { 1357 && value == 0x8243) {
1382 if (i2c_w2(gspca_dev, mt9v011_init[i].reg, 1358 i2c_w2_buf(gspca_dev, mt9v011_init, ARRAY_SIZE(mt9v011_init));
1383 mt9v011_init[i].val) < 0) { 1359 if (gspca_dev->usb_err < 0) {
1384 pr_err("MT9V011 sensor initialization failed\n"); 1360 pr_err("MT9V011 sensor initialization failed\n");
1385 return -ENODEV; 1361 return;
1386 }
1387 } 1362 }
1388 sd->hstart = 2; 1363 sd->hstart = 2;
1389 sd->vstart = 2; 1364 sd->vstart = 2;
1390 sd->sensor = SENSOR_MT9V011; 1365 sd->sensor = SENSOR_MT9V011;
1391 pr_info("MT9V011 sensor detected\n"); 1366 pr_info("MT9V011 sensor detected\n");
1392 return 0; 1367 return;
1393 } 1368 }
1394 1369
1370 gspca_dev->usb_err = 0;
1395 sd->i2c_addr = 0x5c; 1371 sd->i2c_addr = 0x5c;
1396 i2c_w2(gspca_dev, 0x01, 0x0004); 1372 i2c_w2(gspca_dev, 0x01, 0x0004);
1397 ret = i2c_r2(gspca_dev, 0xff, &value); 1373 i2c_r2(gspca_dev, 0xff, &value);
1398 if ((ret == 0) && (value == 0x823a)) { 1374 if (gspca_dev->usb_err >= 0
1399 for (i = 0; i < ARRAY_SIZE(mt9v111_init); i++) { 1375 && value == 0x823a) {
1400 if (i2c_w2(gspca_dev, mt9v111_init[i].reg, 1376 i2c_w2_buf(gspca_dev, mt9v111_init, ARRAY_SIZE(mt9v111_init));
1401 mt9v111_init[i].val) < 0) { 1377 if (gspca_dev->usb_err < 0) {
1402 pr_err("MT9V111 sensor initialization failed\n"); 1378 pr_err("MT9V111 sensor initialization failed\n");
1403 return -ENODEV; 1379 return;
1404 }
1405 } 1380 }
1406 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) 1381 gspca_dev->ctrl_dis = (1 << EXPOSURE)
1407 | (1 << AUTOGAIN_IDX) 1382 | (1 << AUTOGAIN)
1408 | (1 << GAIN_IDX); 1383 | (1 << GAIN);
1409 sd->hstart = 2; 1384 sd->hstart = 2;
1410 sd->vstart = 2; 1385 sd->vstart = 2;
1411 sd->sensor = SENSOR_MT9V111; 1386 sd->sensor = SENSOR_MT9V111;
1412 pr_info("MT9V111 sensor detected\n"); 1387 pr_info("MT9V111 sensor detected\n");
1413 return 0; 1388 return;
1414 } 1389 }
1415 1390
1391 gspca_dev->usb_err = 0;
1416 sd->i2c_addr = 0x5d; 1392 sd->i2c_addr = 0x5d;
1417 ret = i2c_w2(gspca_dev, 0xf0, 0x0000); 1393 i2c_w2(gspca_dev, 0xf0, 0x0000);
1418 if (ret < 0) { 1394 if (gspca_dev->usb_err < 0) {
1395 gspca_dev->usb_err = 0;
1419 sd->i2c_addr = 0x48; 1396 sd->i2c_addr = 0x48;
1420 i2c_w2(gspca_dev, 0xf0, 0x0000); 1397 i2c_w2(gspca_dev, 0xf0, 0x0000);
1421 } 1398 }
1422 ret = i2c_r2(gspca_dev, 0x00, &value); 1399 i2c_r2(gspca_dev, 0x00, &value);
1423 if ((ret == 0) && (value == 0x1229)) { 1400 if (gspca_dev->usb_err >= 0
1424 for (i = 0; i < ARRAY_SIZE(mt9v112_init); i++) { 1401 && value == 0x1229) {
1425 if (i2c_w2(gspca_dev, mt9v112_init[i].reg, 1402 i2c_w2_buf(gspca_dev, mt9v112_init, ARRAY_SIZE(mt9v112_init));
1426 mt9v112_init[i].val) < 0) { 1403 if (gspca_dev->usb_err < 0) {
1427 pr_err("MT9V112 sensor initialization failed\n"); 1404 pr_err("MT9V112 sensor initialization failed\n");
1428 return -ENODEV; 1405 return;
1429 }
1430 } 1406 }
1431 sd->hstart = 6; 1407 sd->hstart = 6;
1432 sd->vstart = 2; 1408 sd->vstart = 2;
1433 sd->sensor = SENSOR_MT9V112; 1409 sd->sensor = SENSOR_MT9V112;
1434 pr_info("MT9V112 sensor detected\n"); 1410 pr_info("MT9V112 sensor detected\n");
1435 return 0; 1411 return;
1436 } 1412 }
1437 1413
1438 return -ENODEV; 1414 gspca_dev->usb_err = -ENODEV;
1439} 1415}
1440 1416
1441static int mt9m112_init_sensor(struct gspca_dev *gspca_dev) 1417static void mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1442{ 1418{
1443 struct sd *sd = (struct sd *) gspca_dev; 1419 struct sd *sd = (struct sd *) gspca_dev;
1444 int i; 1420
1445 for (i = 0; i < ARRAY_SIZE(mt9m112_init); i++) { 1421 i2c_w2_buf(gspca_dev, mt9m112_init, ARRAY_SIZE(mt9m112_init));
1446 if (i2c_w2(gspca_dev, mt9m112_init[i].reg, 1422 if (gspca_dev->usb_err < 0)
1447 mt9m112_init[i].val) < 0) { 1423 pr_err("MT9M112 sensor initialization failed\n");
1448 pr_err("MT9M112 sensor initialization failed\n"); 1424
1449 return -ENODEV; 1425 gspca_dev->ctrl_dis = (1 << EXPOSURE) | (1 << AUTOGAIN)
1450 } 1426 | (1 << GAIN);
1451 }
1452 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX)
1453 | (1 << GAIN_IDX);
1454 sd->hstart = 0; 1427 sd->hstart = 0;
1455 sd->vstart = 2; 1428 sd->vstart = 2;
1456 return 0;
1457} 1429}
1458 1430
1459static int mt9m111_init_sensor(struct gspca_dev *gspca_dev) 1431static void mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1460{ 1432{
1461 struct sd *sd = (struct sd *) gspca_dev; 1433 struct sd *sd = (struct sd *) gspca_dev;
1462 int i; 1434
1463 for (i = 0; i < ARRAY_SIZE(mt9m111_init); i++) { 1435 i2c_w2_buf(gspca_dev, mt9m111_init, ARRAY_SIZE(mt9m111_init));
1464 if (i2c_w2(gspca_dev, mt9m111_init[i].reg, 1436 if (gspca_dev->usb_err < 0)
1465 mt9m111_init[i].val) < 0) { 1437 pr_err("MT9M111 sensor initialization failed\n");
1466 pr_err("MT9M111 sensor initialization failed\n"); 1438
1467 return -ENODEV; 1439 gspca_dev->ctrl_dis = (1 << EXPOSURE) | (1 << AUTOGAIN)
1468 } 1440 | (1 << GAIN);
1469 }
1470 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX)
1471 | (1 << GAIN_IDX);
1472 sd->hstart = 0; 1441 sd->hstart = 0;
1473 sd->vstart = 2; 1442 sd->vstart = 2;
1474 return 0;
1475} 1443}
1476 1444
1477static int mt9m001_init_sensor(struct gspca_dev *gspca_dev) 1445static void mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1478{ 1446{
1479 struct sd *sd = (struct sd *) gspca_dev; 1447 struct sd *sd = (struct sd *) gspca_dev;
1480 int i;
1481 u16 id; 1448 u16 id;
1482 1449
1483 if (i2c_r2(gspca_dev, 0x00, &id) < 0) 1450 i2c_r2(gspca_dev, 0x00, &id);
1484 return -EINVAL; 1451 if (gspca_dev->usb_err < 0)
1452 return;
1485 1453
1486 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */ 1454 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
1487 switch (id) { 1455 switch (id) {
@@ -1494,85 +1462,78 @@ static int mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1494 break; 1462 break;
1495 default: 1463 default:
1496 pr_err("No MT9M001 chip detected, ID = %x\n\n", id); 1464 pr_err("No MT9M001 chip detected, ID = %x\n\n", id);
1497 return -ENODEV; 1465 gspca_dev->usb_err = -ENODEV;
1466 return;
1498 } 1467 }
1499 1468
1500 for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) { 1469 i2c_w2_buf(gspca_dev, mt9m001_init, ARRAY_SIZE(mt9m001_init));
1501 if (i2c_w2(gspca_dev, mt9m001_init[i].reg, 1470 if (gspca_dev->usb_err < 0)
1502 mt9m001_init[i].val) < 0) { 1471 pr_err("MT9M001 sensor initialization failed\n");
1503 pr_err("MT9M001 sensor initialization failed\n"); 1472
1504 return -ENODEV;
1505 }
1506 }
1507 /* disable hflip and vflip */ 1473 /* disable hflip and vflip */
1508 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); 1474 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
1509 sd->hstart = 1; 1475 sd->hstart = 1;
1510 sd->vstart = 1; 1476 sd->vstart = 1;
1511 return 0;
1512} 1477}
1513 1478
1514static int hv7131r_init_sensor(struct gspca_dev *gspca_dev) 1479static void hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1515{ 1480{
1516 int i;
1517 struct sd *sd = (struct sd *) gspca_dev; 1481 struct sd *sd = (struct sd *) gspca_dev;
1518 1482
1519 for (i = 0; i < ARRAY_SIZE(hv7131r_init); i++) { 1483 i2c_w1_buf(gspca_dev, hv7131r_init, ARRAY_SIZE(hv7131r_init));
1520 if (i2c_w1(gspca_dev, hv7131r_init[i].reg, 1484 if (gspca_dev->usb_err < 0)
1521 hv7131r_init[i].val) < 0) { 1485 pr_err("HV7131R Sensor initialization failed\n");
1522 pr_err("HV7131R Sensor initialization failed\n"); 1486
1523 return -ENODEV;
1524 }
1525 }
1526 sd->hstart = 0; 1487 sd->hstart = 0;
1527 sd->vstart = 1; 1488 sd->vstart = 1;
1528 return 0;
1529} 1489}
1530 1490
1531static int set_cmatrix(struct gspca_dev *gspca_dev) 1491static void set_cmatrix(struct gspca_dev *gspca_dev)
1532{ 1492{
1533 struct sd *sd = (struct sd *) gspca_dev; 1493 struct sd *sd = (struct sd *) gspca_dev;
1534 s32 hue_coord, hue_index = 180 + sd->hue; 1494 int satur;
1495 s32 hue_coord, hue_index = 180 + sd->ctrls[HUE].val;
1535 u8 cmatrix[21]; 1496 u8 cmatrix[21];
1536 1497
1537 memset(cmatrix, 0, sizeof cmatrix); 1498 memset(cmatrix, 0, sizeof cmatrix);
1538 cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26; 1499 cmatrix[2] = (sd->ctrls[CONTRAST].val * 0x25 / 0x100) + 0x26;
1539 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25; 1500 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1540 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25; 1501 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1541 cmatrix[18] = sd->brightness - 0x80; 1502 cmatrix[18] = sd->ctrls[BRIGHTNESS].val - 0x80;
1542 1503
1543 hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8; 1504 satur = sd->ctrls[SATURATION].val;
1505 hue_coord = (hsv_red_x[hue_index] * satur) >> 8;
1544 cmatrix[6] = hue_coord; 1506 cmatrix[6] = hue_coord;
1545 cmatrix[7] = (hue_coord >> 8) & 0x0f; 1507 cmatrix[7] = (hue_coord >> 8) & 0x0f;
1546 1508
1547 hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8; 1509 hue_coord = (hsv_red_y[hue_index] * satur) >> 8;
1548 cmatrix[8] = hue_coord; 1510 cmatrix[8] = hue_coord;
1549 cmatrix[9] = (hue_coord >> 8) & 0x0f; 1511 cmatrix[9] = (hue_coord >> 8) & 0x0f;
1550 1512
1551 hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8; 1513 hue_coord = (hsv_green_x[hue_index] * satur) >> 8;
1552 cmatrix[10] = hue_coord; 1514 cmatrix[10] = hue_coord;
1553 cmatrix[11] = (hue_coord >> 8) & 0x0f; 1515 cmatrix[11] = (hue_coord >> 8) & 0x0f;
1554 1516
1555 hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8; 1517 hue_coord = (hsv_green_y[hue_index] * satur) >> 8;
1556 cmatrix[12] = hue_coord; 1518 cmatrix[12] = hue_coord;
1557 cmatrix[13] = (hue_coord >> 8) & 0x0f; 1519 cmatrix[13] = (hue_coord >> 8) & 0x0f;
1558 1520
1559 hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8; 1521 hue_coord = (hsv_blue_x[hue_index] * satur) >> 8;
1560 cmatrix[14] = hue_coord; 1522 cmatrix[14] = hue_coord;
1561 cmatrix[15] = (hue_coord >> 8) & 0x0f; 1523 cmatrix[15] = (hue_coord >> 8) & 0x0f;
1562 1524
1563 hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8; 1525 hue_coord = (hsv_blue_y[hue_index] * satur) >> 8;
1564 cmatrix[16] = hue_coord; 1526 cmatrix[16] = hue_coord;
1565 cmatrix[17] = (hue_coord >> 8) & 0x0f; 1527 cmatrix[17] = (hue_coord >> 8) & 0x0f;
1566 1528
1567 return reg_w(gspca_dev, 0x10e1, cmatrix, 21); 1529 reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1568} 1530}
1569 1531
1570static int set_gamma(struct gspca_dev *gspca_dev) 1532static void set_gamma(struct gspca_dev *gspca_dev)
1571{ 1533{
1572 struct sd *sd = (struct sd *) gspca_dev; 1534 struct sd *sd = (struct sd *) gspca_dev;
1573 u8 gamma[17]; 1535 u8 gamma[17];
1574 u8 gval = sd->gamma * 0xb8 / 0x100; 1536 u8 gval = sd->ctrls[GAMMA].val * 0xb8 / 0x100;
1575
1576 1537
1577 gamma[0] = 0x0a; 1538 gamma[0] = 0x0a;
1578 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8); 1539 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
@@ -1592,29 +1553,29 @@ static int set_gamma(struct gspca_dev *gspca_dev)
1592 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8); 1553 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1593 gamma[16] = 0xf5; 1554 gamma[16] = 0xf5;
1594 1555
1595 return reg_w(gspca_dev, 0x1190, gamma, 17); 1556 reg_w(gspca_dev, 0x1190, gamma, 17);
1596} 1557}
1597 1558
1598static int set_redblue(struct gspca_dev *gspca_dev) 1559static void set_redblue(struct gspca_dev *gspca_dev)
1599{ 1560{
1600 struct sd *sd = (struct sd *) gspca_dev; 1561 struct sd *sd = (struct sd *) gspca_dev;
1601 reg_w1(gspca_dev, 0x118c, sd->red); 1562
1602 reg_w1(gspca_dev, 0x118f, sd->blue); 1563 reg_w1(gspca_dev, 0x118c, sd->ctrls[RED].val);
1603 return 0; 1564 reg_w1(gspca_dev, 0x118f, sd->ctrls[BLUE].val);
1604} 1565}
1605 1566
1606static int set_hvflip(struct gspca_dev *gspca_dev) 1567static void set_hvflip(struct gspca_dev *gspca_dev)
1607{ 1568{
1608 u8 value, tslb, hflip, vflip; 1569 u8 value, tslb, hflip, vflip;
1609 u16 value2; 1570 u16 value2;
1610 struct sd *sd = (struct sd *) gspca_dev; 1571 struct sd *sd = (struct sd *) gspca_dev;
1611 1572
1612 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) { 1573 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1613 hflip = !sd->hflip; 1574 hflip = !sd->ctrls[HFLIP].val;
1614 vflip = !sd->vflip; 1575 vflip = !sd->ctrls[VFLIP].val;
1615 } else { 1576 } else {
1616 hflip = sd->hflip; 1577 hflip = sd->ctrls[HFLIP].val;
1617 vflip = sd->vflip; 1578 vflip = sd->ctrls[VFLIP].val;
1618 } 1579 }
1619 1580
1620 switch (sd->sensor) { 1581 switch (sd->sensor) {
@@ -1625,8 +1586,9 @@ static int set_hvflip(struct gspca_dev *gspca_dev)
1625 if (vflip) { 1586 if (vflip) {
1626 value |= 0x10; 1587 value |= 0x10;
1627 sd->vstart = 2; 1588 sd->vstart = 2;
1628 } else 1589 } else {
1629 sd->vstart = 3; 1590 sd->vstart = 3;
1591 }
1630 reg_w1(gspca_dev, 0x1182, sd->vstart); 1592 reg_w1(gspca_dev, 0x1182, sd->vstart);
1631 i2c_w1(gspca_dev, 0x1e, value); 1593 i2c_w1(gspca_dev, 0x1e, value);
1632 break; 1594 break;
@@ -1674,13 +1636,15 @@ static int set_hvflip(struct gspca_dev *gspca_dev)
1674 i2c_w1(gspca_dev, 0x01, value); 1636 i2c_w1(gspca_dev, 0x01, value);
1675 break; 1637 break;
1676 } 1638 }
1677 return 0;
1678} 1639}
1679 1640
1680static int set_exposure(struct gspca_dev *gspca_dev) 1641static void set_exposure(struct gspca_dev *gspca_dev)
1681{ 1642{
1682 struct sd *sd = (struct sd *) gspca_dev; 1643 struct sd *sd = (struct sd *) gspca_dev;
1683 u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e}; 1644 u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1645 int expo;
1646
1647 expo = sd->ctrls[EXPOSURE].val;
1684 switch (sd->sensor) { 1648 switch (sd->sensor) {
1685 case SENSOR_OV7660: 1649 case SENSOR_OV7660:
1686 case SENSOR_OV7670: 1650 case SENSOR_OV7670:
@@ -1688,35 +1652,37 @@ static int set_exposure(struct gspca_dev *gspca_dev)
1688 case SENSOR_OV9650: 1652 case SENSOR_OV9650:
1689 exp[0] |= (3 << 4); 1653 exp[0] |= (3 << 4);
1690 exp[2] = 0x2d; 1654 exp[2] = 0x2d;
1691 exp[3] = sd->exposure & 0xff; 1655 exp[3] = expo;
1692 exp[4] = sd->exposure >> 8; 1656 exp[4] = expo >> 8;
1693 break; 1657 break;
1694 case SENSOR_MT9M001: 1658 case SENSOR_MT9M001:
1695 case SENSOR_MT9V112: 1659 case SENSOR_MT9V112:
1696 case SENSOR_MT9V011: 1660 case SENSOR_MT9V011:
1697 exp[0] |= (3 << 4); 1661 exp[0] |= (3 << 4);
1698 exp[2] = 0x09; 1662 exp[2] = 0x09;
1699 exp[3] = sd->exposure >> 8; 1663 exp[3] = expo >> 8;
1700 exp[4] = sd->exposure & 0xff; 1664 exp[4] = expo;
1701 break; 1665 break;
1702 case SENSOR_HV7131R: 1666 case SENSOR_HV7131R:
1703 exp[0] |= (4 << 4); 1667 exp[0] |= (4 << 4);
1704 exp[2] = 0x25; 1668 exp[2] = 0x25;
1705 exp[3] = (sd->exposure >> 5) & 0xff; 1669 exp[3] = expo >> 5;
1706 exp[4] = (sd->exposure << 3) & 0xff; 1670 exp[4] = expo << 3;
1707 exp[5] = 0; 1671 exp[5] = 0;
1708 break; 1672 break;
1709 default: 1673 default:
1710 return 0; 1674 return;
1711 } 1675 }
1712 i2c_w(gspca_dev, exp); 1676 i2c_w(gspca_dev, exp);
1713 return 0;
1714} 1677}
1715 1678
1716static int set_gain(struct gspca_dev *gspca_dev) 1679static void set_gain(struct gspca_dev *gspca_dev)
1717{ 1680{
1718 struct sd *sd = (struct sd *) gspca_dev; 1681 struct sd *sd = (struct sd *) gspca_dev;
1719 u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d}; 1682 u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1683 int g;
1684
1685 g = sd->ctrls[GAIN].val;
1720 switch (sd->sensor) { 1686 switch (sd->sensor) {
1721 case SENSOR_OV7660: 1687 case SENSOR_OV7660:
1722 case SENSOR_OV7670: 1688 case SENSOR_OV7670:
@@ -1724,238 +1690,50 @@ static int set_gain(struct gspca_dev *gspca_dev)
1724 case SENSOR_OV9655: 1690 case SENSOR_OV9655:
1725 case SENSOR_OV9650: 1691 case SENSOR_OV9650:
1726 gain[0] |= (2 << 4); 1692 gain[0] |= (2 << 4);
1727 gain[3] = ov_gain[sd->gain]; 1693 gain[3] = ov_gain[g];
1728 break; 1694 break;
1729 case SENSOR_MT9V011: 1695 case SENSOR_MT9V011:
1730 gain[0] |= (3 << 4); 1696 gain[0] |= (3 << 4);
1731 gain[2] = 0x35; 1697 gain[2] = 0x35;
1732 gain[3] = micron1_gain[sd->gain] >> 8; 1698 gain[3] = micron1_gain[g] >> 8;
1733 gain[4] = micron1_gain[sd->gain] & 0xff; 1699 gain[4] = micron1_gain[g];
1734 break; 1700 break;
1735 case SENSOR_MT9V112: 1701 case SENSOR_MT9V112:
1736 gain[0] |= (3 << 4); 1702 gain[0] |= (3 << 4);
1737 gain[2] = 0x2f; 1703 gain[2] = 0x2f;
1738 gain[3] = micron1_gain[sd->gain] >> 8; 1704 gain[3] = micron1_gain[g] >> 8;
1739 gain[4] = micron1_gain[sd->gain] & 0xff; 1705 gain[4] = micron1_gain[g];
1740 break; 1706 break;
1741 case SENSOR_MT9M001: 1707 case SENSOR_MT9M001:
1742 gain[0] |= (3 << 4); 1708 gain[0] |= (3 << 4);
1743 gain[2] = 0x2f; 1709 gain[2] = 0x2f;
1744 gain[3] = micron2_gain[sd->gain] >> 8; 1710 gain[3] = micron2_gain[g] >> 8;
1745 gain[4] = micron2_gain[sd->gain] & 0xff; 1711 gain[4] = micron2_gain[g];
1746 break; 1712 break;
1747 case SENSOR_HV7131R: 1713 case SENSOR_HV7131R:
1748 gain[0] |= (2 << 4); 1714 gain[0] |= (2 << 4);
1749 gain[2] = 0x30; 1715 gain[2] = 0x30;
1750 gain[3] = hv7131r_gain[sd->gain]; 1716 gain[3] = hv7131r_gain[g];
1751 break; 1717 break;
1752 default: 1718 default:
1753 return 0; 1719 return;
1754 } 1720 }
1755 i2c_w(gspca_dev, gain); 1721 i2c_w(gspca_dev, gain);
1756 return 0;
1757}
1758
1759static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val)
1760{
1761 struct sd *sd = (struct sd *) gspca_dev;
1762
1763 sd->brightness = val;
1764 if (gspca_dev->streaming)
1765 return set_cmatrix(gspca_dev);
1766 return 0;
1767}
1768
1769static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val)
1770{
1771 struct sd *sd = (struct sd *) gspca_dev;
1772 *val = sd->brightness;
1773 return 0;
1774}
1775
1776
1777static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val)
1778{
1779 struct sd *sd = (struct sd *) gspca_dev;
1780
1781 sd->contrast = val;
1782 if (gspca_dev->streaming)
1783 return set_cmatrix(gspca_dev);
1784 return 0;
1785}
1786
1787static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val)
1788{
1789 struct sd *sd = (struct sd *) gspca_dev;
1790 *val = sd->contrast;
1791 return 0;
1792}
1793
1794static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val)
1795{
1796 struct sd *sd = (struct sd *) gspca_dev;
1797
1798 sd->saturation = val;
1799 if (gspca_dev->streaming)
1800 return set_cmatrix(gspca_dev);
1801 return 0;
1802} 1722}
1803 1723
1804static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val) 1724static void set_quality(struct gspca_dev *gspca_dev)
1805{ 1725{
1806 struct sd *sd = (struct sd *) gspca_dev; 1726 struct sd *sd = (struct sd *) gspca_dev;
1807 *val = sd->saturation;
1808 return 0;
1809}
1810
1811static int sd_sethue(struct gspca_dev *gspca_dev, s32 val)
1812{
1813 struct sd *sd = (struct sd *) gspca_dev;
1814
1815 sd->hue = val;
1816 if (gspca_dev->streaming)
1817 return set_cmatrix(gspca_dev);
1818 return 0;
1819}
1820
1821static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val)
1822{
1823 struct sd *sd = (struct sd *) gspca_dev;
1824 *val = sd->hue;
1825 return 0;
1826}
1827
1828static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val)
1829{
1830 struct sd *sd = (struct sd *) gspca_dev;
1831
1832 sd->gamma = val;
1833 if (gspca_dev->streaming)
1834 return set_gamma(gspca_dev);
1835 return 0;
1836}
1837
1838static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val)
1839{
1840 struct sd *sd = (struct sd *) gspca_dev;
1841 *val = sd->gamma;
1842 return 0;
1843}
1844
1845static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val)
1846{
1847 struct sd *sd = (struct sd *) gspca_dev;
1848
1849 sd->red = val;
1850 if (gspca_dev->streaming)
1851 return set_redblue(gspca_dev);
1852 return 0;
1853}
1854
1855static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val)
1856{
1857 struct sd *sd = (struct sd *) gspca_dev;
1858 *val = sd->red;
1859 return 0;
1860}
1861
1862static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val)
1863{
1864 struct sd *sd = (struct sd *) gspca_dev;
1865
1866 sd->blue = val;
1867 if (gspca_dev->streaming)
1868 return set_redblue(gspca_dev);
1869 return 0;
1870}
1871
1872static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val)
1873{
1874 struct sd *sd = (struct sd *) gspca_dev;
1875 *val = sd->blue;
1876 return 0;
1877}
1878
1879static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val)
1880{
1881 struct sd *sd = (struct sd *) gspca_dev;
1882
1883 sd->hflip = val;
1884 if (gspca_dev->streaming)
1885 return set_hvflip(gspca_dev);
1886 return 0;
1887}
1888
1889static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val)
1890{
1891 struct sd *sd = (struct sd *) gspca_dev;
1892 *val = sd->hflip;
1893 return 0;
1894}
1895
1896static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val)
1897{
1898 struct sd *sd = (struct sd *) gspca_dev;
1899
1900 sd->vflip = val;
1901 if (gspca_dev->streaming)
1902 return set_hvflip(gspca_dev);
1903 return 0;
1904}
1905
1906static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val)
1907{
1908 struct sd *sd = (struct sd *) gspca_dev;
1909 *val = sd->vflip;
1910 return 0;
1911}
1912
1913static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val)
1914{
1915 struct sd *sd = (struct sd *) gspca_dev;
1916
1917 sd->exposure = val;
1918 if (gspca_dev->streaming)
1919 return set_exposure(gspca_dev);
1920 return 0;
1921}
1922
1923static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val)
1924{
1925 struct sd *sd = (struct sd *) gspca_dev;
1926 *val = sd->exposure;
1927 return 0;
1928}
1929
1930static int sd_setgain(struct gspca_dev *gspca_dev, s32 val)
1931{
1932 struct sd *sd = (struct sd *) gspca_dev;
1933
1934 sd->gain = val;
1935 if (gspca_dev->streaming)
1936 return set_gain(gspca_dev);
1937 return 0;
1938}
1939
1940static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val)
1941{
1942 struct sd *sd = (struct sd *) gspca_dev;
1943 *val = sd->gain;
1944 return 0;
1945}
1946
1947static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val)
1948{
1949 struct sd *sd = (struct sd *) gspca_dev;
1950 sd->auto_exposure = val;
1951 return 0;
1952}
1953 1727
1954static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val) 1728 jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val);
1955{ 1729 reg_w1(gspca_dev, 0x1061, 0x01); /* stop transfer */
1956 struct sd *sd = (struct sd *) gspca_dev; 1730 reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */
1957 *val = sd->auto_exposure; 1731 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
1958 return 0; 1732 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
1733 reg_w1(gspca_dev, 0x1061, 0x03); /* restart transfer */
1734 reg_w1(gspca_dev, 0x10e0, sd->fmt);
1735 sd->fmt ^= 0x0c; /* invert QTAB use + write */
1736 reg_w1(gspca_dev, 0x10e0, sd->fmt);
1959} 1737}
1960 1738
1961#ifdef CONFIG_VIDEO_ADV_DEBUG 1739#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -1963,28 +1741,26 @@ static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1963 struct v4l2_dbg_register *reg) 1741 struct v4l2_dbg_register *reg)
1964{ 1742{
1965 struct sd *sd = (struct sd *) gspca_dev; 1743 struct sd *sd = (struct sd *) gspca_dev;
1744
1966 switch (reg->match.type) { 1745 switch (reg->match.type) {
1967 case V4L2_CHIP_MATCH_HOST: 1746 case V4L2_CHIP_MATCH_HOST:
1968 if (reg->match.addr != 0) 1747 if (reg->match.addr != 0)
1969 return -EINVAL; 1748 return -EINVAL;
1970 if (reg->reg < 0x1000 || reg->reg > 0x11ff) 1749 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1971 return -EINVAL; 1750 return -EINVAL;
1972 if (reg_r(gspca_dev, reg->reg, 1) < 0) 1751 reg_r(gspca_dev, reg->reg, 1);
1973 return -EINVAL;
1974 reg->val = gspca_dev->usb_buf[0]; 1752 reg->val = gspca_dev->usb_buf[0];
1975 return 0; 1753 return gspca_dev->usb_err;
1976 case V4L2_CHIP_MATCH_I2C_ADDR: 1754 case V4L2_CHIP_MATCH_I2C_ADDR:
1977 if (reg->match.addr != sd->i2c_addr) 1755 if (reg->match.addr != sd->i2c_addr)
1978 return -EINVAL; 1756 return -EINVAL;
1979 if (sd->sensor >= SENSOR_MT9V011 && 1757 if (sd->sensor >= SENSOR_MT9V011 &&
1980 sd->sensor <= SENSOR_MT9M112) { 1758 sd->sensor <= SENSOR_MT9M112) {
1981 if (i2c_r2(gspca_dev, reg->reg, (u16 *)&reg->val) < 0) 1759 i2c_r2(gspca_dev, reg->reg, (u16 *) &reg->val);
1982 return -EINVAL;
1983 } else { 1760 } else {
1984 if (i2c_r1(gspca_dev, reg->reg, (u8 *)&reg->val) < 0) 1761 i2c_r1(gspca_dev, reg->reg, (u8 *) &reg->val);
1985 return -EINVAL;
1986 } 1762 }
1987 return 0; 1763 return gspca_dev->usb_err;
1988 } 1764 }
1989 return -EINVAL; 1765 return -EINVAL;
1990} 1766}
@@ -1993,27 +1769,25 @@ static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1993 struct v4l2_dbg_register *reg) 1769 struct v4l2_dbg_register *reg)
1994{ 1770{
1995 struct sd *sd = (struct sd *) gspca_dev; 1771 struct sd *sd = (struct sd *) gspca_dev;
1772
1996 switch (reg->match.type) { 1773 switch (reg->match.type) {
1997 case V4L2_CHIP_MATCH_HOST: 1774 case V4L2_CHIP_MATCH_HOST:
1998 if (reg->match.addr != 0) 1775 if (reg->match.addr != 0)
1999 return -EINVAL; 1776 return -EINVAL;
2000 if (reg->reg < 0x1000 || reg->reg > 0x11ff) 1777 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
2001 return -EINVAL; 1778 return -EINVAL;
2002 if (reg_w1(gspca_dev, reg->reg, reg->val) < 0) 1779 reg_w1(gspca_dev, reg->reg, reg->val);
2003 return -EINVAL; 1780 return gspca_dev->usb_err;
2004 return 0;
2005 case V4L2_CHIP_MATCH_I2C_ADDR: 1781 case V4L2_CHIP_MATCH_I2C_ADDR:
2006 if (reg->match.addr != sd->i2c_addr) 1782 if (reg->match.addr != sd->i2c_addr)
2007 return -EINVAL; 1783 return -EINVAL;
2008 if (sd->sensor >= SENSOR_MT9V011 && 1784 if (sd->sensor >= SENSOR_MT9V011 &&
2009 sd->sensor <= SENSOR_MT9M112) { 1785 sd->sensor <= SENSOR_MT9M112) {
2010 if (i2c_w2(gspca_dev, reg->reg, reg->val) < 0) 1786 i2c_w2(gspca_dev, reg->reg, reg->val);
2011 return -EINVAL;
2012 } else { 1787 } else {
2013 if (i2c_w1(gspca_dev, reg->reg, reg->val) < 0) 1788 i2c_w1(gspca_dev, reg->reg, reg->val);
2014 return -EINVAL;
2015 } 1789 }
2016 return 0; 1790 return gspca_dev->usb_err;
2017 } 1791 }
2018 return -EINVAL; 1792 return -EINVAL;
2019} 1793}
@@ -2050,9 +1824,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
2050 cam = &gspca_dev->cam; 1824 cam = &gspca_dev->cam;
2051 cam->needs_full_bandwidth = 1; 1825 cam->needs_full_bandwidth = 1;
2052 1826
2053 sd->sensor = (id->driver_info >> 8) & 0xff; 1827 sd->sensor = id->driver_info >> 8;
2054 sd->i2c_addr = id->driver_info & 0xff; 1828 sd->i2c_addr = id->driver_info;
2055 sd->flags = (id->driver_info >> 16) & 0xff; 1829 sd->flags = id->driver_info >> 16;
2056 1830
2057 switch (sd->sensor) { 1831 switch (sd->sensor) {
2058 case SENSOR_MT9M112: 1832 case SENSOR_MT9M112:
@@ -2076,21 +1850,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
2076 sd->older_step = 0; 1850 sd->older_step = 0;
2077 sd->exposure_step = 16; 1851 sd->exposure_step = 16;
2078 1852
2079 sd->brightness = BRIGHTNESS_DEFAULT; 1853 gspca_dev->cam.ctrls = sd->ctrls;
2080 sd->contrast = CONTRAST_DEFAULT;
2081 sd->saturation = SATURATION_DEFAULT;
2082 sd->hue = HUE_DEFAULT;
2083 sd->gamma = GAMMA_DEFAULT;
2084 sd->red = RED_DEFAULT;
2085 sd->blue = BLUE_DEFAULT;
2086 1854
2087 sd->hflip = HFLIP_DEFAULT; 1855 INIT_WORK(&sd->work, qual_upd);
2088 sd->vflip = VFLIP_DEFAULT;
2089 sd->exposure = EXPOSURE_DEFAULT;
2090 sd->gain = GAIN_DEFAULT;
2091 sd->auto_exposure = AUTO_EXPOSURE_DEFAULT;
2092
2093 sd->quality = 95;
2094 1856
2095 return 0; 1857 return 0;
2096} 1858}
@@ -2105,9 +1867,10 @@ static int sd_init(struct gspca_dev *gspca_dev)
2105 1867
2106 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) { 1868 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
2107 value = bridge_init[i][1]; 1869 value = bridge_init[i][1];
2108 if (reg_w(gspca_dev, bridge_init[i][0], &value, 1) < 0) { 1870 reg_w(gspca_dev, bridge_init[i][0], &value, 1);
1871 if (gspca_dev->usb_err < 0) {
2109 pr_err("Device initialization failed\n"); 1872 pr_err("Device initialization failed\n");
2110 return -ENODEV; 1873 return gspca_dev->usb_err;
2111 } 1874 }
2112 } 1875 }
2113 1876
@@ -2116,72 +1879,85 @@ static int sd_init(struct gspca_dev *gspca_dev)
2116 else 1879 else
2117 reg_w1(gspca_dev, 0x1006, 0x20); 1880 reg_w1(gspca_dev, 0x1006, 0x20);
2118 1881
2119 if (reg_w(gspca_dev, 0x10c0, i2c_init, 9) < 0) { 1882 reg_w(gspca_dev, 0x10c0, i2c_init, 9);
1883 if (gspca_dev->usb_err < 0) {
2120 pr_err("Device initialization failed\n"); 1884 pr_err("Device initialization failed\n");
2121 return -ENODEV; 1885 return gspca_dev->usb_err;
2122 } 1886 }
2123 1887
2124 switch (sd->sensor) { 1888 switch (sd->sensor) {
2125 case SENSOR_OV9650: 1889 case SENSOR_OV9650:
2126 if (ov9650_init_sensor(gspca_dev) < 0) 1890 ov9650_init_sensor(gspca_dev);
2127 return -ENODEV; 1891 if (gspca_dev->usb_err < 0)
1892 break;
2128 pr_info("OV9650 sensor detected\n"); 1893 pr_info("OV9650 sensor detected\n");
2129 break; 1894 break;
2130 case SENSOR_OV9655: 1895 case SENSOR_OV9655:
2131 if (ov9655_init_sensor(gspca_dev) < 0) 1896 ov9655_init_sensor(gspca_dev);
2132 return -ENODEV; 1897 if (gspca_dev->usb_err < 0)
1898 break;
2133 pr_info("OV9655 sensor detected\n"); 1899 pr_info("OV9655 sensor detected\n");
2134 break; 1900 break;
2135 case SENSOR_SOI968: 1901 case SENSOR_SOI968:
2136 if (soi968_init_sensor(gspca_dev) < 0) 1902 soi968_init_sensor(gspca_dev);
2137 return -ENODEV; 1903 if (gspca_dev->usb_err < 0)
1904 break;
2138 pr_info("SOI968 sensor detected\n"); 1905 pr_info("SOI968 sensor detected\n");
2139 break; 1906 break;
2140 case SENSOR_OV7660: 1907 case SENSOR_OV7660:
2141 if (ov7660_init_sensor(gspca_dev) < 0) 1908 ov7660_init_sensor(gspca_dev);
2142 return -ENODEV; 1909 if (gspca_dev->usb_err < 0)
1910 break;
2143 pr_info("OV7660 sensor detected\n"); 1911 pr_info("OV7660 sensor detected\n");
2144 break; 1912 break;
2145 case SENSOR_OV7670: 1913 case SENSOR_OV7670:
2146 if (ov7670_init_sensor(gspca_dev) < 0) 1914 ov7670_init_sensor(gspca_dev);
2147 return -ENODEV; 1915 if (gspca_dev->usb_err < 0)
1916 break;
2148 pr_info("OV7670 sensor detected\n"); 1917 pr_info("OV7670 sensor detected\n");
2149 break; 1918 break;
2150 case SENSOR_MT9VPRB: 1919 case SENSOR_MT9VPRB:
2151 if (mt9v_init_sensor(gspca_dev) < 0) 1920 mt9v_init_sensor(gspca_dev);
2152 return -ENODEV; 1921 if (gspca_dev->usb_err < 0)
1922 break;
1923 pr_info("MT9VPRB sensor detected\n");
2153 break; 1924 break;
2154 case SENSOR_MT9M111: 1925 case SENSOR_MT9M111:
2155 if (mt9m111_init_sensor(gspca_dev) < 0) 1926 mt9m111_init_sensor(gspca_dev);
2156 return -ENODEV; 1927 if (gspca_dev->usb_err < 0)
1928 break;
2157 pr_info("MT9M111 sensor detected\n"); 1929 pr_info("MT9M111 sensor detected\n");
2158 break; 1930 break;
2159 case SENSOR_MT9M112: 1931 case SENSOR_MT9M112:
2160 if (mt9m112_init_sensor(gspca_dev) < 0) 1932 mt9m112_init_sensor(gspca_dev);
2161 return -ENODEV; 1933 if (gspca_dev->usb_err < 0)
1934 break;
2162 pr_info("MT9M112 sensor detected\n"); 1935 pr_info("MT9M112 sensor detected\n");
2163 break; 1936 break;
2164 case SENSOR_MT9M001: 1937 case SENSOR_MT9M001:
2165 if (mt9m001_init_sensor(gspca_dev) < 0) 1938 mt9m001_init_sensor(gspca_dev);
2166 return -ENODEV; 1939 if (gspca_dev->usb_err < 0)
1940 break;
2167 break; 1941 break;
2168 case SENSOR_HV7131R: 1942 case SENSOR_HV7131R:
2169 if (hv7131r_init_sensor(gspca_dev) < 0) 1943 hv7131r_init_sensor(gspca_dev);
2170 return -ENODEV; 1944 if (gspca_dev->usb_err < 0)
1945 break;
2171 pr_info("HV7131R sensor detected\n"); 1946 pr_info("HV7131R sensor detected\n");
2172 break; 1947 break;
2173 default: 1948 default:
2174 pr_info("Unsupported Sensor\n"); 1949 pr_err("Unsupported sensor\n");
2175 return -ENODEV; 1950 gspca_dev->usb_err = -ENODEV;
2176 } 1951 }
2177 1952
2178 return 0; 1953 return gspca_dev->usb_err;
2179} 1954}
2180 1955
2181static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode) 1956static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
2182{ 1957{
2183 struct sd *sd = (struct sd *) gspca_dev; 1958 struct sd *sd = (struct sd *) gspca_dev;
2184 u8 value; 1959 u8 value;
1960
2185 switch (sd->sensor) { 1961 switch (sd->sensor) {
2186 case SENSOR_SOI968: 1962 case SENSOR_SOI968:
2187 if (mode & MODE_SXGA) { 1963 if (mode & MODE_SXGA) {
@@ -2264,6 +2040,7 @@ static int sd_isoc_init(struct gspca_dev *gspca_dev)
2264 break; 2040 break;
2265 default: /* >= 640x480 */ 2041 default: /* >= 640x480 */
2266 gspca_dev->alt = 9; 2042 gspca_dev->alt = 9;
2043 break;
2267 } 2044 }
2268 } 2045 }
2269 2046
@@ -2290,14 +2067,15 @@ static int sd_start(struct gspca_dev *gspca_dev)
2290 2067
2291 jpeg_define(sd->jpeg_hdr, height, width, 2068 jpeg_define(sd->jpeg_hdr, height, width,
2292 0x21); 2069 0x21);
2293 jpeg_set_qual(sd->jpeg_hdr, sd->quality); 2070 jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val);
2294 2071
2295 if (mode & MODE_RAW) 2072 if (mode & MODE_RAW)
2296 fmt = 0x2d; 2073 fmt = 0x2d;
2297 else if (mode & MODE_JPEG) 2074 else if (mode & MODE_JPEG)
2298 fmt = 0x2c; 2075 fmt = 0x24;
2299 else 2076 else
2300 fmt = 0x2f; /* YUV 420 */ 2077 fmt = 0x2f; /* YUV 420 */
2078 sd->fmt = fmt;
2301 2079
2302 switch (mode & SCALE_MASK) { 2080 switch (mode & SCALE_MASK) {
2303 case SCALE_1280x1024: 2081 case SCALE_1280x1024:
@@ -2334,18 +2112,37 @@ static int sd_start(struct gspca_dev *gspca_dev)
2334 set_hvflip(gspca_dev); 2112 set_hvflip(gspca_dev);
2335 2113
2336 reg_w1(gspca_dev, 0x1007, 0x20); 2114 reg_w1(gspca_dev, 0x1007, 0x20);
2115 reg_w1(gspca_dev, 0x1061, 0x03);
2116
2117 /* if JPEG, prepare the compression quality update */
2118 if (mode & MODE_JPEG) {
2119 sd->pktsz = sd->npkt = 0;
2120 sd->nchg = 0;
2121 sd->work_thread =
2122 create_singlethread_workqueue(KBUILD_MODNAME);
2123 }
2337 2124
2338 reg_r(gspca_dev, 0x1061, 1); 2125 return gspca_dev->usb_err;
2339 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] | 0x02);
2340 return 0;
2341} 2126}
2342 2127
2343static void sd_stopN(struct gspca_dev *gspca_dev) 2128static void sd_stopN(struct gspca_dev *gspca_dev)
2344{ 2129{
2345 reg_w1(gspca_dev, 0x1007, 0x00); 2130 reg_w1(gspca_dev, 0x1007, 0x00);
2131 reg_w1(gspca_dev, 0x1061, 0x01);
2132}
2133
2134/* called on streamoff with alt==0 and on disconnect */
2135/* the usb_lock is held at entry - restore on exit */
2136static void sd_stop0(struct gspca_dev *gspca_dev)
2137{
2138 struct sd *sd = (struct sd *) gspca_dev;
2346 2139
2347 reg_r(gspca_dev, 0x1061, 1); 2140 if (sd->work_thread != NULL) {
2348 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] & ~0x02); 2141 mutex_unlock(&gspca_dev->usb_lock);
2142 destroy_workqueue(sd->work_thread);
2143 mutex_lock(&gspca_dev->usb_lock);
2144 sd->work_thread = NULL;
2145 }
2349} 2146}
2350 2147
2351static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum) 2148static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
@@ -2359,15 +2156,15 @@ static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2359 * and exposure steps 2156 * and exposure steps
2360 */ 2157 */
2361 if (avg_lum < MIN_AVG_LUM) { 2158 if (avg_lum < MIN_AVG_LUM) {
2362 if (sd->exposure > 0x1770) 2159 if (sd->ctrls[EXPOSURE].val > 0x1770)
2363 return; 2160 return;
2364 2161
2365 new_exp = sd->exposure + sd->exposure_step; 2162 new_exp = sd->ctrls[EXPOSURE].val + sd->exposure_step;
2366 if (new_exp > 0x1770) 2163 if (new_exp > 0x1770)
2367 new_exp = 0x1770; 2164 new_exp = 0x1770;
2368 if (new_exp < 0x10) 2165 if (new_exp < 0x10)
2369 new_exp = 0x10; 2166 new_exp = 0x10;
2370 sd->exposure = new_exp; 2167 sd->ctrls[EXPOSURE].val = new_exp;
2371 set_exposure(gspca_dev); 2168 set_exposure(gspca_dev);
2372 2169
2373 sd->older_step = sd->old_step; 2170 sd->older_step = sd->old_step;
@@ -2379,14 +2176,14 @@ static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2379 sd->exposure_step += 2; 2176 sd->exposure_step += 2;
2380 } 2177 }
2381 if (avg_lum > MAX_AVG_LUM) { 2178 if (avg_lum > MAX_AVG_LUM) {
2382 if (sd->exposure < 0x10) 2179 if (sd->ctrls[EXPOSURE].val < 0x10)
2383 return; 2180 return;
2384 new_exp = sd->exposure - sd->exposure_step; 2181 new_exp = sd->ctrls[EXPOSURE].val - sd->exposure_step;
2385 if (new_exp > 0x1700) 2182 if (new_exp > 0x1700)
2386 new_exp = 0x1770; 2183 new_exp = 0x1770;
2387 if (new_exp < 0x10) 2184 if (new_exp < 0x10)
2388 new_exp = 0x10; 2185 new_exp = 0x10;
2389 sd->exposure = new_exp; 2186 sd->ctrls[EXPOSURE].val = new_exp;
2390 set_exposure(gspca_dev); 2187 set_exposure(gspca_dev);
2391 sd->older_step = sd->old_step; 2188 sd->older_step = sd->old_step;
2392 sd->old_step = 0; 2189 sd->old_step = 0;
@@ -2403,14 +2200,14 @@ static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2403 struct sd *sd = (struct sd *) gspca_dev; 2200 struct sd *sd = (struct sd *) gspca_dev;
2404 2201
2405 if (avg_lum < MIN_AVG_LUM) { 2202 if (avg_lum < MIN_AVG_LUM) {
2406 if (sd->gain + 1 <= 28) { 2203 if (sd->ctrls[GAIN].val + 1 <= 28) {
2407 sd->gain++; 2204 sd->ctrls[GAIN].val++;
2408 set_gain(gspca_dev); 2205 set_gain(gspca_dev);
2409 } 2206 }
2410 } 2207 }
2411 if (avg_lum > MAX_AVG_LUM) { 2208 if (avg_lum > MAX_AVG_LUM) {
2412 if (sd->gain > 0) { 2209 if (sd->ctrls[GAIN].val > 0) {
2413 sd->gain--; 2210 sd->ctrls[GAIN].val--;
2414 set_gain(gspca_dev); 2211 set_gain(gspca_dev);
2415 } 2212 }
2416 } 2213 }
@@ -2421,7 +2218,7 @@ static void sd_dqcallback(struct gspca_dev *gspca_dev)
2421 struct sd *sd = (struct sd *) gspca_dev; 2218 struct sd *sd = (struct sd *) gspca_dev;
2422 int avg_lum; 2219 int avg_lum;
2423 2220
2424 if (!sd->auto_exposure) 2221 if (!sd->ctrls[AUTOGAIN].val)
2425 return; 2222 return;
2426 2223
2427 avg_lum = atomic_read(&sd->avg_lum); 2224 avg_lum = atomic_read(&sd->avg_lum);
@@ -2431,33 +2228,92 @@ static void sd_dqcallback(struct gspca_dev *gspca_dev)
2431 do_autoexposure(gspca_dev, avg_lum); 2228 do_autoexposure(gspca_dev, avg_lum);
2432} 2229}
2433 2230
2231/* JPEG quality update */
2232/* This function is executed from a work queue. */
2233static void qual_upd(struct work_struct *work)
2234{
2235 struct sd *sd = container_of(work, struct sd, work);
2236 struct gspca_dev *gspca_dev = &sd->gspca_dev;
2237
2238 mutex_lock(&gspca_dev->usb_lock);
2239 PDEBUG(D_STREAM, "qual_upd %d%%", sd->ctrls[QUALITY].val);
2240 set_quality(gspca_dev);
2241 mutex_unlock(&gspca_dev->usb_lock);
2242}
2243
2434#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 2244#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2435static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, 2245static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2436 u8 *data, /* interrupt packet */ 2246 u8 *data, /* interrupt packet */
2437 int len) /* interrupt packet length */ 2247 int len) /* interrupt packet length */
2438{ 2248{
2439 struct sd *sd = (struct sd *) gspca_dev; 2249 struct sd *sd = (struct sd *) gspca_dev;
2440 int ret = -EINVAL; 2250
2441 if (!(sd->flags & HAS_NO_BUTTON) && len == 1) { 2251 if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
2442 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); 2252 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2443 input_sync(gspca_dev->input_dev); 2253 input_sync(gspca_dev->input_dev);
2444 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); 2254 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2445 input_sync(gspca_dev->input_dev); 2255 input_sync(gspca_dev->input_dev);
2446 ret = 0; 2256 return 0;
2447 } 2257 }
2448 return ret; 2258 return -EINVAL;
2449} 2259}
2450#endif 2260#endif
2451 2261
2262/* check the JPEG compression */
2263static void transfer_check(struct gspca_dev *gspca_dev,
2264 u8 *data)
2265{
2266 struct sd *sd = (struct sd *) gspca_dev;
2267 int new_qual, r;
2268
2269 new_qual = 0;
2270
2271 /* if USB error, discard the frame and decrease the quality */
2272 if (data[6] & 0x08) { /* USB FIFO full */
2273 gspca_dev->last_packet_type = DISCARD_PACKET;
2274 new_qual = -5;
2275 } else {
2276
2277 /* else, compute the filling rate and a new JPEG quality */
2278 r = (sd->pktsz * 100) /
2279 (sd->npkt *
2280 gspca_dev->urb[0]->iso_frame_desc[0].length);
2281 if (r >= 85)
2282 new_qual = -3;
2283 else if (r < 75)
2284 new_qual = 2;
2285 }
2286 if (new_qual != 0) {
2287 sd->nchg += new_qual;
2288 if (sd->nchg < -6 || sd->nchg >= 12) {
2289 sd->nchg = 0;
2290 new_qual += sd->ctrls[QUALITY].val;
2291 if (new_qual < QUALITY_MIN)
2292 new_qual = QUALITY_MIN;
2293 else if (new_qual > QUALITY_MAX)
2294 new_qual = QUALITY_MAX;
2295 if (new_qual != sd->ctrls[QUALITY].val) {
2296 sd->ctrls[QUALITY].val = new_qual;
2297 queue_work(sd->work_thread, &sd->work);
2298 }
2299 }
2300 } else {
2301 sd->nchg = 0;
2302 }
2303 sd->pktsz = sd->npkt = 0;
2304}
2305
2452static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2306static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2453 u8 *data, /* isoc packet */ 2307 u8 *data, /* isoc packet */
2454 int len) /* iso packet length */ 2308 int len) /* iso packet length */
2455{ 2309{
2456 struct sd *sd = (struct sd *) gspca_dev; 2310 struct sd *sd = (struct sd *) gspca_dev;
2457 int avg_lum; 2311 int avg_lum, is_jpeg;
2458 static u8 frame_header[] = 2312 static u8 frame_header[] =
2459 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96}; 2313 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2460 if (len == 64 && memcmp(data, frame_header, 6) == 0) { 2314
2315 is_jpeg = (sd->fmt & 0x03) == 0;
2316 if (len >= 64 && memcmp(data, frame_header, 6) == 0) {
2461 avg_lum = ((data[35] >> 2) & 3) | 2317 avg_lum = ((data[35] >> 2) & 3) |
2462 (data[20] << 2) | 2318 (data[20] << 2) |
2463 (data[19] << 10); 2319 (data[19] << 10);
@@ -2484,12 +2340,18 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2484 (data[33] << 10); 2340 (data[33] << 10);
2485 avg_lum >>= 9; 2341 avg_lum >>= 9;
2486 atomic_set(&sd->avg_lum, avg_lum); 2342 atomic_set(&sd->avg_lum, avg_lum);
2343
2344 if (is_jpeg)
2345 transfer_check(gspca_dev, data);
2346
2487 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); 2347 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2488 return; 2348 len -= 64;
2349 if (len == 0)
2350 return;
2351 data += 64;
2489 } 2352 }
2490 if (gspca_dev->last_packet_type == LAST_PACKET) { 2353 if (gspca_dev->last_packet_type == LAST_PACKET) {
2491 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv 2354 if (is_jpeg) {
2492 & MODE_JPEG) {
2493 gspca_frame_add(gspca_dev, FIRST_PACKET, 2355 gspca_frame_add(gspca_dev, FIRST_PACKET,
2494 sd->jpeg_hdr, JPEG_HDR_SZ); 2356 sd->jpeg_hdr, JPEG_HDR_SZ);
2495 gspca_frame_add(gspca_dev, INTER_PACKET, 2357 gspca_frame_add(gspca_dev, INTER_PACKET,
@@ -2499,13 +2361,18 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2499 data, len); 2361 data, len);
2500 } 2362 }
2501 } else { 2363 } else {
2364 /* if JPEG, count the packets and their size */
2365 if (is_jpeg) {
2366 sd->npkt++;
2367 sd->pktsz += len;
2368 }
2502 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 2369 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2503 } 2370 }
2504} 2371}
2505 2372
2506/* sub-driver description */ 2373/* sub-driver description */
2507static const struct sd_desc sd_desc = { 2374static const struct sd_desc sd_desc = {
2508 .name = MODULE_NAME, 2375 .name = KBUILD_MODNAME,
2509 .ctrls = sd_ctrls, 2376 .ctrls = sd_ctrls,
2510 .nctrls = ARRAY_SIZE(sd_ctrls), 2377 .nctrls = ARRAY_SIZE(sd_ctrls),
2511 .config = sd_config, 2378 .config = sd_config,
@@ -2513,6 +2380,7 @@ static const struct sd_desc sd_desc = {
2513 .isoc_init = sd_isoc_init, 2380 .isoc_init = sd_isoc_init,
2514 .start = sd_start, 2381 .start = sd_start,
2515 .stopN = sd_stopN, 2382 .stopN = sd_stopN,
2383 .stop0 = sd_stop0,
2516 .pkt_scan = sd_pkt_scan, 2384 .pkt_scan = sd_pkt_scan,
2517#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 2385#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2518 .int_pkt_scan = sd_int_pkt_scan, 2386 .int_pkt_scan = sd_int_pkt_scan,
@@ -2581,7 +2449,7 @@ static int sd_probe(struct usb_interface *intf,
2581} 2449}
2582 2450
2583static struct usb_driver sd_driver = { 2451static struct usb_driver sd_driver = {
2584 .name = MODULE_NAME, 2452 .name = KBUILD_MODNAME,
2585 .id_table = device_table, 2453 .id_table = device_table,
2586 .probe = sd_probe, 2454 .probe = sd_probe,
2587 .disconnect = gspca_disconnect, 2455 .disconnect = gspca_disconnect,
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 0c9e6ddabd2c..db8e5084df06 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -39,7 +39,9 @@ enum e_ctrl {
39 BLUE, 39 BLUE,
40 RED, 40 RED,
41 GAMMA, 41 GAMMA,
42 EXPOSURE,
42 AUTOGAIN, 43 AUTOGAIN,
44 GAIN,
43 HFLIP, 45 HFLIP,
44 VFLIP, 46 VFLIP,
45 SHARPNESS, 47 SHARPNESS,
@@ -131,7 +133,9 @@ static void setcontrast(struct gspca_dev *gspca_dev);
131static void setcolors(struct gspca_dev *gspca_dev); 133static void setcolors(struct gspca_dev *gspca_dev);
132static void setredblue(struct gspca_dev *gspca_dev); 134static void setredblue(struct gspca_dev *gspca_dev);
133static void setgamma(struct gspca_dev *gspca_dev); 135static void setgamma(struct gspca_dev *gspca_dev);
134static void setautogain(struct gspca_dev *gspca_dev); 136static void setexposure(struct gspca_dev *gspca_dev);
137static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
138static void setgain(struct gspca_dev *gspca_dev);
135static void sethvflip(struct gspca_dev *gspca_dev); 139static void sethvflip(struct gspca_dev *gspca_dev);
136static void setsharpness(struct gspca_dev *gspca_dev); 140static void setsharpness(struct gspca_dev *gspca_dev);
137static void setillum(struct gspca_dev *gspca_dev); 141static void setillum(struct gspca_dev *gspca_dev);
@@ -213,6 +217,18 @@ static const struct ctrl sd_ctrls[NCTRLS] = {
213 }, 217 },
214 .set_control = setgamma 218 .set_control = setgamma
215 }, 219 },
220[EXPOSURE] = {
221 {
222 .id = V4L2_CID_EXPOSURE,
223 .type = V4L2_CTRL_TYPE_INTEGER,
224 .name = "Exposure",
225 .minimum = 500,
226 .maximum = 1500,
227 .step = 1,
228 .default_value = 1024
229 },
230 .set_control = setexposure
231 },
216[AUTOGAIN] = { 232[AUTOGAIN] = {
217 { 233 {
218 .id = V4L2_CID_AUTOGAIN, 234 .id = V4L2_CID_AUTOGAIN,
@@ -223,7 +239,19 @@ static const struct ctrl sd_ctrls[NCTRLS] = {
223 .step = 1, 239 .step = 1,
224 .default_value = 1 240 .default_value = 1
225 }, 241 },
226 .set_control = setautogain 242 .set = sd_setautogain,
243 },
244[GAIN] = {
245 {
246 .id = V4L2_CID_GAIN,
247 .type = V4L2_CTRL_TYPE_INTEGER,
248 .name = "Gain",
249 .minimum = 4,
250 .maximum = 49,
251 .step = 1,
252 .default_value = 15
253 },
254 .set_control = setgain
227 }, 255 },
228[HFLIP] = { 256[HFLIP] = {
229 { 257 {
@@ -290,60 +318,87 @@ static const struct ctrl sd_ctrls[NCTRLS] = {
290 318
291/* table of the disabled controls */ 319/* table of the disabled controls */
292static const __u32 ctrl_dis[] = { 320static const __u32 ctrl_dis[] = {
293[SENSOR_ADCM1700] = (1 << AUTOGAIN) | 321[SENSOR_ADCM1700] = (1 << EXPOSURE) |
322 (1 << AUTOGAIN) |
323 (1 << GAIN) |
294 (1 << HFLIP) | 324 (1 << HFLIP) |
295 (1 << VFLIP) | 325 (1 << VFLIP) |
296 (1 << FREQ), 326 (1 << FREQ),
297 327
298[SENSOR_GC0307] = (1 << HFLIP) | 328[SENSOR_GC0307] = (1 << EXPOSURE) |
329 (1 << GAIN) |
330 (1 << HFLIP) |
299 (1 << VFLIP) | 331 (1 << VFLIP) |
300 (1 << FREQ), 332 (1 << FREQ),
301 333
302[SENSOR_HV7131R] = (1 << HFLIP) | 334[SENSOR_HV7131R] = (1 << EXPOSURE) |
335 (1 << GAIN) |
336 (1 << HFLIP) |
303 (1 << FREQ), 337 (1 << FREQ),
304 338
305[SENSOR_MI0360] = (1 << HFLIP) | 339[SENSOR_MI0360] = (1 << EXPOSURE) |
340 (1 << GAIN) |
341 (1 << HFLIP) |
306 (1 << VFLIP) | 342 (1 << VFLIP) |
307 (1 << FREQ), 343 (1 << FREQ),
308 344
309[SENSOR_MI0360B] = (1 << HFLIP) | 345[SENSOR_MI0360B] = (1 << EXPOSURE) |
346 (1 << GAIN) |
347 (1 << HFLIP) |
310 (1 << VFLIP) | 348 (1 << VFLIP) |
311 (1 << FREQ), 349 (1 << FREQ),
312 350
313[SENSOR_MO4000] = (1 << HFLIP) | 351[SENSOR_MO4000] = (1 << EXPOSURE) |
352 (1 << GAIN) |
353 (1 << HFLIP) |
314 (1 << VFLIP) | 354 (1 << VFLIP) |
315 (1 << FREQ), 355 (1 << FREQ),
316 356
317[SENSOR_MT9V111] = (1 << HFLIP) | 357[SENSOR_MT9V111] = (1 << EXPOSURE) |
358 (1 << GAIN) |
359 (1 << HFLIP) |
318 (1 << VFLIP) | 360 (1 << VFLIP) |
319 (1 << FREQ), 361 (1 << FREQ),
320 362
321[SENSOR_OM6802] = (1 << HFLIP) | 363[SENSOR_OM6802] = (1 << EXPOSURE) |
364 (1 << GAIN) |
365 (1 << HFLIP) |
322 (1 << VFLIP) | 366 (1 << VFLIP) |
323 (1 << FREQ), 367 (1 << FREQ),
324 368
325[SENSOR_OV7630] = (1 << HFLIP), 369[SENSOR_OV7630] = (1 << EXPOSURE) |
370 (1 << GAIN) |
371 (1 << HFLIP),
326 372
327[SENSOR_OV7648] = (1 << HFLIP), 373[SENSOR_OV7648] = (1 << EXPOSURE) |
374 (1 << GAIN) |
375 (1 << HFLIP),
328 376
329[SENSOR_OV7660] = (1 << AUTOGAIN) | 377[SENSOR_OV7660] = (1 << EXPOSURE) |
378 (1 << AUTOGAIN) |
379 (1 << GAIN) |
330 (1 << HFLIP) | 380 (1 << HFLIP) |
331 (1 << VFLIP), 381 (1 << VFLIP),
332 382
333[SENSOR_PO1030] = (1 << AUTOGAIN) | 383[SENSOR_PO1030] = (1 << EXPOSURE) |
384 (1 << AUTOGAIN) |
385 (1 << GAIN) |
334 (1 << HFLIP) | 386 (1 << HFLIP) |
335 (1 << VFLIP) | 387 (1 << VFLIP) |
336 (1 << FREQ), 388 (1 << FREQ),
337 389
338[SENSOR_PO2030N] = (1 << AUTOGAIN) | 390[SENSOR_PO2030N] = (1 << FREQ),
339 (1 << FREQ),
340 391
341[SENSOR_SOI768] = (1 << AUTOGAIN) | 392[SENSOR_SOI768] = (1 << EXPOSURE) |
393 (1 << AUTOGAIN) |
394 (1 << GAIN) |
342 (1 << HFLIP) | 395 (1 << HFLIP) |
343 (1 << VFLIP) | 396 (1 << VFLIP) |
344 (1 << FREQ), 397 (1 << FREQ),
345 398
346[SENSOR_SP80708] = (1 << AUTOGAIN) | 399[SENSOR_SP80708] = (1 << EXPOSURE) |
400 (1 << AUTOGAIN) |
401 (1 << GAIN) |
347 (1 << HFLIP) | 402 (1 << HFLIP) |
348 (1 << VFLIP) | 403 (1 << VFLIP) |
349 (1 << FREQ), 404 (1 << FREQ),
@@ -1242,14 +1297,6 @@ static const u8 po2030n_sensor_param1[][8] = {
1242 {0xa1, 0x6e, 0x05, 0x6f, 0x00, 0x00, 0x00, 0x10}, 1297 {0xa1, 0x6e, 0x05, 0x6f, 0x00, 0x00, 0x00, 0x10},
1243 {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, 1298 {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
1244 {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10}, 1299 {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
1245 {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
1246 {0xc1, 0x6e, 0x16, 0x52, 0x40, 0x48, 0x00, 0x10},
1247/*after start*/
1248 {0xa1, 0x6e, 0x15, 0x0f, 0x00, 0x00, 0x00, 0x10},
1249 {DELAY, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */
1250 {0xa1, 0x6e, 0x1a, 0x05, 0x00, 0x00, 0x00, 0x10},
1251 {DELAY, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */
1252 {0xa1, 0x6e, 0x1b, 0x53, 0x00, 0x00, 0x00, 0x10},
1253 {} 1300 {}
1254}; 1301};
1255 1302
@@ -1858,7 +1905,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
1858 return gspca_dev->usb_err; 1905 return gspca_dev->usb_err;
1859} 1906}
1860 1907
1861static u32 setexposure(struct gspca_dev *gspca_dev, 1908static u32 expo_adjust(struct gspca_dev *gspca_dev,
1862 u32 expo) 1909 u32 expo)
1863{ 1910{
1864 struct sd *sd = (struct sd *) gspca_dev; 1911 struct sd *sd = (struct sd *) gspca_dev;
@@ -1982,28 +2029,28 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1982 expo = 0x002dc6c0; 2029 expo = 0x002dc6c0;
1983 else if (expo < 0x02a0) 2030 else if (expo < 0x02a0)
1984 expo = 0x02a0; 2031 expo = 0x02a0;
1985 sd->exposure = setexposure(gspca_dev, expo); 2032 sd->exposure = expo_adjust(gspca_dev, expo);
1986 break; 2033 break;
1987 case SENSOR_MI0360: 2034 case SENSOR_MI0360:
1988 case SENSOR_MO4000: 2035 case SENSOR_MO4000:
1989 expo = brightness << 4; 2036 expo = brightness << 4;
1990 sd->exposure = setexposure(gspca_dev, expo); 2037 sd->exposure = expo_adjust(gspca_dev, expo);
1991 break; 2038 break;
1992 case SENSOR_MI0360B: 2039 case SENSOR_MI0360B:
1993 expo = brightness << 2; 2040 expo = brightness << 2;
1994 sd->exposure = setexposure(gspca_dev, expo); 2041 sd->exposure = expo_adjust(gspca_dev, expo);
1995 break; 2042 break;
1996 case SENSOR_GC0307: 2043 case SENSOR_GC0307:
1997 expo = brightness; 2044 expo = brightness;
1998 sd->exposure = setexposure(gspca_dev, expo); 2045 sd->exposure = expo_adjust(gspca_dev, expo);
1999 return; /* don't set the Y offset */ 2046 return; /* don't set the Y offset */
2000 case SENSOR_MT9V111: 2047 case SENSOR_MT9V111:
2001 expo = brightness << 2; 2048 expo = brightness << 2;
2002 sd->exposure = setexposure(gspca_dev, expo); 2049 sd->exposure = expo_adjust(gspca_dev, expo);
2003 return; /* don't set the Y offset */ 2050 return; /* don't set the Y offset */
2004 case SENSOR_OM6802: 2051 case SENSOR_OM6802:
2005 expo = brightness << 2; 2052 expo = brightness << 2;
2006 sd->exposure = setexposure(gspca_dev, expo); 2053 sd->exposure = expo_adjust(gspca_dev, expo);
2007 return; /* Y offset already set */ 2054 return; /* Y offset already set */
2008 } 2055 }
2009 2056
@@ -2112,6 +2159,23 @@ static void setgamma(struct gspca_dev *gspca_dev)
2112 reg_w(gspca_dev, 0x20, gamma, sizeof gamma); 2159 reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
2113} 2160}
2114 2161
2162static void setexposure(struct gspca_dev *gspca_dev)
2163{
2164 struct sd *sd = (struct sd *) gspca_dev;
2165
2166 if (sd->sensor == SENSOR_PO2030N) {
2167 u8 rexpo[] = /* 1a: expo H, 1b: expo M */
2168 {0xa1, 0x6e, 0x1a, 0x00, 0x40, 0x00, 0x00, 0x10};
2169
2170 rexpo[3] = sd->ctrls[EXPOSURE].val >> 8;
2171 i2c_w8(gspca_dev, rexpo);
2172 msleep(6);
2173 rexpo[2] = 0x1b;
2174 rexpo[3] = sd->ctrls[EXPOSURE].val;
2175 i2c_w8(gspca_dev, rexpo);
2176 }
2177}
2178
2115static void setautogain(struct gspca_dev *gspca_dev) 2179static void setautogain(struct gspca_dev *gspca_dev)
2116{ 2180{
2117 struct sd *sd = (struct sd *) gspca_dev; 2181 struct sd *sd = (struct sd *) gspca_dev;
@@ -2139,6 +2203,19 @@ static void setautogain(struct gspca_dev *gspca_dev)
2139 sd->ag_cnt = -1; 2203 sd->ag_cnt = -1;
2140} 2204}
2141 2205
2206static void setgain(struct gspca_dev *gspca_dev)
2207{
2208 struct sd *sd = (struct sd *) gspca_dev;
2209
2210 if (sd->sensor == SENSOR_PO2030N) {
2211 u8 rgain[] = /* 15: gain */
2212 {0xa1, 0x6e, 0x15, 0x00, 0x40, 0x00, 0x00, 0x15};
2213
2214 rgain[3] = sd->ctrls[GAIN].val;
2215 i2c_w8(gspca_dev, rgain);
2216 }
2217}
2218
2142static void sethvflip(struct gspca_dev *gspca_dev) 2219static void sethvflip(struct gspca_dev *gspca_dev)
2143{ 2220{
2144 struct sd *sd = (struct sd *) gspca_dev; 2221 struct sd *sd = (struct sd *) gspca_dev;
@@ -2623,6 +2700,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
2623 setcontrast(gspca_dev); 2700 setcontrast(gspca_dev);
2624 setcolors(gspca_dev); 2701 setcolors(gspca_dev);
2625 setautogain(gspca_dev); 2702 setautogain(gspca_dev);
2703 if (!(gspca_dev->ctrl_inac & ((1 << EXPOSURE) | (1 << GAIN)))) {
2704 setexposure(gspca_dev);
2705 setgain(gspca_dev);
2706 }
2626 setfreq(gspca_dev); 2707 setfreq(gspca_dev);
2627 2708
2628 sd->pktsz = sd->npkt = 0; 2709 sd->pktsz = sd->npkt = 0;
@@ -2719,6 +2800,12 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
2719 } 2800 }
2720} 2801}
2721 2802
2803/* !! coarse_grained_expo_autogain is not used !! */
2804#define exp_too_low_cnt bridge
2805#define exp_too_high_cnt sensor
2806
2807#include "autogain_functions.h"
2808
2722static void do_autogain(struct gspca_dev *gspca_dev) 2809static void do_autogain(struct gspca_dev *gspca_dev)
2723{ 2810{
2724 struct sd *sd = (struct sd *) gspca_dev; 2811 struct sd *sd = (struct sd *) gspca_dev;
@@ -2736,6 +2823,13 @@ static void do_autogain(struct gspca_dev *gspca_dev)
2736 2823
2737 delta = atomic_read(&sd->avg_lum); 2824 delta = atomic_read(&sd->avg_lum);
2738 PDEBUG(D_FRAM, "mean lum %d", delta); 2825 PDEBUG(D_FRAM, "mean lum %d", delta);
2826
2827 if (sd->sensor == SENSOR_PO2030N) {
2828 auto_gain_n_exposure(gspca_dev, delta, luma_mean, luma_delta,
2829 15, 1024);
2830 return;
2831 }
2832
2739 if (delta < luma_mean - luma_delta || 2833 if (delta < luma_mean - luma_delta ||
2740 delta > luma_mean + luma_delta) { 2834 delta > luma_mean + luma_delta) {
2741 switch (sd->sensor) { 2835 switch (sd->sensor) {
@@ -2744,7 +2838,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
2744 expotimes += (luma_mean - delta) >> 6; 2838 expotimes += (luma_mean - delta) >> 6;
2745 if (expotimes < 0) 2839 if (expotimes < 0)
2746 expotimes = 0; 2840 expotimes = 0;
2747 sd->exposure = setexposure(gspca_dev, 2841 sd->exposure = expo_adjust(gspca_dev,
2748 (unsigned int) expotimes); 2842 (unsigned int) expotimes);
2749 break; 2843 break;
2750 case SENSOR_HV7131R: 2844 case SENSOR_HV7131R:
@@ -2752,7 +2846,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
2752 expotimes += (luma_mean - delta) >> 4; 2846 expotimes += (luma_mean - delta) >> 4;
2753 if (expotimes < 0) 2847 if (expotimes < 0)
2754 expotimes = 0; 2848 expotimes = 0;
2755 sd->exposure = setexposure(gspca_dev, 2849 sd->exposure = expo_adjust(gspca_dev,
2756 (unsigned int) (expotimes << 8)); 2850 (unsigned int) (expotimes << 8));
2757 break; 2851 break;
2758 case SENSOR_OM6802: 2852 case SENSOR_OM6802:
@@ -2761,7 +2855,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
2761 expotimes += (luma_mean - delta) >> 2; 2855 expotimes += (luma_mean - delta) >> 2;
2762 if (expotimes < 0) 2856 if (expotimes < 0)
2763 expotimes = 0; 2857 expotimes = 0;
2764 sd->exposure = setexposure(gspca_dev, 2858 sd->exposure = expo_adjust(gspca_dev,
2765 (unsigned int) expotimes); 2859 (unsigned int) expotimes);
2766 setredblue(gspca_dev); 2860 setredblue(gspca_dev);
2767 break; 2861 break;
@@ -2773,7 +2867,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
2773 expotimes += (luma_mean - delta) >> 6; 2867 expotimes += (luma_mean - delta) >> 6;
2774 if (expotimes < 0) 2868 if (expotimes < 0)
2775 expotimes = 0; 2869 expotimes = 0;
2776 sd->exposure = setexposure(gspca_dev, 2870 sd->exposure = expo_adjust(gspca_dev,
2777 (unsigned int) expotimes); 2871 (unsigned int) expotimes);
2778 setredblue(gspca_dev); 2872 setredblue(gspca_dev);
2779 break; 2873 break;
@@ -2948,16 +3042,18 @@ marker_found:
2948 } 3042 }
2949} 3043}
2950 3044
2951static int sd_get_jcomp(struct gspca_dev *gspca_dev, 3045static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2952 struct v4l2_jpegcompression *jcomp)
2953{ 3046{
2954 struct sd *sd = (struct sd *) gspca_dev; 3047 struct sd *sd = (struct sd *) gspca_dev;
2955 3048
2956 memset(jcomp, 0, sizeof *jcomp); 3049 sd->ctrls[AUTOGAIN].val = val;
2957 jcomp->quality = sd->quality; 3050 if (val)
2958 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT 3051 gspca_dev->ctrl_inac |= (1 << EXPOSURE) | (1 << GAIN);
2959 | V4L2_JPEG_MARKER_DQT; 3052 else
2960 return 0; 3053 gspca_dev->ctrl_inac &= ~(1 << EXPOSURE) & ~(1 << GAIN);
3054 if (gspca_dev->streaming)
3055 setautogain(gspca_dev);
3056 return gspca_dev->usb_err;
2961} 3057}
2962 3058
2963static int sd_querymenu(struct gspca_dev *gspca_dev, 3059static int sd_querymenu(struct gspca_dev *gspca_dev,
@@ -3012,7 +3108,6 @@ static const struct sd_desc sd_desc = {
3012 .stop0 = sd_stop0, 3108 .stop0 = sd_stop0,
3013 .pkt_scan = sd_pkt_scan, 3109 .pkt_scan = sd_pkt_scan,
3014 .dq_callback = do_autogain, 3110 .dq_callback = do_autogain,
3015 .get_jcomp = sd_get_jcomp,
3016 .querymenu = sd_querymenu, 3111 .querymenu = sd_querymenu,
3017#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 3112#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
3018 .int_pkt_scan = sd_int_pkt_scan, 3113 .int_pkt_scan = sd_int_pkt_scan,
diff --git a/drivers/media/video/gspca/stv06xx/Makefile b/drivers/media/video/gspca/stv06xx/Makefile
index 5b318faf9aa8..38bc41061d83 100644
--- a/drivers/media/video/gspca/stv06xx/Makefile
+++ b/drivers/media/video/gspca/stv06xx/Makefile
@@ -6,5 +6,5 @@ gspca_stv06xx-objs := stv06xx.o \
6 stv06xx_pb0100.o \ 6 stv06xx_pb0100.o \
7 stv06xx_st6422.o 7 stv06xx_st6422.o
8 8
9ccflags-y += -Idrivers/media/video/gspca 9ccflags-y += -I$(srctree)/drivers/media/video/gspca
10 10
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index b9e15bb0328b..7d9a4f1be9dc 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Z-Star/Vimicro zc301/zc302p/vc30x library 2 * Z-Star/Vimicro zc301/zc302p/vc30x driver
3 * 3 *
4 * Copyright (C) 2009-2011 Jean-Francois Moine <http://moinejf.free.fr> 4 * Copyright (C) 2009-2012 Jean-Francois Moine <http://moinejf.free.fr>
5 * Copyright (C) 2004 2005 2006 Michel Xhaard mxhaard@magic.fr 5 * Copyright (C) 2004 2005 2006 Michel Xhaard mxhaard@magic.fr
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -21,8 +21,6 @@
21 21
22#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 22#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23 23
24#define MODULE_NAME "zc3xx"
25
26#include <linux/input.h> 24#include <linux/input.h>
27#include "gspca.h" 25#include "gspca.h"
28#include "jpeg.h" 26#include "jpeg.h"
@@ -34,7 +32,7 @@ MODULE_LICENSE("GPL");
34 32
35static int force_sensor = -1; 33static int force_sensor = -1;
36 34
37#define QUANT_VAL 1 /* quantization table */ 35#define REG08_DEF 3 /* default JPEG compression (70%) */
38#include "zc3xx-reg.h" 36#include "zc3xx-reg.h"
39 37
40/* controls */ 38/* controls */
@@ -46,6 +44,7 @@ enum e_ctrl {
46 AUTOGAIN, 44 AUTOGAIN,
47 LIGHTFREQ, 45 LIGHTFREQ,
48 SHARPNESS, 46 SHARPNESS,
47 QUALITY,
49 NCTRLS /* number of controls */ 48 NCTRLS /* number of controls */
50}; 49};
51 50
@@ -57,10 +56,10 @@ struct sd {
57 56
58 struct gspca_ctrl ctrls[NCTRLS]; 57 struct gspca_ctrl ctrls[NCTRLS];
59 58
60 u8 quality; /* image quality */ 59 struct work_struct work;
61#define QUALITY_MIN 50 60 struct workqueue_struct *work_thread;
62#define QUALITY_MAX 80 61
63#define QUALITY_DEF 70 62 u8 reg08; /* webcam compression quality */
64 63
65 u8 bridge; 64 u8 bridge;
66 u8 sensor; /* Type of image sensor chip */ 65 u8 sensor; /* Type of image sensor chip */
@@ -101,6 +100,7 @@ static void setexposure(struct gspca_dev *gspca_dev);
101static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 100static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
102static void setlightfreq(struct gspca_dev *gspca_dev); 101static void setlightfreq(struct gspca_dev *gspca_dev);
103static void setsharpness(struct gspca_dev *gspca_dev); 102static void setsharpness(struct gspca_dev *gspca_dev);
103static int sd_setquality(struct gspca_dev *gspca_dev, __s32 val);
104 104
105static const struct ctrl sd_ctrls[NCTRLS] = { 105static const struct ctrl sd_ctrls[NCTRLS] = {
106[BRIGHTNESS] = { 106[BRIGHTNESS] = {
@@ -188,6 +188,18 @@ static const struct ctrl sd_ctrls[NCTRLS] = {
188 }, 188 },
189 .set_control = setsharpness 189 .set_control = setsharpness
190 }, 190 },
191[QUALITY] = {
192 {
193 .id = V4L2_CID_JPEG_COMPRESSION_QUALITY,
194 .type = V4L2_CTRL_TYPE_INTEGER,
195 .name = "Compression Quality",
196 .minimum = 40,
197 .maximum = 70,
198 .step = 1,
199 .default_value = 70 /* updated in sd_init() */
200 },
201 .set = sd_setquality
202 },
191}; 203};
192 204
193static const struct v4l2_pix_format vga_mode[] = { 205static const struct v4l2_pix_format vga_mode[] = {
@@ -229,6 +241,9 @@ static const struct v4l2_pix_format sif_mode[] = {
229 .priv = 0}, 241 .priv = 0},
230}; 242};
231 243
244/* bridge reg08 -> JPEG quality conversion table */
245static u8 jpeg_qual[] = {40, 50, 60, 70, /*80*/};
246
232/* usb exchanges */ 247/* usb exchanges */
233struct usb_action { 248struct usb_action {
234 u8 req; 249 u8 req;
@@ -3894,7 +3909,6 @@ static const struct usb_action pas106b_Initial[] = { /* 352x288 */
3894/* Gains */ 3909/* Gains */
3895 {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF}, 3910 {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF},
3896 {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, 3911 {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP},
3897 {0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN},
3898 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, 3912 {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
3899/* Auto correction */ 3913/* Auto correction */
3900 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, 3914 {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
@@ -5640,7 +5654,7 @@ static const struct usb_action gc0303_NoFlikerScale[] = {
5640 {} 5654 {}
5641}; 5655};
5642 5656
5643static u8 reg_r_i(struct gspca_dev *gspca_dev, 5657static u8 reg_r(struct gspca_dev *gspca_dev,
5644 u16 index) 5658 u16 index)
5645{ 5659{
5646 int ret; 5660 int ret;
@@ -5655,24 +5669,14 @@ static u8 reg_r_i(struct gspca_dev *gspca_dev,
5655 index, gspca_dev->usb_buf, 1, 5669 index, gspca_dev->usb_buf, 1,
5656 500); 5670 500);
5657 if (ret < 0) { 5671 if (ret < 0) {
5658 pr_err("reg_r_i err %d\n", ret); 5672 pr_err("reg_r err %d\n", ret);
5659 gspca_dev->usb_err = ret; 5673 gspca_dev->usb_err = ret;
5660 return 0; 5674 return 0;
5661 } 5675 }
5662 return gspca_dev->usb_buf[0]; 5676 return gspca_dev->usb_buf[0];
5663} 5677}
5664 5678
5665static u8 reg_r(struct gspca_dev *gspca_dev, 5679static void reg_w(struct gspca_dev *gspca_dev,
5666 u16 index)
5667{
5668 u8 ret;
5669
5670 ret = reg_r_i(gspca_dev, index);
5671 PDEBUG(D_USBI, "reg r [%04x] -> %02x", index, ret);
5672 return ret;
5673}
5674
5675static void reg_w_i(struct gspca_dev *gspca_dev,
5676 u8 value, 5680 u8 value,
5677 u16 index) 5681 u16 index)
5678{ 5682{
@@ -5692,14 +5696,6 @@ static void reg_w_i(struct gspca_dev *gspca_dev,
5692 } 5696 }
5693} 5697}
5694 5698
5695static void reg_w(struct gspca_dev *gspca_dev,
5696 u8 value,
5697 u16 index)
5698{
5699 PDEBUG(D_USBO, "reg w [%04x] = %02x", index, value);
5700 reg_w_i(gspca_dev, value, index);
5701}
5702
5703static u16 i2c_read(struct gspca_dev *gspca_dev, 5699static u16 i2c_read(struct gspca_dev *gspca_dev,
5704 u8 reg) 5700 u8 reg)
5705{ 5701{
@@ -5708,16 +5704,14 @@ static u16 i2c_read(struct gspca_dev *gspca_dev,
5708 5704
5709 if (gspca_dev->usb_err < 0) 5705 if (gspca_dev->usb_err < 0)
5710 return 0; 5706 return 0;
5711 reg_w_i(gspca_dev, reg, 0x0092); 5707 reg_w(gspca_dev, reg, 0x0092);
5712 reg_w_i(gspca_dev, 0x02, 0x0090); /* <- read command */ 5708 reg_w(gspca_dev, 0x02, 0x0090); /* <- read command */
5713 msleep(20); 5709 msleep(20);
5714 retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ 5710 retbyte = reg_r(gspca_dev, 0x0091); /* read status */
5715 if (retbyte != 0x00) 5711 if (retbyte != 0x00)
5716 pr_err("i2c_r status error %02x\n", retbyte); 5712 pr_err("i2c_r status error %02x\n", retbyte);
5717 retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ 5713 retval = reg_r(gspca_dev, 0x0095); /* read Lowbyte */
5718 retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */ 5714 retval |= reg_r(gspca_dev, 0x0096) << 8; /* read Hightbyte */
5719 PDEBUG(D_USBI, "i2c r [%02x] -> %04x (%02x)",
5720 reg, retval, retbyte);
5721 return retval; 5715 return retval;
5722} 5716}
5723 5717
@@ -5730,16 +5724,14 @@ static u8 i2c_write(struct gspca_dev *gspca_dev,
5730 5724
5731 if (gspca_dev->usb_err < 0) 5725 if (gspca_dev->usb_err < 0)
5732 return 0; 5726 return 0;
5733 reg_w_i(gspca_dev, reg, 0x92); 5727 reg_w(gspca_dev, reg, 0x92);
5734 reg_w_i(gspca_dev, valL, 0x93); 5728 reg_w(gspca_dev, valL, 0x93);
5735 reg_w_i(gspca_dev, valH, 0x94); 5729 reg_w(gspca_dev, valH, 0x94);
5736 reg_w_i(gspca_dev, 0x01, 0x90); /* <- write command */ 5730 reg_w(gspca_dev, 0x01, 0x90); /* <- write command */
5737 msleep(1); 5731 msleep(1);
5738 retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ 5732 retbyte = reg_r(gspca_dev, 0x0091); /* read status */
5739 if (retbyte != 0x00) 5733 if (retbyte != 0x00)
5740 pr_err("i2c_w status error %02x\n", retbyte); 5734 pr_err("i2c_w status error %02x\n", retbyte);
5741 PDEBUG(D_USBO, "i2c w [%02x] = %02x%02x (%02x)",
5742 reg, valH, valL, retbyte);
5743 return retbyte; 5735 return retbyte;
5744} 5736}
5745 5737
@@ -5906,6 +5898,8 @@ static void getexposure(struct gspca_dev *gspca_dev)
5906{ 5898{
5907 struct sd *sd = (struct sd *) gspca_dev; 5899 struct sd *sd = (struct sd *) gspca_dev;
5908 5900
5901 if (sd->sensor != SENSOR_HV7131R)
5902 return;
5909 sd->ctrls[EXPOSURE].val = (i2c_read(gspca_dev, 0x25) << 9) 5903 sd->ctrls[EXPOSURE].val = (i2c_read(gspca_dev, 0x25) << 9)
5910 | (i2c_read(gspca_dev, 0x26) << 1) 5904 | (i2c_read(gspca_dev, 0x26) << 1)
5911 | (i2c_read(gspca_dev, 0x27) >> 7); 5905 | (i2c_read(gspca_dev, 0x27) >> 7);
@@ -5916,6 +5910,8 @@ static void setexposure(struct gspca_dev *gspca_dev)
5916 struct sd *sd = (struct sd *) gspca_dev; 5910 struct sd *sd = (struct sd *) gspca_dev;
5917 int val; 5911 int val;
5918 5912
5913 if (sd->sensor != SENSOR_HV7131R)
5914 return;
5919 val = sd->ctrls[EXPOSURE].val; 5915 val = sd->ctrls[EXPOSURE].val;
5920 i2c_write(gspca_dev, 0x25, val >> 9, 0x00); 5916 i2c_write(gspca_dev, 0x25, val >> 9, 0x00);
5921 i2c_write(gspca_dev, 0x26, val >> 1, 0x00); 5917 i2c_write(gspca_dev, 0x26, val >> 1, 0x00);
@@ -5925,32 +5921,20 @@ static void setexposure(struct gspca_dev *gspca_dev)
5925static void setquality(struct gspca_dev *gspca_dev) 5921static void setquality(struct gspca_dev *gspca_dev)
5926{ 5922{
5927 struct sd *sd = (struct sd *) gspca_dev; 5923 struct sd *sd = (struct sd *) gspca_dev;
5928 u8 frxt; 5924 s8 reg07;
5929 5925
5926 reg07 = 0;
5930 switch (sd->sensor) { 5927 switch (sd->sensor) {
5931 case SENSOR_ADCM2700:
5932 case SENSOR_GC0305:
5933 case SENSOR_HV7131B:
5934 case SENSOR_HV7131R:
5935 case SENSOR_OV7620: 5928 case SENSOR_OV7620:
5929 reg07 = 0x30;
5930 break;
5931 case SENSOR_HV7131R:
5936 case SENSOR_PAS202B: 5932 case SENSOR_PAS202B:
5937 case SENSOR_PO2030: 5933 return; /* done by work queue */
5938 return;
5939 } 5934 }
5940/*fixme: is it really 0008 0007 0018 for all other sensors? */ 5935 reg_w(gspca_dev, sd->reg08, ZC3XX_R008_CLOCKSETTING);
5941 reg_w(gspca_dev, QUANT_VAL, 0x0008); 5936 if (reg07 != 0)
5942 frxt = 0x30; 5937 reg_w(gspca_dev, reg07, 0x0007);
5943 reg_w(gspca_dev, frxt, 0x0007);
5944#if QUANT_VAL == 0 || QUANT_VAL == 1 || QUANT_VAL == 2
5945 frxt = 0xff;
5946#elif QUANT_VAL == 3
5947 frxt = 0xf0;
5948#elif QUANT_VAL == 4
5949 frxt = 0xe0;
5950#else
5951 frxt = 0x20;
5952#endif
5953 reg_w(gspca_dev, frxt, 0x0018);
5954} 5938}
5955 5939
5956/* Matches the sensor's internal frame rate to the lighting frequency. 5940/* Matches the sensor's internal frame rate to the lighting frequency.
@@ -6084,6 +6068,115 @@ static void setautogain(struct gspca_dev *gspca_dev)
6084 reg_w(gspca_dev, autoval, 0x0180); 6068 reg_w(gspca_dev, autoval, 0x0180);
6085} 6069}
6086 6070
6071/* update the transfer parameters */
6072/* This function is executed from a work queue. */
6073/* The exact use of the bridge registers 07 and 08 is not known.
6074 * The following algorithm has been adapted from ms-win traces */
6075static void transfer_update(struct work_struct *work)
6076{
6077 struct sd *sd = container_of(work, struct sd, work);
6078 struct gspca_dev *gspca_dev = &sd->gspca_dev;
6079 int change, good;
6080 u8 reg07, reg11;
6081
6082 /* synchronize with the main driver and initialize the registers */
6083 mutex_lock(&gspca_dev->usb_lock);
6084 reg07 = 0; /* max */
6085 reg_w(gspca_dev, reg07, 0x0007);
6086 reg_w(gspca_dev, sd->reg08, ZC3XX_R008_CLOCKSETTING);
6087 mutex_unlock(&gspca_dev->usb_lock);
6088
6089 good = 0;
6090 for (;;) {
6091 msleep(100);
6092
6093 /* get the transfer status */
6094 /* the bit 0 of the bridge register 11 indicates overflow */
6095 mutex_lock(&gspca_dev->usb_lock);
6096 if (!gspca_dev->present || !gspca_dev->streaming)
6097 goto err;
6098 reg11 = reg_r(gspca_dev, 0x0011);
6099 if (gspca_dev->usb_err < 0
6100 || !gspca_dev->present || !gspca_dev->streaming)
6101 goto err;
6102
6103 change = reg11 & 0x01;
6104 if (change) { /* overflow */
6105 switch (reg07) {
6106 case 0: /* max */
6107 reg07 = sd->sensor == SENSOR_HV7131R
6108 ? 0x30 : 0x32;
6109 if (sd->reg08 != 0) {
6110 change = 3;
6111 sd->reg08--;
6112 }
6113 break;
6114 case 0x32:
6115 reg07 -= 4;
6116 break;
6117 default:
6118 reg07 -= 2;
6119 break;
6120 case 2:
6121 change = 0; /* already min */
6122 break;
6123 }
6124 good = 0;
6125 } else { /* no overflow */
6126 if (reg07 != 0) { /* if not max */
6127 good++;
6128 if (good >= 10) {
6129 good = 0;
6130 change = 1;
6131 reg07 += 2;
6132 switch (reg07) {
6133 case 0x30:
6134 if (sd->sensor == SENSOR_PAS202B)
6135 reg07 += 2;
6136 break;
6137 case 0x32:
6138 case 0x34:
6139 reg07 = 0;
6140 break;
6141 }
6142 }
6143 } else { /* reg07 max */
6144 if (sd->reg08 < sizeof jpeg_qual - 1) {
6145 good++;
6146 if (good > 10) {
6147 sd->reg08++;
6148 change = 2;
6149 }
6150 }
6151 }
6152 }
6153 if (change) {
6154 if (change & 1) {
6155 reg_w(gspca_dev, reg07, 0x0007);
6156 if (gspca_dev->usb_err < 0
6157 || !gspca_dev->present
6158 || !gspca_dev->streaming)
6159 goto err;
6160 }
6161 if (change & 2) {
6162 reg_w(gspca_dev, sd->reg08,
6163 ZC3XX_R008_CLOCKSETTING);
6164 if (gspca_dev->usb_err < 0
6165 || !gspca_dev->present
6166 || !gspca_dev->streaming)
6167 goto err;
6168 sd->ctrls[QUALITY].val = jpeg_qual[sd->reg08];
6169 jpeg_set_qual(sd->jpeg_hdr,
6170 jpeg_qual[sd->reg08]);
6171 }
6172 }
6173 mutex_unlock(&gspca_dev->usb_lock);
6174 }
6175 return;
6176err:
6177 mutex_unlock(&gspca_dev->usb_lock);
6178}
6179
6087static void send_unknown(struct gspca_dev *gspca_dev, int sensor) 6180static void send_unknown(struct gspca_dev *gspca_dev, int sensor)
6088{ 6181{
6089 reg_w(gspca_dev, 0x01, 0x0000); /* bridge reset */ 6182 reg_w(gspca_dev, 0x01, 0x0000); /* bridge reset */
@@ -6411,7 +6504,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
6411 sd->sensor = id->driver_info; 6504 sd->sensor = id->driver_info;
6412 6505
6413 gspca_dev->cam.ctrls = sd->ctrls; 6506 gspca_dev->cam.ctrls = sd->ctrls;
6414 sd->quality = QUALITY_DEF; 6507 sd->reg08 = REG08_DEF;
6508
6509 INIT_WORK(&sd->work, transfer_update);
6415 6510
6416 return 0; 6511 return 0;
6417} 6512}
@@ -6464,6 +6559,27 @@ static int sd_init(struct gspca_dev *gspca_dev)
6464 [SENSOR_PO2030] = 1, 6559 [SENSOR_PO2030] = 1,
6465 [SENSOR_TAS5130C] = 1, 6560 [SENSOR_TAS5130C] = 1,
6466 }; 6561 };
6562 static const u8 reg08_tb[SENSOR_MAX] = {
6563 [SENSOR_ADCM2700] = 1,
6564 [SENSOR_CS2102] = 3,
6565 [SENSOR_CS2102K] = 3,
6566 [SENSOR_GC0303] = 2,
6567 [SENSOR_GC0305] = 3,
6568 [SENSOR_HDCS2020] = 1,
6569 [SENSOR_HV7131B] = 3,
6570 [SENSOR_HV7131R] = 3,
6571 [SENSOR_ICM105A] = 3,
6572 [SENSOR_MC501CB] = 3,
6573 [SENSOR_MT9V111_1] = 3,
6574 [SENSOR_MT9V111_3] = 3,
6575 [SENSOR_OV7620] = 1,
6576 [SENSOR_OV7630C] = 3,
6577 [SENSOR_PAS106] = 3,
6578 [SENSOR_PAS202B] = 3,
6579 [SENSOR_PB0330] = 3,
6580 [SENSOR_PO2030] = 2,
6581 [SENSOR_TAS5130C] = 3,
6582 };
6467 6583
6468 sensor = zcxx_probeSensor(gspca_dev); 6584 sensor = zcxx_probeSensor(gspca_dev);
6469 if (sensor >= 0) 6585 if (sensor >= 0)
@@ -6528,7 +6644,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
6528 case 0x0e: 6644 case 0x0e:
6529 PDEBUG(D_PROBE, "Find Sensor PAS202B"); 6645 PDEBUG(D_PROBE, "Find Sensor PAS202B");
6530 sd->sensor = SENSOR_PAS202B; 6646 sd->sensor = SENSOR_PAS202B;
6531/* sd->sharpness = 1; */
6532 break; 6647 break;
6533 case 0x0f: 6648 case 0x0f:
6534 PDEBUG(D_PROBE, "Find Sensor PAS106"); 6649 PDEBUG(D_PROBE, "Find Sensor PAS106");
@@ -6616,13 +6731,21 @@ static int sd_init(struct gspca_dev *gspca_dev)
6616 } 6731 }
6617 6732
6618 sd->ctrls[GAMMA].def = gamma[sd->sensor]; 6733 sd->ctrls[GAMMA].def = gamma[sd->sensor];
6734 sd->reg08 = reg08_tb[sd->sensor];
6735 sd->ctrls[QUALITY].def = jpeg_qual[sd->reg08];
6736 sd->ctrls[QUALITY].min = jpeg_qual[0];
6737 sd->ctrls[QUALITY].max = jpeg_qual[ARRAY_SIZE(jpeg_qual) - 1];
6619 6738
6620 switch (sd->sensor) { 6739 switch (sd->sensor) {
6621 case SENSOR_HV7131R: 6740 case SENSOR_HV7131R:
6741 gspca_dev->ctrl_dis = (1 << QUALITY);
6622 break; 6742 break;
6623 case SENSOR_OV7630C: 6743 case SENSOR_OV7630C:
6624 gspca_dev->ctrl_dis = (1 << LIGHTFREQ) | (1 << EXPOSURE); 6744 gspca_dev->ctrl_dis = (1 << LIGHTFREQ) | (1 << EXPOSURE);
6625 break; 6745 break;
6746 case SENSOR_PAS202B:
6747 gspca_dev->ctrl_dis = (1 << QUALITY) | (1 << EXPOSURE);
6748 break;
6626 default: 6749 default:
6627 gspca_dev->ctrl_dis = (1 << EXPOSURE); 6750 gspca_dev->ctrl_dis = (1 << EXPOSURE);
6628 break; 6751 break;
@@ -6685,7 +6808,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
6685 /* create the JPEG header */ 6808 /* create the JPEG header */
6686 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 6809 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
6687 0x21); /* JPEG 422 */ 6810 0x21); /* JPEG 422 */
6688 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
6689 6811
6690 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; 6812 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
6691 switch (sd->sensor) { 6813 switch (sd->sensor) {
@@ -6761,10 +6883,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
6761 reg_r(gspca_dev, 0x0180); /* from win */ 6883 reg_r(gspca_dev, 0x0180); /* from win */
6762 reg_w(gspca_dev, 0x00, 0x0180); 6884 reg_w(gspca_dev, 0x00, 0x0180);
6763 break; 6885 break;
6764 default:
6765 setquality(gspca_dev);
6766 break;
6767 } 6886 }
6887 setquality(gspca_dev);
6888 jpeg_set_qual(sd->jpeg_hdr, jpeg_qual[sd->reg08]);
6768 setlightfreq(gspca_dev); 6889 setlightfreq(gspca_dev);
6769 6890
6770 switch (sd->sensor) { 6891 switch (sd->sensor) {
@@ -6776,8 +6897,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
6776 reg_w(gspca_dev, 0x40, 0x0117); 6897 reg_w(gspca_dev, 0x40, 0x0117);
6777 break; 6898 break;
6778 case SENSOR_HV7131R: 6899 case SENSOR_HV7131R:
6779 if (!sd->ctrls[AUTOGAIN].val) 6900 setexposure(gspca_dev);
6780 setexposure(gspca_dev);
6781 reg_w(gspca_dev, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN); 6901 reg_w(gspca_dev, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN);
6782 break; 6902 break;
6783 case SENSOR_GC0305: 6903 case SENSOR_GC0305:
@@ -6802,13 +6922,19 @@ static int sd_start(struct gspca_dev *gspca_dev)
6802 } 6922 }
6803 6923
6804 setautogain(gspca_dev); 6924 setautogain(gspca_dev);
6805 switch (sd->sensor) { 6925
6806 case SENSOR_PO2030: 6926 /* start the transfer update thread if needed */
6807 msleep(50); 6927 if (gspca_dev->usb_err >= 0) {
6808 reg_w(gspca_dev, 0x00, 0x0007); /* (from win traces) */ 6928 switch (sd->sensor) {
6809 reg_w(gspca_dev, 0x02, ZC3XX_R008_CLOCKSETTING); 6929 case SENSOR_HV7131R:
6810 break; 6930 case SENSOR_PAS202B:
6931 sd->work_thread =
6932 create_singlethread_workqueue(KBUILD_MODNAME);
6933 queue_work(sd->work_thread, &sd->work);
6934 break;
6935 }
6811 } 6936 }
6937
6812 return gspca_dev->usb_err; 6938 return gspca_dev->usb_err;
6813} 6939}
6814 6940
@@ -6817,6 +6943,12 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
6817{ 6943{
6818 struct sd *sd = (struct sd *) gspca_dev; 6944 struct sd *sd = (struct sd *) gspca_dev;
6819 6945
6946 if (sd->work_thread != NULL) {
6947 mutex_unlock(&gspca_dev->usb_lock);
6948 destroy_workqueue(sd->work_thread);
6949 mutex_lock(&gspca_dev->usb_lock);
6950 sd->work_thread = NULL;
6951 }
6820 if (!gspca_dev->present) 6952 if (!gspca_dev->present)
6821 return; 6953 return;
6822 send_unknown(gspca_dev, sd->sensor); 6954 send_unknown(gspca_dev, sd->sensor);
@@ -6893,19 +7025,33 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
6893 return -EINVAL; 7025 return -EINVAL;
6894} 7026}
6895 7027
7028static int sd_setquality(struct gspca_dev *gspca_dev, __s32 val)
7029{
7030 struct sd *sd = (struct sd *) gspca_dev;
7031 int i;
7032
7033 for (i = 0; i < ARRAY_SIZE(jpeg_qual) - 1; i++) {
7034 if (val <= jpeg_qual[i])
7035 break;
7036 }
7037 if (i > 0
7038 && i == sd->reg08
7039 && val < jpeg_qual[sd->reg08])
7040 i--;
7041 sd->reg08 = i;
7042 sd->ctrls[QUALITY].val = jpeg_qual[i];
7043 if (gspca_dev->streaming)
7044 jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val);
7045 return gspca_dev->usb_err;
7046}
7047
6896static int sd_set_jcomp(struct gspca_dev *gspca_dev, 7048static int sd_set_jcomp(struct gspca_dev *gspca_dev,
6897 struct v4l2_jpegcompression *jcomp) 7049 struct v4l2_jpegcompression *jcomp)
6898{ 7050{
6899 struct sd *sd = (struct sd *) gspca_dev; 7051 struct sd *sd = (struct sd *) gspca_dev;
6900 7052
6901 if (jcomp->quality < QUALITY_MIN) 7053 sd_setquality(gspca_dev, jcomp->quality);
6902 sd->quality = QUALITY_MIN; 7054 jcomp->quality = sd->ctrls[QUALITY].val;
6903 else if (jcomp->quality > QUALITY_MAX)
6904 sd->quality = QUALITY_MAX;
6905 else
6906 sd->quality = jcomp->quality;
6907 if (gspca_dev->streaming)
6908 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
6909 return gspca_dev->usb_err; 7055 return gspca_dev->usb_err;
6910} 7056}
6911 7057
@@ -6915,7 +7061,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
6915 struct sd *sd = (struct sd *) gspca_dev; 7061 struct sd *sd = (struct sd *) gspca_dev;
6916 7062
6917 memset(jcomp, 0, sizeof *jcomp); 7063 memset(jcomp, 0, sizeof *jcomp);
6918 jcomp->quality = sd->quality; 7064 jcomp->quality = sd->ctrls[QUALITY].val;
6919 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT 7065 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
6920 | V4L2_JPEG_MARKER_DQT; 7066 | V4L2_JPEG_MARKER_DQT;
6921 return 0; 7067 return 0;
@@ -6938,7 +7084,7 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
6938#endif 7084#endif
6939 7085
6940static const struct sd_desc sd_desc = { 7086static const struct sd_desc sd_desc = {
6941 .name = MODULE_NAME, 7087 .name = KBUILD_MODNAME,
6942 .ctrls = sd_ctrls, 7088 .ctrls = sd_ctrls,
6943 .nctrls = ARRAY_SIZE(sd_ctrls), 7089 .nctrls = ARRAY_SIZE(sd_ctrls),
6944 .config = sd_config, 7090 .config = sd_config,
@@ -7023,7 +7169,7 @@ static int sd_probe(struct usb_interface *intf,
7023 7169
7024/* USB driver */ 7170/* USB driver */
7025static struct usb_driver sd_driver = { 7171static struct usb_driver sd_driver = {
7026 .name = MODULE_NAME, 7172 .name = KBUILD_MODNAME,
7027 .id_table = device_table, 7173 .id_table = device_table,
7028 .probe = sd_probe, 7174 .probe = sd_probe,
7029 .disconnect = gspca_disconnect, 7175 .disconnect = gspca_disconnect,
diff --git a/drivers/media/video/imx074.c b/drivers/media/video/imx074.c
index eec75bb57203..351e9bafe8fe 100644
--- a/drivers/media/video/imx074.c
+++ b/drivers/media/video/imx074.c
@@ -468,18 +468,7 @@ static struct i2c_driver imx074_i2c_driver = {
468 .id_table = imx074_id, 468 .id_table = imx074_id,
469}; 469};
470 470
471static int __init imx074_mod_init(void) 471module_i2c_driver(imx074_i2c_driver);
472{
473 return i2c_add_driver(&imx074_i2c_driver);
474}
475
476static void __exit imx074_mod_exit(void)
477{
478 i2c_del_driver(&imx074_i2c_driver);
479}
480
481module_init(imx074_mod_init);
482module_exit(imx074_mod_exit);
483 472
484MODULE_DESCRIPTION("Sony IMX074 Camera driver"); 473MODULE_DESCRIPTION("Sony IMX074 Camera driver");
485MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); 474MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
diff --git a/drivers/media/video/indycam.c b/drivers/media/video/indycam.c
index e5ed4db32e7b..548236333cce 100644
--- a/drivers/media/video/indycam.c
+++ b/drivers/media/video/indycam.c
@@ -387,15 +387,4 @@ static struct i2c_driver indycam_driver = {
387 .id_table = indycam_id, 387 .id_table = indycam_id,
388}; 388};
389 389
390static __init int init_indycam(void) 390module_i2c_driver(indycam_driver);
391{
392 return i2c_add_driver(&indycam_driver);
393}
394
395static __exit void exit_indycam(void)
396{
397 i2c_del_driver(&indycam_driver);
398}
399
400module_init(init_indycam);
401module_exit(exit_indycam);
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index a7c41d32f414..04f192a0398a 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -471,7 +471,7 @@ static const struct i2c_device_id ir_kbd_id[] = {
471 { } 471 { }
472}; 472};
473 473
474static struct i2c_driver driver = { 474static struct i2c_driver ir_kbd_driver = {
475 .driver = { 475 .driver = {
476 .name = "ir-kbd-i2c", 476 .name = "ir-kbd-i2c",
477 }, 477 },
@@ -480,21 +480,10 @@ static struct i2c_driver driver = {
480 .id_table = ir_kbd_id, 480 .id_table = ir_kbd_id,
481}; 481};
482 482
483module_i2c_driver(ir_kbd_driver);
484
483/* ----------------------------------------------------------------------- */ 485/* ----------------------------------------------------------------------- */
484 486
485MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, Ulrich Mueller"); 487MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, Ulrich Mueller");
486MODULE_DESCRIPTION("input driver for i2c IR remote controls"); 488MODULE_DESCRIPTION("input driver for i2c IR remote controls");
487MODULE_LICENSE("GPL"); 489MODULE_LICENSE("GPL");
488
489static int __init ir_init(void)
490{
491 return i2c_add_driver(&driver);
492}
493
494static void __exit ir_fini(void)
495{
496 i2c_del_driver(&driver);
497}
498
499module_init(ir_init);
500module_exit(ir_fini);
diff --git a/drivers/media/video/ivtv/Makefile b/drivers/media/video/ivtv/Makefile
index 71ab76a5ab26..77de8a45b46f 100644
--- a/drivers/media/video/ivtv/Makefile
+++ b/drivers/media/video/ivtv/Makefile
@@ -7,8 +7,8 @@ ivtv-objs := ivtv-routing.o ivtv-cards.o ivtv-controls.o \
7obj-$(CONFIG_VIDEO_IVTV) += ivtv.o 7obj-$(CONFIG_VIDEO_IVTV) += ivtv.o
8obj-$(CONFIG_VIDEO_FB_IVTV) += ivtvfb.o 8obj-$(CONFIG_VIDEO_FB_IVTV) += ivtvfb.o
9 9
10ccflags-y += -Idrivers/media/video 10ccflags-y += -I$(srctree)/drivers/media/video
11ccflags-y += -Idrivers/media/common/tuners 11ccflags-y += -I$(srctree)/drivers/media/common/tuners
12ccflags-y += -Idrivers/media/dvb/dvb-core 12ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
13ccflags-y += -Idrivers/media/dvb/frontends 13ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
14 14
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c
index b31ee1bceef8..c60424601cb9 100644
--- a/drivers/media/video/ivtv/ivtv-controls.c
+++ b/drivers/media/video/ivtv/ivtv-controls.c
@@ -21,6 +21,7 @@
21#include "ivtv-driver.h" 21#include "ivtv-driver.h"
22#include "ivtv-ioctl.h" 22#include "ivtv-ioctl.h"
23#include "ivtv-controls.h" 23#include "ivtv-controls.h"
24#include "ivtv-mailbox.h"
24 25
25static int ivtv_s_stream_vbi_fmt(struct cx2341x_handler *cxhdl, u32 fmt) 26static int ivtv_s_stream_vbi_fmt(struct cx2341x_handler *cxhdl, u32 fmt)
26{ 27{
@@ -99,3 +100,64 @@ struct cx2341x_handler_ops ivtv_cxhdl_ops = {
99 .s_video_encoding = ivtv_s_video_encoding, 100 .s_video_encoding = ivtv_s_video_encoding,
100 .s_stream_vbi_fmt = ivtv_s_stream_vbi_fmt, 101 .s_stream_vbi_fmt = ivtv_s_stream_vbi_fmt,
101}; 102};
103
104int ivtv_g_pts_frame(struct ivtv *itv, s64 *pts, s64 *frame)
105{
106 u32 data[CX2341X_MBOX_MAX_DATA];
107
108 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
109 *pts = (s64)((u64)itv->last_dec_timing[2] << 32) |
110 (u64)itv->last_dec_timing[1];
111 *frame = itv->last_dec_timing[0];
112 return 0;
113 }
114 *pts = 0;
115 *frame = 0;
116 if (atomic_read(&itv->decoding)) {
117 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
118 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
119 return -EIO;
120 }
121 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
122 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
123 *pts = (s64)((u64) data[2] << 32) | (u64) data[1];
124 *frame = data[0];
125 /*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/
126 }
127 return 0;
128}
129
130static int ivtv_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
131{
132 struct ivtv *itv = container_of(ctrl->handler, struct ivtv, cxhdl.hdl);
133
134 switch (ctrl->id) {
135 /* V4L2_CID_MPEG_VIDEO_DEC_PTS and V4L2_CID_MPEG_VIDEO_DEC_FRAME
136 control cluster */
137 case V4L2_CID_MPEG_VIDEO_DEC_PTS:
138 return ivtv_g_pts_frame(itv, &itv->ctrl_pts->val64,
139 &itv->ctrl_frame->val64);
140 }
141 return 0;
142}
143
144static int ivtv_s_ctrl(struct v4l2_ctrl *ctrl)
145{
146 struct ivtv *itv = container_of(ctrl->handler, struct ivtv, cxhdl.hdl);
147
148 switch (ctrl->id) {
149 /* V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK and MULTILINGUAL_PLAYBACK
150 control cluster */
151 case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK:
152 itv->audio_stereo_mode = itv->ctrl_audio_playback->val - 1;
153 itv->audio_bilingual_mode = itv->ctrl_audio_multilingual_playback->val - 1;
154 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
155 break;
156 }
157 return 0;
158}
159
160const struct v4l2_ctrl_ops ivtv_hdl_out_ops = {
161 .s_ctrl = ivtv_s_ctrl,
162 .g_volatile_ctrl = ivtv_g_volatile_ctrl,
163};
diff --git a/drivers/media/video/ivtv/ivtv-controls.h b/drivers/media/video/ivtv/ivtv-controls.h
index d12893dd0183..3999e6358312 100644
--- a/drivers/media/video/ivtv/ivtv-controls.h
+++ b/drivers/media/video/ivtv/ivtv-controls.h
@@ -22,5 +22,7 @@
22#define IVTV_CONTROLS_H 22#define IVTV_CONTROLS_H
23 23
24extern struct cx2341x_handler_ops ivtv_cxhdl_ops; 24extern struct cx2341x_handler_ops ivtv_cxhdl_ops;
25extern const struct v4l2_ctrl_ops ivtv_hdl_out_ops;
26int ivtv_g_pts_frame(struct ivtv *itv, s64 *pts, s64 *frame);
25 27
26#endif 28#endif
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 3949b7dc2368..679262ed13bc 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -55,7 +55,7 @@
55#include "ivtv-routing.h" 55#include "ivtv-routing.h"
56#include "ivtv-controls.h" 56#include "ivtv-controls.h"
57#include "ivtv-gpio.h" 57#include "ivtv-gpio.h"
58 58#include <linux/dma-mapping.h>
59#include <media/tveeprom.h> 59#include <media/tveeprom.h>
60#include <media/saa7115.h> 60#include <media/saa7115.h>
61#include <media/v4l2-chip-ident.h> 61#include <media/v4l2-chip-ident.h>
@@ -99,7 +99,7 @@ static int i2c_clock_period[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
99 99
100static unsigned int cardtype_c = 1; 100static unsigned int cardtype_c = 1;
101static unsigned int tuner_c = 1; 101static unsigned int tuner_c = 1;
102static bool radio_c = 1; 102static int radio_c = 1;
103static unsigned int i2c_clock_period_c = 1; 103static unsigned int i2c_clock_period_c = 1;
104static char pal[] = "---"; 104static char pal[] = "---";
105static char secam[] = "--"; 105static char secam[] = "--";
@@ -139,7 +139,7 @@ static int tunertype = -1;
139static int newi2c = -1; 139static int newi2c = -1;
140 140
141module_param_array(tuner, int, &tuner_c, 0644); 141module_param_array(tuner, int, &tuner_c, 0644);
142module_param_array(radio, bool, &radio_c, 0644); 142module_param_array(radio, int, &radio_c, 0644);
143module_param_array(cardtype, int, &cardtype_c, 0644); 143module_param_array(cardtype, int, &cardtype_c, 0644);
144module_param_string(pal, pal, sizeof(pal), 0644); 144module_param_string(pal, pal, sizeof(pal), 0644);
145module_param_string(secam, secam, sizeof(secam), 0644); 145module_param_string(secam, secam, sizeof(secam), 0644);
@@ -744,8 +744,6 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
744 744
745 itv->cur_dma_stream = -1; 745 itv->cur_dma_stream = -1;
746 itv->cur_pio_stream = -1; 746 itv->cur_pio_stream = -1;
747 itv->audio_stereo_mode = AUDIO_STEREO;
748 itv->audio_bilingual_mode = AUDIO_MONO_LEFT;
749 747
750 /* Ctrls */ 748 /* Ctrls */
751 itv->speed = 1000; 749 itv->speed = 1000;
@@ -815,7 +813,7 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev,
815 IVTV_ERR("Can't enable device!\n"); 813 IVTV_ERR("Can't enable device!\n");
816 return -EIO; 814 return -EIO;
817 } 815 }
818 if (pci_set_dma_mask(pdev, 0xffffffff)) { 816 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
819 IVTV_ERR("No suitable DMA available.\n"); 817 IVTV_ERR("No suitable DMA available.\n");
820 return -EIO; 818 return -EIO;
821 } 819 }
@@ -1200,6 +1198,32 @@ static int __devinit ivtv_probe(struct pci_dev *pdev,
1200 itv->tuner_std = itv->std; 1198 itv->tuner_std = itv->std;
1201 1199
1202 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { 1200 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1201 struct v4l2_ctrl_handler *hdl = itv->v4l2_dev.ctrl_handler;
1202
1203 itv->ctrl_pts = v4l2_ctrl_new_std(hdl, &ivtv_hdl_out_ops,
1204 V4L2_CID_MPEG_VIDEO_DEC_PTS, 0, 0, 1, 0);
1205 itv->ctrl_frame = v4l2_ctrl_new_std(hdl, &ivtv_hdl_out_ops,
1206 V4L2_CID_MPEG_VIDEO_DEC_FRAME, 0, 0x7fffffff, 1, 0);
1207 /* Note: V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO is not supported,
1208 mask that menu item. */
1209 itv->ctrl_audio_playback =
1210 v4l2_ctrl_new_std_menu(hdl, &ivtv_hdl_out_ops,
1211 V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK,
1212 V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO,
1213 1 << V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO,
1214 V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO);
1215 itv->ctrl_audio_multilingual_playback =
1216 v4l2_ctrl_new_std_menu(hdl, &ivtv_hdl_out_ops,
1217 V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK,
1218 V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO,
1219 1 << V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO,
1220 V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT);
1221 if (hdl->error) {
1222 retval = hdl->error;
1223 goto free_i2c;
1224 }
1225 v4l2_ctrl_cluster(2, &itv->ctrl_pts);
1226 v4l2_ctrl_cluster(2, &itv->ctrl_audio_playback);
1203 ivtv_call_all(itv, video, s_std_output, itv->std); 1227 ivtv_call_all(itv, video, s_std_output, itv->std);
1204 /* Turn off the output signal. The mpeg decoder is not yet 1228 /* Turn off the output signal. The mpeg decoder is not yet
1205 active so without this you would get a green image until the 1229 active so without this you would get a green image until the
@@ -1236,6 +1260,7 @@ free_streams:
1236free_irq: 1260free_irq:
1237 free_irq(itv->pdev->irq, (void *)itv); 1261 free_irq(itv->pdev->irq, (void *)itv);
1238free_i2c: 1262free_i2c:
1263 v4l2_ctrl_handler_free(&itv->cxhdl.hdl);
1239 exit_ivtv_i2c(itv); 1264 exit_ivtv_i2c(itv);
1240free_io: 1265free_io:
1241 ivtv_iounmap(itv); 1266 ivtv_iounmap(itv);
@@ -1375,7 +1400,7 @@ static void ivtv_remove(struct pci_dev *pdev)
1375 else 1400 else
1376 type = IVTV_DEC_STREAM_TYPE_MPG; 1401 type = IVTV_DEC_STREAM_TYPE_MPG;
1377 ivtv_stop_v4l2_decode_stream(&itv->streams[type], 1402 ivtv_stop_v4l2_decode_stream(&itv->streams[type],
1378 VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0); 1403 V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY, 0);
1379 } 1404 }
1380 ivtv_halt_firmware(itv); 1405 ivtv_halt_firmware(itv);
1381 } 1406 }
@@ -1391,6 +1416,8 @@ static void ivtv_remove(struct pci_dev *pdev)
1391 ivtv_streams_cleanup(itv, 1); 1416 ivtv_streams_cleanup(itv, 1);
1392 ivtv_udma_free(itv); 1417 ivtv_udma_free(itv);
1393 1418
1419 v4l2_ctrl_handler_free(&itv->cxhdl.hdl);
1420
1394 exit_ivtv_i2c(itv); 1421 exit_ivtv_i2c(itv);
1395 1422
1396 free_irq(itv->pdev->irq, (void *)itv); 1423 free_irq(itv->pdev->irq, (void *)itv);
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 06f3d78389bf..f767df943954 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -331,6 +331,7 @@ struct ivtv_stream {
331 struct ivtv *itv; /* for ease of use */ 331 struct ivtv *itv; /* for ease of use */
332 const char *name; /* name of the stream */ 332 const char *name; /* name of the stream */
333 int type; /* stream type */ 333 int type; /* stream type */
334 u32 caps; /* V4L2 capabilities */
334 335
335 struct v4l2_fh *fh; /* pointer to the streaming filehandle */ 336 struct v4l2_fh *fh; /* pointer to the streaming filehandle */
336 spinlock_t qlock; /* locks access to the queues */ 337 spinlock_t qlock; /* locks access to the queues */
@@ -630,6 +631,16 @@ struct ivtv {
630 631
631 struct v4l2_device v4l2_dev; 632 struct v4l2_device v4l2_dev;
632 struct cx2341x_handler cxhdl; 633 struct cx2341x_handler cxhdl;
634 struct {
635 /* PTS/Frame count control cluster */
636 struct v4l2_ctrl *ctrl_pts;
637 struct v4l2_ctrl *ctrl_frame;
638 };
639 struct {
640 /* Audio Playback control cluster */
641 struct v4l2_ctrl *ctrl_audio_playback;
642 struct v4l2_ctrl *ctrl_audio_multilingual_playback;
643 };
633 struct v4l2_ctrl_handler hdl_gpio; 644 struct v4l2_ctrl_handler hdl_gpio;
634 struct v4l2_subdev sd_gpio; /* GPIO sub-device */ 645 struct v4l2_subdev sd_gpio; /* GPIO sub-device */
635 u16 instance; 646 u16 instance;
@@ -649,7 +660,6 @@ struct ivtv {
649 u8 audio_stereo_mode; /* decoder setting how to handle stereo MPEG audio */ 660 u8 audio_stereo_mode; /* decoder setting how to handle stereo MPEG audio */
650 u8 audio_bilingual_mode; /* decoder setting how to handle bilingual MPEG audio */ 661 u8 audio_bilingual_mode; /* decoder setting how to handle bilingual MPEG audio */
651 662
652
653 /* Locking */ 663 /* Locking */
654 spinlock_t lock; /* lock access to this struct */ 664 spinlock_t lock; /* lock access to this struct */
655 struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */ 665 struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index 2cd6c89b7d91..c9663e885b9f 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -900,7 +900,7 @@ int ivtv_v4l2_close(struct file *filp)
900 if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) { 900 if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) {
901 struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT]; 901 struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT];
902 902
903 ivtv_stop_decoding(id, VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0); 903 ivtv_stop_decoding(id, V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY, 0);
904 904
905 /* If all output streams are closed, and if the user doesn't have 905 /* If all output streams are closed, and if the user doesn't have
906 IVTV_DEC_STREAM_TYPE_VOUT open, then disable CC on TV-out. */ 906 IVTV_DEC_STREAM_TYPE_VOUT open, then disable CC on TV-out. */
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index c4bc48143098..5452beef8e11 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -246,34 +246,40 @@ static int ivtv_validate_speed(int cur_speed, int new_speed)
246} 246}
247 247
248static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id, 248static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
249 struct video_command *vc, int try) 249 struct v4l2_decoder_cmd *dc, int try)
250{ 250{
251 struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG]; 251 struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
252 252
253 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 253 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
254 return -EINVAL; 254 return -EINVAL;
255 255
256 switch (vc->cmd) { 256 switch (dc->cmd) {
257 case VIDEO_CMD_PLAY: { 257 case V4L2_DEC_CMD_START: {
258 vc->flags = 0; 258 dc->flags &= V4L2_DEC_CMD_START_MUTE_AUDIO;
259 vc->play.speed = ivtv_validate_speed(itv->speed, vc->play.speed); 259 dc->start.speed = ivtv_validate_speed(itv->speed, dc->start.speed);
260 if (vc->play.speed < 0) 260 if (dc->start.speed < 0)
261 vc->play.format = VIDEO_PLAY_FMT_GOP; 261 dc->start.format = V4L2_DEC_START_FMT_GOP;
262 else
263 dc->start.format = V4L2_DEC_START_FMT_NONE;
264 if (dc->start.speed != 500 && dc->start.speed != 1500)
265 dc->flags = dc->start.speed == 1000 ? 0 :
266 V4L2_DEC_CMD_START_MUTE_AUDIO;
262 if (try) break; 267 if (try) break;
263 268
269 itv->speed_mute_audio = dc->flags & V4L2_DEC_CMD_START_MUTE_AUDIO;
264 if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG) 270 if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG)
265 return -EBUSY; 271 return -EBUSY;
266 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) { 272 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
267 /* forces ivtv_set_speed to be called */ 273 /* forces ivtv_set_speed to be called */
268 itv->speed = 0; 274 itv->speed = 0;
269 } 275 }
270 return ivtv_start_decoding(id, vc->play.speed); 276 return ivtv_start_decoding(id, dc->start.speed);
271 } 277 }
272 278
273 case VIDEO_CMD_STOP: 279 case V4L2_DEC_CMD_STOP:
274 vc->flags &= VIDEO_CMD_STOP_IMMEDIATELY|VIDEO_CMD_STOP_TO_BLACK; 280 dc->flags &= V4L2_DEC_CMD_STOP_IMMEDIATELY | V4L2_DEC_CMD_STOP_TO_BLACK;
275 if (vc->flags & VIDEO_CMD_STOP_IMMEDIATELY) 281 if (dc->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY)
276 vc->stop.pts = 0; 282 dc->stop.pts = 0;
277 if (try) break; 283 if (try) break;
278 if (atomic_read(&itv->decoding) == 0) 284 if (atomic_read(&itv->decoding) == 0)
279 return 0; 285 return 0;
@@ -281,22 +287,22 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
281 return -EBUSY; 287 return -EBUSY;
282 288
283 itv->output_mode = OUT_NONE; 289 itv->output_mode = OUT_NONE;
284 return ivtv_stop_v4l2_decode_stream(s, vc->flags, vc->stop.pts); 290 return ivtv_stop_v4l2_decode_stream(s, dc->flags, dc->stop.pts);
285 291
286 case VIDEO_CMD_FREEZE: 292 case V4L2_DEC_CMD_PAUSE:
287 vc->flags &= VIDEO_CMD_FREEZE_TO_BLACK; 293 dc->flags &= V4L2_DEC_CMD_PAUSE_TO_BLACK;
288 if (try) break; 294 if (try) break;
289 if (itv->output_mode != OUT_MPG) 295 if (itv->output_mode != OUT_MPG)
290 return -EBUSY; 296 return -EBUSY;
291 if (atomic_read(&itv->decoding) > 0) { 297 if (atomic_read(&itv->decoding) > 0) {
292 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 298 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1,
293 (vc->flags & VIDEO_CMD_FREEZE_TO_BLACK) ? 1 : 0); 299 (dc->flags & V4L2_DEC_CMD_PAUSE_TO_BLACK) ? 1 : 0);
294 set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags); 300 set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
295 } 301 }
296 break; 302 break;
297 303
298 case VIDEO_CMD_CONTINUE: 304 case V4L2_DEC_CMD_RESUME:
299 vc->flags = 0; 305 dc->flags = 0;
300 if (try) break; 306 if (try) break;
301 if (itv->output_mode != OUT_MPG) 307 if (itv->output_mode != OUT_MPG)
302 return -EBUSY; 308 return -EBUSY;
@@ -754,12 +760,15 @@ static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register
754 760
755static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap) 761static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
756{ 762{
757 struct ivtv *itv = fh2id(fh)->itv; 763 struct ivtv_open_id *id = fh2id(file->private_data);
764 struct ivtv *itv = id->itv;
765 struct ivtv_stream *s = &itv->streams[id->type];
758 766
759 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver)); 767 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
760 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card)); 768 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
761 snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev)); 769 snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
762 vcap->capabilities = itv->v4l2_cap; /* capabilities */ 770 vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS;
771 vcap->device_caps = s->caps;
763 return 0; 772 return 0;
764} 773}
765 774
@@ -1476,8 +1485,6 @@ static int ivtv_log_status(struct file *file, void *fh)
1476 struct v4l2_audio audin; 1485 struct v4l2_audio audin;
1477 int i; 1486 int i;
1478 1487
1479 IVTV_INFO("================= START STATUS CARD #%d =================\n",
1480 itv->instance);
1481 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name); 1488 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
1482 if (itv->hw_flags & IVTV_HW_TVEEPROM) { 1489 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1483 struct tveeprom tv; 1490 struct tveeprom tv;
@@ -1501,13 +1508,6 @@ static int ivtv_log_status(struct file *file, void *fh)
1501 "YUV Frames", 1508 "YUV Frames",
1502 "Passthrough", 1509 "Passthrough",
1503 }; 1510 };
1504 static const char * const audio_modes[5] = {
1505 "Stereo",
1506 "Left",
1507 "Right",
1508 "Mono",
1509 "Swapped"
1510 };
1511 static const char * const alpha_mode[4] = { 1511 static const char * const alpha_mode[4] = {
1512 "None", 1512 "None",
1513 "Global", 1513 "Global",
@@ -1536,9 +1536,6 @@ static int ivtv_log_status(struct file *file, void *fh)
1536 ivtv_get_output(itv, itv->active_output, &vidout); 1536 ivtv_get_output(itv, itv->active_output, &vidout);
1537 ivtv_get_audio_output(itv, 0, &audout); 1537 ivtv_get_audio_output(itv, 0, &audout);
1538 IVTV_INFO("Video Output: %s\n", vidout.name); 1538 IVTV_INFO("Video Output: %s\n", vidout.name);
1539 IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name,
1540 audio_modes[itv->audio_stereo_mode],
1541 audio_modes[itv->audio_bilingual_mode]);
1542 if (mode < 0 || mode > OUT_PASSTHROUGH) 1539 if (mode < 0 || mode > OUT_PASSTHROUGH)
1543 mode = OUT_NONE; 1540 mode = OUT_NONE;
1544 IVTV_INFO("Output Mode: %s\n", output_modes[mode]); 1541 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
@@ -1566,12 +1563,27 @@ static int ivtv_log_status(struct file *file, void *fh)
1566 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n", 1563 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n",
1567 (long long)itv->mpg_data_received, 1564 (long long)itv->mpg_data_received,
1568 (long long)itv->vbi_data_inserted); 1565 (long long)itv->vbi_data_inserted);
1569 IVTV_INFO("================== END STATUS CARD #%d ==================\n",
1570 itv->instance);
1571
1572 return 0; 1566 return 0;
1573} 1567}
1574 1568
1569static int ivtv_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
1570{
1571 struct ivtv_open_id *id = fh2id(file->private_data);
1572 struct ivtv *itv = id->itv;
1573
1574 IVTV_DEBUG_IOCTL("VIDIOC_DECODER_CMD %d\n", dec->cmd);
1575 return ivtv_video_command(itv, id, dec, false);
1576}
1577
1578static int ivtv_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
1579{
1580 struct ivtv_open_id *id = fh2id(file->private_data);
1581 struct ivtv *itv = id->itv;
1582
1583 IVTV_DEBUG_IOCTL("VIDIOC_TRY_DECODER_CMD %d\n", dec->cmd);
1584 return ivtv_video_command(itv, id, dec, true);
1585}
1586
1575static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) 1587static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
1576{ 1588{
1577 struct ivtv_open_id *id = fh2id(filp->private_data); 1589 struct ivtv_open_id *id = fh2id(filp->private_data);
@@ -1605,9 +1617,15 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
1605 return ivtv_yuv_prep_frame(itv, args); 1617 return ivtv_yuv_prep_frame(itv, args);
1606 } 1618 }
1607 1619
1620 case IVTV_IOC_PASSTHROUGH_MODE:
1621 IVTV_DEBUG_IOCTL("IVTV_IOC_PASSTHROUGH_MODE\n");
1622 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1623 return -EINVAL;
1624 return ivtv_passthrough_mode(itv, *(int *)arg != 0);
1625
1608 case VIDEO_GET_PTS: { 1626 case VIDEO_GET_PTS: {
1609 u32 data[CX2341X_MBOX_MAX_DATA]; 1627 s64 *pts = arg;
1610 u64 *pts = arg; 1628 s64 frame;
1611 1629
1612 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n"); 1630 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
1613 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) { 1631 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
@@ -1616,29 +1634,12 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
1616 } 1634 }
1617 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 1635 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1618 return -EINVAL; 1636 return -EINVAL;
1619 1637 return ivtv_g_pts_frame(itv, pts, &frame);
1620 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1621 *pts = (u64) ((u64)itv->last_dec_timing[2] << 32) |
1622 (u64)itv->last_dec_timing[1];
1623 break;
1624 }
1625 *pts = 0;
1626 if (atomic_read(&itv->decoding)) {
1627 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1628 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1629 return -EIO;
1630 }
1631 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1632 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1633 *pts = (u64) ((u64) data[2] << 32) | (u64) data[1];
1634 /*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/
1635 }
1636 break;
1637 } 1638 }
1638 1639
1639 case VIDEO_GET_FRAME_COUNT: { 1640 case VIDEO_GET_FRAME_COUNT: {
1640 u32 data[CX2341X_MBOX_MAX_DATA]; 1641 s64 *frame = arg;
1641 u64 *frame = arg; 1642 s64 pts;
1642 1643
1643 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n"); 1644 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
1644 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) { 1645 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
@@ -1647,71 +1648,58 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
1647 } 1648 }
1648 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 1649 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1649 return -EINVAL; 1650 return -EINVAL;
1650 1651 return ivtv_g_pts_frame(itv, &pts, frame);
1651 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1652 *frame = itv->last_dec_timing[0];
1653 break;
1654 }
1655 *frame = 0;
1656 if (atomic_read(&itv->decoding)) {
1657 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1658 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1659 return -EIO;
1660 }
1661 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1662 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1663 *frame = data[0];
1664 }
1665 break;
1666 } 1652 }
1667 1653
1668 case VIDEO_PLAY: { 1654 case VIDEO_PLAY: {
1669 struct video_command vc; 1655 struct v4l2_decoder_cmd dc;
1670 1656
1671 IVTV_DEBUG_IOCTL("VIDEO_PLAY\n"); 1657 IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
1672 memset(&vc, 0, sizeof(vc)); 1658 memset(&dc, 0, sizeof(dc));
1673 vc.cmd = VIDEO_CMD_PLAY; 1659 dc.cmd = V4L2_DEC_CMD_START;
1674 return ivtv_video_command(itv, id, &vc, 0); 1660 return ivtv_video_command(itv, id, &dc, 0);
1675 } 1661 }
1676 1662
1677 case VIDEO_STOP: { 1663 case VIDEO_STOP: {
1678 struct video_command vc; 1664 struct v4l2_decoder_cmd dc;
1679 1665
1680 IVTV_DEBUG_IOCTL("VIDEO_STOP\n"); 1666 IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
1681 memset(&vc, 0, sizeof(vc)); 1667 memset(&dc, 0, sizeof(dc));
1682 vc.cmd = VIDEO_CMD_STOP; 1668 dc.cmd = V4L2_DEC_CMD_STOP;
1683 vc.flags = VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY; 1669 dc.flags = V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY;
1684 return ivtv_video_command(itv, id, &vc, 0); 1670 return ivtv_video_command(itv, id, &dc, 0);
1685 } 1671 }
1686 1672
1687 case VIDEO_FREEZE: { 1673 case VIDEO_FREEZE: {
1688 struct video_command vc; 1674 struct v4l2_decoder_cmd dc;
1689 1675
1690 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n"); 1676 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
1691 memset(&vc, 0, sizeof(vc)); 1677 memset(&dc, 0, sizeof(dc));
1692 vc.cmd = VIDEO_CMD_FREEZE; 1678 dc.cmd = V4L2_DEC_CMD_PAUSE;
1693 return ivtv_video_command(itv, id, &vc, 0); 1679 return ivtv_video_command(itv, id, &dc, 0);
1694 } 1680 }
1695 1681
1696 case VIDEO_CONTINUE: { 1682 case VIDEO_CONTINUE: {
1697 struct video_command vc; 1683 struct v4l2_decoder_cmd dc;
1698 1684
1699 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n"); 1685 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
1700 memset(&vc, 0, sizeof(vc)); 1686 memset(&dc, 0, sizeof(dc));
1701 vc.cmd = VIDEO_CMD_CONTINUE; 1687 dc.cmd = V4L2_DEC_CMD_RESUME;
1702 return ivtv_video_command(itv, id, &vc, 0); 1688 return ivtv_video_command(itv, id, &dc, 0);
1703 } 1689 }
1704 1690
1705 case VIDEO_COMMAND: 1691 case VIDEO_COMMAND:
1706 case VIDEO_TRY_COMMAND: { 1692 case VIDEO_TRY_COMMAND: {
1707 struct video_command *vc = arg; 1693 /* Note: struct v4l2_decoder_cmd has the same layout as
1694 struct video_command */
1695 struct v4l2_decoder_cmd *dc = arg;
1708 int try = (cmd == VIDEO_TRY_COMMAND); 1696 int try = (cmd == VIDEO_TRY_COMMAND);
1709 1697
1710 if (try) 1698 if (try)
1711 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", vc->cmd); 1699 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", dc->cmd);
1712 else 1700 else
1713 IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", vc->cmd); 1701 IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", dc->cmd);
1714 return ivtv_video_command(itv, id, vc, try); 1702 return ivtv_video_command(itv, id, dc, try);
1715 } 1703 }
1716 1704
1717 case VIDEO_GET_EVENT: { 1705 case VIDEO_GET_EVENT: {
@@ -1775,17 +1763,13 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
1775 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n"); 1763 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1776 if (iarg > AUDIO_STEREO_SWAPPED) 1764 if (iarg > AUDIO_STEREO_SWAPPED)
1777 return -EINVAL; 1765 return -EINVAL;
1778 itv->audio_stereo_mode = iarg; 1766 return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg);
1779 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1780 return 0;
1781 1767
1782 case AUDIO_BILINGUAL_CHANNEL_SELECT: 1768 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1783 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n"); 1769 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1784 if (iarg > AUDIO_STEREO_SWAPPED) 1770 if (iarg > AUDIO_STEREO_SWAPPED)
1785 return -EINVAL; 1771 return -EINVAL;
1786 itv->audio_bilingual_mode = iarg; 1772 return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg);
1787 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1788 return 0;
1789 1773
1790 default: 1774 default:
1791 return -EINVAL; 1775 return -EINVAL;
@@ -1800,6 +1784,7 @@ static long ivtv_default(struct file *file, void *fh, bool valid_prio,
1800 1784
1801 if (!valid_prio) { 1785 if (!valid_prio) {
1802 switch (cmd) { 1786 switch (cmd) {
1787 case IVTV_IOC_PASSTHROUGH_MODE:
1803 case VIDEO_PLAY: 1788 case VIDEO_PLAY:
1804 case VIDEO_STOP: 1789 case VIDEO_STOP:
1805 case VIDEO_FREEZE: 1790 case VIDEO_FREEZE:
@@ -1825,6 +1810,7 @@ static long ivtv_default(struct file *file, void *fh, bool valid_prio,
1825 } 1810 }
1826 1811
1827 case IVTV_IOC_DMA_FRAME: 1812 case IVTV_IOC_DMA_FRAME:
1813 case IVTV_IOC_PASSTHROUGH_MODE:
1828 case VIDEO_GET_PTS: 1814 case VIDEO_GET_PTS:
1829 case VIDEO_GET_FRAME_COUNT: 1815 case VIDEO_GET_FRAME_COUNT:
1830 case VIDEO_GET_EVENT: 1816 case VIDEO_GET_EVENT:
@@ -1889,6 +1875,8 @@ static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
1889 .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap, 1875 .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap,
1890 .vidioc_encoder_cmd = ivtv_encoder_cmd, 1876 .vidioc_encoder_cmd = ivtv_encoder_cmd,
1891 .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd, 1877 .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd,
1878 .vidioc_decoder_cmd = ivtv_decoder_cmd,
1879 .vidioc_try_decoder_cmd = ivtv_try_decoder_cmd,
1892 .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out, 1880 .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out,
1893 .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap, 1881 .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap,
1894 .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap, 1882 .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap,
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index c6e28b4ebbed..7ea5ca7f012b 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -78,60 +78,73 @@ static struct {
78 int num_offset; 78 int num_offset;
79 int dma, pio; 79 int dma, pio;
80 enum v4l2_buf_type buf_type; 80 enum v4l2_buf_type buf_type;
81 u32 v4l2_caps;
81 const struct v4l2_file_operations *fops; 82 const struct v4l2_file_operations *fops;
82} ivtv_stream_info[] = { 83} ivtv_stream_info[] = {
83 { /* IVTV_ENC_STREAM_TYPE_MPG */ 84 { /* IVTV_ENC_STREAM_TYPE_MPG */
84 "encoder MPG", 85 "encoder MPG",
85 VFL_TYPE_GRABBER, 0, 86 VFL_TYPE_GRABBER, 0,
86 PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 87 PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE,
88 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
89 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
87 &ivtv_v4l2_enc_fops 90 &ivtv_v4l2_enc_fops
88 }, 91 },
89 { /* IVTV_ENC_STREAM_TYPE_YUV */ 92 { /* IVTV_ENC_STREAM_TYPE_YUV */
90 "encoder YUV", 93 "encoder YUV",
91 VFL_TYPE_GRABBER, IVTV_V4L2_ENC_YUV_OFFSET, 94 VFL_TYPE_GRABBER, IVTV_V4L2_ENC_YUV_OFFSET,
92 PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 95 PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE,
96 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
97 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
93 &ivtv_v4l2_enc_fops 98 &ivtv_v4l2_enc_fops
94 }, 99 },
95 { /* IVTV_ENC_STREAM_TYPE_VBI */ 100 { /* IVTV_ENC_STREAM_TYPE_VBI */
96 "encoder VBI", 101 "encoder VBI",
97 VFL_TYPE_VBI, 0, 102 VFL_TYPE_VBI, 0,
98 PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VBI_CAPTURE, 103 PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VBI_CAPTURE,
104 V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_TUNER |
105 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
99 &ivtv_v4l2_enc_fops 106 &ivtv_v4l2_enc_fops
100 }, 107 },
101 { /* IVTV_ENC_STREAM_TYPE_PCM */ 108 { /* IVTV_ENC_STREAM_TYPE_PCM */
102 "encoder PCM", 109 "encoder PCM",
103 VFL_TYPE_GRABBER, IVTV_V4L2_ENC_PCM_OFFSET, 110 VFL_TYPE_GRABBER, IVTV_V4L2_ENC_PCM_OFFSET,
104 PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_PRIVATE, 111 PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_PRIVATE,
112 V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
105 &ivtv_v4l2_enc_fops 113 &ivtv_v4l2_enc_fops
106 }, 114 },
107 { /* IVTV_ENC_STREAM_TYPE_RAD */ 115 { /* IVTV_ENC_STREAM_TYPE_RAD */
108 "encoder radio", 116 "encoder radio",
109 VFL_TYPE_RADIO, 0, 117 VFL_TYPE_RADIO, 0,
110 PCI_DMA_NONE, 1, V4L2_BUF_TYPE_PRIVATE, 118 PCI_DMA_NONE, 1, V4L2_BUF_TYPE_PRIVATE,
119 V4L2_CAP_RADIO | V4L2_CAP_TUNER,
111 &ivtv_v4l2_enc_fops 120 &ivtv_v4l2_enc_fops
112 }, 121 },
113 { /* IVTV_DEC_STREAM_TYPE_MPG */ 122 { /* IVTV_DEC_STREAM_TYPE_MPG */
114 "decoder MPG", 123 "decoder MPG",
115 VFL_TYPE_GRABBER, IVTV_V4L2_DEC_MPG_OFFSET, 124 VFL_TYPE_GRABBER, IVTV_V4L2_DEC_MPG_OFFSET,
116 PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT, 125 PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT,
126 V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
117 &ivtv_v4l2_dec_fops 127 &ivtv_v4l2_dec_fops
118 }, 128 },
119 { /* IVTV_DEC_STREAM_TYPE_VBI */ 129 { /* IVTV_DEC_STREAM_TYPE_VBI */
120 "decoder VBI", 130 "decoder VBI",
121 VFL_TYPE_VBI, IVTV_V4L2_DEC_VBI_OFFSET, 131 VFL_TYPE_VBI, IVTV_V4L2_DEC_VBI_OFFSET,
122 PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_CAPTURE, 132 PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_CAPTURE,
133 V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_READWRITE,
123 &ivtv_v4l2_enc_fops 134 &ivtv_v4l2_enc_fops
124 }, 135 },
125 { /* IVTV_DEC_STREAM_TYPE_VOUT */ 136 { /* IVTV_DEC_STREAM_TYPE_VOUT */
126 "decoder VOUT", 137 "decoder VOUT",
127 VFL_TYPE_VBI, IVTV_V4L2_DEC_VOUT_OFFSET, 138 VFL_TYPE_VBI, IVTV_V4L2_DEC_VOUT_OFFSET,
128 PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_OUTPUT, 139 PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_OUTPUT,
140 V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
129 &ivtv_v4l2_dec_fops 141 &ivtv_v4l2_dec_fops
130 }, 142 },
131 { /* IVTV_DEC_STREAM_TYPE_YUV */ 143 { /* IVTV_DEC_STREAM_TYPE_YUV */
132 "decoder YUV", 144 "decoder YUV",
133 VFL_TYPE_GRABBER, IVTV_V4L2_DEC_YUV_OFFSET, 145 VFL_TYPE_GRABBER, IVTV_V4L2_DEC_YUV_OFFSET,
134 PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT, 146 PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT,
147 V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
135 &ivtv_v4l2_dec_fops 148 &ivtv_v4l2_dec_fops
136 } 149 }
137}; 150};
@@ -149,6 +162,7 @@ static void ivtv_stream_init(struct ivtv *itv, int type)
149 s->itv = itv; 162 s->itv = itv;
150 s->type = type; 163 s->type = type;
151 s->name = ivtv_stream_info[type].name; 164 s->name = ivtv_stream_info[type].name;
165 s->caps = ivtv_stream_info[type].v4l2_caps;
152 166
153 if (ivtv_stream_info[type].pio) 167 if (ivtv_stream_info[type].pio)
154 s->dma = PCI_DMA_NONE; 168 s->dma = PCI_DMA_NONE;
@@ -209,8 +223,8 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
209 223
210 s->vdev->num = num; 224 s->vdev->num = num;
211 s->vdev->v4l2_dev = &itv->v4l2_dev; 225 s->vdev->v4l2_dev = &itv->v4l2_dev;
212 s->vdev->ctrl_handler = itv->v4l2_dev.ctrl_handler;
213 s->vdev->fops = ivtv_stream_info[type].fops; 226 s->vdev->fops = ivtv_stream_info[type].fops;
227 s->vdev->ctrl_handler = itv->v4l2_dev.ctrl_handler;
214 s->vdev->release = video_device_release; 228 s->vdev->release = video_device_release;
215 s->vdev->tvnorms = V4L2_STD_ALL; 229 s->vdev->tvnorms = V4L2_STD_ALL;
216 s->vdev->lock = &itv->serialize_lock; 230 s->vdev->lock = &itv->serialize_lock;
@@ -891,7 +905,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
891 IVTV_DEBUG_INFO("Stop Decode at %llu, flags: %x\n", (unsigned long long)pts, flags); 905 IVTV_DEBUG_INFO("Stop Decode at %llu, flags: %x\n", (unsigned long long)pts, flags);
892 906
893 /* Stop Decoder */ 907 /* Stop Decoder */
894 if (!(flags & VIDEO_CMD_STOP_IMMEDIATELY) || pts) { 908 if (!(flags & V4L2_DEC_CMD_STOP_IMMEDIATELY) || pts) {
895 u32 tmp = 0; 909 u32 tmp = 0;
896 910
897 /* Wait until the decoder is no longer running */ 911 /* Wait until the decoder is no longer running */
@@ -911,7 +925,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
911 break; 925 break;
912 } 926 }
913 } 927 }
914 ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 3, flags & VIDEO_CMD_STOP_TO_BLACK, 0, 0); 928 ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 3, flags & V4L2_DEC_CMD_STOP_TO_BLACK, 0, 0);
915 929
916 /* turn off notification of dual/stereo mode change */ 930 /* turn off notification of dual/stereo mode change */
917 ivtv_vapi(itv, CX2341X_DEC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_DEC_AUD_MODE_CHG, -1); 931 ivtv_vapi(itv, CX2341X_DEC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_DEC_AUD_MODE_CHG, -1);
diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c
index afa91182b448..ee7ca2dcca2f 100644
--- a/drivers/media/video/ks0127.c
+++ b/drivers/media/video/ks0127.c
@@ -721,15 +721,4 @@ static struct i2c_driver ks0127_driver = {
721 .id_table = ks0127_id, 721 .id_table = ks0127_id,
722}; 722};
723 723
724static __init int init_ks0127(void) 724module_i2c_driver(ks0127_driver);
725{
726 return i2c_add_driver(&ks0127_driver);
727}
728
729static __exit void exit_ks0127(void)
730{
731 i2c_del_driver(&ks0127_driver);
732}
733
734module_init(init_ks0127);
735module_exit(exit_ks0127);
diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c
index 303ffa7df4ac..0991576f4c82 100644
--- a/drivers/media/video/m52790.c
+++ b/drivers/media/video/m52790.c
@@ -213,15 +213,4 @@ static struct i2c_driver m52790_driver = {
213 .id_table = m52790_id, 213 .id_table = m52790_id,
214}; 214};
215 215
216static __init int init_m52790(void) 216module_i2c_driver(m52790_driver);
217{
218 return i2c_add_driver(&m52790_driver);
219}
220
221static __exit void exit_m52790(void)
222{
223 i2c_del_driver(&m52790_driver);
224}
225
226module_init(init_m52790);
227module_exit(exit_m52790);
diff --git a/drivers/media/video/m5mols/m5mols_core.c b/drivers/media/video/m5mols/m5mols_core.c
index 93d768db9f33..d718aee01c77 100644
--- a/drivers/media/video/m5mols/m5mols_core.c
+++ b/drivers/media/video/m5mols/m5mols_core.c
@@ -982,8 +982,8 @@ static int __devinit m5mols_probe(struct i2c_client *client,
982 } 982 }
983 983
984 sd = &info->sd; 984 sd = &info->sd;
985 strlcpy(sd->name, MODULE_NAME, sizeof(sd->name));
986 v4l2_i2c_subdev_init(sd, client, &m5mols_ops); 985 v4l2_i2c_subdev_init(sd, client, &m5mols_ops);
986 strlcpy(sd->name, MODULE_NAME, sizeof(sd->name));
987 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 987 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
988 988
989 sd->internal_ops = &m5mols_subdev_internal_ops; 989 sd->internal_ops = &m5mols_subdev_internal_ops;
@@ -1057,18 +1057,7 @@ static struct i2c_driver m5mols_i2c_driver = {
1057 .id_table = m5mols_id, 1057 .id_table = m5mols_id,
1058}; 1058};
1059 1059
1060static int __init m5mols_mod_init(void) 1060module_i2c_driver(m5mols_i2c_driver);
1061{
1062 return i2c_add_driver(&m5mols_i2c_driver);
1063}
1064
1065static void __exit m5mols_mod_exit(void)
1066{
1067 i2c_del_driver(&m5mols_i2c_driver);
1068}
1069
1070module_init(m5mols_mod_init);
1071module_exit(m5mols_mod_exit);
1072 1061
1073MODULE_AUTHOR("HeungJun Kim <riverful.kim@samsung.com>"); 1062MODULE_AUTHOR("HeungJun Kim <riverful.kim@samsung.com>");
1074MODULE_AUTHOR("Dongsoo Kim <dongsoo45.kim@samsung.com>"); 1063MODULE_AUTHOR("Dongsoo Kim <dongsoo45.kim@samsung.com>");
diff --git a/drivers/media/video/marvell-ccic/mcam-core.c b/drivers/media/video/marvell-ccic/mcam-core.c
index 37d20e73908a..996ac34d9a89 100644
--- a/drivers/media/video/marvell-ccic/mcam-core.c
+++ b/drivers/media/video/marvell-ccic/mcam-core.c
@@ -509,11 +509,17 @@ static void mcam_sg_next_buffer(struct mcam_camera *cam)
509 509
510 buf = list_first_entry(&cam->buffers, struct mcam_vb_buffer, queue); 510 buf = list_first_entry(&cam->buffers, struct mcam_vb_buffer, queue);
511 list_del_init(&buf->queue); 511 list_del_init(&buf->queue);
512 /*
513 * Very Bad Not Good Things happen if you don't clear
514 * C1_DESC_ENA before making any descriptor changes.
515 */
516 mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_ENA);
512 mcam_reg_write(cam, REG_DMA_DESC_Y, buf->dma_desc_pa); 517 mcam_reg_write(cam, REG_DMA_DESC_Y, buf->dma_desc_pa);
513 mcam_reg_write(cam, REG_DESC_LEN_Y, 518 mcam_reg_write(cam, REG_DESC_LEN_Y,
514 buf->dma_desc_nent*sizeof(struct mcam_dma_desc)); 519 buf->dma_desc_nent*sizeof(struct mcam_dma_desc));
515 mcam_reg_write(cam, REG_DESC_LEN_U, 0); 520 mcam_reg_write(cam, REG_DESC_LEN_U, 0);
516 mcam_reg_write(cam, REG_DESC_LEN_V, 0); 521 mcam_reg_write(cam, REG_DESC_LEN_V, 0);
522 mcam_reg_set_bit(cam, REG_CTRL1, C1_DESC_ENA);
517 cam->vb_bufs[0] = buf; 523 cam->vb_bufs[0] = buf;
518} 524}
519 525
@@ -533,7 +539,6 @@ static void mcam_ctlr_dma_sg(struct mcam_camera *cam)
533 539
534 mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_3WORD); 540 mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_3WORD);
535 mcam_sg_next_buffer(cam); 541 mcam_sg_next_buffer(cam);
536 mcam_reg_set_bit(cam, REG_CTRL1, C1_DESC_ENA);
537 cam->nbufs = 3; 542 cam->nbufs = 3;
538} 543}
539 544
@@ -556,17 +561,16 @@ static void mcam_dma_sg_done(struct mcam_camera *cam, int frame)
556 struct mcam_vb_buffer *buf = cam->vb_bufs[0]; 561 struct mcam_vb_buffer *buf = cam->vb_bufs[0];
557 562
558 /* 563 /*
559 * Very Bad Not Good Things happen if you don't clear 564 * If we're no longer supposed to be streaming, don't do anything.
560 * C1_DESC_ENA before making any descriptor changes.
561 */ 565 */
562 mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_ENA); 566 if (cam->state != S_STREAMING)
567 return;
563 /* 568 /*
564 * If we have another buffer available, put it in and 569 * If we have another buffer available, put it in and
565 * restart the engine. 570 * restart the engine.
566 */ 571 */
567 if (!list_empty(&cam->buffers)) { 572 if (!list_empty(&cam->buffers)) {
568 mcam_sg_next_buffer(cam); 573 mcam_sg_next_buffer(cam);
569 mcam_reg_set_bit(cam, REG_CTRL1, C1_DESC_ENA);
570 mcam_ctlr_start(cam); 574 mcam_ctlr_start(cam);
571 /* 575 /*
572 * Otherwise set CF_SG_RESTART and the controller will 576 * Otherwise set CF_SG_RESTART and the controller will
@@ -737,7 +741,14 @@ static void mcam_ctlr_stop_dma(struct mcam_camera *cam)
737 mcam_ctlr_stop(cam); 741 mcam_ctlr_stop(cam);
738 cam->state = S_IDLE; 742 cam->state = S_IDLE;
739 spin_unlock_irqrestore(&cam->dev_lock, flags); 743 spin_unlock_irqrestore(&cam->dev_lock, flags);
740 msleep(40); 744 /*
745 * This is a brutally long sleep, but experience shows that
746 * it can take the controller a while to get the message that
747 * it needs to stop grabbing frames. In particular, we can
748 * sometimes (on mmp) get a frame at the end WITHOUT the
749 * start-of-frame indication.
750 */
751 msleep(150);
741 if (test_bit(CF_DMA_ACTIVE, &cam->flags)) 752 if (test_bit(CF_DMA_ACTIVE, &cam->flags))
742 cam_err(cam, "Timeout waiting for DMA to end\n"); 753 cam_err(cam, "Timeout waiting for DMA to end\n");
743 /* This would be bad news - what now? */ 754 /* This would be bad news - what now? */
@@ -880,6 +891,7 @@ static int mcam_read_setup(struct mcam_camera *cam)
880 * Turn it loose. 891 * Turn it loose.
881 */ 892 */
882 spin_lock_irqsave(&cam->dev_lock, flags); 893 spin_lock_irqsave(&cam->dev_lock, flags);
894 clear_bit(CF_DMA_ACTIVE, &cam->flags);
883 mcam_reset_buffers(cam); 895 mcam_reset_buffers(cam);
884 mcam_ctlr_irq_enable(cam); 896 mcam_ctlr_irq_enable(cam);
885 cam->state = S_STREAMING; 897 cam->state = S_STREAMING;
@@ -922,7 +934,7 @@ static void mcam_vb_buf_queue(struct vb2_buffer *vb)
922 spin_lock_irqsave(&cam->dev_lock, flags); 934 spin_lock_irqsave(&cam->dev_lock, flags);
923 start = (cam->state == S_BUFWAIT) && !list_empty(&cam->buffers); 935 start = (cam->state == S_BUFWAIT) && !list_empty(&cam->buffers);
924 list_add(&mvb->queue, &cam->buffers); 936 list_add(&mvb->queue, &cam->buffers);
925 if (test_bit(CF_SG_RESTART, &cam->flags)) 937 if (cam->state == S_STREAMING && test_bit(CF_SG_RESTART, &cam->flags))
926 mcam_sg_restart(cam); 938 mcam_sg_restart(cam);
927 spin_unlock_irqrestore(&cam->dev_lock, flags); 939 spin_unlock_irqrestore(&cam->dev_lock, flags);
928 if (start) 940 if (start)
@@ -1555,15 +1567,12 @@ static int mcam_v4l_release(struct file *filp)
1555{ 1567{
1556 struct mcam_camera *cam = filp->private_data; 1568 struct mcam_camera *cam = filp->private_data;
1557 1569
1558 cam_err(cam, "Release, %d frames, %d singles, %d delivered\n", frames, 1570 cam_dbg(cam, "Release, %d frames, %d singles, %d delivered\n", frames,
1559 singles, delivered); 1571 singles, delivered);
1560 mutex_lock(&cam->s_mutex); 1572 mutex_lock(&cam->s_mutex);
1561 (cam->users)--; 1573 (cam->users)--;
1562 if (filp == cam->owner) {
1563 mcam_ctlr_stop_dma(cam);
1564 cam->owner = NULL;
1565 }
1566 if (cam->users == 0) { 1574 if (cam->users == 0) {
1575 mcam_ctlr_stop_dma(cam);
1567 mcam_cleanup_vb2(cam); 1576 mcam_cleanup_vb2(cam);
1568 mcam_ctlr_power_down(cam); 1577 mcam_ctlr_power_down(cam);
1569 if (cam->buffer_mode == B_vmalloc && alloc_bufs_at_read) 1578 if (cam->buffer_mode == B_vmalloc && alloc_bufs_at_read)
@@ -1688,6 +1697,8 @@ int mccic_irq(struct mcam_camera *cam, unsigned int irqs)
1688 if (irqs & (IRQ_EOF0 << frame)) { 1697 if (irqs & (IRQ_EOF0 << frame)) {
1689 mcam_frame_complete(cam, frame); 1698 mcam_frame_complete(cam, frame);
1690 handled = 1; 1699 handled = 1;
1700 if (cam->buffer_mode == B_DMA_sg)
1701 break;
1691 } 1702 }
1692 /* 1703 /*
1693 * If a frame starts, note that we have DMA active. This 1704 * If a frame starts, note that we have DMA active. This
diff --git a/drivers/media/video/marvell-ccic/mcam-core.h b/drivers/media/video/marvell-ccic/mcam-core.h
index 917200e63255..bd6acba9fb37 100644
--- a/drivers/media/video/marvell-ccic/mcam-core.h
+++ b/drivers/media/video/marvell-ccic/mcam-core.h
@@ -107,7 +107,6 @@ struct mcam_camera {
107 enum mcam_state state; 107 enum mcam_state state;
108 unsigned long flags; /* Buffer status, mainly (dev_lock) */ 108 unsigned long flags; /* Buffer status, mainly (dev_lock) */
109 int users; /* How many open FDs */ 109 int users; /* How many open FDs */
110 struct file *owner; /* Who has data access (v4l2) */
111 110
112 /* 111 /*
113 * Subsystem structures. 112 * Subsystem structures.
diff --git a/drivers/media/video/marvell-ccic/mmp-driver.c b/drivers/media/video/marvell-ccic/mmp-driver.c
index 0d64e2d7474a..d23552323f45 100644
--- a/drivers/media/video/marvell-ccic/mmp-driver.c
+++ b/drivers/media/video/marvell-ccic/mmp-driver.c
@@ -106,6 +106,13 @@ static struct mmp_camera *mmpcam_find_device(struct platform_device *pdev)
106/* 106/*
107 * Power control. 107 * Power control.
108 */ 108 */
109static void mmpcam_power_up_ctlr(struct mmp_camera *cam)
110{
111 iowrite32(0x3f, cam->power_regs + REG_CCIC_DCGCR);
112 iowrite32(0x3805b, cam->power_regs + REG_CCIC_CRCR);
113 mdelay(1);
114}
115
109static void mmpcam_power_up(struct mcam_camera *mcam) 116static void mmpcam_power_up(struct mcam_camera *mcam)
110{ 117{
111 struct mmp_camera *cam = mcam_to_cam(mcam); 118 struct mmp_camera *cam = mcam_to_cam(mcam);
@@ -113,9 +120,7 @@ static void mmpcam_power_up(struct mcam_camera *mcam)
113/* 120/*
114 * Turn on power and clocks to the controller. 121 * Turn on power and clocks to the controller.
115 */ 122 */
116 iowrite32(0x3f, cam->power_regs + REG_CCIC_DCGCR); 123 mmpcam_power_up_ctlr(cam);
117 iowrite32(0x3805b, cam->power_regs + REG_CCIC_CRCR);
118 mdelay(1);
119/* 124/*
120 * Provide power to the sensor. 125 * Provide power to the sensor.
121 */ 126 */
@@ -335,7 +340,7 @@ static int mmpcam_resume(struct platform_device *pdev)
335 * touch a register even if nothing was active before; trust 340 * touch a register even if nothing was active before; trust
336 * me, it's better this way. 341 * me, it's better this way.
337 */ 342 */
338 mmpcam_power_up(&cam->mcam); 343 mmpcam_power_up_ctlr(cam);
339 return mccic_resume(&cam->mcam); 344 return mccic_resume(&cam->mcam);
340} 345}
341 346
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index d7cd0f633f63..82ce50721de3 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -881,18 +881,7 @@ static struct i2c_driver msp_driver = {
881 .id_table = msp_id, 881 .id_table = msp_id,
882}; 882};
883 883
884static __init int init_msp(void) 884module_i2c_driver(msp_driver);
885{
886 return i2c_add_driver(&msp_driver);
887}
888
889static __exit void exit_msp(void)
890{
891 i2c_del_driver(&msp_driver);
892}
893
894module_init(init_msp);
895module_exit(exit_msp);
896 885
897/* 886/*
898 * Overrides for Emacs so that we follow Linus's tabbing style. 887 * Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 097c9d3d04a8..7e648183f157 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -730,18 +730,7 @@ static struct i2c_driver mt9m001_i2c_driver = {
730 .id_table = mt9m001_id, 730 .id_table = mt9m001_id,
731}; 731};
732 732
733static int __init mt9m001_mod_init(void) 733module_i2c_driver(mt9m001_i2c_driver);
734{
735 return i2c_add_driver(&mt9m001_i2c_driver);
736}
737
738static void __exit mt9m001_mod_exit(void)
739{
740 i2c_del_driver(&mt9m001_i2c_driver);
741}
742
743module_init(mt9m001_mod_init);
744module_exit(mt9m001_mod_exit);
745 734
746MODULE_DESCRIPTION("Micron MT9M001 Camera driver"); 735MODULE_DESCRIPTION("Micron MT9M001 Camera driver");
747MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>"); 736MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
diff --git a/drivers/media/video/mt9m032.c b/drivers/media/video/mt9m032.c
new file mode 100644
index 000000000000..7636672c3548
--- /dev/null
+++ b/drivers/media/video/mt9m032.c
@@ -0,0 +1,868 @@
1/*
2 * Driver for MT9M032 CMOS Image Sensor from Micron
3 *
4 * Copyright (C) 2010-2011 Lund Engineering
5 * Contact: Gil Lund <gwlund@lundeng.com>
6 * Author: Martin Hostettler <martin@neutronstar.dyndns.org>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 */
22
23#include <linux/delay.h>
24#include <linux/i2c.h>
25#include <linux/init.h>
26#include <linux/kernel.h>
27#include <linux/math64.h>
28#include <linux/module.h>
29#include <linux/mutex.h>
30#include <linux/slab.h>
31#include <linux/v4l2-mediabus.h>
32
33#include <media/media-entity.h>
34#include <media/mt9m032.h>
35#include <media/v4l2-ctrls.h>
36#include <media/v4l2-device.h>
37#include <media/v4l2-subdev.h>
38
39#include "aptina-pll.h"
40
41/*
42 * width and height include active boundary and black parts
43 *
44 * column 0- 15 active boundary
45 * column 16-1455 image
46 * column 1456-1471 active boundary
47 * column 1472-1599 black
48 *
49 * row 0- 51 black
50 * row 53- 59 active boundary
51 * row 60-1139 image
52 * row 1140-1147 active boundary
53 * row 1148-1151 black
54 */
55
56#define MT9M032_PIXEL_ARRAY_WIDTH 1600
57#define MT9M032_PIXEL_ARRAY_HEIGHT 1152
58
59#define MT9M032_CHIP_VERSION 0x00
60#define MT9M032_CHIP_VERSION_VALUE 0x1402
61#define MT9M032_ROW_START 0x01
62#define MT9M032_ROW_START_MIN 0
63#define MT9M032_ROW_START_MAX 1152
64#define MT9M032_ROW_START_DEF 60
65#define MT9M032_COLUMN_START 0x02
66#define MT9M032_COLUMN_START_MIN 0
67#define MT9M032_COLUMN_START_MAX 1600
68#define MT9M032_COLUMN_START_DEF 16
69#define MT9M032_ROW_SIZE 0x03
70#define MT9M032_ROW_SIZE_MIN 32
71#define MT9M032_ROW_SIZE_MAX 1152
72#define MT9M032_ROW_SIZE_DEF 1080
73#define MT9M032_COLUMN_SIZE 0x04
74#define MT9M032_COLUMN_SIZE_MIN 32
75#define MT9M032_COLUMN_SIZE_MAX 1600
76#define MT9M032_COLUMN_SIZE_DEF 1440
77#define MT9M032_HBLANK 0x05
78#define MT9M032_VBLANK 0x06
79#define MT9M032_VBLANK_MAX 0x7ff
80#define MT9M032_SHUTTER_WIDTH_HIGH 0x08
81#define MT9M032_SHUTTER_WIDTH_LOW 0x09
82#define MT9M032_SHUTTER_WIDTH_MIN 1
83#define MT9M032_SHUTTER_WIDTH_MAX 1048575
84#define MT9M032_SHUTTER_WIDTH_DEF 1943
85#define MT9M032_PIX_CLK_CTRL 0x0a
86#define MT9M032_PIX_CLK_CTRL_INV_PIXCLK 0x8000
87#define MT9M032_RESTART 0x0b
88#define MT9M032_RESET 0x0d
89#define MT9M032_PLL_CONFIG1 0x11
90#define MT9M032_PLL_CONFIG1_OUTDIV_MASK 0x3f
91#define MT9M032_PLL_CONFIG1_MUL_SHIFT 8
92#define MT9M032_READ_MODE1 0x1e
93#define MT9M032_READ_MODE2 0x20
94#define MT9M032_READ_MODE2_VFLIP_SHIFT 15
95#define MT9M032_READ_MODE2_HFLIP_SHIFT 14
96#define MT9M032_READ_MODE2_ROW_BLC 0x40
97#define MT9M032_GAIN_GREEN1 0x2b
98#define MT9M032_GAIN_BLUE 0x2c
99#define MT9M032_GAIN_RED 0x2d
100#define MT9M032_GAIN_GREEN2 0x2e
101
102/* write only */
103#define MT9M032_GAIN_ALL 0x35
104#define MT9M032_GAIN_DIGITAL_MASK 0x7f
105#define MT9M032_GAIN_DIGITAL_SHIFT 8
106#define MT9M032_GAIN_AMUL_SHIFT 6
107#define MT9M032_GAIN_ANALOG_MASK 0x3f
108#define MT9M032_FORMATTER1 0x9e
109#define MT9M032_FORMATTER2 0x9f
110#define MT9M032_FORMATTER2_DOUT_EN 0x1000
111#define MT9M032_FORMATTER2_PIXCLK_EN 0x2000
112
113/*
114 * The available MT9M032 datasheet is missing documentation for register 0x10
115 * MT9P031 seems to be close enough, so use constants from that datasheet for
116 * now.
117 * But keep the name MT9P031 to remind us, that this isn't really confirmed
118 * for this sensor.
119 */
120#define MT9P031_PLL_CONTROL 0x10
121#define MT9P031_PLL_CONTROL_PWROFF 0x0050
122#define MT9P031_PLL_CONTROL_PWRON 0x0051
123#define MT9P031_PLL_CONTROL_USEPLL 0x0052
124#define MT9P031_PLL_CONFIG2 0x11
125#define MT9P031_PLL_CONFIG2_P1_DIV_MASK 0x1f
126
127struct mt9m032 {
128 struct v4l2_subdev subdev;
129 struct media_pad pad;
130 struct mt9m032_platform_data *pdata;
131
132 unsigned int pix_clock;
133
134 struct v4l2_ctrl_handler ctrls;
135 struct {
136 struct v4l2_ctrl *hflip;
137 struct v4l2_ctrl *vflip;
138 };
139
140 struct mutex lock; /* Protects streaming, format, interval and crop */
141
142 bool streaming;
143
144 struct v4l2_mbus_framefmt format;
145 struct v4l2_rect crop;
146 struct v4l2_fract frame_interval;
147};
148
149#define to_mt9m032(sd) container_of(sd, struct mt9m032, subdev)
150#define to_dev(sensor) \
151 (&((struct i2c_client *)v4l2_get_subdevdata(&(sensor)->subdev))->dev)
152
153static int mt9m032_read(struct i2c_client *client, u8 reg)
154{
155 return i2c_smbus_read_word_swapped(client, reg);
156}
157
158static int mt9m032_write(struct i2c_client *client, u8 reg, const u16 data)
159{
160 return i2c_smbus_write_word_swapped(client, reg, data);
161}
162
163static u32 mt9m032_row_time(struct mt9m032 *sensor, unsigned int width)
164{
165 unsigned int effective_width;
166 u32 ns;
167
168 effective_width = width + 716; /* empirical value */
169 ns = div_u64(1000000000ULL * effective_width, sensor->pix_clock);
170 dev_dbg(to_dev(sensor), "MT9M032 line time: %u ns\n", ns);
171 return ns;
172}
173
174static int mt9m032_update_timing(struct mt9m032 *sensor,
175 struct v4l2_fract *interval)
176{
177 struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
178 struct v4l2_rect *crop = &sensor->crop;
179 unsigned int min_vblank;
180 unsigned int vblank;
181 u32 row_time;
182
183 if (!interval)
184 interval = &sensor->frame_interval;
185
186 row_time = mt9m032_row_time(sensor, crop->width);
187
188 vblank = div_u64(1000000000ULL * interval->numerator,
189 (u64)row_time * interval->denominator)
190 - crop->height;
191
192 if (vblank > MT9M032_VBLANK_MAX) {
193 /* hardware limits to 11 bit values */
194 interval->denominator = 1000;
195 interval->numerator =
196 div_u64((crop->height + MT9M032_VBLANK_MAX) *
197 (u64)row_time * interval->denominator,
198 1000000000ULL);
199 vblank = div_u64(1000000000ULL * interval->numerator,
200 (u64)row_time * interval->denominator)
201 - crop->height;
202 }
203 /* enforce minimal 1.6ms blanking time. */
204 min_vblank = 1600000 / row_time;
205 vblank = clamp_t(unsigned int, vblank, min_vblank, MT9M032_VBLANK_MAX);
206
207 return mt9m032_write(client, MT9M032_VBLANK, vblank);
208}
209
210static int mt9m032_update_geom_timing(struct mt9m032 *sensor)
211{
212 struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
213 int ret;
214
215 ret = mt9m032_write(client, MT9M032_COLUMN_SIZE,
216 sensor->crop.width - 1);
217 if (!ret)
218 ret = mt9m032_write(client, MT9M032_ROW_SIZE,
219 sensor->crop.height - 1);
220 if (!ret)
221 ret = mt9m032_write(client, MT9M032_COLUMN_START,
222 sensor->crop.left);
223 if (!ret)
224 ret = mt9m032_write(client, MT9M032_ROW_START,
225 sensor->crop.top);
226 if (!ret)
227 ret = mt9m032_update_timing(sensor, NULL);
228 return ret;
229}
230
231static int update_formatter2(struct mt9m032 *sensor, bool streaming)
232{
233 struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
234 u16 reg_val = MT9M032_FORMATTER2_DOUT_EN
235 | 0x0070; /* parts reserved! */
236 /* possibly for changing to 14-bit mode */
237
238 if (streaming)
239 reg_val |= MT9M032_FORMATTER2_PIXCLK_EN; /* pixclock enable */
240
241 return mt9m032_write(client, MT9M032_FORMATTER2, reg_val);
242}
243
244static int mt9m032_setup_pll(struct mt9m032 *sensor)
245{
246 static const struct aptina_pll_limits limits = {
247 .ext_clock_min = 8000000,
248 .ext_clock_max = 16500000,
249 .int_clock_min = 2000000,
250 .int_clock_max = 24000000,
251 .out_clock_min = 322000000,
252 .out_clock_max = 693000000,
253 .pix_clock_max = 99000000,
254 .n_min = 1,
255 .n_max = 64,
256 .m_min = 16,
257 .m_max = 255,
258 .p1_min = 1,
259 .p1_max = 128,
260 };
261
262 struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
263 struct mt9m032_platform_data *pdata = sensor->pdata;
264 struct aptina_pll pll;
265 int ret;
266
267 pll.ext_clock = pdata->ext_clock;
268 pll.pix_clock = pdata->pix_clock;
269
270 ret = aptina_pll_calculate(&client->dev, &limits, &pll);
271 if (ret < 0)
272 return ret;
273
274 sensor->pix_clock = pdata->pix_clock;
275
276 ret = mt9m032_write(client, MT9M032_PLL_CONFIG1,
277 (pll.m << MT9M032_PLL_CONFIG1_MUL_SHIFT)
278 | (pll.p1 - 1));
279 if (!ret)
280 ret = mt9m032_write(client, MT9P031_PLL_CONFIG2, pll.n - 1);
281 if (!ret)
282 ret = mt9m032_write(client, MT9P031_PLL_CONTROL,
283 MT9P031_PLL_CONTROL_PWRON |
284 MT9P031_PLL_CONTROL_USEPLL);
285 if (!ret) /* more reserved, Continuous, Master Mode */
286 ret = mt9m032_write(client, MT9M032_READ_MODE1, 0x8006);
287 if (!ret) /* Set 14-bit mode, select 7 divider */
288 ret = mt9m032_write(client, MT9M032_FORMATTER1, 0x111e);
289
290 return ret;
291}
292
293/* -----------------------------------------------------------------------------
294 * Subdev pad operations
295 */
296
297static int mt9m032_enum_mbus_code(struct v4l2_subdev *subdev,
298 struct v4l2_subdev_fh *fh,
299 struct v4l2_subdev_mbus_code_enum *code)
300{
301 if (code->index != 0)
302 return -EINVAL;
303
304 code->code = V4L2_MBUS_FMT_Y8_1X8;
305 return 0;
306}
307
308static int mt9m032_enum_frame_size(struct v4l2_subdev *subdev,
309 struct v4l2_subdev_fh *fh,
310 struct v4l2_subdev_frame_size_enum *fse)
311{
312 if (fse->index != 0 || fse->code != V4L2_MBUS_FMT_Y8_1X8)
313 return -EINVAL;
314
315 fse->min_width = MT9M032_COLUMN_SIZE_DEF;
316 fse->max_width = MT9M032_COLUMN_SIZE_DEF;
317 fse->min_height = MT9M032_ROW_SIZE_DEF;
318 fse->max_height = MT9M032_ROW_SIZE_DEF;
319
320 return 0;
321}
322
323/**
324 * __mt9m032_get_pad_crop() - get crop rect
325 * @sensor: pointer to the sensor struct
326 * @fh: file handle for getting the try crop rect from
327 * @which: select try or active crop rect
328 *
329 * Returns a pointer the current active or fh relative try crop rect
330 */
331static struct v4l2_rect *
332__mt9m032_get_pad_crop(struct mt9m032 *sensor, struct v4l2_subdev_fh *fh,
333 enum v4l2_subdev_format_whence which)
334{
335 switch (which) {
336 case V4L2_SUBDEV_FORMAT_TRY:
337 return v4l2_subdev_get_try_crop(fh, 0);
338 case V4L2_SUBDEV_FORMAT_ACTIVE:
339 return &sensor->crop;
340 default:
341 return NULL;
342 }
343}
344
345/**
346 * __mt9m032_get_pad_format() - get format
347 * @sensor: pointer to the sensor struct
348 * @fh: file handle for getting the try format from
349 * @which: select try or active format
350 *
351 * Returns a pointer the current active or fh relative try format
352 */
353static struct v4l2_mbus_framefmt *
354__mt9m032_get_pad_format(struct mt9m032 *sensor, struct v4l2_subdev_fh *fh,
355 enum v4l2_subdev_format_whence which)
356{
357 switch (which) {
358 case V4L2_SUBDEV_FORMAT_TRY:
359 return v4l2_subdev_get_try_format(fh, 0);
360 case V4L2_SUBDEV_FORMAT_ACTIVE:
361 return &sensor->format;
362 default:
363 return NULL;
364 }
365}
366
367static int mt9m032_get_pad_format(struct v4l2_subdev *subdev,
368 struct v4l2_subdev_fh *fh,
369 struct v4l2_subdev_format *fmt)
370{
371 struct mt9m032 *sensor = to_mt9m032(subdev);
372
373 mutex_lock(&sensor->lock);
374 fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which);
375 mutex_unlock(&sensor->lock);
376
377 return 0;
378}
379
380static int mt9m032_set_pad_format(struct v4l2_subdev *subdev,
381 struct v4l2_subdev_fh *fh,
382 struct v4l2_subdev_format *fmt)
383{
384 struct mt9m032 *sensor = to_mt9m032(subdev);
385 int ret;
386
387 mutex_lock(&sensor->lock);
388
389 if (sensor->streaming && fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
390 ret = -EBUSY;
391 goto done;
392 }
393
394 /* Scaling is not supported, the format is thus fixed. */
395 ret = mt9m032_get_pad_format(subdev, fh, fmt);
396
397done:
398 mutex_lock(&sensor->lock);
399 return ret;
400}
401
402static int mt9m032_get_pad_crop(struct v4l2_subdev *subdev,
403 struct v4l2_subdev_fh *fh,
404 struct v4l2_subdev_crop *crop)
405{
406 struct mt9m032 *sensor = to_mt9m032(subdev);
407
408 mutex_lock(&sensor->lock);
409 crop->rect = *__mt9m032_get_pad_crop(sensor, fh, crop->which);
410 mutex_unlock(&sensor->lock);
411
412 return 0;
413}
414
415static int mt9m032_set_pad_crop(struct v4l2_subdev *subdev,
416 struct v4l2_subdev_fh *fh,
417 struct v4l2_subdev_crop *crop)
418{
419 struct mt9m032 *sensor = to_mt9m032(subdev);
420 struct v4l2_mbus_framefmt *format;
421 struct v4l2_rect *__crop;
422 struct v4l2_rect rect;
423 int ret = 0;
424
425 mutex_lock(&sensor->lock);
426
427 if (sensor->streaming && crop->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
428 ret = -EBUSY;
429 goto done;
430 }
431
432 /* Clamp the crop rectangle boundaries and align them to a multiple of 2
433 * pixels to ensure a GRBG Bayer pattern.
434 */
435 rect.left = clamp(ALIGN(crop->rect.left, 2), MT9M032_COLUMN_START_MIN,
436 MT9M032_COLUMN_START_MAX);
437 rect.top = clamp(ALIGN(crop->rect.top, 2), MT9M032_ROW_START_MIN,
438 MT9M032_ROW_START_MAX);
439 rect.width = clamp(ALIGN(crop->rect.width, 2), MT9M032_COLUMN_SIZE_MIN,
440 MT9M032_COLUMN_SIZE_MAX);
441 rect.height = clamp(ALIGN(crop->rect.height, 2), MT9M032_ROW_SIZE_MIN,
442 MT9M032_ROW_SIZE_MAX);
443
444 rect.width = min(rect.width, MT9M032_PIXEL_ARRAY_WIDTH - rect.left);
445 rect.height = min(rect.height, MT9M032_PIXEL_ARRAY_HEIGHT - rect.top);
446
447 __crop = __mt9m032_get_pad_crop(sensor, fh, crop->which);
448
449 if (rect.width != __crop->width || rect.height != __crop->height) {
450 /* Reset the output image size if the crop rectangle size has
451 * been modified.
452 */
453 format = __mt9m032_get_pad_format(sensor, fh, crop->which);
454 format->width = rect.width;
455 format->height = rect.height;
456 }
457
458 *__crop = rect;
459 crop->rect = rect;
460
461 if (crop->which == V4L2_SUBDEV_FORMAT_ACTIVE)
462 ret = mt9m032_update_geom_timing(sensor);
463
464done:
465 mutex_unlock(&sensor->lock);
466 return ret;
467}
468
469static int mt9m032_get_frame_interval(struct v4l2_subdev *subdev,
470 struct v4l2_subdev_frame_interval *fi)
471{
472 struct mt9m032 *sensor = to_mt9m032(subdev);
473
474 mutex_lock(&sensor->lock);
475 memset(fi, 0, sizeof(*fi));
476 fi->interval = sensor->frame_interval;
477 mutex_unlock(&sensor->lock);
478
479 return 0;
480}
481
482static int mt9m032_set_frame_interval(struct v4l2_subdev *subdev,
483 struct v4l2_subdev_frame_interval *fi)
484{
485 struct mt9m032 *sensor = to_mt9m032(subdev);
486 int ret;
487
488 mutex_lock(&sensor->lock);
489
490 if (sensor->streaming) {
491 ret = -EBUSY;
492 goto done;
493 }
494
495 /* Avoid divisions by 0. */
496 if (fi->interval.denominator == 0)
497 fi->interval.denominator = 1;
498
499 ret = mt9m032_update_timing(sensor, &fi->interval);
500 if (!ret)
501 sensor->frame_interval = fi->interval;
502
503done:
504 mutex_unlock(&sensor->lock);
505 return ret;
506}
507
508static int mt9m032_s_stream(struct v4l2_subdev *subdev, int streaming)
509{
510 struct mt9m032 *sensor = to_mt9m032(subdev);
511 int ret;
512
513 mutex_lock(&sensor->lock);
514 ret = update_formatter2(sensor, streaming);
515 if (!ret)
516 sensor->streaming = streaming;
517 mutex_unlock(&sensor->lock);
518
519 return ret;
520}
521
522/* -----------------------------------------------------------------------------
523 * V4L2 subdev core operations
524 */
525
526#ifdef CONFIG_VIDEO_ADV_DEBUG
527static int mt9m032_g_register(struct v4l2_subdev *sd,
528 struct v4l2_dbg_register *reg)
529{
530 struct mt9m032 *sensor = to_mt9m032(sd);
531 struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
532 int val;
533
534 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
535 return -EINVAL;
536 if (reg->match.addr != client->addr)
537 return -ENODEV;
538
539 val = mt9m032_read(client, reg->reg);
540 if (val < 0)
541 return -EIO;
542
543 reg->size = 2;
544 reg->val = val;
545
546 return 0;
547}
548
549static int mt9m032_s_register(struct v4l2_subdev *sd,
550 struct v4l2_dbg_register *reg)
551{
552 struct mt9m032 *sensor = to_mt9m032(sd);
553 struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
554
555 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
556 return -EINVAL;
557
558 if (reg->match.addr != client->addr)
559 return -ENODEV;
560
561 return mt9m032_write(client, reg->reg, reg->val);
562}
563#endif
564
565/* -----------------------------------------------------------------------------
566 * V4L2 subdev control operations
567 */
568
569static int update_read_mode2(struct mt9m032 *sensor, bool vflip, bool hflip)
570{
571 struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
572 int reg_val = (vflip << MT9M032_READ_MODE2_VFLIP_SHIFT)
573 | (hflip << MT9M032_READ_MODE2_HFLIP_SHIFT)
574 | MT9M032_READ_MODE2_ROW_BLC
575 | 0x0007;
576
577 return mt9m032_write(client, MT9M032_READ_MODE2, reg_val);
578}
579
580static int mt9m032_set_gain(struct mt9m032 *sensor, s32 val)
581{
582 struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
583 int digital_gain_val; /* in 1/8th (0..127) */
584 int analog_mul; /* 0 or 1 */
585 int analog_gain_val; /* in 1/16th. (0..63) */
586 u16 reg_val;
587
588 digital_gain_val = 51; /* from setup example */
589
590 if (val < 63) {
591 analog_mul = 0;
592 analog_gain_val = val;
593 } else {
594 analog_mul = 1;
595 analog_gain_val = val / 2;
596 }
597
598 /* a_gain = (1 + analog_mul) + (analog_gain_val + 1) / 16 */
599 /* overall_gain = a_gain * (1 + digital_gain_val / 8) */
600
601 reg_val = ((digital_gain_val & MT9M032_GAIN_DIGITAL_MASK)
602 << MT9M032_GAIN_DIGITAL_SHIFT)
603 | ((analog_mul & 1) << MT9M032_GAIN_AMUL_SHIFT)
604 | (analog_gain_val & MT9M032_GAIN_ANALOG_MASK);
605
606 return mt9m032_write(client, MT9M032_GAIN_ALL, reg_val);
607}
608
609static int mt9m032_try_ctrl(struct v4l2_ctrl *ctrl)
610{
611 if (ctrl->id == V4L2_CID_GAIN && ctrl->val >= 63) {
612 /* round because of multiplier used for values >= 63 */
613 ctrl->val &= ~1;
614 }
615
616 return 0;
617}
618
619static int mt9m032_set_ctrl(struct v4l2_ctrl *ctrl)
620{
621 struct mt9m032 *sensor =
622 container_of(ctrl->handler, struct mt9m032, ctrls);
623 struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
624 int ret;
625
626 switch (ctrl->id) {
627 case V4L2_CID_GAIN:
628 return mt9m032_set_gain(sensor, ctrl->val);
629
630 case V4L2_CID_HFLIP:
631 /* case V4L2_CID_VFLIP: -- In the same cluster */
632 return update_read_mode2(sensor, sensor->vflip->val,
633 sensor->hflip->val);
634
635 case V4L2_CID_EXPOSURE:
636 ret = mt9m032_write(client, MT9M032_SHUTTER_WIDTH_HIGH,
637 (ctrl->val >> 16) & 0xffff);
638 if (ret < 0)
639 return ret;
640
641 return mt9m032_write(client, MT9M032_SHUTTER_WIDTH_LOW,
642 ctrl->val & 0xffff);
643 }
644
645 return 0;
646}
647
648static struct v4l2_ctrl_ops mt9m032_ctrl_ops = {
649 .s_ctrl = mt9m032_set_ctrl,
650 .try_ctrl = mt9m032_try_ctrl,
651};
652
653/* -------------------------------------------------------------------------- */
654
655static const struct v4l2_subdev_core_ops mt9m032_core_ops = {
656#ifdef CONFIG_VIDEO_ADV_DEBUG
657 .g_register = mt9m032_g_register,
658 .s_register = mt9m032_s_register,
659#endif
660};
661
662static const struct v4l2_subdev_video_ops mt9m032_video_ops = {
663 .s_stream = mt9m032_s_stream,
664 .g_frame_interval = mt9m032_get_frame_interval,
665 .s_frame_interval = mt9m032_set_frame_interval,
666};
667
668static const struct v4l2_subdev_pad_ops mt9m032_pad_ops = {
669 .enum_mbus_code = mt9m032_enum_mbus_code,
670 .enum_frame_size = mt9m032_enum_frame_size,
671 .get_fmt = mt9m032_get_pad_format,
672 .set_fmt = mt9m032_set_pad_format,
673 .set_crop = mt9m032_set_pad_crop,
674 .get_crop = mt9m032_get_pad_crop,
675};
676
677static const struct v4l2_subdev_ops mt9m032_ops = {
678 .core = &mt9m032_core_ops,
679 .video = &mt9m032_video_ops,
680 .pad = &mt9m032_pad_ops,
681};
682
683/* -----------------------------------------------------------------------------
684 * Driver initialization and probing
685 */
686
687static int mt9m032_probe(struct i2c_client *client,
688 const struct i2c_device_id *devid)
689{
690 struct i2c_adapter *adapter = client->adapter;
691 struct mt9m032 *sensor;
692 int chip_version;
693 int ret;
694
695 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
696 dev_warn(&client->dev,
697 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
698 return -EIO;
699 }
700
701 if (!client->dev.platform_data)
702 return -ENODEV;
703
704 sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
705 if (sensor == NULL)
706 return -ENOMEM;
707
708 mutex_init(&sensor->lock);
709
710 sensor->pdata = client->dev.platform_data;
711
712 v4l2_i2c_subdev_init(&sensor->subdev, client, &mt9m032_ops);
713 sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
714
715 chip_version = mt9m032_read(client, MT9M032_CHIP_VERSION);
716 if (chip_version != MT9M032_CHIP_VERSION_VALUE) {
717 dev_err(&client->dev, "MT9M032 not detected, wrong version "
718 "0x%04x\n", chip_version);
719 ret = -ENODEV;
720 goto error_sensor;
721 }
722
723 dev_info(&client->dev, "MT9M032 detected at address 0x%02x\n",
724 client->addr);
725
726 sensor->frame_interval.numerator = 1;
727 sensor->frame_interval.denominator = 30;
728
729 sensor->crop.left = MT9M032_COLUMN_START_DEF;
730 sensor->crop.top = MT9M032_ROW_START_DEF;
731 sensor->crop.width = MT9M032_COLUMN_SIZE_DEF;
732 sensor->crop.height = MT9M032_ROW_SIZE_DEF;
733
734 sensor->format.width = sensor->crop.width;
735 sensor->format.height = sensor->crop.height;
736 sensor->format.code = V4L2_MBUS_FMT_Y8_1X8;
737 sensor->format.field = V4L2_FIELD_NONE;
738 sensor->format.colorspace = V4L2_COLORSPACE_SRGB;
739
740 v4l2_ctrl_handler_init(&sensor->ctrls, 4);
741
742 v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops,
743 V4L2_CID_GAIN, 0, 127, 1, 64);
744
745 sensor->hflip = v4l2_ctrl_new_std(&sensor->ctrls,
746 &mt9m032_ctrl_ops,
747 V4L2_CID_HFLIP, 0, 1, 1, 0);
748 sensor->vflip = v4l2_ctrl_new_std(&sensor->ctrls,
749 &mt9m032_ctrl_ops,
750 V4L2_CID_VFLIP, 0, 1, 1, 0);
751
752 v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops,
753 V4L2_CID_EXPOSURE, MT9M032_SHUTTER_WIDTH_MIN,
754 MT9M032_SHUTTER_WIDTH_MAX, 1,
755 MT9M032_SHUTTER_WIDTH_DEF);
756
757 if (sensor->ctrls.error) {
758 ret = sensor->ctrls.error;
759 dev_err(&client->dev, "control initialization error %d\n", ret);
760 goto error_ctrl;
761 }
762
763 v4l2_ctrl_cluster(2, &sensor->hflip);
764
765 sensor->subdev.ctrl_handler = &sensor->ctrls;
766 sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
767 ret = media_entity_init(&sensor->subdev.entity, 1, &sensor->pad, 0);
768 if (ret < 0)
769 goto error_ctrl;
770
771 ret = mt9m032_write(client, MT9M032_RESET, 1); /* reset on */
772 if (ret < 0)
773 goto error_entity;
774 mt9m032_write(client, MT9M032_RESET, 0); /* reset off */
775 if (ret < 0)
776 goto error_entity;
777
778 ret = mt9m032_setup_pll(sensor);
779 if (ret < 0)
780 goto error_entity;
781 usleep_range(10000, 11000);
782
783 ret = v4l2_ctrl_handler_setup(&sensor->ctrls);
784 if (ret < 0)
785 goto error_entity;
786
787 /* SIZE */
788 ret = mt9m032_update_geom_timing(sensor);
789 if (ret < 0)
790 goto error_entity;
791
792 ret = mt9m032_write(client, 0x41, 0x0000); /* reserved !!! */
793 if (ret < 0)
794 goto error_entity;
795 ret = mt9m032_write(client, 0x42, 0x0003); /* reserved !!! */
796 if (ret < 0)
797 goto error_entity;
798 ret = mt9m032_write(client, 0x43, 0x0003); /* reserved !!! */
799 if (ret < 0)
800 goto error_entity;
801 ret = mt9m032_write(client, 0x7f, 0x0000); /* reserved !!! */
802 if (ret < 0)
803 goto error_entity;
804 if (sensor->pdata->invert_pixclock) {
805 ret = mt9m032_write(client, MT9M032_PIX_CLK_CTRL,
806 MT9M032_PIX_CLK_CTRL_INV_PIXCLK);
807 if (ret < 0)
808 goto error_entity;
809 }
810
811 ret = mt9m032_write(client, MT9M032_RESTART, 1); /* Restart on */
812 if (ret < 0)
813 goto error_entity;
814 msleep(100);
815 ret = mt9m032_write(client, MT9M032_RESTART, 0); /* Restart off */
816 if (ret < 0)
817 goto error_entity;
818 msleep(100);
819 ret = update_formatter2(sensor, false);
820 if (ret < 0)
821 goto error_entity;
822
823 return ret;
824
825error_entity:
826 media_entity_cleanup(&sensor->subdev.entity);
827error_ctrl:
828 v4l2_ctrl_handler_free(&sensor->ctrls);
829error_sensor:
830 mutex_destroy(&sensor->lock);
831 kfree(sensor);
832 return ret;
833}
834
835static int mt9m032_remove(struct i2c_client *client)
836{
837 struct v4l2_subdev *subdev = i2c_get_clientdata(client);
838 struct mt9m032 *sensor = to_mt9m032(subdev);
839
840 v4l2_device_unregister_subdev(&sensor->subdev);
841 v4l2_ctrl_handler_free(&sensor->ctrls);
842 media_entity_cleanup(&sensor->subdev.entity);
843 mutex_destroy(&sensor->lock);
844 kfree(sensor);
845 return 0;
846}
847
848static const struct i2c_device_id mt9m032_id_table[] = {
849 { MT9M032_NAME, 0 },
850 { }
851};
852
853MODULE_DEVICE_TABLE(i2c, mt9m032_id_table);
854
855static struct i2c_driver mt9m032_i2c_driver = {
856 .driver = {
857 .name = MT9M032_NAME,
858 },
859 .probe = mt9m032_probe,
860 .remove = mt9m032_remove,
861 .id_table = mt9m032_id_table,
862};
863
864module_i2c_driver(mt9m032_i2c_driver);
865
866MODULE_AUTHOR("Martin Hostettler <martin@neutronstar.dyndns.org>");
867MODULE_DESCRIPTION("MT9M032 camera sensor driver");
868MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index bee65bff46e8..b0c529964329 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -1008,18 +1008,7 @@ static struct i2c_driver mt9m111_i2c_driver = {
1008 .id_table = mt9m111_id, 1008 .id_table = mt9m111_id,
1009}; 1009};
1010 1010
1011static int __init mt9m111_mod_init(void) 1011module_i2c_driver(mt9m111_i2c_driver);
1012{
1013 return i2c_add_driver(&mt9m111_i2c_driver);
1014}
1015
1016static void __exit mt9m111_mod_exit(void)
1017{
1018 i2c_del_driver(&mt9m111_i2c_driver);
1019}
1020
1021module_init(mt9m111_mod_init);
1022module_exit(mt9m111_mod_exit);
1023 1012
1024MODULE_DESCRIPTION("Micron/Aptina MT9M111/MT9M112/MT9M131 Camera driver"); 1013MODULE_DESCRIPTION("Micron/Aptina MT9M111/MT9M112/MT9M131 Camera driver");
1025MODULE_AUTHOR("Robert Jarzmik"); 1014MODULE_AUTHOR("Robert Jarzmik");
diff --git a/drivers/media/video/mt9p031.c b/drivers/media/video/mt9p031.c
index 93c3ec7426e8..c81eaf4fbe01 100644
--- a/drivers/media/video/mt9p031.c
+++ b/drivers/media/video/mt9p031.c
@@ -19,7 +19,6 @@
19#include <linux/log2.h> 19#include <linux/log2.h>
20#include <linux/pm.h> 20#include <linux/pm.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <media/v4l2-subdev.h>
23#include <linux/videodev2.h> 22#include <linux/videodev2.h>
24 23
25#include <media/mt9p031.h> 24#include <media/mt9p031.h>
@@ -28,6 +27,8 @@
28#include <media/v4l2-device.h> 27#include <media/v4l2-device.h>
29#include <media/v4l2-subdev.h> 28#include <media/v4l2-subdev.h>
30 29
30#include "aptina-pll.h"
31
31#define MT9P031_PIXEL_ARRAY_WIDTH 2752 32#define MT9P031_PIXEL_ARRAY_WIDTH 2752
32#define MT9P031_PIXEL_ARRAY_HEIGHT 2004 33#define MT9P031_PIXEL_ARRAY_HEIGHT 2004
33 34
@@ -98,14 +99,6 @@
98#define MT9P031_TEST_PATTERN_RED 0xa2 99#define MT9P031_TEST_PATTERN_RED 0xa2
99#define MT9P031_TEST_PATTERN_BLUE 0xa3 100#define MT9P031_TEST_PATTERN_BLUE 0xa3
100 101
101struct mt9p031_pll_divs {
102 u32 ext_freq;
103 u32 target_freq;
104 u8 m;
105 u8 n;
106 u8 p1;
107};
108
109struct mt9p031 { 102struct mt9p031 {
110 struct v4l2_subdev subdev; 103 struct v4l2_subdev subdev;
111 struct media_pad pad; 104 struct media_pad pad;
@@ -115,10 +108,8 @@ struct mt9p031 {
115 struct mt9p031_platform_data *pdata; 108 struct mt9p031_platform_data *pdata;
116 struct mutex power_lock; /* lock to protect power_count */ 109 struct mutex power_lock; /* lock to protect power_count */
117 int power_count; 110 int power_count;
118 u16 xskip;
119 u16 yskip;
120 111
121 const struct mt9p031_pll_divs *pll; 112 struct aptina_pll pll;
122 113
123 /* Registers cache */ 114 /* Registers cache */
124 u16 output_control; 115 u16 output_control;
@@ -186,33 +177,31 @@ static int mt9p031_reset(struct mt9p031 *mt9p031)
186 0); 177 0);
187} 178}
188 179
189/* 180static int mt9p031_pll_setup(struct mt9p031 *mt9p031)
190 * This static table uses ext_freq and vdd_io values to select suitable
191 * PLL dividers m, n and p1 which have been calculated as specifiec in p36
192 * of Aptina's mt9p031 datasheet. New values should be added here.
193 */
194static const struct mt9p031_pll_divs mt9p031_divs[] = {
195 /* ext_freq target_freq m n p1 */
196 {21000000, 48000000, 26, 2, 6}
197};
198
199static int mt9p031_pll_get_divs(struct mt9p031 *mt9p031)
200{ 181{
182 static const struct aptina_pll_limits limits = {
183 .ext_clock_min = 6000000,
184 .ext_clock_max = 27000000,
185 .int_clock_min = 2000000,
186 .int_clock_max = 13500000,
187 .out_clock_min = 180000000,
188 .out_clock_max = 360000000,
189 .pix_clock_max = 96000000,
190 .n_min = 1,
191 .n_max = 64,
192 .m_min = 16,
193 .m_max = 255,
194 .p1_min = 1,
195 .p1_max = 128,
196 };
197
201 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev); 198 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
202 int i; 199 struct mt9p031_platform_data *pdata = mt9p031->pdata;
203 200
204 for (i = 0; i < ARRAY_SIZE(mt9p031_divs); i++) { 201 mt9p031->pll.ext_clock = pdata->ext_freq;
205 if (mt9p031_divs[i].ext_freq == mt9p031->pdata->ext_freq && 202 mt9p031->pll.pix_clock = pdata->target_freq;
206 mt9p031_divs[i].target_freq == mt9p031->pdata->target_freq) {
207 mt9p031->pll = &mt9p031_divs[i];
208 return 0;
209 }
210 }
211 203
212 dev_err(&client->dev, "Couldn't find PLL dividers for ext_freq = %d, " 204 return aptina_pll_calculate(&client->dev, &limits, &mt9p031->pll);
213 "target_freq = %d\n", mt9p031->pdata->ext_freq,
214 mt9p031->pdata->target_freq);
215 return -EINVAL;
216} 205}
217 206
218static int mt9p031_pll_enable(struct mt9p031 *mt9p031) 207static int mt9p031_pll_enable(struct mt9p031 *mt9p031)
@@ -226,11 +215,11 @@ static int mt9p031_pll_enable(struct mt9p031 *mt9p031)
226 return ret; 215 return ret;
227 216
228 ret = mt9p031_write(client, MT9P031_PLL_CONFIG_1, 217 ret = mt9p031_write(client, MT9P031_PLL_CONFIG_1,
229 (mt9p031->pll->m << 8) | (mt9p031->pll->n - 1)); 218 (mt9p031->pll.m << 8) | (mt9p031->pll.n - 1));
230 if (ret < 0) 219 if (ret < 0)
231 return ret; 220 return ret;
232 221
233 ret = mt9p031_write(client, MT9P031_PLL_CONFIG_2, mt9p031->pll->p1 - 1); 222 ret = mt9p031_write(client, MT9P031_PLL_CONFIG_2, mt9p031->pll.p1 - 1);
234 if (ret < 0) 223 if (ret < 0)
235 return ret; 224 return ret;
236 225
@@ -785,8 +774,6 @@ static int mt9p031_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
785 format->field = V4L2_FIELD_NONE; 774 format->field = V4L2_FIELD_NONE;
786 format->colorspace = V4L2_COLORSPACE_SRGB; 775 format->colorspace = V4L2_COLORSPACE_SRGB;
787 776
788 mt9p031->xskip = 1;
789 mt9p031->yskip = 1;
790 return mt9p031_set_power(subdev, 1); 777 return mt9p031_set_power(subdev, 1);
791} 778}
792 779
@@ -905,7 +892,7 @@ static int mt9p031_probe(struct i2c_client *client,
905 mt9p031->format.field = V4L2_FIELD_NONE; 892 mt9p031->format.field = V4L2_FIELD_NONE;
906 mt9p031->format.colorspace = V4L2_COLORSPACE_SRGB; 893 mt9p031->format.colorspace = V4L2_COLORSPACE_SRGB;
907 894
908 ret = mt9p031_pll_get_divs(mt9p031); 895 ret = mt9p031_pll_setup(mt9p031);
909 896
910done: 897done:
911 if (ret < 0) { 898 if (ret < 0) {
@@ -945,18 +932,7 @@ static struct i2c_driver mt9p031_i2c_driver = {
945 .id_table = mt9p031_id, 932 .id_table = mt9p031_id,
946}; 933};
947 934
948static int __init mt9p031_mod_init(void) 935module_i2c_driver(mt9p031_i2c_driver);
949{
950 return i2c_add_driver(&mt9p031_i2c_driver);
951}
952
953static void __exit mt9p031_mod_exit(void)
954{
955 i2c_del_driver(&mt9p031_i2c_driver);
956}
957
958module_init(mt9p031_mod_init);
959module_exit(mt9p031_mod_exit);
960 936
961MODULE_DESCRIPTION("Aptina MT9P031 Camera driver"); 937MODULE_DESCRIPTION("Aptina MT9P031 Camera driver");
962MODULE_AUTHOR("Bastian Hecht <hechtb@gmail.com>"); 938MODULE_AUTHOR("Bastian Hecht <hechtb@gmail.com>");
diff --git a/drivers/media/video/mt9t001.c b/drivers/media/video/mt9t001.c
index cd81d04a529e..49ca3cbfc6f1 100644
--- a/drivers/media/video/mt9t001.c
+++ b/drivers/media/video/mt9t001.c
@@ -817,18 +817,7 @@ static struct i2c_driver mt9t001_driver = {
817 .id_table = mt9t001_id, 817 .id_table = mt9t001_id,
818}; 818};
819 819
820static int __init mt9t001_init(void) 820module_i2c_driver(mt9t001_driver);
821{
822 return i2c_add_driver(&mt9t001_driver);
823}
824
825static void __exit mt9t001_exit(void)
826{
827 i2c_del_driver(&mt9t001_driver);
828}
829
830module_init(mt9t001_init);
831module_exit(mt9t001_exit);
832 821
833MODULE_DESCRIPTION("Aptina (Micron) MT9T001 Camera driver"); 822MODULE_DESCRIPTION("Aptina (Micron) MT9T001 Camera driver");
834MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); 823MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index 84add1aef139..1415074138a5 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -850,18 +850,7 @@ static struct i2c_driver mt9t031_i2c_driver = {
850 .id_table = mt9t031_id, 850 .id_table = mt9t031_id,
851}; 851};
852 852
853static int __init mt9t031_mod_init(void) 853module_i2c_driver(mt9t031_i2c_driver);
854{
855 return i2c_add_driver(&mt9t031_i2c_driver);
856}
857
858static void __exit mt9t031_mod_exit(void)
859{
860 i2c_del_driver(&mt9t031_i2c_driver);
861}
862
863module_init(mt9t031_mod_init);
864module_exit(mt9t031_mod_exit);
865 854
866MODULE_DESCRIPTION("Micron MT9T031 Camera driver"); 855MODULE_DESCRIPTION("Micron MT9T031 Camera driver");
867MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>"); 856MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
diff --git a/drivers/media/video/mt9t112.c b/drivers/media/video/mt9t112.c
index 7b34b11daf24..8d1445f12708 100644
--- a/drivers/media/video/mt9t112.c
+++ b/drivers/media/video/mt9t112.c
@@ -1117,21 +1117,7 @@ static struct i2c_driver mt9t112_i2c_driver = {
1117 .id_table = mt9t112_id, 1117 .id_table = mt9t112_id,
1118}; 1118};
1119 1119
1120/************************************************************************ 1120module_i2c_driver(mt9t112_i2c_driver);
1121 module function
1122************************************************************************/
1123static int __init mt9t112_module_init(void)
1124{
1125 return i2c_add_driver(&mt9t112_i2c_driver);
1126}
1127
1128static void __exit mt9t112_module_exit(void)
1129{
1130 i2c_del_driver(&mt9t112_i2c_driver);
1131}
1132
1133module_init(mt9t112_module_init);
1134module_exit(mt9t112_module_exit);
1135 1121
1136MODULE_DESCRIPTION("SoC Camera driver for mt9t112"); 1122MODULE_DESCRIPTION("SoC Camera driver for mt9t112");
1137MODULE_AUTHOR("Kuninori Morimoto"); 1123MODULE_AUTHOR("Kuninori Morimoto");
diff --git a/drivers/media/video/mt9v011.c b/drivers/media/video/mt9v011.c
index db74dd27c722..6bf01ad62765 100644
--- a/drivers/media/video/mt9v011.c
+++ b/drivers/media/video/mt9v011.c
@@ -709,15 +709,4 @@ static struct i2c_driver mt9v011_driver = {
709 .id_table = mt9v011_id, 709 .id_table = mt9v011_id,
710}; 710};
711 711
712static __init int init_mt9v011(void) 712module_i2c_driver(mt9v011_driver);
713{
714 return i2c_add_driver(&mt9v011_driver);
715}
716
717static __exit void exit_mt9v011(void)
718{
719 i2c_del_driver(&mt9v011_driver);
720}
721
722module_init(init_mt9v011);
723module_exit(exit_mt9v011);
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index 944940758fa3..bf63417adb8f 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -872,18 +872,7 @@ static struct i2c_driver mt9v022_i2c_driver = {
872 .id_table = mt9v022_id, 872 .id_table = mt9v022_id,
873}; 873};
874 874
875static int __init mt9v022_mod_init(void) 875module_i2c_driver(mt9v022_i2c_driver);
876{
877 return i2c_add_driver(&mt9v022_i2c_driver);
878}
879
880static void __exit mt9v022_mod_exit(void)
881{
882 i2c_del_driver(&mt9v022_i2c_driver);
883}
884
885module_init(mt9v022_mod_init);
886module_exit(mt9v022_mod_exit);
887 876
888MODULE_DESCRIPTION("Micron MT9V022 Camera driver"); 877MODULE_DESCRIPTION("Micron MT9V022 Camera driver");
889MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>"); 878MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
diff --git a/drivers/media/video/mt9v032.c b/drivers/media/video/mt9v032.c
index d90b982cc218..75e253a343c5 100644
--- a/drivers/media/video/mt9v032.c
+++ b/drivers/media/video/mt9v032.c
@@ -756,18 +756,7 @@ static struct i2c_driver mt9v032_driver = {
756 .id_table = mt9v032_id, 756 .id_table = mt9v032_id,
757}; 757};
758 758
759static int __init mt9v032_init(void) 759module_i2c_driver(mt9v032_driver);
760{
761 return i2c_add_driver(&mt9v032_driver);
762}
763
764static void __exit mt9v032_exit(void)
765{
766 i2c_del_driver(&mt9v032_driver);
767}
768
769module_init(mt9v032_init);
770module_exit(mt9v032_exit);
771 760
772MODULE_DESCRIPTION("Aptina MT9V032 Camera driver"); 761MODULE_DESCRIPTION("Aptina MT9V032 Camera driver");
773MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); 762MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c
index 04aab0c538aa..18afaeeadb7b 100644
--- a/drivers/media/video/mx2_camera.c
+++ b/drivers/media/video/mx2_camera.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright (C) 2008, Sascha Hauer, Pengutronix 4 * Copyright (C) 2008, Sascha Hauer, Pengutronix
5 * Copyright (C) 2010, Baruch Siach, Orex Computed Radiography 5 * Copyright (C) 2010, Baruch Siach, Orex Computed Radiography
6 * Copyright (C) 2012, Javier Martin, Vista Silicon S.L.
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -18,6 +19,7 @@
18#include <linux/dma-mapping.h> 19#include <linux/dma-mapping.h>
19#include <linux/errno.h> 20#include <linux/errno.h>
20#include <linux/fs.h> 21#include <linux/fs.h>
22#include <linux/gcd.h>
21#include <linux/interrupt.h> 23#include <linux/interrupt.h>
22#include <linux/kernel.h> 24#include <linux/kernel.h>
23#include <linux/mm.h> 25#include <linux/mm.h>
@@ -30,17 +32,14 @@
30 32
31#include <media/v4l2-common.h> 33#include <media/v4l2-common.h>
32#include <media/v4l2-dev.h> 34#include <media/v4l2-dev.h>
33#include <media/videobuf-core.h> 35#include <media/videobuf2-core.h>
34#include <media/videobuf-dma-contig.h> 36#include <media/videobuf2-dma-contig.h>
35#include <media/soc_camera.h> 37#include <media/soc_camera.h>
36#include <media/soc_mediabus.h> 38#include <media/soc_mediabus.h>
37 39
38#include <linux/videodev2.h> 40#include <linux/videodev2.h>
39 41
40#include <mach/mx2_cam.h> 42#include <mach/mx2_cam.h>
41#ifdef CONFIG_MACH_MX27
42#include <mach/dma-mx1-mx2.h>
43#endif
44#include <mach/hardware.h> 43#include <mach/hardware.h>
45 44
46#include <asm/dma.h> 45#include <asm/dma.h>
@@ -206,10 +205,23 @@
206#define PRP_INTR_LBOVF (1 << 7) 205#define PRP_INTR_LBOVF (1 << 7)
207#define PRP_INTR_CH2OVF (1 << 8) 206#define PRP_INTR_CH2OVF (1 << 8)
208 207
209#define mx27_camera_emma(pcdev) (cpu_is_mx27() && pcdev->use_emma) 208/* Resizing registers */
209#define PRP_RZ_VALID_TBL_LEN(x) ((x) << 24)
210#define PRP_RZ_VALID_BILINEAR (1 << 31)
210 211
211#define MAX_VIDEO_MEM 16 212#define MAX_VIDEO_MEM 16
212 213
214#define RESIZE_NUM_MIN 1
215#define RESIZE_NUM_MAX 20
216#define BC_COEF 3
217#define SZ_COEF (1 << BC_COEF)
218
219#define RESIZE_DIR_H 0
220#define RESIZE_DIR_V 1
221
222#define RESIZE_ALGO_BILINEAR 0
223#define RESIZE_ALGO_AVERAGING 1
224
213struct mx2_prp_cfg { 225struct mx2_prp_cfg {
214 int channel; 226 int channel;
215 u32 in_fmt; 227 u32 in_fmt;
@@ -219,6 +231,13 @@ struct mx2_prp_cfg {
219 u32 irq_flags; 231 u32 irq_flags;
220}; 232};
221 233
234/* prp resizing parameters */
235struct emma_prp_resize {
236 int algo; /* type of algorithm used */
237 int len; /* number of coefficients */
238 unsigned char s[RESIZE_NUM_MAX]; /* table of coefficients */
239};
240
222/* prp configuration for a client-host fmt pair */ 241/* prp configuration for a client-host fmt pair */
223struct mx2_fmt_cfg { 242struct mx2_fmt_cfg {
224 enum v4l2_mbus_pixelcode in_fmt; 243 enum v4l2_mbus_pixelcode in_fmt;
@@ -226,6 +245,26 @@ struct mx2_fmt_cfg {
226 struct mx2_prp_cfg cfg; 245 struct mx2_prp_cfg cfg;
227}; 246};
228 247
248enum mx2_buffer_state {
249 MX2_STATE_QUEUED,
250 MX2_STATE_ACTIVE,
251 MX2_STATE_DONE,
252};
253
254struct mx2_buf_internal {
255 struct list_head queue;
256 int bufnum;
257 bool discard;
258};
259
260/* buffer for one video frame */
261struct mx2_buffer {
262 /* common v4l buffer stuff -- must be first */
263 struct vb2_buffer vb;
264 enum mx2_buffer_state state;
265 struct mx2_buf_internal internal;
266};
267
229struct mx2_camera_dev { 268struct mx2_camera_dev {
230 struct device *dev; 269 struct device *dev;
231 struct soc_camera_host soc_host; 270 struct soc_camera_host soc_host;
@@ -242,6 +281,7 @@ struct mx2_camera_dev {
242 281
243 struct list_head capture; 282 struct list_head capture;
244 struct list_head active_bufs; 283 struct list_head active_bufs;
284 struct list_head discard;
245 285
246 spinlock_t lock; 286 spinlock_t lock;
247 287
@@ -250,26 +290,23 @@ struct mx2_camera_dev {
250 struct mx2_buffer *fb1_active; 290 struct mx2_buffer *fb1_active;
251 struct mx2_buffer *fb2_active; 291 struct mx2_buffer *fb2_active;
252 292
253 int use_emma;
254
255 u32 csicr1; 293 u32 csicr1;
256 294
295 struct mx2_buf_internal buf_discard[2];
257 void *discard_buffer; 296 void *discard_buffer;
258 dma_addr_t discard_buffer_dma; 297 dma_addr_t discard_buffer_dma;
259 size_t discard_size; 298 size_t discard_size;
260 struct mx2_fmt_cfg *emma_prp; 299 struct mx2_fmt_cfg *emma_prp;
300 struct emma_prp_resize resizing[2];
301 unsigned int s_width, s_height;
261 u32 frame_count; 302 u32 frame_count;
303 struct vb2_alloc_ctx *alloc_ctx;
262}; 304};
263 305
264/* buffer for one video frame */ 306static struct mx2_buffer *mx2_ibuf_to_buf(struct mx2_buf_internal *int_buf)
265struct mx2_buffer { 307{
266 /* common v4l buffer stuff -- must be first */ 308 return container_of(int_buf, struct mx2_buffer, internal);
267 struct videobuf_buffer vb; 309}
268
269 enum v4l2_mbus_pixelcode code;
270
271 int bufnum;
272};
273 310
274static struct mx2_fmt_cfg mx27_emma_prp_table[] = { 311static struct mx2_fmt_cfg mx27_emma_prp_table[] = {
275 /* 312 /*
@@ -324,13 +361,36 @@ static struct mx2_fmt_cfg *mx27_emma_prp_get_format(
324 return &mx27_emma_prp_table[0]; 361 return &mx27_emma_prp_table[0];
325}; 362};
326 363
364static void mx27_update_emma_buf(struct mx2_camera_dev *pcdev,
365 unsigned long phys, int bufnum)
366{
367 struct mx2_fmt_cfg *prp = pcdev->emma_prp;
368
369 if (prp->cfg.channel == 1) {
370 writel(phys, pcdev->base_emma +
371 PRP_DEST_RGB1_PTR + 4 * bufnum);
372 } else {
373 writel(phys, pcdev->base_emma +
374 PRP_DEST_Y_PTR - 0x14 * bufnum);
375 if (prp->out_fmt == V4L2_PIX_FMT_YUV420) {
376 u32 imgsize = pcdev->icd->user_height *
377 pcdev->icd->user_width;
378
379 writel(phys + imgsize, pcdev->base_emma +
380 PRP_DEST_CB_PTR - 0x14 * bufnum);
381 writel(phys + ((5 * imgsize) / 4), pcdev->base_emma +
382 PRP_DEST_CR_PTR - 0x14 * bufnum);
383 }
384 }
385}
386
327static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev) 387static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev)
328{ 388{
329 unsigned long flags; 389 unsigned long flags;
330 390
331 clk_disable(pcdev->clk_csi); 391 clk_disable(pcdev->clk_csi);
332 writel(0, pcdev->base_csi + CSICR1); 392 writel(0, pcdev->base_csi + CSICR1);
333 if (mx27_camera_emma(pcdev)) { 393 if (cpu_is_mx27()) {
334 writel(0, pcdev->base_emma + PRP_CNTL); 394 writel(0, pcdev->base_emma + PRP_CNTL);
335 } else if (cpu_is_mx25()) { 395 } else if (cpu_is_mx25()) {
336 spin_lock_irqsave(&pcdev->lock, flags); 396 spin_lock_irqsave(&pcdev->lock, flags);
@@ -362,7 +422,7 @@ static int mx2_camera_add_device(struct soc_camera_device *icd)
362 422
363 csicr1 = CSICR1_MCLKEN; 423 csicr1 = CSICR1_MCLKEN;
364 424
365 if (mx27_camera_emma(pcdev)) { 425 if (cpu_is_mx27()) {
366 csicr1 |= CSICR1_PRP_IF_EN | CSICR1_FCC | 426 csicr1 |= CSICR1_PRP_IF_EN | CSICR1_FCC |
367 CSICR1_RXFF_LEVEL(0); 427 CSICR1_RXFF_LEVEL(0);
368 } else if (cpu_is_mx27()) 428 } else if (cpu_is_mx27())
@@ -392,56 +452,13 @@ static void mx2_camera_remove_device(struct soc_camera_device *icd)
392 452
393 mx2_camera_deactivate(pcdev); 453 mx2_camera_deactivate(pcdev);
394 454
395 if (pcdev->discard_buffer) {
396 dma_free_coherent(ici->v4l2_dev.dev, pcdev->discard_size,
397 pcdev->discard_buffer,
398 pcdev->discard_buffer_dma);
399 pcdev->discard_buffer = NULL;
400 }
401
402 pcdev->icd = NULL; 455 pcdev->icd = NULL;
403} 456}
404 457
405#ifdef CONFIG_MACH_MX27
406static void mx27_camera_dma_enable(struct mx2_camera_dev *pcdev)
407{
408 u32 tmp;
409
410 imx_dma_enable(pcdev->dma);
411
412 tmp = readl(pcdev->base_csi + CSICR1);
413 tmp |= CSICR1_RF_OR_INTEN;
414 writel(tmp, pcdev->base_csi + CSICR1);
415}
416
417static irqreturn_t mx27_camera_irq(int irq_csi, void *data)
418{
419 struct mx2_camera_dev *pcdev = data;
420 u32 status = readl(pcdev->base_csi + CSISR);
421
422 if (status & CSISR_SOF_INT && pcdev->active) {
423 u32 tmp;
424
425 tmp = readl(pcdev->base_csi + CSICR1);
426 writel(tmp | CSICR1_CLR_RXFIFO, pcdev->base_csi + CSICR1);
427 mx27_camera_dma_enable(pcdev);
428 }
429
430 writel(CSISR_SOF_INT | CSISR_RFF_OR_INT, pcdev->base_csi + CSISR);
431
432 return IRQ_HANDLED;
433}
434#else
435static irqreturn_t mx27_camera_irq(int irq_csi, void *data)
436{
437 return IRQ_NONE;
438}
439#endif /* CONFIG_MACH_MX27 */
440
441static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb, 458static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb,
442 int state) 459 int state)
443{ 460{
444 struct videobuf_buffer *vb; 461 struct vb2_buffer *vb;
445 struct mx2_buffer *buf; 462 struct mx2_buffer *buf;
446 struct mx2_buffer **fb_active = fb == 1 ? &pcdev->fb1_active : 463 struct mx2_buffer **fb_active = fb == 1 ? &pcdev->fb1_active :
447 &pcdev->fb2_active; 464 &pcdev->fb2_active;
@@ -454,25 +471,24 @@ static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb,
454 goto out; 471 goto out;
455 472
456 vb = &(*fb_active)->vb; 473 vb = &(*fb_active)->vb;
457 dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 474 dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%p %lu\n", __func__,
458 vb, vb->baddr, vb->bsize); 475 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
459 476
460 vb->state = state; 477 do_gettimeofday(&vb->v4l2_buf.timestamp);
461 do_gettimeofday(&vb->ts); 478 vb->v4l2_buf.sequence++;
462 vb->field_count++; 479 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
463
464 wake_up(&vb->done);
465 480
466 if (list_empty(&pcdev->capture)) { 481 if (list_empty(&pcdev->capture)) {
467 buf = NULL; 482 buf = NULL;
468 writel(0, pcdev->base_csi + fb_reg); 483 writel(0, pcdev->base_csi + fb_reg);
469 } else { 484 } else {
470 buf = list_entry(pcdev->capture.next, struct mx2_buffer, 485 buf = list_first_entry(&pcdev->capture, struct mx2_buffer,
471 vb.queue); 486 internal.queue);
472 vb = &buf->vb; 487 vb = &buf->vb;
473 list_del(&vb->queue); 488 list_del(&buf->internal.queue);
474 vb->state = VIDEOBUF_ACTIVE; 489 buf->state = MX2_STATE_ACTIVE;
475 writel(videobuf_to_dma_contig(vb), pcdev->base_csi + fb_reg); 490 writel(vb2_dma_contig_plane_dma_addr(vb, 0),
491 pcdev->base_csi + fb_reg);
476 } 492 }
477 493
478 *fb_active = buf; 494 *fb_active = buf;
@@ -487,9 +503,9 @@ static irqreturn_t mx25_camera_irq(int irq_csi, void *data)
487 u32 status = readl(pcdev->base_csi + CSISR); 503 u32 status = readl(pcdev->base_csi + CSISR);
488 504
489 if (status & CSISR_DMA_TSF_FB1_INT) 505 if (status & CSISR_DMA_TSF_FB1_INT)
490 mx25_camera_frame_done(pcdev, 1, VIDEOBUF_DONE); 506 mx25_camera_frame_done(pcdev, 1, MX2_STATE_DONE);
491 else if (status & CSISR_DMA_TSF_FB2_INT) 507 else if (status & CSISR_DMA_TSF_FB2_INT)
492 mx25_camera_frame_done(pcdev, 2, VIDEOBUF_DONE); 508 mx25_camera_frame_done(pcdev, 2, MX2_STATE_DONE);
493 509
494 /* FIXME: handle CSISR_RFF_OR_INT */ 510 /* FIXME: handle CSISR_RFF_OR_INT */
495 511
@@ -501,59 +517,50 @@ static irqreturn_t mx25_camera_irq(int irq_csi, void *data)
501/* 517/*
502 * Videobuf operations 518 * Videobuf operations
503 */ 519 */
504static int mx2_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, 520static int mx2_videobuf_setup(struct vb2_queue *vq,
505 unsigned int *size) 521 const struct v4l2_format *fmt,
522 unsigned int *count, unsigned int *num_planes,
523 unsigned int sizes[], void *alloc_ctxs[])
506{ 524{
507 struct soc_camera_device *icd = vq->priv_data; 525 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
526 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
527 struct mx2_camera_dev *pcdev = ici->priv;
508 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 528 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
509 icd->current_fmt->host_fmt); 529 icd->current_fmt->host_fmt);
510 530
511 dev_dbg(icd->parent, "count=%d, size=%d\n", *count, *size); 531 dev_dbg(icd->parent, "count=%d, size=%d\n", *count, sizes[0]);
532
533 /* TODO: support for VIDIOC_CREATE_BUFS not ready */
534 if (fmt != NULL)
535 return -ENOTTY;
512 536
513 if (bytes_per_line < 0) 537 if (bytes_per_line < 0)
514 return bytes_per_line; 538 return bytes_per_line;
515 539
516 *size = bytes_per_line * icd->user_height; 540 alloc_ctxs[0] = pcdev->alloc_ctx;
541
542 sizes[0] = bytes_per_line * icd->user_height;
517 543
518 if (0 == *count) 544 if (0 == *count)
519 *count = 32; 545 *count = 32;
520 if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024) 546 if (!*num_planes &&
521 *count = (MAX_VIDEO_MEM * 1024 * 1024) / *size; 547 sizes[0] * *count > MAX_VIDEO_MEM * 1024 * 1024)
548 *count = (MAX_VIDEO_MEM * 1024 * 1024) / sizes[0];
522 549
523 return 0; 550 *num_planes = 1;
524}
525 551
526static void free_buffer(struct videobuf_queue *vq, struct mx2_buffer *buf) 552 return 0;
527{
528 struct soc_camera_device *icd = vq->priv_data;
529 struct videobuf_buffer *vb = &buf->vb;
530
531 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
532 vb, vb->baddr, vb->bsize);
533
534 /*
535 * This waits until this buffer is out of danger, i.e., until it is no
536 * longer in state VIDEOBUF_QUEUED or VIDEOBUF_ACTIVE
537 */
538 videobuf_waiton(vq, vb, 0, 0);
539
540 videobuf_dma_contig_free(vq, vb);
541 dev_dbg(icd->parent, "%s freed\n", __func__);
542
543 vb->state = VIDEOBUF_NEEDS_INIT;
544} 553}
545 554
546static int mx2_videobuf_prepare(struct videobuf_queue *vq, 555static int mx2_videobuf_prepare(struct vb2_buffer *vb)
547 struct videobuf_buffer *vb, enum v4l2_field field)
548{ 556{
549 struct soc_camera_device *icd = vq->priv_data; 557 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
550 struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb);
551 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 558 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
552 icd->current_fmt->host_fmt); 559 icd->current_fmt->host_fmt);
553 int ret = 0; 560 int ret = 0;
554 561
555 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 562 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
556 vb, vb->baddr, vb->bsize); 563 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
557 564
558 if (bytes_per_line < 0) 565 if (bytes_per_line < 0)
559 return bytes_per_line; 566 return bytes_per_line;
@@ -563,99 +570,58 @@ static int mx2_videobuf_prepare(struct videobuf_queue *vq,
563 * This can be useful if you want to see if we actually fill 570 * This can be useful if you want to see if we actually fill
564 * the buffer with something 571 * the buffer with something
565 */ 572 */
566 memset((void *)vb->baddr, 0xaa, vb->bsize); 573 memset((void *)vb2_plane_vaddr(vb, 0),
574 0xaa, vb2_get_plane_payload(vb, 0));
567#endif 575#endif
568 576
569 if (buf->code != icd->current_fmt->code || 577 vb2_set_plane_payload(vb, 0, bytes_per_line * icd->user_height);
570 vb->width != icd->user_width || 578 if (vb2_plane_vaddr(vb, 0) &&
571 vb->height != icd->user_height || 579 vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) {
572 vb->field != field) {
573 buf->code = icd->current_fmt->code;
574 vb->width = icd->user_width;
575 vb->height = icd->user_height;
576 vb->field = field;
577 vb->state = VIDEOBUF_NEEDS_INIT;
578 }
579
580 vb->size = bytes_per_line * vb->height;
581 if (vb->baddr && vb->bsize < vb->size) {
582 ret = -EINVAL; 580 ret = -EINVAL;
583 goto out; 581 goto out;
584 } 582 }
585 583
586 if (vb->state == VIDEOBUF_NEEDS_INIT) {
587 ret = videobuf_iolock(vq, vb, NULL);
588 if (ret)
589 goto fail;
590
591 vb->state = VIDEOBUF_PREPARED;
592 }
593
594 return 0; 584 return 0;
595 585
596fail:
597 free_buffer(vq, buf);
598out: 586out:
599 return ret; 587 return ret;
600} 588}
601 589
602static void mx2_videobuf_queue(struct videobuf_queue *vq, 590static void mx2_videobuf_queue(struct vb2_buffer *vb)
603 struct videobuf_buffer *vb)
604{ 591{
605 struct soc_camera_device *icd = vq->priv_data; 592 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
606 struct soc_camera_host *ici = 593 struct soc_camera_host *ici =
607 to_soc_camera_host(icd->parent); 594 to_soc_camera_host(icd->parent);
608 struct mx2_camera_dev *pcdev = ici->priv; 595 struct mx2_camera_dev *pcdev = ici->priv;
609 struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb); 596 struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb);
610 unsigned long flags; 597 unsigned long flags;
611 598
612 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 599 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
613 vb, vb->baddr, vb->bsize); 600 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
614 601
615 spin_lock_irqsave(&pcdev->lock, flags); 602 spin_lock_irqsave(&pcdev->lock, flags);
616 603
617 vb->state = VIDEOBUF_QUEUED; 604 buf->state = MX2_STATE_QUEUED;
618 list_add_tail(&vb->queue, &pcdev->capture); 605 list_add_tail(&buf->internal.queue, &pcdev->capture);
619 606
620 if (mx27_camera_emma(pcdev)) { 607 if (cpu_is_mx25()) {
621 goto out;
622#ifdef CONFIG_MACH_MX27
623 } else if (cpu_is_mx27()) {
624 int ret;
625
626 if (pcdev->active == NULL) {
627 ret = imx_dma_setup_single(pcdev->dma,
628 videobuf_to_dma_contig(vb), vb->size,
629 (u32)pcdev->base_dma + 0x10,
630 DMA_MODE_READ);
631 if (ret) {
632 vb->state = VIDEOBUF_ERROR;
633 wake_up(&vb->done);
634 goto out;
635 }
636
637 vb->state = VIDEOBUF_ACTIVE;
638 pcdev->active = buf;
639 }
640#endif
641 } else { /* cpu_is_mx25() */
642 u32 csicr3, dma_inten = 0; 608 u32 csicr3, dma_inten = 0;
643 609
644 if (pcdev->fb1_active == NULL) { 610 if (pcdev->fb1_active == NULL) {
645 writel(videobuf_to_dma_contig(vb), 611 writel(vb2_dma_contig_plane_dma_addr(vb, 0),
646 pcdev->base_csi + CSIDMASA_FB1); 612 pcdev->base_csi + CSIDMASA_FB1);
647 pcdev->fb1_active = buf; 613 pcdev->fb1_active = buf;
648 dma_inten = CSICR1_FB1_DMA_INTEN; 614 dma_inten = CSICR1_FB1_DMA_INTEN;
649 } else if (pcdev->fb2_active == NULL) { 615 } else if (pcdev->fb2_active == NULL) {
650 writel(videobuf_to_dma_contig(vb), 616 writel(vb2_dma_contig_plane_dma_addr(vb, 0),
651 pcdev->base_csi + CSIDMASA_FB2); 617 pcdev->base_csi + CSIDMASA_FB2);
652 pcdev->fb2_active = buf; 618 pcdev->fb2_active = buf;
653 dma_inten = CSICR1_FB2_DMA_INTEN; 619 dma_inten = CSICR1_FB2_DMA_INTEN;
654 } 620 }
655 621
656 if (dma_inten) { 622 if (dma_inten) {
657 list_del(&vb->queue); 623 list_del(&buf->internal.queue);
658 vb->state = VIDEOBUF_ACTIVE; 624 buf->state = MX2_STATE_ACTIVE;
659 625
660 csicr3 = readl(pcdev->base_csi + CSICR3); 626 csicr3 = readl(pcdev->base_csi + CSICR3);
661 627
@@ -674,36 +640,31 @@ static void mx2_videobuf_queue(struct videobuf_queue *vq,
674 } 640 }
675 } 641 }
676 642
677out:
678 spin_unlock_irqrestore(&pcdev->lock, flags); 643 spin_unlock_irqrestore(&pcdev->lock, flags);
679} 644}
680 645
681static void mx2_videobuf_release(struct videobuf_queue *vq, 646static void mx2_videobuf_release(struct vb2_buffer *vb)
682 struct videobuf_buffer *vb)
683{ 647{
684 struct soc_camera_device *icd = vq->priv_data; 648 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
685 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 649 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
686 struct mx2_camera_dev *pcdev = ici->priv; 650 struct mx2_camera_dev *pcdev = ici->priv;
687 struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb); 651 struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb);
688 unsigned long flags; 652 unsigned long flags;
689 653
690#ifdef DEBUG 654#ifdef DEBUG
691 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 655 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
692 vb, vb->baddr, vb->bsize); 656 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
693 657
694 switch (vb->state) { 658 switch (buf->state) {
695 case VIDEOBUF_ACTIVE: 659 case MX2_STATE_ACTIVE:
696 dev_info(icd->parent, "%s (active)\n", __func__); 660 dev_info(icd->parent, "%s (active)\n", __func__);
697 break; 661 break;
698 case VIDEOBUF_QUEUED: 662 case MX2_STATE_QUEUED:
699 dev_info(icd->parent, "%s (queued)\n", __func__); 663 dev_info(icd->parent, "%s (queued)\n", __func__);
700 break; 664 break;
701 case VIDEOBUF_PREPARED:
702 dev_info(icd->parent, "%s (prepared)\n", __func__);
703 break;
704 default: 665 default:
705 dev_info(icd->parent, "%s (unknown) %d\n", __func__, 666 dev_info(icd->parent, "%s (unknown) %d\n", __func__,
706 vb->state); 667 buf->state);
707 break; 668 break;
708 } 669 }
709#endif 670#endif
@@ -717,11 +678,9 @@ static void mx2_videobuf_release(struct videobuf_queue *vq,
717 * state. This requires a specific handling for each of the these DMA 678 * state. This requires a specific handling for each of the these DMA
718 * types. 679 * types.
719 */ 680 */
681
720 spin_lock_irqsave(&pcdev->lock, flags); 682 spin_lock_irqsave(&pcdev->lock, flags);
721 if (vb->state == VIDEOBUF_QUEUED) { 683 if (cpu_is_mx25() && buf->state == MX2_STATE_ACTIVE) {
722 list_del(&vb->queue);
723 vb->state = VIDEOBUF_ERROR;
724 } else if (cpu_is_mx25() && vb->state == VIDEOBUF_ACTIVE) {
725 if (pcdev->fb1_active == buf) { 684 if (pcdev->fb1_active == buf) {
726 pcdev->csicr1 &= ~CSICR1_FB1_DMA_INTEN; 685 pcdev->csicr1 &= ~CSICR1_FB1_DMA_INTEN;
727 writel(0, pcdev->base_csi + CSIDMASA_FB1); 686 writel(0, pcdev->base_csi + CSIDMASA_FB1);
@@ -732,75 +691,178 @@ static void mx2_videobuf_release(struct videobuf_queue *vq,
732 pcdev->fb2_active = NULL; 691 pcdev->fb2_active = NULL;
733 } 692 }
734 writel(pcdev->csicr1, pcdev->base_csi + CSICR1); 693 writel(pcdev->csicr1, pcdev->base_csi + CSICR1);
735 vb->state = VIDEOBUF_ERROR;
736 } 694 }
737 spin_unlock_irqrestore(&pcdev->lock, flags); 695 spin_unlock_irqrestore(&pcdev->lock, flags);
738
739 free_buffer(vq, buf);
740} 696}
741 697
742static struct videobuf_queue_ops mx2_videobuf_ops = { 698static void mx27_camera_emma_buf_init(struct soc_camera_device *icd,
743 .buf_setup = mx2_videobuf_setup, 699 int bytesperline)
744 .buf_prepare = mx2_videobuf_prepare,
745 .buf_queue = mx2_videobuf_queue,
746 .buf_release = mx2_videobuf_release,
747};
748
749static void mx2_camera_init_videobuf(struct videobuf_queue *q,
750 struct soc_camera_device *icd)
751{ 700{
752 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 701 struct soc_camera_host *ici =
702 to_soc_camera_host(icd->parent);
753 struct mx2_camera_dev *pcdev = ici->priv; 703 struct mx2_camera_dev *pcdev = ici->priv;
704 struct mx2_fmt_cfg *prp = pcdev->emma_prp;
754 705
755 videobuf_queue_dma_contig_init(q, &mx2_videobuf_ops, pcdev->dev, 706 writel((pcdev->s_width << 16) | pcdev->s_height,
756 &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, 707 pcdev->base_emma + PRP_SRC_FRAME_SIZE);
757 V4L2_FIELD_NONE, sizeof(struct mx2_buffer), 708 writel(prp->cfg.src_pixel,
758 icd, &icd->video_lock); 709 pcdev->base_emma + PRP_SRC_PIXEL_FORMAT_CNTL);
759} 710 if (prp->cfg.channel == 1) {
711 writel((icd->user_width << 16) | icd->user_height,
712 pcdev->base_emma + PRP_CH1_OUT_IMAGE_SIZE);
713 writel(bytesperline,
714 pcdev->base_emma + PRP_DEST_CH1_LINE_STRIDE);
715 writel(prp->cfg.ch1_pixel,
716 pcdev->base_emma + PRP_CH1_PIXEL_FORMAT_CNTL);
717 } else { /* channel 2 */
718 writel((icd->user_width << 16) | icd->user_height,
719 pcdev->base_emma + PRP_CH2_OUT_IMAGE_SIZE);
720 }
760 721
761#define MX2_BUS_FLAGS (V4L2_MBUS_MASTER | \ 722 /* Enable interrupts */
762 V4L2_MBUS_VSYNC_ACTIVE_HIGH | \ 723 writel(prp->cfg.irq_flags, pcdev->base_emma + PRP_INTR_CNTL);
763 V4L2_MBUS_VSYNC_ACTIVE_LOW | \ 724}
764 V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
765 V4L2_MBUS_HSYNC_ACTIVE_LOW | \
766 V4L2_MBUS_PCLK_SAMPLE_RISING | \
767 V4L2_MBUS_PCLK_SAMPLE_FALLING | \
768 V4L2_MBUS_DATA_ACTIVE_HIGH | \
769 V4L2_MBUS_DATA_ACTIVE_LOW)
770 725
771static int mx27_camera_emma_prp_reset(struct mx2_camera_dev *pcdev) 726static void mx2_prp_resize_commit(struct mx2_camera_dev *pcdev)
772{ 727{
773 u32 cntl; 728 int dir;
774 int count = 0;
775 729
776 cntl = readl(pcdev->base_emma + PRP_CNTL); 730 for (dir = RESIZE_DIR_H; dir <= RESIZE_DIR_V; dir++) {
777 writel(PRP_CNTL_SWRST, pcdev->base_emma + PRP_CNTL); 731 unsigned char *s = pcdev->resizing[dir].s;
778 while (count++ < 100) { 732 int len = pcdev->resizing[dir].len;
779 if (!(readl(pcdev->base_emma + PRP_CNTL) & PRP_CNTL_SWRST)) 733 unsigned int coeff[2] = {0, 0};
780 return 0; 734 unsigned int valid = 0;
781 barrier(); 735 int i;
782 udelay(1);
783 }
784 736
785 return -ETIMEDOUT; 737 if (len == 0)
738 continue;
739
740 for (i = RESIZE_NUM_MAX - 1; i >= 0; i--) {
741 int j;
742
743 j = i > 9 ? 1 : 0;
744 coeff[j] = (coeff[j] << BC_COEF) |
745 (s[i] & (SZ_COEF - 1));
746
747 if (i == 5 || i == 15)
748 coeff[j] <<= 1;
749
750 valid = (valid << 1) | (s[i] >> BC_COEF);
751 }
752
753 valid |= PRP_RZ_VALID_TBL_LEN(len);
754
755 if (pcdev->resizing[dir].algo == RESIZE_ALGO_BILINEAR)
756 valid |= PRP_RZ_VALID_BILINEAR;
757
758 if (pcdev->emma_prp->cfg.channel == 1) {
759 if (dir == RESIZE_DIR_H) {
760 writel(coeff[0], pcdev->base_emma +
761 PRP_CH1_RZ_HORI_COEF1);
762 writel(coeff[1], pcdev->base_emma +
763 PRP_CH1_RZ_HORI_COEF2);
764 writel(valid, pcdev->base_emma +
765 PRP_CH1_RZ_HORI_VALID);
766 } else {
767 writel(coeff[0], pcdev->base_emma +
768 PRP_CH1_RZ_VERT_COEF1);
769 writel(coeff[1], pcdev->base_emma +
770 PRP_CH1_RZ_VERT_COEF2);
771 writel(valid, pcdev->base_emma +
772 PRP_CH1_RZ_VERT_VALID);
773 }
774 } else {
775 if (dir == RESIZE_DIR_H) {
776 writel(coeff[0], pcdev->base_emma +
777 PRP_CH2_RZ_HORI_COEF1);
778 writel(coeff[1], pcdev->base_emma +
779 PRP_CH2_RZ_HORI_COEF2);
780 writel(valid, pcdev->base_emma +
781 PRP_CH2_RZ_HORI_VALID);
782 } else {
783 writel(coeff[0], pcdev->base_emma +
784 PRP_CH2_RZ_VERT_COEF1);
785 writel(coeff[1], pcdev->base_emma +
786 PRP_CH2_RZ_VERT_COEF2);
787 writel(valid, pcdev->base_emma +
788 PRP_CH2_RZ_VERT_VALID);
789 }
790 }
791 }
786} 792}
787 793
788static void mx27_camera_emma_buf_init(struct soc_camera_device *icd, 794static int mx2_start_streaming(struct vb2_queue *q, unsigned int count)
789 int bytesperline)
790{ 795{
796 struct soc_camera_device *icd = soc_camera_from_vb2q(q);
791 struct soc_camera_host *ici = 797 struct soc_camera_host *ici =
792 to_soc_camera_host(icd->parent); 798 to_soc_camera_host(icd->parent);
793 struct mx2_camera_dev *pcdev = ici->priv; 799 struct mx2_camera_dev *pcdev = ici->priv;
794 struct mx2_fmt_cfg *prp = pcdev->emma_prp; 800 struct mx2_fmt_cfg *prp = pcdev->emma_prp;
795 u32 imgsize = pcdev->icd->user_height * pcdev->icd->user_width; 801 struct vb2_buffer *vb;
802 struct mx2_buffer *buf;
803 unsigned long phys;
804 int bytesperline;
796 805
797 if (prp->cfg.channel == 1) { 806 if (cpu_is_mx27()) {
798 writel(pcdev->discard_buffer_dma, 807 unsigned long flags;
799 pcdev->base_emma + PRP_DEST_RGB1_PTR); 808 if (count < 2)
800 writel(pcdev->discard_buffer_dma, 809 return -EINVAL;
801 pcdev->base_emma + PRP_DEST_RGB2_PTR); 810
811 spin_lock_irqsave(&pcdev->lock, flags);
812
813 buf = list_first_entry(&pcdev->capture, struct mx2_buffer,
814 internal.queue);
815 buf->internal.bufnum = 0;
816 vb = &buf->vb;
817 buf->state = MX2_STATE_ACTIVE;
818
819 phys = vb2_dma_contig_plane_dma_addr(vb, 0);
820 mx27_update_emma_buf(pcdev, phys, buf->internal.bufnum);
821 list_move_tail(pcdev->capture.next, &pcdev->active_bufs);
822
823 buf = list_first_entry(&pcdev->capture, struct mx2_buffer,
824 internal.queue);
825 buf->internal.bufnum = 1;
826 vb = &buf->vb;
827 buf->state = MX2_STATE_ACTIVE;
802 828
803 writel(PRP_CNTL_CH1EN | 829 phys = vb2_dma_contig_plane_dma_addr(vb, 0);
830 mx27_update_emma_buf(pcdev, phys, buf->internal.bufnum);
831 list_move_tail(pcdev->capture.next, &pcdev->active_bufs);
832
833 bytesperline = soc_mbus_bytes_per_line(icd->user_width,
834 icd->current_fmt->host_fmt);
835 if (bytesperline < 0)
836 return bytesperline;
837
838 /*
839 * I didn't manage to properly enable/disable the prp
840 * on a per frame basis during running transfers,
841 * thus we allocate a buffer here and use it to
842 * discard frames when no buffer is available.
843 * Feel free to work on this ;)
844 */
845 pcdev->discard_size = icd->user_height * bytesperline;
846 pcdev->discard_buffer = dma_alloc_coherent(ici->v4l2_dev.dev,
847 pcdev->discard_size, &pcdev->discard_buffer_dma,
848 GFP_KERNEL);
849 if (!pcdev->discard_buffer)
850 return -ENOMEM;
851
852 pcdev->buf_discard[0].discard = true;
853 list_add_tail(&pcdev->buf_discard[0].queue,
854 &pcdev->discard);
855
856 pcdev->buf_discard[1].discard = true;
857 list_add_tail(&pcdev->buf_discard[1].queue,
858 &pcdev->discard);
859
860 mx2_prp_resize_commit(pcdev);
861
862 mx27_camera_emma_buf_init(icd, bytesperline);
863
864 if (prp->cfg.channel == 1) {
865 writel(PRP_CNTL_CH1EN |
804 PRP_CNTL_CSIEN | 866 PRP_CNTL_CSIEN |
805 prp->cfg.in_fmt | 867 prp->cfg.in_fmt |
806 prp->cfg.out_fmt | 868 prp->cfg.out_fmt |
@@ -809,56 +871,107 @@ static void mx27_camera_emma_buf_init(struct soc_camera_device *icd,
809 PRP_CNTL_CH1_TSKIP(0) | 871 PRP_CNTL_CH1_TSKIP(0) |
810 PRP_CNTL_IN_TSKIP(0), 872 PRP_CNTL_IN_TSKIP(0),
811 pcdev->base_emma + PRP_CNTL); 873 pcdev->base_emma + PRP_CNTL);
874 } else {
875 writel(PRP_CNTL_CH2EN |
876 PRP_CNTL_CSIEN |
877 prp->cfg.in_fmt |
878 prp->cfg.out_fmt |
879 PRP_CNTL_CH2_LEN |
880 PRP_CNTL_CH2_TSKIP(0) |
881 PRP_CNTL_IN_TSKIP(0),
882 pcdev->base_emma + PRP_CNTL);
883 }
884 spin_unlock_irqrestore(&pcdev->lock, flags);
885 }
812 886
813 writel((icd->user_width << 16) | icd->user_height, 887 return 0;
814 pcdev->base_emma + PRP_SRC_FRAME_SIZE); 888}
815 writel((icd->user_width << 16) | icd->user_height, 889
816 pcdev->base_emma + PRP_CH1_OUT_IMAGE_SIZE); 890static int mx2_stop_streaming(struct vb2_queue *q)
817 writel(bytesperline, 891{
818 pcdev->base_emma + PRP_DEST_CH1_LINE_STRIDE); 892 struct soc_camera_device *icd = soc_camera_from_vb2q(q);
819 writel(prp->cfg.src_pixel, 893 struct soc_camera_host *ici =
820 pcdev->base_emma + PRP_SRC_PIXEL_FORMAT_CNTL); 894 to_soc_camera_host(icd->parent);
821 writel(prp->cfg.ch1_pixel, 895 struct mx2_camera_dev *pcdev = ici->priv;
822 pcdev->base_emma + PRP_CH1_PIXEL_FORMAT_CNTL); 896 struct mx2_fmt_cfg *prp = pcdev->emma_prp;
823 } else { /* channel 2 */ 897 unsigned long flags;
824 writel(pcdev->discard_buffer_dma, 898 void *b;
825 pcdev->base_emma + PRP_DEST_Y_PTR); 899 u32 cntl;
826 writel(pcdev->discard_buffer_dma, 900
827 pcdev->base_emma + PRP_SOURCE_Y_PTR); 901 if (cpu_is_mx27()) {
828 902 spin_lock_irqsave(&pcdev->lock, flags);
829 if (prp->cfg.out_fmt == PRP_CNTL_CH2_OUT_YUV420) { 903
830 writel(pcdev->discard_buffer_dma + imgsize, 904 cntl = readl(pcdev->base_emma + PRP_CNTL);
831 pcdev->base_emma + PRP_DEST_CB_PTR); 905 if (prp->cfg.channel == 1) {
832 writel(pcdev->discard_buffer_dma + ((5 * imgsize) / 4), 906 writel(cntl & ~PRP_CNTL_CH1EN,
833 pcdev->base_emma + PRP_DEST_CR_PTR); 907 pcdev->base_emma + PRP_CNTL);
834 writel(pcdev->discard_buffer_dma + imgsize, 908 } else {
835 pcdev->base_emma + PRP_SOURCE_CB_PTR); 909 writel(cntl & ~PRP_CNTL_CH2EN,
836 writel(pcdev->discard_buffer_dma + ((5 * imgsize) / 4), 910 pcdev->base_emma + PRP_CNTL);
837 pcdev->base_emma + PRP_SOURCE_CR_PTR);
838 } 911 }
912 INIT_LIST_HEAD(&pcdev->capture);
913 INIT_LIST_HEAD(&pcdev->active_bufs);
914 INIT_LIST_HEAD(&pcdev->discard);
839 915
840 writel(PRP_CNTL_CH2EN | 916 b = pcdev->discard_buffer;
841 PRP_CNTL_CSIEN | 917 pcdev->discard_buffer = NULL;
842 prp->cfg.in_fmt |
843 prp->cfg.out_fmt |
844 PRP_CNTL_CH2_LEN |
845 PRP_CNTL_CH2_TSKIP(0) |
846 PRP_CNTL_IN_TSKIP(0),
847 pcdev->base_emma + PRP_CNTL);
848 918
849 writel((icd->user_width << 16) | icd->user_height, 919 spin_unlock_irqrestore(&pcdev->lock, flags);
850 pcdev->base_emma + PRP_SRC_FRAME_SIZE);
851 920
852 writel((icd->user_width << 16) | icd->user_height, 921 dma_free_coherent(ici->v4l2_dev.dev,
853 pcdev->base_emma + PRP_CH2_OUT_IMAGE_SIZE); 922 pcdev->discard_size, b, pcdev->discard_buffer_dma);
923 }
854 924
855 writel(prp->cfg.src_pixel, 925 return 0;
856 pcdev->base_emma + PRP_SRC_PIXEL_FORMAT_CNTL); 926}
927
928static struct vb2_ops mx2_videobuf_ops = {
929 .queue_setup = mx2_videobuf_setup,
930 .buf_prepare = mx2_videobuf_prepare,
931 .buf_queue = mx2_videobuf_queue,
932 .buf_cleanup = mx2_videobuf_release,
933 .start_streaming = mx2_start_streaming,
934 .stop_streaming = mx2_stop_streaming,
935};
936
937static int mx2_camera_init_videobuf(struct vb2_queue *q,
938 struct soc_camera_device *icd)
939{
940 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
941 q->io_modes = VB2_MMAP | VB2_USERPTR;
942 q->drv_priv = icd;
943 q->ops = &mx2_videobuf_ops;
944 q->mem_ops = &vb2_dma_contig_memops;
945 q->buf_struct_size = sizeof(struct mx2_buffer);
946
947 return vb2_queue_init(q);
948}
857 949
950#define MX2_BUS_FLAGS (V4L2_MBUS_MASTER | \
951 V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
952 V4L2_MBUS_VSYNC_ACTIVE_LOW | \
953 V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
954 V4L2_MBUS_HSYNC_ACTIVE_LOW | \
955 V4L2_MBUS_PCLK_SAMPLE_RISING | \
956 V4L2_MBUS_PCLK_SAMPLE_FALLING | \
957 V4L2_MBUS_DATA_ACTIVE_HIGH | \
958 V4L2_MBUS_DATA_ACTIVE_LOW)
959
960static int mx27_camera_emma_prp_reset(struct mx2_camera_dev *pcdev)
961{
962 u32 cntl;
963 int count = 0;
964
965 cntl = readl(pcdev->base_emma + PRP_CNTL);
966 writel(PRP_CNTL_SWRST, pcdev->base_emma + PRP_CNTL);
967 while (count++ < 100) {
968 if (!(readl(pcdev->base_emma + PRP_CNTL) & PRP_CNTL_SWRST))
969 return 0;
970 barrier();
971 udelay(1);
858 } 972 }
859 973
860 /* Enable interrupts */ 974 return -ETIMEDOUT;
861 writel(prp->cfg.irq_flags, pcdev->base_emma + PRP_INTR_CNTL);
862} 975}
863 976
864static int mx2_camera_set_bus_param(struct soc_camera_device *icd) 977static int mx2_camera_set_bus_param(struct soc_camera_device *icd)
@@ -939,31 +1052,10 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd)
939 if (bytesperline < 0) 1052 if (bytesperline < 0)
940 return bytesperline; 1053 return bytesperline;
941 1054
942 if (mx27_camera_emma(pcdev)) { 1055 if (cpu_is_mx27()) {
943 ret = mx27_camera_emma_prp_reset(pcdev); 1056 ret = mx27_camera_emma_prp_reset(pcdev);
944 if (ret) 1057 if (ret)
945 return ret; 1058 return ret;
946
947 if (pcdev->discard_buffer)
948 dma_free_coherent(ici->v4l2_dev.dev,
949 pcdev->discard_size, pcdev->discard_buffer,
950 pcdev->discard_buffer_dma);
951
952 /*
953 * I didn't manage to properly enable/disable the prp
954 * on a per frame basis during running transfers,
955 * thus we allocate a buffer here and use it to
956 * discard frames when no buffer is available.
957 * Feel free to work on this ;)
958 */
959 pcdev->discard_size = icd->user_height * bytesperline;
960 pcdev->discard_buffer = dma_alloc_coherent(ici->v4l2_dev.dev,
961 pcdev->discard_size, &pcdev->discard_buffer_dma,
962 GFP_KERNEL);
963 if (!pcdev->discard_buffer)
964 return -ENOMEM;
965
966 mx27_camera_emma_buf_init(icd, bytesperline);
967 } else if (cpu_is_mx25()) { 1059 } else if (cpu_is_mx25()) {
968 writel((bytesperline * icd->user_height) >> 2, 1060 writel((bytesperline * icd->user_height) >> 2,
969 pcdev->base_csi + CSIRXCNT); 1061 pcdev->base_csi + CSIRXCNT);
@@ -1052,6 +1144,123 @@ static int mx2_camera_get_formats(struct soc_camera_device *icd,
1052 return formats; 1144 return formats;
1053} 1145}
1054 1146
1147static int mx2_emmaprp_resize(struct mx2_camera_dev *pcdev,
1148 struct v4l2_mbus_framefmt *mf_in,
1149 struct v4l2_pix_format *pix_out, bool apply)
1150{
1151 int num, den;
1152 unsigned long m;
1153 int i, dir;
1154
1155 for (dir = RESIZE_DIR_H; dir <= RESIZE_DIR_V; dir++) {
1156 struct emma_prp_resize tmprsz;
1157 unsigned char *s = tmprsz.s;
1158 int len = 0;
1159 int in, out;
1160
1161 if (dir == RESIZE_DIR_H) {
1162 in = mf_in->width;
1163 out = pix_out->width;
1164 } else {
1165 in = mf_in->height;
1166 out = pix_out->height;
1167 }
1168
1169 if (in < out)
1170 return -EINVAL;
1171 else if (in == out)
1172 continue;
1173
1174 /* Calculate ratio */
1175 m = gcd(in, out);
1176 num = in / m;
1177 den = out / m;
1178 if (num > RESIZE_NUM_MAX)
1179 return -EINVAL;
1180
1181 if ((num >= 2 * den) && (den == 1) &&
1182 (num < 9) && (!(num & 0x01))) {
1183 int sum = 0;
1184 int j;
1185
1186 /* Average scaling for >= 2:1 ratios */
1187 /* Support can be added for num >=9 and odd values */
1188
1189 tmprsz.algo = RESIZE_ALGO_AVERAGING;
1190 len = num;
1191
1192 for (i = 0; i < (len / 2); i++)
1193 s[i] = 8;
1194
1195 do {
1196 for (i = 0; i < (len / 2); i++) {
1197 s[i] = s[i] >> 1;
1198 sum = 0;
1199 for (j = 0; j < (len / 2); j++)
1200 sum += s[j];
1201 if (sum == 4)
1202 break;
1203 }
1204 } while (sum != 4);
1205
1206 for (i = (len / 2); i < len; i++)
1207 s[i] = s[len - i - 1];
1208
1209 s[len - 1] |= SZ_COEF;
1210 } else {
1211 /* bilinear scaling for < 2:1 ratios */
1212 int v; /* overflow counter */
1213 int coeff, nxt; /* table output */
1214 int in_pos_inc = 2 * den;
1215 int out_pos = num;
1216 int out_pos_inc = 2 * num;
1217 int init_carry = num - den;
1218 int carry = init_carry;
1219
1220 tmprsz.algo = RESIZE_ALGO_BILINEAR;
1221 v = den + in_pos_inc;
1222 do {
1223 coeff = v - out_pos;
1224 out_pos += out_pos_inc;
1225 carry += out_pos_inc;
1226 for (nxt = 0; v < out_pos; nxt++) {
1227 v += in_pos_inc;
1228 carry -= in_pos_inc;
1229 }
1230
1231 if (len > RESIZE_NUM_MAX)
1232 return -EINVAL;
1233
1234 coeff = ((coeff << BC_COEF) +
1235 (in_pos_inc >> 1)) / in_pos_inc;
1236
1237 if (coeff >= (SZ_COEF - 1))
1238 coeff--;
1239
1240 coeff |= SZ_COEF;
1241 s[len] = (unsigned char)coeff;
1242 len++;
1243
1244 for (i = 1; i < nxt; i++) {
1245 if (len >= RESIZE_NUM_MAX)
1246 return -EINVAL;
1247 s[len] = 0;
1248 len++;
1249 }
1250 } while (carry != init_carry);
1251 }
1252 tmprsz.len = len;
1253 if (dir == RESIZE_DIR_H)
1254 mf_in->width = pix_out->width;
1255 else
1256 mf_in->height = pix_out->height;
1257
1258 if (apply)
1259 memcpy(&pcdev->resizing[dir], &tmprsz, sizeof(tmprsz));
1260 }
1261 return 0;
1262}
1263
1055static int mx2_camera_set_fmt(struct soc_camera_device *icd, 1264static int mx2_camera_set_fmt(struct soc_camera_device *icd,
1056 struct v4l2_format *f) 1265 struct v4l2_format *f)
1057{ 1266{
@@ -1063,6 +1272,9 @@ static int mx2_camera_set_fmt(struct soc_camera_device *icd,
1063 struct v4l2_mbus_framefmt mf; 1272 struct v4l2_mbus_framefmt mf;
1064 int ret; 1273 int ret;
1065 1274
1275 dev_dbg(icd->parent, "%s: requested params: width = %d, height = %d\n",
1276 __func__, pix->width, pix->height);
1277
1066 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); 1278 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1067 if (!xlate) { 1279 if (!xlate) {
1068 dev_warn(icd->parent, "Format %x not found\n", 1280 dev_warn(icd->parent, "Format %x not found\n",
@@ -1080,6 +1292,22 @@ static int mx2_camera_set_fmt(struct soc_camera_device *icd,
1080 if (ret < 0 && ret != -ENOIOCTLCMD) 1292 if (ret < 0 && ret != -ENOIOCTLCMD)
1081 return ret; 1293 return ret;
1082 1294
1295 /* Store width and height returned by the sensor for resizing */
1296 pcdev->s_width = mf.width;
1297 pcdev->s_height = mf.height;
1298 dev_dbg(icd->parent, "%s: sensor params: width = %d, height = %d\n",
1299 __func__, pcdev->s_width, pcdev->s_height);
1300
1301 pcdev->emma_prp = mx27_emma_prp_get_format(xlate->code,
1302 xlate->host_fmt->fourcc);
1303
1304 memset(pcdev->resizing, 0, sizeof(pcdev->resizing));
1305 if ((mf.width != pix->width || mf.height != pix->height) &&
1306 pcdev->emma_prp->cfg.in_fmt == PRP_CNTL_DATA_IN_YUV422) {
1307 if (mx2_emmaprp_resize(pcdev, &mf, pix, true) < 0)
1308 dev_dbg(icd->parent, "%s: can't resize\n", __func__);
1309 }
1310
1083 if (mf.code != xlate->code) 1311 if (mf.code != xlate->code)
1084 return -EINVAL; 1312 return -EINVAL;
1085 1313
@@ -1089,9 +1317,8 @@ static int mx2_camera_set_fmt(struct soc_camera_device *icd,
1089 pix->colorspace = mf.colorspace; 1317 pix->colorspace = mf.colorspace;
1090 icd->current_fmt = xlate; 1318 icd->current_fmt = xlate;
1091 1319
1092 if (mx27_camera_emma(pcdev)) 1320 dev_dbg(icd->parent, "%s: returned params: width = %d, height = %d\n",
1093 pcdev->emma_prp = mx27_emma_prp_get_format(xlate->code, 1321 __func__, pix->width, pix->height);
1094 xlate->host_fmt->fourcc);
1095 1322
1096 return 0; 1323 return 0;
1097} 1324}
@@ -1104,9 +1331,14 @@ static int mx2_camera_try_fmt(struct soc_camera_device *icd,
1104 struct v4l2_pix_format *pix = &f->fmt.pix; 1331 struct v4l2_pix_format *pix = &f->fmt.pix;
1105 struct v4l2_mbus_framefmt mf; 1332 struct v4l2_mbus_framefmt mf;
1106 __u32 pixfmt = pix->pixelformat; 1333 __u32 pixfmt = pix->pixelformat;
1334 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1335 struct mx2_camera_dev *pcdev = ici->priv;
1107 unsigned int width_limit; 1336 unsigned int width_limit;
1108 int ret; 1337 int ret;
1109 1338
1339 dev_dbg(icd->parent, "%s: requested params: width = %d, height = %d\n",
1340 __func__, pix->width, pix->height);
1341
1110 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 1342 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1111 if (pixfmt && !xlate) { 1343 if (pixfmt && !xlate) {
1112 dev_warn(icd->parent, "Format %x not found\n", pixfmt); 1344 dev_warn(icd->parent, "Format %x not found\n", pixfmt);
@@ -1156,6 +1388,20 @@ static int mx2_camera_try_fmt(struct soc_camera_device *icd,
1156 if (ret < 0) 1388 if (ret < 0)
1157 return ret; 1389 return ret;
1158 1390
1391 dev_dbg(icd->parent, "%s: sensor params: width = %d, height = %d\n",
1392 __func__, pcdev->s_width, pcdev->s_height);
1393
1394 /* If the sensor does not support image size try PrP resizing */
1395 pcdev->emma_prp = mx27_emma_prp_get_format(xlate->code,
1396 xlate->host_fmt->fourcc);
1397
1398 memset(pcdev->resizing, 0, sizeof(pcdev->resizing));
1399 if ((mf.width != pix->width || mf.height != pix->height) &&
1400 pcdev->emma_prp->cfg.in_fmt == PRP_CNTL_DATA_IN_YUV422) {
1401 if (mx2_emmaprp_resize(pcdev, &mf, pix, false) < 0)
1402 dev_dbg(icd->parent, "%s: can't resize\n", __func__);
1403 }
1404
1159 if (mf.field == V4L2_FIELD_ANY) 1405 if (mf.field == V4L2_FIELD_ANY)
1160 mf.field = V4L2_FIELD_NONE; 1406 mf.field = V4L2_FIELD_NONE;
1161 /* 1407 /*
@@ -1174,6 +1420,9 @@ static int mx2_camera_try_fmt(struct soc_camera_device *icd,
1174 pix->field = mf.field; 1420 pix->field = mf.field;
1175 pix->colorspace = mf.colorspace; 1421 pix->colorspace = mf.colorspace;
1176 1422
1423 dev_dbg(icd->parent, "%s: returned params: width = %d, height = %d\n",
1424 __func__, pix->width, pix->height);
1425
1177 return 0; 1426 return 0;
1178} 1427}
1179 1428
@@ -1187,136 +1436,11 @@ static int mx2_camera_querycap(struct soc_camera_host *ici,
1187 return 0; 1436 return 0;
1188} 1437}
1189 1438
1190static int mx2_camera_reqbufs(struct soc_camera_device *icd,
1191 struct v4l2_requestbuffers *p)
1192{
1193 int i;
1194
1195 for (i = 0; i < p->count; i++) {
1196 struct mx2_buffer *buf = container_of(icd->vb_vidq.bufs[i],
1197 struct mx2_buffer, vb);
1198 INIT_LIST_HEAD(&buf->vb.queue);
1199 }
1200
1201 return 0;
1202}
1203
1204#ifdef CONFIG_MACH_MX27
1205static void mx27_camera_frame_done(struct mx2_camera_dev *pcdev, int state)
1206{
1207 struct videobuf_buffer *vb;
1208 struct mx2_buffer *buf;
1209 unsigned long flags;
1210 int ret;
1211
1212 spin_lock_irqsave(&pcdev->lock, flags);
1213
1214 if (!pcdev->active) {
1215 dev_err(pcdev->dev, "%s called with no active buffer!\n",
1216 __func__);
1217 goto out;
1218 }
1219
1220 vb = &pcdev->active->vb;
1221 buf = container_of(vb, struct mx2_buffer, vb);
1222 WARN_ON(list_empty(&vb->queue));
1223 dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
1224 vb, vb->baddr, vb->bsize);
1225
1226 /* _init is used to debug races, see comment in pxa_camera_reqbufs() */
1227 list_del_init(&vb->queue);
1228 vb->state = state;
1229 do_gettimeofday(&vb->ts);
1230 vb->field_count++;
1231
1232 wake_up(&vb->done);
1233
1234 if (list_empty(&pcdev->capture)) {
1235 pcdev->active = NULL;
1236 goto out;
1237 }
1238
1239 pcdev->active = list_entry(pcdev->capture.next,
1240 struct mx2_buffer, vb.queue);
1241
1242 vb = &pcdev->active->vb;
1243 vb->state = VIDEOBUF_ACTIVE;
1244
1245 ret = imx_dma_setup_single(pcdev->dma, videobuf_to_dma_contig(vb),
1246 vb->size, (u32)pcdev->base_dma + 0x10, DMA_MODE_READ);
1247
1248 if (ret) {
1249 vb->state = VIDEOBUF_ERROR;
1250 pcdev->active = NULL;
1251 wake_up(&vb->done);
1252 }
1253
1254out:
1255 spin_unlock_irqrestore(&pcdev->lock, flags);
1256}
1257
1258static void mx27_camera_dma_err_callback(int channel, void *data, int err)
1259{
1260 struct mx2_camera_dev *pcdev = data;
1261
1262 mx27_camera_frame_done(pcdev, VIDEOBUF_ERROR);
1263}
1264
1265static void mx27_camera_dma_callback(int channel, void *data)
1266{
1267 struct mx2_camera_dev *pcdev = data;
1268
1269 mx27_camera_frame_done(pcdev, VIDEOBUF_DONE);
1270}
1271
1272#define DMA_REQ_CSI_RX 31 /* FIXME: Add this to a resource */
1273
1274static int __devinit mx27_camera_dma_init(struct platform_device *pdev,
1275 struct mx2_camera_dev *pcdev)
1276{
1277 int err;
1278
1279 pcdev->dma = imx_dma_request_by_prio("CSI RX DMA", DMA_PRIO_HIGH);
1280 if (pcdev->dma < 0) {
1281 dev_err(&pdev->dev, "%s failed to request DMA channel\n",
1282 __func__);
1283 return pcdev->dma;
1284 }
1285
1286 err = imx_dma_setup_handlers(pcdev->dma, mx27_camera_dma_callback,
1287 mx27_camera_dma_err_callback, pcdev);
1288 if (err) {
1289 dev_err(&pdev->dev, "%s failed to set DMA callback\n",
1290 __func__);
1291 goto err_out;
1292 }
1293
1294 err = imx_dma_config_channel(pcdev->dma,
1295 IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_FIFO,
1296 IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
1297 DMA_REQ_CSI_RX, 1);
1298 if (err) {
1299 dev_err(&pdev->dev, "%s failed to config DMA channel\n",
1300 __func__);
1301 goto err_out;
1302 }
1303
1304 imx_dma_config_burstlen(pcdev->dma, 64);
1305
1306 return 0;
1307
1308err_out:
1309 imx_dma_free(pcdev->dma);
1310
1311 return err;
1312}
1313#endif /* CONFIG_MACH_MX27 */
1314
1315static unsigned int mx2_camera_poll(struct file *file, poll_table *pt) 1439static unsigned int mx2_camera_poll(struct file *file, poll_table *pt)
1316{ 1440{
1317 struct soc_camera_device *icd = file->private_data; 1441 struct soc_camera_device *icd = file->private_data;
1318 1442
1319 return videobuf_poll_stream(file, &icd->vb_vidq, pt); 1443 return vb2_poll(&icd->vb2_vidq, file, pt);
1320} 1444}
1321 1445
1322static struct soc_camera_host_ops mx2_soc_camera_host_ops = { 1446static struct soc_camera_host_ops mx2_soc_camera_host_ops = {
@@ -1327,144 +1451,148 @@ static struct soc_camera_host_ops mx2_soc_camera_host_ops = {
1327 .set_crop = mx2_camera_set_crop, 1451 .set_crop = mx2_camera_set_crop,
1328 .get_formats = mx2_camera_get_formats, 1452 .get_formats = mx2_camera_get_formats,
1329 .try_fmt = mx2_camera_try_fmt, 1453 .try_fmt = mx2_camera_try_fmt,
1330 .init_videobuf = mx2_camera_init_videobuf, 1454 .init_videobuf2 = mx2_camera_init_videobuf,
1331 .reqbufs = mx2_camera_reqbufs,
1332 .poll = mx2_camera_poll, 1455 .poll = mx2_camera_poll,
1333 .querycap = mx2_camera_querycap, 1456 .querycap = mx2_camera_querycap,
1334 .set_bus_param = mx2_camera_set_bus_param, 1457 .set_bus_param = mx2_camera_set_bus_param,
1335}; 1458};
1336 1459
1337static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev, 1460static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev,
1338 int bufnum, int state) 1461 int bufnum, bool err)
1339{ 1462{
1340 u32 imgsize = pcdev->icd->user_height * pcdev->icd->user_width; 1463#ifdef DEBUG
1341 struct mx2_fmt_cfg *prp = pcdev->emma_prp; 1464 struct mx2_fmt_cfg *prp = pcdev->emma_prp;
1465#endif
1466 struct mx2_buf_internal *ibuf;
1342 struct mx2_buffer *buf; 1467 struct mx2_buffer *buf;
1343 struct videobuf_buffer *vb; 1468 struct vb2_buffer *vb;
1344 unsigned long phys; 1469 unsigned long phys;
1345 1470
1346 if (!list_empty(&pcdev->active_bufs)) { 1471 ibuf = list_first_entry(&pcdev->active_bufs, struct mx2_buf_internal,
1347 buf = list_entry(pcdev->active_bufs.next, 1472 queue);
1348 struct mx2_buffer, vb.queue); 1473
1474 BUG_ON(ibuf->bufnum != bufnum);
1349 1475
1350 BUG_ON(buf->bufnum != bufnum); 1476 if (ibuf->discard) {
1477 /*
1478 * Discard buffer must not be returned to user space.
1479 * Just return it to the discard queue.
1480 */
1481 list_move_tail(pcdev->active_bufs.next, &pcdev->discard);
1482 } else {
1483 buf = mx2_ibuf_to_buf(ibuf);
1351 1484
1352 vb = &buf->vb; 1485 vb = &buf->vb;
1353#ifdef DEBUG 1486#ifdef DEBUG
1354 phys = videobuf_to_dma_contig(vb); 1487 phys = vb2_dma_contig_plane_dma_addr(vb, 0);
1355 if (prp->cfg.channel == 1) { 1488 if (prp->cfg.channel == 1) {
1356 if (readl(pcdev->base_emma + PRP_DEST_RGB1_PTR + 1489 if (readl(pcdev->base_emma + PRP_DEST_RGB1_PTR +
1357 4 * bufnum) != phys) { 1490 4 * bufnum) != phys) {
1358 dev_err(pcdev->dev, "%p != %p\n", phys, 1491 dev_err(pcdev->dev, "%lx != %x\n", phys,
1359 readl(pcdev->base_emma + 1492 readl(pcdev->base_emma +
1360 PRP_DEST_RGB1_PTR + 1493 PRP_DEST_RGB1_PTR + 4 * bufnum));
1361 4 * bufnum));
1362 } 1494 }
1363 } else { 1495 } else {
1364 if (readl(pcdev->base_emma + PRP_DEST_Y_PTR - 1496 if (readl(pcdev->base_emma + PRP_DEST_Y_PTR -
1365 0x14 * bufnum) != phys) { 1497 0x14 * bufnum) != phys) {
1366 dev_err(pcdev->dev, "%p != %p\n", phys, 1498 dev_err(pcdev->dev, "%lx != %x\n", phys,
1367 readl(pcdev->base_emma + 1499 readl(pcdev->base_emma +
1368 PRP_DEST_Y_PTR - 1500 PRP_DEST_Y_PTR - 0x14 * bufnum));
1369 0x14 * bufnum));
1370 } 1501 }
1371 } 1502 }
1372#endif 1503#endif
1373 dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, vb, 1504 dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%p %lu\n", __func__, vb,
1374 vb->baddr, vb->bsize); 1505 vb2_plane_vaddr(vb, 0),
1506 vb2_get_plane_payload(vb, 0));
1375 1507
1376 list_del(&vb->queue); 1508 list_del_init(&buf->internal.queue);
1377 vb->state = state; 1509 do_gettimeofday(&vb->v4l2_buf.timestamp);
1378 do_gettimeofday(&vb->ts); 1510 vb->v4l2_buf.sequence = pcdev->frame_count;
1379 vb->field_count = pcdev->frame_count * 2; 1511 if (err)
1380 pcdev->frame_count++; 1512 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
1381 1513 else
1382 wake_up(&vb->done); 1514 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
1383 } 1515 }
1384 1516
1517 pcdev->frame_count++;
1518
1385 if (list_empty(&pcdev->capture)) { 1519 if (list_empty(&pcdev->capture)) {
1386 if (prp->cfg.channel == 1) { 1520 if (list_empty(&pcdev->discard)) {
1387 writel(pcdev->discard_buffer_dma, pcdev->base_emma + 1521 dev_warn(pcdev->dev, "%s: trying to access empty discard list\n",
1388 PRP_DEST_RGB1_PTR + 4 * bufnum); 1522 __func__);
1389 } else { 1523 return;
1390 writel(pcdev->discard_buffer_dma, pcdev->base_emma +
1391 PRP_DEST_Y_PTR -
1392 0x14 * bufnum);
1393 if (prp->out_fmt == V4L2_PIX_FMT_YUV420) {
1394 writel(pcdev->discard_buffer_dma + imgsize,
1395 pcdev->base_emma + PRP_DEST_CB_PTR -
1396 0x14 * bufnum);
1397 writel(pcdev->discard_buffer_dma +
1398 ((5 * imgsize) / 4), pcdev->base_emma +
1399 PRP_DEST_CR_PTR - 0x14 * bufnum);
1400 }
1401 } 1524 }
1525
1526 ibuf = list_first_entry(&pcdev->discard,
1527 struct mx2_buf_internal, queue);
1528 ibuf->bufnum = bufnum;
1529
1530 list_move_tail(pcdev->discard.next, &pcdev->active_bufs);
1531 mx27_update_emma_buf(pcdev, pcdev->discard_buffer_dma, bufnum);
1402 return; 1532 return;
1403 } 1533 }
1404 1534
1405 buf = list_entry(pcdev->capture.next, 1535 buf = list_first_entry(&pcdev->capture, struct mx2_buffer,
1406 struct mx2_buffer, vb.queue); 1536 internal.queue);
1407 1537
1408 buf->bufnum = !bufnum; 1538 buf->internal.bufnum = bufnum;
1409 1539
1410 list_move_tail(pcdev->capture.next, &pcdev->active_bufs); 1540 list_move_tail(pcdev->capture.next, &pcdev->active_bufs);
1411 1541
1412 vb = &buf->vb; 1542 vb = &buf->vb;
1413 vb->state = VIDEOBUF_ACTIVE; 1543 buf->state = MX2_STATE_ACTIVE;
1414 1544
1415 phys = videobuf_to_dma_contig(vb); 1545 phys = vb2_dma_contig_plane_dma_addr(vb, 0);
1416 if (prp->cfg.channel == 1) { 1546 mx27_update_emma_buf(pcdev, phys, bufnum);
1417 writel(phys, pcdev->base_emma + PRP_DEST_RGB1_PTR + 4 * bufnum);
1418 } else {
1419 writel(phys, pcdev->base_emma +
1420 PRP_DEST_Y_PTR - 0x14 * bufnum);
1421 if (prp->cfg.out_fmt == PRP_CNTL_CH2_OUT_YUV420) {
1422 writel(phys + imgsize, pcdev->base_emma +
1423 PRP_DEST_CB_PTR - 0x14 * bufnum);
1424 writel(phys + ((5 * imgsize) / 4), pcdev->base_emma +
1425 PRP_DEST_CR_PTR - 0x14 * bufnum);
1426 }
1427 }
1428} 1547}
1429 1548
1430static irqreturn_t mx27_camera_emma_irq(int irq_emma, void *data) 1549static irqreturn_t mx27_camera_emma_irq(int irq_emma, void *data)
1431{ 1550{
1432 struct mx2_camera_dev *pcdev = data; 1551 struct mx2_camera_dev *pcdev = data;
1433 unsigned int status = readl(pcdev->base_emma + PRP_INTRSTATUS); 1552 unsigned int status = readl(pcdev->base_emma + PRP_INTRSTATUS);
1434 struct mx2_buffer *buf; 1553 struct mx2_buf_internal *ibuf;
1554
1555 spin_lock(&pcdev->lock);
1556
1557 if (list_empty(&pcdev->active_bufs)) {
1558 dev_warn(pcdev->dev, "%s: called while active list is empty\n",
1559 __func__);
1560
1561 if (!status) {
1562 spin_unlock(&pcdev->lock);
1563 return IRQ_NONE;
1564 }
1565 }
1435 1566
1436 if (status & (1 << 7)) { /* overflow */ 1567 if (status & (1 << 7)) { /* overflow */
1437 u32 cntl; 1568 u32 cntl = readl(pcdev->base_emma + PRP_CNTL);
1438 /*
1439 * We only disable channel 1 here since this is the only
1440 * enabled channel
1441 *
1442 * FIXME: the correct DMA overflow handling should be resetting
1443 * the buffer, returning an error frame, and continuing with
1444 * the next one.
1445 */
1446 cntl = readl(pcdev->base_emma + PRP_CNTL);
1447 writel(cntl & ~(PRP_CNTL_CH1EN | PRP_CNTL_CH2EN), 1569 writel(cntl & ~(PRP_CNTL_CH1EN | PRP_CNTL_CH2EN),
1448 pcdev->base_emma + PRP_CNTL); 1570 pcdev->base_emma + PRP_CNTL);
1449 writel(cntl, pcdev->base_emma + PRP_CNTL); 1571 writel(cntl, pcdev->base_emma + PRP_CNTL);
1450 } 1572
1451 if ((((status & (3 << 5)) == (3 << 5)) || 1573 ibuf = list_first_entry(&pcdev->active_bufs,
1452 ((status & (3 << 3)) == (3 << 3))) 1574 struct mx2_buf_internal, queue);
1453 && !list_empty(&pcdev->active_bufs)) { 1575 mx27_camera_frame_done_emma(pcdev,
1576 ibuf->bufnum, true);
1577
1578 status &= ~(1 << 7);
1579 } else if (((status & (3 << 5)) == (3 << 5)) ||
1580 ((status & (3 << 3)) == (3 << 3))) {
1454 /* 1581 /*
1455 * Both buffers have triggered, process the one we're expecting 1582 * Both buffers have triggered, process the one we're expecting
1456 * to first 1583 * to first
1457 */ 1584 */
1458 buf = list_entry(pcdev->active_bufs.next, 1585 ibuf = list_first_entry(&pcdev->active_bufs,
1459 struct mx2_buffer, vb.queue); 1586 struct mx2_buf_internal, queue);
1460 mx27_camera_frame_done_emma(pcdev, buf->bufnum, VIDEOBUF_DONE); 1587 mx27_camera_frame_done_emma(pcdev, ibuf->bufnum, false);
1461 status &= ~(1 << (6 - buf->bufnum)); /* mark processed */ 1588 status &= ~(1 << (6 - ibuf->bufnum)); /* mark processed */
1589 } else if ((status & (1 << 6)) || (status & (1 << 4))) {
1590 mx27_camera_frame_done_emma(pcdev, 0, false);
1591 } else if ((status & (1 << 5)) || (status & (1 << 3))) {
1592 mx27_camera_frame_done_emma(pcdev, 1, false);
1462 } 1593 }
1463 if ((status & (1 << 6)) || (status & (1 << 4)))
1464 mx27_camera_frame_done_emma(pcdev, 0, VIDEOBUF_DONE);
1465 if ((status & (1 << 5)) || (status & (1 << 3)))
1466 mx27_camera_frame_done_emma(pcdev, 1, VIDEOBUF_DONE);
1467 1594
1595 spin_unlock(&pcdev->lock);
1468 writel(status, pcdev->base_emma + PRP_INTRSTATUS); 1596 writel(status, pcdev->base_emma + PRP_INTRSTATUS);
1469 1597
1470 return IRQ_HANDLED; 1598 return IRQ_HANDLED;
@@ -1527,8 +1655,6 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
1527 struct resource *res_csi, *res_emma; 1655 struct resource *res_csi, *res_emma;
1528 void __iomem *base_csi; 1656 void __iomem *base_csi;
1529 int irq_csi, irq_emma; 1657 int irq_csi, irq_emma;
1530 irq_handler_t mx2_cam_irq_handler = cpu_is_mx25() ? mx25_camera_irq
1531 : mx27_camera_irq;
1532 int err = 0; 1658 int err = 0;
1533 1659
1534 dev_dbg(&pdev->dev, "initialising\n"); 1660 dev_dbg(&pdev->dev, "initialising\n");
@@ -1550,22 +1676,11 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
1550 1676
1551 pcdev->clk_csi = clk_get(&pdev->dev, NULL); 1677 pcdev->clk_csi = clk_get(&pdev->dev, NULL);
1552 if (IS_ERR(pcdev->clk_csi)) { 1678 if (IS_ERR(pcdev->clk_csi)) {
1679 dev_err(&pdev->dev, "Could not get csi clock\n");
1553 err = PTR_ERR(pcdev->clk_csi); 1680 err = PTR_ERR(pcdev->clk_csi);
1554 goto exit_kfree; 1681 goto exit_kfree;
1555 } 1682 }
1556 1683
1557 dev_dbg(&pdev->dev, "Camera clock frequency: %ld\n",
1558 clk_get_rate(pcdev->clk_csi));
1559
1560 /* Initialize DMA */
1561#ifdef CONFIG_MACH_MX27
1562 if (cpu_is_mx27()) {
1563 err = mx27_camera_dma_init(pdev, pcdev);
1564 if (err)
1565 goto exit_clk_put;
1566 }
1567#endif /* CONFIG_MACH_MX27 */
1568
1569 pcdev->res_csi = res_csi; 1684 pcdev->res_csi = res_csi;
1570 pcdev->pdata = pdev->dev.platform_data; 1685 pcdev->pdata = pdev->dev.platform_data;
1571 if (pcdev->pdata) { 1686 if (pcdev->pdata) {
@@ -1585,6 +1700,7 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
1585 1700
1586 INIT_LIST_HEAD(&pcdev->capture); 1701 INIT_LIST_HEAD(&pcdev->capture);
1587 INIT_LIST_HEAD(&pcdev->active_bufs); 1702 INIT_LIST_HEAD(&pcdev->active_bufs);
1703 INIT_LIST_HEAD(&pcdev->discard);
1588 spin_lock_init(&pcdev->lock); 1704 spin_lock_init(&pcdev->lock);
1589 1705
1590 /* 1706 /*
@@ -1606,11 +1722,13 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
1606 pcdev->base_dma = res_csi->start; 1722 pcdev->base_dma = res_csi->start;
1607 pcdev->dev = &pdev->dev; 1723 pcdev->dev = &pdev->dev;
1608 1724
1609 err = request_irq(pcdev->irq_csi, mx2_cam_irq_handler, 0, 1725 if (cpu_is_mx25()) {
1610 MX2_CAM_DRV_NAME, pcdev); 1726 err = request_irq(pcdev->irq_csi, mx25_camera_irq, 0,
1611 if (err) { 1727 MX2_CAM_DRV_NAME, pcdev);
1612 dev_err(pcdev->dev, "Camera interrupt register failed \n"); 1728 if (err) {
1613 goto exit_iounmap; 1729 dev_err(pcdev->dev, "Camera interrupt register failed \n");
1730 goto exit_iounmap;
1731 }
1614 } 1732 }
1615 1733
1616 if (cpu_is_mx27()) { 1734 if (cpu_is_mx27()) {
@@ -1618,14 +1736,15 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
1618 res_emma = platform_get_resource(pdev, IORESOURCE_MEM, 1); 1736 res_emma = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1619 irq_emma = platform_get_irq(pdev, 1); 1737 irq_emma = platform_get_irq(pdev, 1);
1620 1738
1621 if (res_emma && irq_emma >= 0) { 1739 if (!res_emma || !irq_emma) {
1622 dev_info(&pdev->dev, "Using EMMA\n"); 1740 dev_err(&pdev->dev, "no EMMA resources\n");
1623 pcdev->use_emma = 1; 1741 goto exit_free_irq;
1624 pcdev->res_emma = res_emma;
1625 pcdev->irq_emma = irq_emma;
1626 if (mx27_camera_emma_init(pcdev))
1627 goto exit_free_irq;
1628 } 1742 }
1743
1744 pcdev->res_emma = res_emma;
1745 pcdev->irq_emma = irq_emma;
1746 if (mx27_camera_emma_init(pcdev))
1747 goto exit_free_irq;
1629 } 1748 }
1630 1749
1631 pcdev->soc_host.drv_name = MX2_CAM_DRV_NAME, 1750 pcdev->soc_host.drv_name = MX2_CAM_DRV_NAME,
@@ -1633,6 +1752,12 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
1633 pcdev->soc_host.priv = pcdev; 1752 pcdev->soc_host.priv = pcdev;
1634 pcdev->soc_host.v4l2_dev.dev = &pdev->dev; 1753 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
1635 pcdev->soc_host.nr = pdev->id; 1754 pcdev->soc_host.nr = pdev->id;
1755
1756 pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1757 if (IS_ERR(pcdev->alloc_ctx)) {
1758 err = PTR_ERR(pcdev->alloc_ctx);
1759 goto eallocctx;
1760 }
1636 err = soc_camera_host_register(&pcdev->soc_host); 1761 err = soc_camera_host_register(&pcdev->soc_host);
1637 if (err) 1762 if (err)
1638 goto exit_free_emma; 1763 goto exit_free_emma;
@@ -1643,26 +1768,24 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
1643 return 0; 1768 return 0;
1644 1769
1645exit_free_emma: 1770exit_free_emma:
1646 if (mx27_camera_emma(pcdev)) { 1771 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
1772eallocctx:
1773 if (cpu_is_mx27()) {
1647 free_irq(pcdev->irq_emma, pcdev); 1774 free_irq(pcdev->irq_emma, pcdev);
1648 clk_disable(pcdev->clk_emma); 1775 clk_disable(pcdev->clk_emma);
1649 clk_put(pcdev->clk_emma); 1776 clk_put(pcdev->clk_emma);
1650 iounmap(pcdev->base_emma); 1777 iounmap(pcdev->base_emma);
1651 release_mem_region(res_emma->start, resource_size(res_emma)); 1778 release_mem_region(pcdev->res_emma->start, resource_size(pcdev->res_emma));
1652 } 1779 }
1653exit_free_irq: 1780exit_free_irq:
1654 free_irq(pcdev->irq_csi, pcdev); 1781 if (cpu_is_mx25())
1782 free_irq(pcdev->irq_csi, pcdev);
1655exit_iounmap: 1783exit_iounmap:
1656 iounmap(base_csi); 1784 iounmap(base_csi);
1657exit_release: 1785exit_release:
1658 release_mem_region(res_csi->start, resource_size(res_csi)); 1786 release_mem_region(res_csi->start, resource_size(res_csi));
1659exit_dma_free: 1787exit_dma_free:
1660#ifdef CONFIG_MACH_MX27
1661 if (cpu_is_mx27())
1662 imx_dma_free(pcdev->dma);
1663exit_clk_put:
1664 clk_put(pcdev->clk_csi); 1788 clk_put(pcdev->clk_csi);
1665#endif /* CONFIG_MACH_MX27 */
1666exit_kfree: 1789exit_kfree:
1667 kfree(pcdev); 1790 kfree(pcdev);
1668exit: 1791exit:
@@ -1677,19 +1800,18 @@ static int __devexit mx2_camera_remove(struct platform_device *pdev)
1677 struct resource *res; 1800 struct resource *res;
1678 1801
1679 clk_put(pcdev->clk_csi); 1802 clk_put(pcdev->clk_csi);
1680#ifdef CONFIG_MACH_MX27 1803 if (cpu_is_mx25())
1804 free_irq(pcdev->irq_csi, pcdev);
1681 if (cpu_is_mx27()) 1805 if (cpu_is_mx27())
1682 imx_dma_free(pcdev->dma);
1683#endif /* CONFIG_MACH_MX27 */
1684 free_irq(pcdev->irq_csi, pcdev);
1685 if (mx27_camera_emma(pcdev))
1686 free_irq(pcdev->irq_emma, pcdev); 1806 free_irq(pcdev->irq_emma, pcdev);
1687 1807
1688 soc_camera_host_unregister(&pcdev->soc_host); 1808 soc_camera_host_unregister(&pcdev->soc_host);
1689 1809
1810 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
1811
1690 iounmap(pcdev->base_csi); 1812 iounmap(pcdev->base_csi);
1691 1813
1692 if (mx27_camera_emma(pcdev)) { 1814 if (cpu_is_mx27()) {
1693 clk_disable(pcdev->clk_emma); 1815 clk_disable(pcdev->clk_emma);
1694 clk_put(pcdev->clk_emma); 1816 clk_put(pcdev->clk_emma);
1695 iounmap(pcdev->base_emma); 1817 iounmap(pcdev->base_emma);
diff --git a/drivers/media/video/mx2_emmaprp.c b/drivers/media/video/mx2_emmaprp.c
new file mode 100644
index 000000000000..ba89a7401c8c
--- /dev/null
+++ b/drivers/media/video/mx2_emmaprp.c
@@ -0,0 +1,1008 @@
1/*
2 * Support eMMa-PrP through mem2mem framework.
3 *
4 * eMMa-PrP is a piece of HW that allows fetching buffers
5 * from one memory location and do several operations on
6 * them such as scaling or format conversion giving, as a result
7 * a new processed buffer in another memory location.
8 *
9 * Based on mem2mem_testdev.c by Pawel Osciak.
10 *
11 * Copyright (c) 2011 Vista Silicon S.L.
12 * Javier Martin <javier.martin@vista-silicon.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version
18 */
19#include <linux/module.h>
20#include <linux/clk.h>
21#include <linux/slab.h>
22#include <linux/interrupt.h>
23#include <linux/io.h>
24
25#include <linux/platform_device.h>
26#include <media/v4l2-mem2mem.h>
27#include <media/v4l2-device.h>
28#include <media/v4l2-ioctl.h>
29#include <media/videobuf2-dma-contig.h>
30#include <asm/sizes.h>
31
32#define EMMAPRP_MODULE_NAME "mem2mem-emmaprp"
33
34MODULE_DESCRIPTION("Mem-to-mem device which supports eMMa-PrP present in mx2 SoCs");
35MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com");
36MODULE_LICENSE("GPL");
37MODULE_VERSION("0.0.1");
38
39static bool debug;
40module_param(debug, bool, 0644);
41
42#define MIN_W 32
43#define MIN_H 32
44#define MAX_W 2040
45#define MAX_H 2046
46
47#define S_ALIGN 1 /* multiple of 2 */
48#define W_ALIGN_YUV420 3 /* multiple of 8 */
49#define W_ALIGN_OTHERS 2 /* multiple of 4 */
50#define H_ALIGN 1 /* multiple of 2 */
51
52/* Flags that indicate a format can be used for capture/output */
53#define MEM2MEM_CAPTURE (1 << 0)
54#define MEM2MEM_OUTPUT (1 << 1)
55
56#define MEM2MEM_NAME "m2m-emmaprp"
57
58/* In bytes, per queue */
59#define MEM2MEM_VID_MEM_LIMIT SZ_16M
60
61#define dprintk(dev, fmt, arg...) \
62 v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)
63
64/* EMMA PrP */
65#define PRP_CNTL 0x00
66#define PRP_INTR_CNTL 0x04
67#define PRP_INTRSTATUS 0x08
68#define PRP_SOURCE_Y_PTR 0x0c
69#define PRP_SOURCE_CB_PTR 0x10
70#define PRP_SOURCE_CR_PTR 0x14
71#define PRP_DEST_RGB1_PTR 0x18
72#define PRP_DEST_RGB2_PTR 0x1c
73#define PRP_DEST_Y_PTR 0x20
74#define PRP_DEST_CB_PTR 0x24
75#define PRP_DEST_CR_PTR 0x28
76#define PRP_SRC_FRAME_SIZE 0x2c
77#define PRP_DEST_CH1_LINE_STRIDE 0x30
78#define PRP_SRC_PIXEL_FORMAT_CNTL 0x34
79#define PRP_CH1_PIXEL_FORMAT_CNTL 0x38
80#define PRP_CH1_OUT_IMAGE_SIZE 0x3c
81#define PRP_CH2_OUT_IMAGE_SIZE 0x40
82#define PRP_SRC_LINE_STRIDE 0x44
83#define PRP_CSC_COEF_012 0x48
84#define PRP_CSC_COEF_345 0x4c
85#define PRP_CSC_COEF_678 0x50
86#define PRP_CH1_RZ_HORI_COEF1 0x54
87#define PRP_CH1_RZ_HORI_COEF2 0x58
88#define PRP_CH1_RZ_HORI_VALID 0x5c
89#define PRP_CH1_RZ_VERT_COEF1 0x60
90#define PRP_CH1_RZ_VERT_COEF2 0x64
91#define PRP_CH1_RZ_VERT_VALID 0x68
92#define PRP_CH2_RZ_HORI_COEF1 0x6c
93#define PRP_CH2_RZ_HORI_COEF2 0x70
94#define PRP_CH2_RZ_HORI_VALID 0x74
95#define PRP_CH2_RZ_VERT_COEF1 0x78
96#define PRP_CH2_RZ_VERT_COEF2 0x7c
97#define PRP_CH2_RZ_VERT_VALID 0x80
98
99#define PRP_CNTL_CH1EN (1 << 0)
100#define PRP_CNTL_CH2EN (1 << 1)
101#define PRP_CNTL_CSIEN (1 << 2)
102#define PRP_CNTL_DATA_IN_YUV420 (0 << 3)
103#define PRP_CNTL_DATA_IN_YUV422 (1 << 3)
104#define PRP_CNTL_DATA_IN_RGB16 (2 << 3)
105#define PRP_CNTL_DATA_IN_RGB32 (3 << 3)
106#define PRP_CNTL_CH1_OUT_RGB8 (0 << 5)
107#define PRP_CNTL_CH1_OUT_RGB16 (1 << 5)
108#define PRP_CNTL_CH1_OUT_RGB32 (2 << 5)
109#define PRP_CNTL_CH1_OUT_YUV422 (3 << 5)
110#define PRP_CNTL_CH2_OUT_YUV420 (0 << 7)
111#define PRP_CNTL_CH2_OUT_YUV422 (1 << 7)
112#define PRP_CNTL_CH2_OUT_YUV444 (2 << 7)
113#define PRP_CNTL_CH1_LEN (1 << 9)
114#define PRP_CNTL_CH2_LEN (1 << 10)
115#define PRP_CNTL_SKIP_FRAME (1 << 11)
116#define PRP_CNTL_SWRST (1 << 12)
117#define PRP_CNTL_CLKEN (1 << 13)
118#define PRP_CNTL_WEN (1 << 14)
119#define PRP_CNTL_CH1BYP (1 << 15)
120#define PRP_CNTL_IN_TSKIP(x) ((x) << 16)
121#define PRP_CNTL_CH1_TSKIP(x) ((x) << 19)
122#define PRP_CNTL_CH2_TSKIP(x) ((x) << 22)
123#define PRP_CNTL_INPUT_FIFO_LEVEL(x) ((x) << 25)
124#define PRP_CNTL_RZ_FIFO_LEVEL(x) ((x) << 27)
125#define PRP_CNTL_CH2B1EN (1 << 29)
126#define PRP_CNTL_CH2B2EN (1 << 30)
127#define PRP_CNTL_CH2FEN (1 << 31)
128
129#define PRP_SIZE_HEIGHT(x) (x)
130#define PRP_SIZE_WIDTH(x) ((x) << 16)
131
132/* IRQ Enable and status register */
133#define PRP_INTR_RDERR (1 << 0)
134#define PRP_INTR_CH1WERR (1 << 1)
135#define PRP_INTR_CH2WERR (1 << 2)
136#define PRP_INTR_CH1FC (1 << 3)
137#define PRP_INTR_CH2FC (1 << 5)
138#define PRP_INTR_LBOVF (1 << 7)
139#define PRP_INTR_CH2OVF (1 << 8)
140
141#define PRP_INTR_ST_RDERR (1 << 0)
142#define PRP_INTR_ST_CH1WERR (1 << 1)
143#define PRP_INTR_ST_CH2WERR (1 << 2)
144#define PRP_INTR_ST_CH2B2CI (1 << 3)
145#define PRP_INTR_ST_CH2B1CI (1 << 4)
146#define PRP_INTR_ST_CH1B2CI (1 << 5)
147#define PRP_INTR_ST_CH1B1CI (1 << 6)
148#define PRP_INTR_ST_LBOVF (1 << 7)
149#define PRP_INTR_ST_CH2OVF (1 << 8)
150
151struct emmaprp_fmt {
152 char *name;
153 u32 fourcc;
154 /* Types the format can be used for */
155 u32 types;
156};
157
158static struct emmaprp_fmt formats[] = {
159 {
160 .name = "YUV 4:2:0 Planar",
161 .fourcc = V4L2_PIX_FMT_YUV420,
162 .types = MEM2MEM_CAPTURE,
163 },
164 {
165 .name = "4:2:2, packed, YUYV",
166 .fourcc = V4L2_PIX_FMT_YUYV,
167 .types = MEM2MEM_OUTPUT,
168 },
169};
170
171/* Per-queue, driver-specific private data */
172struct emmaprp_q_data {
173 unsigned int width;
174 unsigned int height;
175 unsigned int sizeimage;
176 struct emmaprp_fmt *fmt;
177};
178
179enum {
180 V4L2_M2M_SRC = 0,
181 V4L2_M2M_DST = 1,
182};
183
184#define NUM_FORMATS ARRAY_SIZE(formats)
185
186static struct emmaprp_fmt *find_format(struct v4l2_format *f)
187{
188 struct emmaprp_fmt *fmt;
189 unsigned int k;
190
191 for (k = 0; k < NUM_FORMATS; k++) {
192 fmt = &formats[k];
193 if (fmt->fourcc == f->fmt.pix.pixelformat)
194 break;
195 }
196
197 if (k == NUM_FORMATS)
198 return NULL;
199
200 return &formats[k];
201}
202
203struct emmaprp_dev {
204 struct v4l2_device v4l2_dev;
205 struct video_device *vfd;
206
207 struct mutex dev_mutex;
208 spinlock_t irqlock;
209
210 int irq_emma;
211 void __iomem *base_emma;
212 struct clk *clk_emma;
213 struct resource *res_emma;
214
215 struct v4l2_m2m_dev *m2m_dev;
216 struct vb2_alloc_ctx *alloc_ctx;
217};
218
219struct emmaprp_ctx {
220 struct emmaprp_dev *dev;
221 /* Abort requested by m2m */
222 int aborting;
223 struct emmaprp_q_data q_data[2];
224 struct v4l2_m2m_ctx *m2m_ctx;
225};
226
227static struct emmaprp_q_data *get_q_data(struct emmaprp_ctx *ctx,
228 enum v4l2_buf_type type)
229{
230 switch (type) {
231 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
232 return &(ctx->q_data[V4L2_M2M_SRC]);
233 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
234 return &(ctx->q_data[V4L2_M2M_DST]);
235 default:
236 BUG();
237 }
238 return NULL;
239}
240
241/*
242 * mem2mem callbacks
243 */
244static void emmaprp_job_abort(void *priv)
245{
246 struct emmaprp_ctx *ctx = priv;
247 struct emmaprp_dev *pcdev = ctx->dev;
248
249 ctx->aborting = 1;
250
251 dprintk(pcdev, "Aborting task\n");
252
253 v4l2_m2m_job_finish(pcdev->m2m_dev, ctx->m2m_ctx);
254}
255
256static void emmaprp_lock(void *priv)
257{
258 struct emmaprp_ctx *ctx = priv;
259 struct emmaprp_dev *pcdev = ctx->dev;
260 mutex_lock(&pcdev->dev_mutex);
261}
262
263static void emmaprp_unlock(void *priv)
264{
265 struct emmaprp_ctx *ctx = priv;
266 struct emmaprp_dev *pcdev = ctx->dev;
267 mutex_unlock(&pcdev->dev_mutex);
268}
269
270static inline void emmaprp_dump_regs(struct emmaprp_dev *pcdev)
271{
272 dprintk(pcdev,
273 "eMMa-PrP Registers:\n"
274 " SOURCE_Y_PTR = 0x%08X\n"
275 " SRC_FRAME_SIZE = 0x%08X\n"
276 " DEST_Y_PTR = 0x%08X\n"
277 " DEST_CR_PTR = 0x%08X\n"
278 " DEST_CB_PTR = 0x%08X\n"
279 " CH2_OUT_IMAGE_SIZE = 0x%08X\n"
280 " CNTL = 0x%08X\n",
281 readl(pcdev->base_emma + PRP_SOURCE_Y_PTR),
282 readl(pcdev->base_emma + PRP_SRC_FRAME_SIZE),
283 readl(pcdev->base_emma + PRP_DEST_Y_PTR),
284 readl(pcdev->base_emma + PRP_DEST_CR_PTR),
285 readl(pcdev->base_emma + PRP_DEST_CB_PTR),
286 readl(pcdev->base_emma + PRP_CH2_OUT_IMAGE_SIZE),
287 readl(pcdev->base_emma + PRP_CNTL));
288}
289
290static void emmaprp_device_run(void *priv)
291{
292 struct emmaprp_ctx *ctx = priv;
293 struct emmaprp_q_data *s_q_data, *d_q_data;
294 struct vb2_buffer *src_buf, *dst_buf;
295 struct emmaprp_dev *pcdev = ctx->dev;
296 unsigned int s_width, s_height;
297 unsigned int d_width, d_height;
298 unsigned int d_size;
299 dma_addr_t p_in, p_out;
300 u32 tmp;
301
302 src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
303 dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
304
305 s_q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
306 s_width = s_q_data->width;
307 s_height = s_q_data->height;
308
309 d_q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
310 d_width = d_q_data->width;
311 d_height = d_q_data->height;
312 d_size = d_width * d_height;
313
314 p_in = vb2_dma_contig_plane_dma_addr(src_buf, 0);
315 p_out = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
316 if (!p_in || !p_out) {
317 v4l2_err(&pcdev->v4l2_dev,
318 "Acquiring kernel pointers to buffers failed\n");
319 return;
320 }
321
322 /* Input frame parameters */
323 writel(p_in, pcdev->base_emma + PRP_SOURCE_Y_PTR);
324 writel(PRP_SIZE_WIDTH(s_width) | PRP_SIZE_HEIGHT(s_height),
325 pcdev->base_emma + PRP_SRC_FRAME_SIZE);
326
327 /* Output frame parameters */
328 writel(p_out, pcdev->base_emma + PRP_DEST_Y_PTR);
329 writel(p_out + d_size, pcdev->base_emma + PRP_DEST_CB_PTR);
330 writel(p_out + d_size + (d_size >> 2),
331 pcdev->base_emma + PRP_DEST_CR_PTR);
332 writel(PRP_SIZE_WIDTH(d_width) | PRP_SIZE_HEIGHT(d_height),
333 pcdev->base_emma + PRP_CH2_OUT_IMAGE_SIZE);
334
335 /* IRQ configuration */
336 tmp = readl(pcdev->base_emma + PRP_INTR_CNTL);
337 writel(tmp | PRP_INTR_RDERR |
338 PRP_INTR_CH2WERR |
339 PRP_INTR_CH2FC,
340 pcdev->base_emma + PRP_INTR_CNTL);
341
342 emmaprp_dump_regs(pcdev);
343
344 /* Enable transfer */
345 tmp = readl(pcdev->base_emma + PRP_CNTL);
346 writel(tmp | PRP_CNTL_CH2_OUT_YUV420 |
347 PRP_CNTL_DATA_IN_YUV422 |
348 PRP_CNTL_CH2EN,
349 pcdev->base_emma + PRP_CNTL);
350}
351
352static irqreturn_t emmaprp_irq(int irq_emma, void *data)
353{
354 struct emmaprp_dev *pcdev = data;
355 struct emmaprp_ctx *curr_ctx;
356 struct vb2_buffer *src_vb, *dst_vb;
357 unsigned long flags;
358 u32 irqst;
359
360 /* Check irq flags and clear irq */
361 irqst = readl(pcdev->base_emma + PRP_INTRSTATUS);
362 writel(irqst, pcdev->base_emma + PRP_INTRSTATUS);
363 dprintk(pcdev, "irqst = 0x%08x\n", irqst);
364
365 curr_ctx = v4l2_m2m_get_curr_priv(pcdev->m2m_dev);
366 if (curr_ctx == NULL) {
367 pr_err("Instance released before the end of transaction\n");
368 return IRQ_HANDLED;
369 }
370
371 if (!curr_ctx->aborting) {
372 if ((irqst & PRP_INTR_ST_RDERR) ||
373 (irqst & PRP_INTR_ST_CH2WERR)) {
374 pr_err("PrP bus error ocurred, this transfer is probably corrupted\n");
375 writel(PRP_CNTL_SWRST, pcdev->base_emma + PRP_CNTL);
376 } else if (irqst & PRP_INTR_ST_CH2B1CI) { /* buffer ready */
377 src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
378 dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
379
380 spin_lock_irqsave(&pcdev->irqlock, flags);
381 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
382 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
383 spin_unlock_irqrestore(&pcdev->irqlock, flags);
384 }
385 }
386
387 v4l2_m2m_job_finish(pcdev->m2m_dev, curr_ctx->m2m_ctx);
388 return IRQ_HANDLED;
389}
390
391/*
392 * video ioctls
393 */
394static int vidioc_querycap(struct file *file, void *priv,
395 struct v4l2_capability *cap)
396{
397 strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1);
398 strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1);
399 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT
400 | V4L2_CAP_STREAMING;
401
402 return 0;
403}
404
405static int enum_fmt(struct v4l2_fmtdesc *f, u32 type)
406{
407 int i, num;
408 struct emmaprp_fmt *fmt;
409
410 num = 0;
411
412 for (i = 0; i < NUM_FORMATS; ++i) {
413 if (formats[i].types & type) {
414 /* index-th format of type type found ? */
415 if (num == f->index)
416 break;
417 /* Correct type but haven't reached our index yet,
418 * just increment per-type index */
419 ++num;
420 }
421 }
422
423 if (i < NUM_FORMATS) {
424 /* Format found */
425 fmt = &formats[i];
426 strlcpy(f->description, fmt->name, sizeof(f->description) - 1);
427 f->pixelformat = fmt->fourcc;
428 return 0;
429 }
430
431 /* Format not found */
432 return -EINVAL;
433}
434
435static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
436 struct v4l2_fmtdesc *f)
437{
438 return enum_fmt(f, MEM2MEM_CAPTURE);
439}
440
441static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
442 struct v4l2_fmtdesc *f)
443{
444 return enum_fmt(f, MEM2MEM_OUTPUT);
445}
446
447static int vidioc_g_fmt(struct emmaprp_ctx *ctx, struct v4l2_format *f)
448{
449 struct vb2_queue *vq;
450 struct emmaprp_q_data *q_data;
451
452 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
453 if (!vq)
454 return -EINVAL;
455
456 q_data = get_q_data(ctx, f->type);
457
458 f->fmt.pix.width = q_data->width;
459 f->fmt.pix.height = q_data->height;
460 f->fmt.pix.field = V4L2_FIELD_NONE;
461 f->fmt.pix.pixelformat = q_data->fmt->fourcc;
462 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
463 f->fmt.pix.bytesperline = q_data->width * 3 / 2;
464 else /* YUYV */
465 f->fmt.pix.bytesperline = q_data->width * 2;
466 f->fmt.pix.sizeimage = q_data->sizeimage;
467
468 return 0;
469}
470
471static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
472 struct v4l2_format *f)
473{
474 return vidioc_g_fmt(priv, f);
475}
476
477static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
478 struct v4l2_format *f)
479{
480 return vidioc_g_fmt(priv, f);
481}
482
483static int vidioc_try_fmt(struct v4l2_format *f)
484{
485 enum v4l2_field field;
486
487
488 if (!find_format(f))
489 return -EINVAL;
490
491 field = f->fmt.pix.field;
492 if (field == V4L2_FIELD_ANY)
493 field = V4L2_FIELD_NONE;
494 else if (V4L2_FIELD_NONE != field)
495 return -EINVAL;
496
497 /* V4L2 specification suggests the driver corrects the format struct
498 * if any of the dimensions is unsupported */
499 f->fmt.pix.field = field;
500
501 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420) {
502 v4l_bound_align_image(&f->fmt.pix.width, MIN_W, MAX_W,
503 W_ALIGN_YUV420, &f->fmt.pix.height,
504 MIN_H, MAX_H, H_ALIGN, S_ALIGN);
505 f->fmt.pix.bytesperline = f->fmt.pix.width * 3 / 2;
506 } else {
507 v4l_bound_align_image(&f->fmt.pix.width, MIN_W, MAX_W,
508 W_ALIGN_OTHERS, &f->fmt.pix.height,
509 MIN_H, MAX_H, H_ALIGN, S_ALIGN);
510 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
511 }
512 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
513
514 return 0;
515}
516
517static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
518 struct v4l2_format *f)
519{
520 struct emmaprp_fmt *fmt;
521 struct emmaprp_ctx *ctx = priv;
522
523 fmt = find_format(f);
524 if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) {
525 v4l2_err(&ctx->dev->v4l2_dev,
526 "Fourcc format (0x%08x) invalid.\n",
527 f->fmt.pix.pixelformat);
528 return -EINVAL;
529 }
530
531 return vidioc_try_fmt(f);
532}
533
534static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
535 struct v4l2_format *f)
536{
537 struct emmaprp_fmt *fmt;
538 struct emmaprp_ctx *ctx = priv;
539
540 fmt = find_format(f);
541 if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) {
542 v4l2_err(&ctx->dev->v4l2_dev,
543 "Fourcc format (0x%08x) invalid.\n",
544 f->fmt.pix.pixelformat);
545 return -EINVAL;
546 }
547
548 return vidioc_try_fmt(f);
549}
550
551static int vidioc_s_fmt(struct emmaprp_ctx *ctx, struct v4l2_format *f)
552{
553 struct emmaprp_q_data *q_data;
554 struct vb2_queue *vq;
555 int ret;
556
557 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
558 if (!vq)
559 return -EINVAL;
560
561 q_data = get_q_data(ctx, f->type);
562 if (!q_data)
563 return -EINVAL;
564
565 if (vb2_is_busy(vq)) {
566 v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__);
567 return -EBUSY;
568 }
569
570 ret = vidioc_try_fmt(f);
571 if (ret)
572 return ret;
573
574 q_data->fmt = find_format(f);
575 q_data->width = f->fmt.pix.width;
576 q_data->height = f->fmt.pix.height;
577 if (q_data->fmt->fourcc == V4L2_PIX_FMT_YUV420)
578 q_data->sizeimage = q_data->width * q_data->height * 3 / 2;
579 else /* YUYV */
580 q_data->sizeimage = q_data->width * q_data->height * 2;
581
582 dprintk(ctx->dev,
583 "Setting format for type %d, wxh: %dx%d, fmt: %d\n",
584 f->type, q_data->width, q_data->height, q_data->fmt->fourcc);
585
586 return 0;
587}
588
589static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
590 struct v4l2_format *f)
591{
592 int ret;
593
594 ret = vidioc_try_fmt_vid_cap(file, priv, f);
595 if (ret)
596 return ret;
597
598 return vidioc_s_fmt(priv, f);
599}
600
601static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
602 struct v4l2_format *f)
603{
604 int ret;
605
606 ret = vidioc_try_fmt_vid_out(file, priv, f);
607 if (ret)
608 return ret;
609
610 return vidioc_s_fmt(priv, f);
611}
612
613static int vidioc_reqbufs(struct file *file, void *priv,
614 struct v4l2_requestbuffers *reqbufs)
615{
616 struct emmaprp_ctx *ctx = priv;
617
618 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
619}
620
621static int vidioc_querybuf(struct file *file, void *priv,
622 struct v4l2_buffer *buf)
623{
624 struct emmaprp_ctx *ctx = priv;
625
626 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
627}
628
629static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
630{
631 struct emmaprp_ctx *ctx = priv;
632
633 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
634}
635
636static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
637{
638 struct emmaprp_ctx *ctx = priv;
639
640 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
641}
642
643static int vidioc_streamon(struct file *file, void *priv,
644 enum v4l2_buf_type type)
645{
646 struct emmaprp_ctx *ctx = priv;
647
648 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
649}
650
651static int vidioc_streamoff(struct file *file, void *priv,
652 enum v4l2_buf_type type)
653{
654 struct emmaprp_ctx *ctx = priv;
655
656 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
657}
658
659static const struct v4l2_ioctl_ops emmaprp_ioctl_ops = {
660 .vidioc_querycap = vidioc_querycap,
661
662 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
663 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
664 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
665 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
666
667 .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
668 .vidioc_g_fmt_vid_out = vidioc_g_fmt_vid_out,
669 .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out,
670 .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out,
671
672 .vidioc_reqbufs = vidioc_reqbufs,
673 .vidioc_querybuf = vidioc_querybuf,
674
675 .vidioc_qbuf = vidioc_qbuf,
676 .vidioc_dqbuf = vidioc_dqbuf,
677
678 .vidioc_streamon = vidioc_streamon,
679 .vidioc_streamoff = vidioc_streamoff,
680};
681
682
683/*
684 * Queue operations
685 */
686static int emmaprp_queue_setup(struct vb2_queue *vq,
687 const struct v4l2_format *fmt,
688 unsigned int *nbuffers, unsigned int *nplanes,
689 unsigned int sizes[], void *alloc_ctxs[])
690{
691 struct emmaprp_ctx *ctx = vb2_get_drv_priv(vq);
692 struct emmaprp_q_data *q_data;
693 unsigned int size, count = *nbuffers;
694
695 q_data = get_q_data(ctx, vq->type);
696
697 if (q_data->fmt->fourcc == V4L2_PIX_FMT_YUV420)
698 size = q_data->width * q_data->height * 3 / 2;
699 else
700 size = q_data->width * q_data->height * 2;
701
702 while (size * count > MEM2MEM_VID_MEM_LIMIT)
703 (count)--;
704
705 *nplanes = 1;
706 *nbuffers = count;
707 sizes[0] = size;
708
709 alloc_ctxs[0] = ctx->dev->alloc_ctx;
710
711 dprintk(ctx->dev, "get %d buffer(s) of size %d each.\n", count, size);
712
713 return 0;
714}
715
716static int emmaprp_buf_prepare(struct vb2_buffer *vb)
717{
718 struct emmaprp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
719 struct emmaprp_q_data *q_data;
720
721 dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type);
722
723 q_data = get_q_data(ctx, vb->vb2_queue->type);
724
725 if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
726 dprintk(ctx->dev, "%s data will not fit into plane"
727 "(%lu < %lu)\n", __func__,
728 vb2_plane_size(vb, 0),
729 (long)q_data->sizeimage);
730 return -EINVAL;
731 }
732
733 vb2_set_plane_payload(vb, 0, q_data->sizeimage);
734
735 return 0;
736}
737
738static void emmaprp_buf_queue(struct vb2_buffer *vb)
739{
740 struct emmaprp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
741 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
742}
743
744static struct vb2_ops emmaprp_qops = {
745 .queue_setup = emmaprp_queue_setup,
746 .buf_prepare = emmaprp_buf_prepare,
747 .buf_queue = emmaprp_buf_queue,
748};
749
750static int queue_init(void *priv, struct vb2_queue *src_vq,
751 struct vb2_queue *dst_vq)
752{
753 struct emmaprp_ctx *ctx = priv;
754 int ret;
755
756 memset(src_vq, 0, sizeof(*src_vq));
757 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
758 src_vq->io_modes = VB2_MMAP;
759 src_vq->drv_priv = ctx;
760 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
761 src_vq->ops = &emmaprp_qops;
762 src_vq->mem_ops = &vb2_dma_contig_memops;
763
764 ret = vb2_queue_init(src_vq);
765 if (ret)
766 return ret;
767
768 memset(dst_vq, 0, sizeof(*dst_vq));
769 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
770 dst_vq->io_modes = VB2_MMAP;
771 dst_vq->drv_priv = ctx;
772 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
773 dst_vq->ops = &emmaprp_qops;
774 dst_vq->mem_ops = &vb2_dma_contig_memops;
775
776 return vb2_queue_init(dst_vq);
777}
778
779/*
780 * File operations
781 */
782static int emmaprp_open(struct file *file)
783{
784 struct emmaprp_dev *pcdev = video_drvdata(file);
785 struct emmaprp_ctx *ctx;
786
787 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
788 if (!ctx)
789 return -ENOMEM;
790
791 file->private_data = ctx;
792 ctx->dev = pcdev;
793
794 ctx->m2m_ctx = v4l2_m2m_ctx_init(pcdev->m2m_dev, ctx, &queue_init);
795
796 if (IS_ERR(ctx->m2m_ctx)) {
797 int ret = PTR_ERR(ctx->m2m_ctx);
798
799 kfree(ctx);
800 return ret;
801 }
802
803 clk_enable(pcdev->clk_emma);
804 ctx->q_data[V4L2_M2M_SRC].fmt = &formats[1];
805 ctx->q_data[V4L2_M2M_DST].fmt = &formats[0];
806
807 dprintk(pcdev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->m2m_ctx);
808
809 return 0;
810}
811
812static int emmaprp_release(struct file *file)
813{
814 struct emmaprp_dev *pcdev = video_drvdata(file);
815 struct emmaprp_ctx *ctx = file->private_data;
816
817 dprintk(pcdev, "Releasing instance %p\n", ctx);
818
819 clk_disable(pcdev->clk_emma);
820 v4l2_m2m_ctx_release(ctx->m2m_ctx);
821 kfree(ctx);
822
823 return 0;
824}
825
826static unsigned int emmaprp_poll(struct file *file,
827 struct poll_table_struct *wait)
828{
829 struct emmaprp_ctx *ctx = file->private_data;
830
831 return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
832}
833
834static int emmaprp_mmap(struct file *file, struct vm_area_struct *vma)
835{
836 struct emmaprp_ctx *ctx = file->private_data;
837
838 return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
839}
840
841static const struct v4l2_file_operations emmaprp_fops = {
842 .owner = THIS_MODULE,
843 .open = emmaprp_open,
844 .release = emmaprp_release,
845 .poll = emmaprp_poll,
846 .unlocked_ioctl = video_ioctl2,
847 .mmap = emmaprp_mmap,
848};
849
850static struct video_device emmaprp_videodev = {
851 .name = MEM2MEM_NAME,
852 .fops = &emmaprp_fops,
853 .ioctl_ops = &emmaprp_ioctl_ops,
854 .minor = -1,
855 .release = video_device_release,
856};
857
858static struct v4l2_m2m_ops m2m_ops = {
859 .device_run = emmaprp_device_run,
860 .job_abort = emmaprp_job_abort,
861 .lock = emmaprp_lock,
862 .unlock = emmaprp_unlock,
863};
864
865static int emmaprp_probe(struct platform_device *pdev)
866{
867 struct emmaprp_dev *pcdev;
868 struct video_device *vfd;
869 struct resource *res_emma;
870 int irq_emma;
871 int ret;
872
873 pcdev = kzalloc(sizeof *pcdev, GFP_KERNEL);
874 if (!pcdev)
875 return -ENOMEM;
876
877 spin_lock_init(&pcdev->irqlock);
878
879 pcdev->clk_emma = clk_get(&pdev->dev, NULL);
880 if (IS_ERR(pcdev->clk_emma)) {
881 ret = PTR_ERR(pcdev->clk_emma);
882 goto free_dev;
883 }
884
885 irq_emma = platform_get_irq(pdev, 0);
886 res_emma = platform_get_resource(pdev, IORESOURCE_MEM, 0);
887 if (irq_emma < 0 || res_emma == NULL) {
888 dev_err(&pdev->dev, "Missing platform resources data\n");
889 ret = -ENODEV;
890 goto free_clk;
891 }
892
893 ret = v4l2_device_register(&pdev->dev, &pcdev->v4l2_dev);
894 if (ret)
895 goto free_clk;
896
897 mutex_init(&pcdev->dev_mutex);
898
899 vfd = video_device_alloc();
900 if (!vfd) {
901 v4l2_err(&pcdev->v4l2_dev, "Failed to allocate video device\n");
902 ret = -ENOMEM;
903 goto unreg_dev;
904 }
905
906 *vfd = emmaprp_videodev;
907 vfd->lock = &pcdev->dev_mutex;
908
909 video_set_drvdata(vfd, pcdev);
910 snprintf(vfd->name, sizeof(vfd->name), "%s", emmaprp_videodev.name);
911 pcdev->vfd = vfd;
912 v4l2_info(&pcdev->v4l2_dev, EMMAPRP_MODULE_NAME
913 " Device registered as /dev/video%d\n", vfd->num);
914
915 platform_set_drvdata(pdev, pcdev);
916
917 if (devm_request_mem_region(&pdev->dev, res_emma->start,
918 resource_size(res_emma), MEM2MEM_NAME) == NULL)
919 goto rel_vdev;
920
921 pcdev->base_emma = devm_ioremap(&pdev->dev, res_emma->start,
922 resource_size(res_emma));
923 if (!pcdev->base_emma)
924 goto rel_vdev;
925
926 pcdev->irq_emma = irq_emma;
927 pcdev->res_emma = res_emma;
928
929 if (devm_request_irq(&pdev->dev, pcdev->irq_emma, emmaprp_irq,
930 0, MEM2MEM_NAME, pcdev) < 0)
931 goto rel_vdev;
932
933 pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
934 if (IS_ERR(pcdev->alloc_ctx)) {
935 v4l2_err(&pcdev->v4l2_dev, "Failed to alloc vb2 context\n");
936 ret = PTR_ERR(pcdev->alloc_ctx);
937 goto rel_vdev;
938 }
939
940 pcdev->m2m_dev = v4l2_m2m_init(&m2m_ops);
941 if (IS_ERR(pcdev->m2m_dev)) {
942 v4l2_err(&pcdev->v4l2_dev, "Failed to init mem2mem device\n");
943 ret = PTR_ERR(pcdev->m2m_dev);
944 goto rel_ctx;
945 }
946
947 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
948 if (ret) {
949 v4l2_err(&pcdev->v4l2_dev, "Failed to register video device\n");
950 goto rel_m2m;
951 }
952
953 return 0;
954
955
956rel_m2m:
957 v4l2_m2m_release(pcdev->m2m_dev);
958rel_ctx:
959 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
960rel_vdev:
961 video_device_release(vfd);
962unreg_dev:
963 v4l2_device_unregister(&pcdev->v4l2_dev);
964free_clk:
965 clk_put(pcdev->clk_emma);
966free_dev:
967 kfree(pcdev);
968
969 return ret;
970}
971
972static int emmaprp_remove(struct platform_device *pdev)
973{
974 struct emmaprp_dev *pcdev = platform_get_drvdata(pdev);
975
976 v4l2_info(&pcdev->v4l2_dev, "Removing " EMMAPRP_MODULE_NAME);
977
978 video_unregister_device(pcdev->vfd);
979 v4l2_m2m_release(pcdev->m2m_dev);
980 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
981 v4l2_device_unregister(&pcdev->v4l2_dev);
982 clk_put(pcdev->clk_emma);
983 kfree(pcdev);
984
985 return 0;
986}
987
988static struct platform_driver emmaprp_pdrv = {
989 .probe = emmaprp_probe,
990 .remove = emmaprp_remove,
991 .driver = {
992 .name = MEM2MEM_NAME,
993 .owner = THIS_MODULE,
994 },
995};
996
997static void __exit emmaprp_exit(void)
998{
999 platform_driver_unregister(&emmaprp_pdrv);
1000}
1001
1002static int __init emmaprp_init(void)
1003{
1004 return platform_driver_register(&emmaprp_pdrv);
1005}
1006
1007module_init(emmaprp_init);
1008module_exit(emmaprp_exit);
diff --git a/drivers/media/video/noon010pc30.c b/drivers/media/video/noon010pc30.c
index 50838bf84204..440c12962bae 100644
--- a/drivers/media/video/noon010pc30.c
+++ b/drivers/media/video/noon010pc30.c
@@ -725,8 +725,8 @@ static int noon010_probe(struct i2c_client *client,
725 725
726 mutex_init(&info->lock); 726 mutex_init(&info->lock);
727 sd = &info->sd; 727 sd = &info->sd;
728 strlcpy(sd->name, MODULE_NAME, sizeof(sd->name));
729 v4l2_i2c_subdev_init(sd, client, &noon010_ops); 728 v4l2_i2c_subdev_init(sd, client, &noon010_ops);
729 strlcpy(sd->name, MODULE_NAME, sizeof(sd->name));
730 730
731 sd->internal_ops = &noon010_subdev_internal_ops; 731 sd->internal_ops = &noon010_subdev_internal_ops;
732 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 732 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
@@ -844,18 +844,7 @@ static struct i2c_driver noon010_i2c_driver = {
844 .id_table = noon010_id, 844 .id_table = noon010_id,
845}; 845};
846 846
847static int __init noon010_init(void) 847module_i2c_driver(noon010_i2c_driver);
848{
849 return i2c_add_driver(&noon010_i2c_driver);
850}
851
852static void __exit noon010_exit(void)
853{
854 i2c_del_driver(&noon010_i2c_driver);
855}
856
857module_init(noon010_init);
858module_exit(noon010_exit);
859 848
860MODULE_DESCRIPTION("Siliconfile NOON010PC30 camera driver"); 849MODULE_DESCRIPTION("Siliconfile NOON010PC30 camera driver");
861MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>"); 850MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index 1fb7d5bd5ec2..88cf9d952631 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -2268,13 +2268,12 @@ static struct platform_driver omap_vout_driver = {
2268 .driver = { 2268 .driver = {
2269 .name = VOUT_NAME, 2269 .name = VOUT_NAME,
2270 }, 2270 },
2271 .probe = omap_vout_probe,
2272 .remove = omap_vout_remove, 2271 .remove = omap_vout_remove,
2273}; 2272};
2274 2273
2275static int __init omap_vout_init(void) 2274static int __init omap_vout_init(void)
2276{ 2275{
2277 if (platform_driver_register(&omap_vout_driver) != 0) { 2276 if (platform_driver_probe(&omap_vout_driver, omap_vout_probe) != 0) {
2278 printk(KERN_ERR VOUT_NAME ":Could not register Video driver\n"); 2277 printk(KERN_ERR VOUT_NAME ":Could not register Video driver\n");
2279 return -EINVAL; 2278 return -EINVAL;
2280 } 2279 }
diff --git a/drivers/media/video/ov2640.c b/drivers/media/video/ov2640.c
index b5247cb64fde..3c2c5d3bcc6b 100644
--- a/drivers/media/video/ov2640.c
+++ b/drivers/media/video/ov2640.c
@@ -1103,21 +1103,7 @@ static struct i2c_driver ov2640_i2c_driver = {
1103 .id_table = ov2640_id, 1103 .id_table = ov2640_id,
1104}; 1104};
1105 1105
1106/* 1106module_i2c_driver(ov2640_i2c_driver);
1107 * Module functions
1108 */
1109static int __init ov2640_module_init(void)
1110{
1111 return i2c_add_driver(&ov2640_i2c_driver);
1112}
1113
1114static void __exit ov2640_module_exit(void)
1115{
1116 i2c_del_driver(&ov2640_i2c_driver);
1117}
1118
1119module_init(ov2640_module_init);
1120module_exit(ov2640_module_exit);
1121 1107
1122MODULE_DESCRIPTION("SoC Camera driver for Omni Vision 2640 sensor"); 1108MODULE_DESCRIPTION("SoC Camera driver for Omni Vision 2640 sensor");
1123MODULE_AUTHOR("Alberto Panizzo"); 1109MODULE_AUTHOR("Alberto Panizzo");
diff --git a/drivers/media/video/ov5642.c b/drivers/media/video/ov5642.c
index bb37ec80f274..80e07794ac8e 100644
--- a/drivers/media/video/ov5642.c
+++ b/drivers/media/video/ov5642.c
@@ -1068,18 +1068,7 @@ static struct i2c_driver ov5642_i2c_driver = {
1068 .id_table = ov5642_id, 1068 .id_table = ov5642_id,
1069}; 1069};
1070 1070
1071static int __init ov5642_mod_init(void) 1071module_i2c_driver(ov5642_i2c_driver);
1072{
1073 return i2c_add_driver(&ov5642_i2c_driver);
1074}
1075
1076static void __exit ov5642_mod_exit(void)
1077{
1078 i2c_del_driver(&ov5642_i2c_driver);
1079}
1080
1081module_init(ov5642_mod_init);
1082module_exit(ov5642_mod_exit);
1083 1072
1084MODULE_DESCRIPTION("Omnivision OV5642 Camera driver"); 1073MODULE_DESCRIPTION("Omnivision OV5642 Camera driver");
1085MODULE_AUTHOR("Bastian Hecht <hechtb@gmail.com>"); 1074MODULE_AUTHOR("Bastian Hecht <hechtb@gmail.com>");
diff --git a/drivers/media/video/ov6650.c b/drivers/media/video/ov6650.c
index 3627f3225bbb..3e028b1970dd 100644
--- a/drivers/media/video/ov6650.c
+++ b/drivers/media/video/ov6650.c
@@ -1046,18 +1046,7 @@ static struct i2c_driver ov6650_i2c_driver = {
1046 .id_table = ov6650_id, 1046 .id_table = ov6650_id,
1047}; 1047};
1048 1048
1049static int __init ov6650_module_init(void) 1049module_i2c_driver(ov6650_i2c_driver);
1050{
1051 return i2c_add_driver(&ov6650_i2c_driver);
1052}
1053
1054static void __exit ov6650_module_exit(void)
1055{
1056 i2c_del_driver(&ov6650_i2c_driver);
1057}
1058
1059module_init(ov6650_module_init);
1060module_exit(ov6650_module_exit);
1061 1050
1062MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV6650"); 1051MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV6650");
1063MODULE_AUTHOR("Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>"); 1052MODULE_AUTHOR("Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>");
diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index 6a564964853a..e7c82b297514 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -1583,15 +1583,4 @@ static struct i2c_driver ov7670_driver = {
1583 .id_table = ov7670_id, 1583 .id_table = ov7670_id,
1584}; 1584};
1585 1585
1586static __init int init_ov7670(void) 1586module_i2c_driver(ov7670_driver);
1587{
1588 return i2c_add_driver(&ov7670_driver);
1589}
1590
1591static __exit void exit_ov7670(void)
1592{
1593 i2c_del_driver(&ov7670_driver);
1594}
1595
1596module_init(init_ov7670);
1597module_exit(exit_ov7670);
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index 9f6ce3d8a29e..74e77d327ed8 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -1123,22 +1123,7 @@ static struct i2c_driver ov772x_i2c_driver = {
1123 .id_table = ov772x_id, 1123 .id_table = ov772x_id,
1124}; 1124};
1125 1125
1126/* 1126module_i2c_driver(ov772x_i2c_driver);
1127 * module function
1128 */
1129
1130static int __init ov772x_module_init(void)
1131{
1132 return i2c_add_driver(&ov772x_i2c_driver);
1133}
1134
1135static void __exit ov772x_module_exit(void)
1136{
1137 i2c_del_driver(&ov772x_i2c_driver);
1138}
1139
1140module_init(ov772x_module_init);
1141module_exit(ov772x_module_exit);
1142 1127
1143MODULE_DESCRIPTION("SoC Camera driver for ov772x"); 1128MODULE_DESCRIPTION("SoC Camera driver for ov772x");
1144MODULE_AUTHOR("Kuninori Morimoto"); 1129MODULE_AUTHOR("Kuninori Morimoto");
diff --git a/drivers/media/video/ov9640.c b/drivers/media/video/ov9640.c
index a4f99797eb56..23412debb36b 100644
--- a/drivers/media/video/ov9640.c
+++ b/drivers/media/video/ov9640.c
@@ -738,18 +738,7 @@ static struct i2c_driver ov9640_i2c_driver = {
738 .id_table = ov9640_id, 738 .id_table = ov9640_id,
739}; 739};
740 740
741static int __init ov9640_module_init(void) 741module_i2c_driver(ov9640_i2c_driver);
742{
743 return i2c_add_driver(&ov9640_i2c_driver);
744}
745
746static void __exit ov9640_module_exit(void)
747{
748 i2c_del_driver(&ov9640_i2c_driver);
749}
750
751module_init(ov9640_module_init);
752module_exit(ov9640_module_exit);
753 742
754MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV96xx"); 743MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV96xx");
755MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>"); 744MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
diff --git a/drivers/media/video/ov9740.c b/drivers/media/video/ov9740.c
index d9a9f7174f7a..3eb07c22516e 100644
--- a/drivers/media/video/ov9740.c
+++ b/drivers/media/video/ov9740.c
@@ -998,18 +998,7 @@ static struct i2c_driver ov9740_i2c_driver = {
998 .id_table = ov9740_id, 998 .id_table = ov9740_id,
999}; 999};
1000 1000
1001static int __init ov9740_module_init(void) 1001module_i2c_driver(ov9740_i2c_driver);
1002{
1003 return i2c_add_driver(&ov9740_i2c_driver);
1004}
1005
1006static void __exit ov9740_module_exit(void)
1007{
1008 i2c_del_driver(&ov9740_i2c_driver);
1009}
1010
1011module_init(ov9740_module_init);
1012module_exit(ov9740_module_exit);
1013 1002
1014MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV9740"); 1003MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV9740");
1015MODULE_AUTHOR("Andrew Chew <achew@nvidia.com>"); 1004MODULE_AUTHOR("Andrew Chew <achew@nvidia.com>");
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index c6da8f77e1a2..d8c898278e8c 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -320,7 +320,17 @@ static struct tda829x_config tda829x_no_probe = {
320 .probe_tuner = TDA829X_DONT_PROBE, 320 .probe_tuner = TDA829X_DONT_PROBE,
321}; 321};
322 322
323static struct tda18271_std_map hauppauge_tda18271_dvbt_std_map = {
324 .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4,
325 .if_lvl = 1, .rfagc_top = 0x37, },
326 .dvbt_7 = { .if_freq = 3800, .agc_mode = 3, .std = 5,
327 .if_lvl = 1, .rfagc_top = 0x37, },
328 .dvbt_8 = { .if_freq = 4300, .agc_mode = 3, .std = 6,
329 .if_lvl = 1, .rfagc_top = 0x37, },
330};
331
323static struct tda18271_config hauppauge_tda18271_dvb_config = { 332static struct tda18271_config hauppauge_tda18271_dvb_config = {
333 .std_map = &hauppauge_tda18271_dvbt_std_map,
324 .gate = TDA18271_GATE_ANALOG, 334 .gate = TDA18271_GATE_ANALOG,
325 .output_opt = TDA18271_OUTPUT_LT_OFF, 335 .output_opt = TDA18271_OUTPUT_LT_OFF,
326}; 336};
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 6d666174dbb4..e1111d968a3d 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -96,7 +96,6 @@ static struct v4l2_capability pvr_capability ={
96 .capabilities = (V4L2_CAP_VIDEO_CAPTURE | 96 .capabilities = (V4L2_CAP_VIDEO_CAPTURE |
97 V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | 97 V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
98 V4L2_CAP_READWRITE), 98 V4L2_CAP_READWRITE),
99 .reserved = {0,0,0,0}
100}; 99};
101 100
102static struct v4l2_fmtdesc pvr_fmtdesc [] = { 101static struct v4l2_fmtdesc pvr_fmtdesc [] = {
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index f495eeb5403a..2834e3e65b39 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -1146,14 +1146,6 @@ leave:
1146 return ret; 1146 return ret;
1147} 1147}
1148 1148
1149static int pwc_log_status(struct file *file, void *priv)
1150{
1151 struct pwc_device *pdev = video_drvdata(file);
1152
1153 v4l2_ctrl_handler_log_status(&pdev->ctrl_handler, PWC_NAME);
1154 return 0;
1155}
1156
1157const struct v4l2_ioctl_ops pwc_ioctl_ops = { 1149const struct v4l2_ioctl_ops pwc_ioctl_ops = {
1158 .vidioc_querycap = pwc_querycap, 1150 .vidioc_querycap = pwc_querycap,
1159 .vidioc_enum_input = pwc_enum_input, 1151 .vidioc_enum_input = pwc_enum_input,
@@ -1169,7 +1161,7 @@ const struct v4l2_ioctl_ops pwc_ioctl_ops = {
1169 .vidioc_dqbuf = pwc_dqbuf, 1161 .vidioc_dqbuf = pwc_dqbuf,
1170 .vidioc_streamon = pwc_streamon, 1162 .vidioc_streamon = pwc_streamon,
1171 .vidioc_streamoff = pwc_streamoff, 1163 .vidioc_streamoff = pwc_streamoff,
1172 .vidioc_log_status = pwc_log_status, 1164 .vidioc_log_status = v4l2_ctrl_log_status,
1173 .vidioc_enum_framesizes = pwc_enum_framesizes, 1165 .vidioc_enum_framesizes = pwc_enum_framesizes,
1174 .vidioc_enum_frameintervals = pwc_enum_frameintervals, 1166 .vidioc_enum_frameintervals = pwc_enum_frameintervals,
1175 .vidioc_g_parm = pwc_g_parm, 1167 .vidioc_g_parm = pwc_g_parm,
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 0bd7da26d018..5a413f4427e0 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -921,12 +921,12 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
921 /* "Safe default" - 13MHz */ 921 /* "Safe default" - 13MHz */
922 recalculate_fifo_timeout(pcdev, 13000000); 922 recalculate_fifo_timeout(pcdev, 13000000);
923 923
924 clk_enable(pcdev->clk); 924 clk_prepare_enable(pcdev->clk);
925} 925}
926 926
927static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev) 927static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev)
928{ 928{
929 clk_disable(pcdev->clk); 929 clk_disable_unprepare(pcdev->clk);
930} 930}
931 931
932static irqreturn_t pxa_camera_irq(int irq, void *data) 932static irqreturn_t pxa_camera_irq(int irq, void *data)
diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c
index 9937386a3bae..f6419b22c258 100644
--- a/drivers/media/video/rj54n1cb0c.c
+++ b/drivers/media/video/rj54n1cb0c.c
@@ -1407,18 +1407,7 @@ static struct i2c_driver rj54n1_i2c_driver = {
1407 .id_table = rj54n1_id, 1407 .id_table = rj54n1_id,
1408}; 1408};
1409 1409
1410static int __init rj54n1_mod_init(void) 1410module_i2c_driver(rj54n1_i2c_driver);
1411{
1412 return i2c_add_driver(&rj54n1_i2c_driver);
1413}
1414
1415static void __exit rj54n1_mod_exit(void)
1416{
1417 i2c_del_driver(&rj54n1_i2c_driver);
1418}
1419
1420module_init(rj54n1_mod_init);
1421module_exit(rj54n1_mod_exit);
1422 1411
1423MODULE_DESCRIPTION("Sharp RJ54N1CB0C Camera driver"); 1412MODULE_DESCRIPTION("Sharp RJ54N1CB0C Camera driver");
1424MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); 1413MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index c1bef6187661..4894cbb1c547 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -134,7 +134,7 @@
134 134
135/* usb config commands */ 135/* usb config commands */
136#define IN_DATA_TOKEN cpu_to_le32(0x2255c0de) 136#define IN_DATA_TOKEN cpu_to_le32(0x2255c0de)
137#define CMD_2255 cpu_to_le32(0xc2255000) 137#define CMD_2255 0xc2255000
138#define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10)) 138#define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10))
139#define CMD_START cpu_to_le32((CMD_2255 | 0x20)) 139#define CMD_START cpu_to_le32((CMD_2255 | 0x20))
140#define CMD_STOP cpu_to_le32((CMD_2255 | 0x30)) 140#define CMD_STOP cpu_to_le32((CMD_2255 | 0x30))
@@ -852,15 +852,13 @@ static int vidioc_querycap(struct file *file, void *priv,
852static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, 852static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
853 struct v4l2_fmtdesc *f) 853 struct v4l2_fmtdesc *f)
854{ 854{
855 int index = 0; 855 int index = f->index;
856 if (f)
857 index = f->index;
858 856
859 if (index >= ARRAY_SIZE(formats)) 857 if (index >= ARRAY_SIZE(formats))
860 return -EINVAL; 858 return -EINVAL;
861 if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) || 859 if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
862 (formats[index].fourcc == V4L2_PIX_FMT_MJPEG))) 860 (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
863 return -EINVAL; 861 return -EINVAL;
864 dprintk(4, "name %s\n", formats[index].name); 862 dprintk(4, "name %s\n", formats[index].name);
865 strlcpy(f->description, formats[index].name, sizeof(f->description)); 863 strlcpy(f->description, formats[index].name, sizeof(f->description));
866 f->pixelformat = formats[index].fourcc; 864 f->pixelformat = formats[index].fourcc;
@@ -2027,7 +2025,7 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
2027 pdata[1]); 2025 pdata[1]);
2028 offset = jj + PREFIX_SIZE; 2026 offset = jj + PREFIX_SIZE;
2029 bframe = 1; 2027 bframe = 1;
2030 cc = pdword[1]; 2028 cc = le32_to_cpu(pdword[1]);
2031 if (cc >= MAX_CHANNELS) { 2029 if (cc >= MAX_CHANNELS) {
2032 printk(KERN_ERR 2030 printk(KERN_ERR
2033 "bad channel\n"); 2031 "bad channel\n");
@@ -2036,22 +2034,22 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
2036 /* reverse it */ 2034 /* reverse it */
2037 dev->cc = G_chnmap[cc]; 2035 dev->cc = G_chnmap[cc];
2038 channel = &dev->channel[dev->cc]; 2036 channel = &dev->channel[dev->cc];
2039 payload = pdword[3]; 2037 payload = le32_to_cpu(pdword[3]);
2040 if (payload > channel->req_image_size) { 2038 if (payload > channel->req_image_size) {
2041 channel->bad_payload++; 2039 channel->bad_payload++;
2042 /* discard the bad frame */ 2040 /* discard the bad frame */
2043 return -EINVAL; 2041 return -EINVAL;
2044 } 2042 }
2045 channel->pkt_size = payload; 2043 channel->pkt_size = payload;
2046 channel->jpg_size = pdword[4]; 2044 channel->jpg_size = le32_to_cpu(pdword[4]);
2047 break; 2045 break;
2048 case S2255_MARKER_RESPONSE: 2046 case S2255_MARKER_RESPONSE:
2049 2047
2050 pdata += DEF_USB_BLOCK; 2048 pdata += DEF_USB_BLOCK;
2051 jj += DEF_USB_BLOCK; 2049 jj += DEF_USB_BLOCK;
2052 if (pdword[1] >= MAX_CHANNELS) 2050 if (le32_to_cpu(pdword[1]) >= MAX_CHANNELS)
2053 break; 2051 break;
2054 cc = G_chnmap[pdword[1]]; 2052 cc = G_chnmap[le32_to_cpu(pdword[1])];
2055 if (cc >= MAX_CHANNELS) 2053 if (cc >= MAX_CHANNELS)
2056 break; 2054 break;
2057 channel = &dev->channel[cc]; 2055 channel = &dev->channel[cc];
@@ -2074,11 +2072,11 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
2074 wake_up(&dev->fw_data->wait_fw); 2072 wake_up(&dev->fw_data->wait_fw);
2075 break; 2073 break;
2076 case S2255_RESPONSE_STATUS: 2074 case S2255_RESPONSE_STATUS:
2077 channel->vidstatus = pdword[3]; 2075 channel->vidstatus = le32_to_cpu(pdword[3]);
2078 channel->vidstatus_ready = 1; 2076 channel->vidstatus_ready = 1;
2079 wake_up(&channel->wait_vidstatus); 2077 wake_up(&channel->wait_vidstatus);
2080 dprintk(5, "got vidstatus %x chan %d\n", 2078 dprintk(5, "got vidstatus %x chan %d\n",
2081 pdword[3], cc); 2079 le32_to_cpu(pdword[3]), cc);
2082 break; 2080 break;
2083 default: 2081 default:
2084 printk(KERN_INFO "s2255 unknown resp\n"); 2082 printk(KERN_INFO "s2255 unknown resp\n");
@@ -2605,10 +2603,11 @@ static int s2255_probe(struct usb_interface *interface,
2605 __le32 *pRel; 2603 __le32 *pRel;
2606 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4]; 2604 pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
2607 printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel); 2605 printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel);
2608 dev->dsp_fw_ver = *pRel; 2606 dev->dsp_fw_ver = le32_to_cpu(*pRel);
2609 if (*pRel < S2255_CUR_DSP_FWVER) 2607 if (dev->dsp_fw_ver < S2255_CUR_DSP_FWVER)
2610 printk(KERN_INFO "s2255: f2255usb.bin out of date.\n"); 2608 printk(KERN_INFO "s2255: f2255usb.bin out of date.\n");
2611 if (dev->pid == 0x2257 && *pRel < S2255_MIN_DSP_COLORFILTER) 2609 if (dev->pid == 0x2257 &&
2610 dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
2612 printk(KERN_WARNING "s2255: 2257 requires firmware %d" 2611 printk(KERN_WARNING "s2255: 2257 requires firmware %d"
2613 " or above.\n", S2255_MIN_DSP_COLORFILTER); 2612 " or above.\n", S2255_MIN_DSP_COLORFILTER);
2614 } 2613 }
diff --git a/drivers/media/video/s5k6aa.c b/drivers/media/video/s5k6aa.c
index 0df7f2a41814..6625e46a4638 100644
--- a/drivers/media/video/s5k6aa.c
+++ b/drivers/media/video/s5k6aa.c
@@ -1582,8 +1582,8 @@ static int s5k6aa_probe(struct i2c_client *client,
1582 s5k6aa->inv_vflip = pdata->vert_flip; 1582 s5k6aa->inv_vflip = pdata->vert_flip;
1583 1583
1584 sd = &s5k6aa->sd; 1584 sd = &s5k6aa->sd;
1585 strlcpy(sd->name, DRIVER_NAME, sizeof(sd->name));
1586 v4l2_i2c_subdev_init(sd, client, &s5k6aa_subdev_ops); 1585 v4l2_i2c_subdev_init(sd, client, &s5k6aa_subdev_ops);
1586 strlcpy(sd->name, DRIVER_NAME, sizeof(sd->name));
1587 1587
1588 sd->internal_ops = &s5k6aa_subdev_internal_ops; 1588 sd->internal_ops = &s5k6aa_subdev_internal_ops;
1589 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 1589 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
@@ -1663,18 +1663,7 @@ static struct i2c_driver s5k6aa_i2c_driver = {
1663 .id_table = s5k6aa_id, 1663 .id_table = s5k6aa_id,
1664}; 1664};
1665 1665
1666static int __init s5k6aa_init(void) 1666module_i2c_driver(s5k6aa_i2c_driver);
1667{
1668 return i2c_add_driver(&s5k6aa_i2c_driver);
1669}
1670
1671static void __exit s5k6aa_exit(void)
1672{
1673 i2c_del_driver(&s5k6aa_i2c_driver);
1674}
1675
1676module_init(s5k6aa_init);
1677module_exit(s5k6aa_exit);
1678 1667
1679MODULE_DESCRIPTION("Samsung S5K6AA(FX) SXGA camera driver"); 1668MODULE_DESCRIPTION("Samsung S5K6AA(FX) SXGA camera driver");
1680MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>"); 1669MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c
index a9e9653beeb4..b06efd208328 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -1019,52 +1019,117 @@ static int fimc_cap_dqbuf(struct file *file, void *priv,
1019 return vb2_dqbuf(&fimc->vid_cap.vbq, buf, file->f_flags & O_NONBLOCK); 1019 return vb2_dqbuf(&fimc->vid_cap.vbq, buf, file->f_flags & O_NONBLOCK);
1020} 1020}
1021 1021
1022static int fimc_cap_cropcap(struct file *file, void *fh, 1022static int fimc_cap_create_bufs(struct file *file, void *priv,
1023 struct v4l2_cropcap *cr) 1023 struct v4l2_create_buffers *create)
1024{ 1024{
1025 struct fimc_dev *fimc = video_drvdata(file); 1025 struct fimc_dev *fimc = video_drvdata(file);
1026 struct fimc_frame *f = &fimc->vid_cap.ctx->s_frame;
1027 1026
1028 if (cr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 1027 return vb2_create_bufs(&fimc->vid_cap.vbq, create);
1029 return -EINVAL; 1028}
1030 1029
1031 cr->bounds.left = 0; 1030static int fimc_cap_prepare_buf(struct file *file, void *priv,
1032 cr->bounds.top = 0; 1031 struct v4l2_buffer *b)
1033 cr->bounds.width = f->o_width; 1032{
1034 cr->bounds.height = f->o_height; 1033 struct fimc_dev *fimc = video_drvdata(file);
1035 cr->defrect = cr->bounds;
1036 1034
1037 return 0; 1035 return vb2_prepare_buf(&fimc->vid_cap.vbq, b);
1038} 1036}
1039 1037
1040static int fimc_cap_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) 1038static int fimc_cap_g_selection(struct file *file, void *fh,
1039 struct v4l2_selection *s)
1041{ 1040{
1042 struct fimc_dev *fimc = video_drvdata(file); 1041 struct fimc_dev *fimc = video_drvdata(file);
1043 struct fimc_frame *f = &fimc->vid_cap.ctx->s_frame; 1042 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
1043 struct fimc_frame *f = &ctx->s_frame;
1044 1044
1045 cr->c.left = f->offs_h; 1045 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1046 cr->c.top = f->offs_v; 1046 return -EINVAL;
1047 cr->c.width = f->width;
1048 cr->c.height = f->height;
1049 1047
1050 return 0; 1048 switch (s->target) {
1049 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1050 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1051 f = &ctx->d_frame;
1052 case V4L2_SEL_TGT_CROP_BOUNDS:
1053 case V4L2_SEL_TGT_CROP_DEFAULT:
1054 s->r.left = 0;
1055 s->r.top = 0;
1056 s->r.width = f->o_width;
1057 s->r.height = f->o_height;
1058 return 0;
1059
1060 case V4L2_SEL_TGT_COMPOSE_ACTIVE:
1061 f = &ctx->d_frame;
1062 case V4L2_SEL_TGT_CROP_ACTIVE:
1063 s->r.left = f->offs_h;
1064 s->r.top = f->offs_v;
1065 s->r.width = f->width;
1066 s->r.height = f->height;
1067 return 0;
1068 }
1069
1070 return -EINVAL;
1051} 1071}
1052 1072
1053static int fimc_cap_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) 1073/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
1074int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
1075{
1076 if (a->left < b->left || a->top < b->top)
1077 return 0;
1078 if (a->left + a->width > b->left + b->width)
1079 return 0;
1080 if (a->top + a->height > b->top + b->height)
1081 return 0;
1082
1083 return 1;
1084}
1085
1086static int fimc_cap_s_selection(struct file *file, void *fh,
1087 struct v4l2_selection *s)
1054{ 1088{
1055 struct fimc_dev *fimc = video_drvdata(file); 1089 struct fimc_dev *fimc = video_drvdata(file);
1056 struct fimc_ctx *ctx = fimc->vid_cap.ctx; 1090 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
1057 struct fimc_frame *ff; 1091 struct v4l2_rect rect = s->r;
1092 struct fimc_frame *f;
1058 unsigned long flags; 1093 unsigned long flags;
1094 unsigned int pad;
1059 1095
1060 fimc_capture_try_crop(ctx, &cr->c, FIMC_SD_PAD_SINK); 1096 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1061 ff = &ctx->s_frame; 1097 return -EINVAL;
1062 1098
1099 switch (s->target) {
1100 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1101 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1102 case V4L2_SEL_TGT_COMPOSE_ACTIVE:
1103 f = &ctx->d_frame;
1104 pad = FIMC_SD_PAD_SOURCE;
1105 break;
1106 case V4L2_SEL_TGT_CROP_BOUNDS:
1107 case V4L2_SEL_TGT_CROP_DEFAULT:
1108 case V4L2_SEL_TGT_CROP_ACTIVE:
1109 f = &ctx->s_frame;
1110 pad = FIMC_SD_PAD_SINK;
1111 break;
1112 default:
1113 return -EINVAL;
1114 }
1115
1116 fimc_capture_try_crop(ctx, &rect, pad);
1117
1118 if (s->flags & V4L2_SEL_FLAG_LE &&
1119 !enclosed_rectangle(&rect, &s->r))
1120 return -ERANGE;
1121
1122 if (s->flags & V4L2_SEL_FLAG_GE &&
1123 !enclosed_rectangle(&s->r, &rect))
1124 return -ERANGE;
1125
1126 s->r = rect;
1063 spin_lock_irqsave(&fimc->slock, flags); 1127 spin_lock_irqsave(&fimc->slock, flags);
1064 set_frame_crop(ff, cr->c.left, cr->c.top, cr->c.width, cr->c.height); 1128 set_frame_crop(f, s->r.left, s->r.top, s->r.width,
1065 set_bit(ST_CAPT_APPLY_CFG, &fimc->state); 1129 s->r.height);
1066 spin_unlock_irqrestore(&fimc->slock, flags); 1130 spin_unlock_irqrestore(&fimc->slock, flags);
1067 1131
1132 set_bit(ST_CAPT_APPLY_CFG, &fimc->state);
1068 return 0; 1133 return 0;
1069} 1134}
1070 1135
@@ -1082,12 +1147,14 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = {
1082 .vidioc_qbuf = fimc_cap_qbuf, 1147 .vidioc_qbuf = fimc_cap_qbuf,
1083 .vidioc_dqbuf = fimc_cap_dqbuf, 1148 .vidioc_dqbuf = fimc_cap_dqbuf,
1084 1149
1150 .vidioc_prepare_buf = fimc_cap_prepare_buf,
1151 .vidioc_create_bufs = fimc_cap_create_bufs,
1152
1085 .vidioc_streamon = fimc_cap_streamon, 1153 .vidioc_streamon = fimc_cap_streamon,
1086 .vidioc_streamoff = fimc_cap_streamoff, 1154 .vidioc_streamoff = fimc_cap_streamoff,
1087 1155
1088 .vidioc_g_crop = fimc_cap_g_crop, 1156 .vidioc_g_selection = fimc_cap_g_selection,
1089 .vidioc_s_crop = fimc_cap_s_crop, 1157 .vidioc_s_selection = fimc_cap_s_selection,
1090 .vidioc_cropcap = fimc_cap_cropcap,
1091 1158
1092 .vidioc_enum_input = fimc_cap_enum_input, 1159 .vidioc_enum_input = fimc_cap_enum_input,
1093 .vidioc_s_input = fimc_cap_s_input, 1160 .vidioc_s_input = fimc_cap_s_input,
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c
index 81bcbb9492ea..e184e650022a 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.c
+++ b/drivers/media/video/s5p-fimc/fimc-core.c
@@ -1602,24 +1602,35 @@ static void fimc_clk_put(struct fimc_dev *fimc)
1602{ 1602{
1603 int i; 1603 int i;
1604 for (i = 0; i < fimc->num_clocks; i++) { 1604 for (i = 0; i < fimc->num_clocks; i++) {
1605 if (fimc->clock[i]) 1605 if (IS_ERR_OR_NULL(fimc->clock[i]))
1606 clk_put(fimc->clock[i]); 1606 continue;
1607 clk_unprepare(fimc->clock[i]);
1608 clk_put(fimc->clock[i]);
1609 fimc->clock[i] = NULL;
1607 } 1610 }
1608} 1611}
1609 1612
1610static int fimc_clk_get(struct fimc_dev *fimc) 1613static int fimc_clk_get(struct fimc_dev *fimc)
1611{ 1614{
1612 int i; 1615 int i, ret;
1616
1613 for (i = 0; i < fimc->num_clocks; i++) { 1617 for (i = 0; i < fimc->num_clocks; i++) {
1614 fimc->clock[i] = clk_get(&fimc->pdev->dev, fimc_clocks[i]); 1618 fimc->clock[i] = clk_get(&fimc->pdev->dev, fimc_clocks[i]);
1615 if (!IS_ERR_OR_NULL(fimc->clock[i])) 1619 if (IS_ERR(fimc->clock[i]))
1616 continue; 1620 goto err;
1617 dev_err(&fimc->pdev->dev, "failed to get fimc clock: %s\n", 1621 ret = clk_prepare(fimc->clock[i]);
1618 fimc_clocks[i]); 1622 if (ret < 0) {
1619 return -ENXIO; 1623 clk_put(fimc->clock[i]);
1624 fimc->clock[i] = NULL;
1625 goto err;
1626 }
1620 } 1627 }
1621
1622 return 0; 1628 return 0;
1629err:
1630 fimc_clk_put(fimc);
1631 dev_err(&fimc->pdev->dev, "failed to get clock: %s\n",
1632 fimc_clocks[i]);
1633 return -ENXIO;
1623} 1634}
1624 1635
1625static int fimc_m2m_suspend(struct fimc_dev *fimc) 1636static int fimc_m2m_suspend(struct fimc_dev *fimc)
@@ -1667,8 +1678,6 @@ static int fimc_probe(struct platform_device *pdev)
1667 struct s5p_platform_fimc *pdata; 1678 struct s5p_platform_fimc *pdata;
1668 int ret = 0; 1679 int ret = 0;
1669 1680
1670 dev_dbg(&pdev->dev, "%s():\n", __func__);
1671
1672 drv_data = (struct samsung_fimc_driverdata *) 1681 drv_data = (struct samsung_fimc_driverdata *)
1673 platform_get_device_id(pdev)->driver_data; 1682 platform_get_device_id(pdev)->driver_data;
1674 1683
@@ -1678,7 +1687,7 @@ static int fimc_probe(struct platform_device *pdev)
1678 return -EINVAL; 1687 return -EINVAL;
1679 } 1688 }
1680 1689
1681 fimc = kzalloc(sizeof(struct fimc_dev), GFP_KERNEL); 1690 fimc = devm_kzalloc(&pdev->dev, sizeof(*fimc), GFP_KERNEL);
1682 if (!fimc) 1691 if (!fimc)
1683 return -ENOMEM; 1692 return -ENOMEM;
1684 1693
@@ -1689,51 +1698,35 @@ static int fimc_probe(struct platform_device *pdev)
1689 pdata = pdev->dev.platform_data; 1698 pdata = pdev->dev.platform_data;
1690 fimc->pdata = pdata; 1699 fimc->pdata = pdata;
1691 1700
1692
1693 init_waitqueue_head(&fimc->irq_queue); 1701 init_waitqueue_head(&fimc->irq_queue);
1694 spin_lock_init(&fimc->slock); 1702 spin_lock_init(&fimc->slock);
1695 mutex_init(&fimc->lock); 1703 mutex_init(&fimc->lock);
1696 1704
1697 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1705 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1698 if (!res) { 1706 fimc->regs = devm_request_and_ioremap(&pdev->dev, res);
1699 dev_err(&pdev->dev, "failed to find the registers\n"); 1707 if (fimc->regs == NULL) {
1700 ret = -ENOENT; 1708 dev_err(&pdev->dev, "Failed to obtain io memory\n");
1701 goto err_info; 1709 return -ENOENT;
1702 }
1703
1704 fimc->regs_res = request_mem_region(res->start, resource_size(res),
1705 dev_name(&pdev->dev));
1706 if (!fimc->regs_res) {
1707 dev_err(&pdev->dev, "failed to obtain register region\n");
1708 ret = -ENOENT;
1709 goto err_info;
1710 }
1711
1712 fimc->regs = ioremap(res->start, resource_size(res));
1713 if (!fimc->regs) {
1714 dev_err(&pdev->dev, "failed to map registers\n");
1715 ret = -ENXIO;
1716 goto err_req_region;
1717 } 1710 }
1718 1711
1719 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 1712 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1720 if (!res) { 1713 if (res == NULL) {
1721 dev_err(&pdev->dev, "failed to get IRQ resource\n"); 1714 dev_err(&pdev->dev, "Failed to get IRQ resource\n");
1722 ret = -ENXIO; 1715 return -ENXIO;
1723 goto err_regs_unmap;
1724 } 1716 }
1725 fimc->irq = res->start; 1717 fimc->irq = res->start;
1726 1718
1727 fimc->num_clocks = MAX_FIMC_CLOCKS; 1719 fimc->num_clocks = MAX_FIMC_CLOCKS;
1728 ret = fimc_clk_get(fimc); 1720 ret = fimc_clk_get(fimc);
1729 if (ret) 1721 if (ret)
1730 goto err_regs_unmap; 1722 return ret;
1731 clk_set_rate(fimc->clock[CLK_BUS], drv_data->lclk_frequency); 1723 clk_set_rate(fimc->clock[CLK_BUS], drv_data->lclk_frequency);
1732 clk_enable(fimc->clock[CLK_BUS]); 1724 clk_enable(fimc->clock[CLK_BUS]);
1733 1725
1734 platform_set_drvdata(pdev, fimc); 1726 platform_set_drvdata(pdev, fimc);
1735 1727
1736 ret = request_irq(fimc->irq, fimc_irq_handler, 0, pdev->name, fimc); 1728 ret = devm_request_irq(&pdev->dev, fimc->irq, fimc_irq_handler,
1729 0, pdev->name, fimc);
1737 if (ret) { 1730 if (ret) {
1738 dev_err(&pdev->dev, "failed to install irq (%d)\n", ret); 1731 dev_err(&pdev->dev, "failed to install irq (%d)\n", ret);
1739 goto err_clk; 1732 goto err_clk;
@@ -1742,7 +1735,7 @@ static int fimc_probe(struct platform_device *pdev)
1742 pm_runtime_enable(&pdev->dev); 1735 pm_runtime_enable(&pdev->dev);
1743 ret = pm_runtime_get_sync(&pdev->dev); 1736 ret = pm_runtime_get_sync(&pdev->dev);
1744 if (ret < 0) 1737 if (ret < 0)
1745 goto err_irq; 1738 goto err_clk;
1746 /* Initialize contiguous memory allocator */ 1739 /* Initialize contiguous memory allocator */
1747 fimc->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); 1740 fimc->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1748 if (IS_ERR(fimc->alloc_ctx)) { 1741 if (IS_ERR(fimc->alloc_ctx)) {
@@ -1757,17 +1750,8 @@ static int fimc_probe(struct platform_device *pdev)
1757 1750
1758err_pm: 1751err_pm:
1759 pm_runtime_put(&pdev->dev); 1752 pm_runtime_put(&pdev->dev);
1760err_irq:
1761 free_irq(fimc->irq, fimc);
1762err_clk: 1753err_clk:
1763 fimc_clk_put(fimc); 1754 fimc_clk_put(fimc);
1764err_regs_unmap:
1765 iounmap(fimc->regs);
1766err_req_region:
1767 release_resource(fimc->regs_res);
1768 kfree(fimc->regs_res);
1769err_info:
1770 kfree(fimc);
1771 return ret; 1755 return ret;
1772} 1756}
1773 1757
@@ -1854,11 +1838,6 @@ static int __devexit fimc_remove(struct platform_device *pdev)
1854 1838
1855 clk_disable(fimc->clock[CLK_BUS]); 1839 clk_disable(fimc->clock[CLK_BUS]);
1856 fimc_clk_put(fimc); 1840 fimc_clk_put(fimc);
1857 free_irq(fimc->irq, fimc);
1858 iounmap(fimc->regs);
1859 release_resource(fimc->regs_res);
1860 kfree(fimc->regs_res);
1861 kfree(fimc);
1862 1841
1863 dev_info(&pdev->dev, "driver unloaded\n"); 1842 dev_info(&pdev->dev, "driver unloaded\n");
1864 return 0; 1843 return 0;
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h
index 4e20560c73d4..a18291e648e2 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.h
+++ b/drivers/media/video/s5p-fimc/fimc-core.h
@@ -434,7 +434,6 @@ struct fimc_ctx;
434 * @num_clocks: the number of clocks managed by this device instance 434 * @num_clocks: the number of clocks managed by this device instance
435 * @clock: clocks required for FIMC operation 435 * @clock: clocks required for FIMC operation
436 * @regs: the mapped hardware registers 436 * @regs: the mapped hardware registers
437 * @regs_res: the resource claimed for IO registers
438 * @irq: FIMC interrupt number 437 * @irq: FIMC interrupt number
439 * @irq_queue: interrupt handler waitqueue 438 * @irq_queue: interrupt handler waitqueue
440 * @v4l2_dev: root v4l2_device 439 * @v4l2_dev: root v4l2_device
@@ -454,7 +453,6 @@ struct fimc_dev {
454 u16 num_clocks; 453 u16 num_clocks;
455 struct clk *clock[MAX_FIMC_CLOCKS]; 454 struct clk *clock[MAX_FIMC_CLOCKS];
456 void __iomem *regs; 455 void __iomem *regs;
457 struct resource *regs_res;
458 int irq; 456 int irq;
459 wait_queue_head_t irq_queue; 457 wait_queue_head_t irq_queue;
460 struct v4l2_device *v4l2_dev; 458 struct v4l2_device *v4l2_dev;
diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/video/s5p-fimc/fimc-mdevice.c
index 63eccb55728f..62ed37e40149 100644
--- a/drivers/media/video/s5p-fimc/fimc-mdevice.c
+++ b/drivers/media/video/s5p-fimc/fimc-mdevice.c
@@ -750,7 +750,7 @@ static int __devinit fimc_md_probe(struct platform_device *pdev)
750 struct fimc_md *fmd; 750 struct fimc_md *fmd;
751 int ret; 751 int ret;
752 752
753 fmd = kzalloc(sizeof(struct fimc_md), GFP_KERNEL); 753 fmd = devm_kzalloc(&pdev->dev, sizeof(*fmd), GFP_KERNEL);
754 if (!fmd) 754 if (!fmd)
755 return -ENOMEM; 755 return -ENOMEM;
756 756
@@ -771,7 +771,7 @@ static int __devinit fimc_md_probe(struct platform_device *pdev)
771 ret = v4l2_device_register(&pdev->dev, &fmd->v4l2_dev); 771 ret = v4l2_device_register(&pdev->dev, &fmd->v4l2_dev);
772 if (ret < 0) { 772 if (ret < 0) {
773 v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret); 773 v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret);
774 goto err1; 774 return ret;
775 } 775 }
776 ret = media_device_register(&fmd->media_dev); 776 ret = media_device_register(&fmd->media_dev);
777 if (ret < 0) { 777 if (ret < 0) {
@@ -813,8 +813,6 @@ err3:
813 fimc_md_unregister_entities(fmd); 813 fimc_md_unregister_entities(fmd);
814err2: 814err2:
815 v4l2_device_unregister(&fmd->v4l2_dev); 815 v4l2_device_unregister(&fmd->v4l2_dev);
816err1:
817 kfree(fmd);
818 return ret; 816 return ret;
819} 817}
820 818
@@ -828,7 +826,6 @@ static int __devexit fimc_md_remove(struct platform_device *pdev)
828 fimc_md_unregister_entities(fmd); 826 fimc_md_unregister_entities(fmd);
829 media_device_unregister(&fmd->media_dev); 827 media_device_unregister(&fmd->media_dev);
830 fimc_md_put_clocks(fmd); 828 fimc_md_put_clocks(fmd);
831 kfree(fmd);
832 return 0; 829 return 0;
833} 830}
834 831
diff --git a/drivers/media/video/s5p-fimc/mipi-csis.c b/drivers/media/video/s5p-fimc/mipi-csis.c
index 130335cf62fd..f44f690397f7 100644
--- a/drivers/media/video/s5p-fimc/mipi-csis.c
+++ b/drivers/media/video/s5p-fimc/mipi-csis.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver 2 * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
3 * 3 *
4 * Copyright (C) 2011 Samsung Electronics Co., Ltd. 4 * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd.
5 * Contact: Sylwester Nawrocki, <s.nawrocki@samsung.com> 5 * Sylwester Nawrocki, <s.nawrocki@samsung.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -100,7 +100,6 @@ enum {
100 * @pads: CSIS pads array 100 * @pads: CSIS pads array
101 * @sd: v4l2_subdev associated with CSIS device instance 101 * @sd: v4l2_subdev associated with CSIS device instance
102 * @pdev: CSIS platform device 102 * @pdev: CSIS platform device
103 * @regs_res: requested I/O register memory resource
104 * @regs: mmaped I/O registers memory 103 * @regs: mmaped I/O registers memory
105 * @clock: CSIS clocks 104 * @clock: CSIS clocks
106 * @irq: requested s5p-mipi-csis irq number 105 * @irq: requested s5p-mipi-csis irq number
@@ -113,7 +112,6 @@ struct csis_state {
113 struct media_pad pads[CSIS_PADS_NUM]; 112 struct media_pad pads[CSIS_PADS_NUM];
114 struct v4l2_subdev sd; 113 struct v4l2_subdev sd;
115 struct platform_device *pdev; 114 struct platform_device *pdev;
116 struct resource *regs_res;
117 void __iomem *regs; 115 void __iomem *regs;
118 struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES]; 116 struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES];
119 struct clk *clock[NUM_CSIS_CLOCKS]; 117 struct clk *clock[NUM_CSIS_CLOCKS];
@@ -258,26 +256,36 @@ static void s5pcsis_clk_put(struct csis_state *state)
258{ 256{
259 int i; 257 int i;
260 258
261 for (i = 0; i < NUM_CSIS_CLOCKS; i++) 259 for (i = 0; i < NUM_CSIS_CLOCKS; i++) {
262 if (!IS_ERR_OR_NULL(state->clock[i])) 260 if (IS_ERR_OR_NULL(state->clock[i]))
263 clk_put(state->clock[i]); 261 continue;
262 clk_unprepare(state->clock[i]);
263 clk_put(state->clock[i]);
264 state->clock[i] = NULL;
265 }
264} 266}
265 267
266static int s5pcsis_clk_get(struct csis_state *state) 268static int s5pcsis_clk_get(struct csis_state *state)
267{ 269{
268 struct device *dev = &state->pdev->dev; 270 struct device *dev = &state->pdev->dev;
269 int i; 271 int i, ret;
270 272
271 for (i = 0; i < NUM_CSIS_CLOCKS; i++) { 273 for (i = 0; i < NUM_CSIS_CLOCKS; i++) {
272 state->clock[i] = clk_get(dev, csi_clock_name[i]); 274 state->clock[i] = clk_get(dev, csi_clock_name[i]);
273 if (IS_ERR(state->clock[i])) { 275 if (IS_ERR(state->clock[i]))
274 s5pcsis_clk_put(state); 276 goto err;
275 dev_err(dev, "failed to get clock: %s\n", 277 ret = clk_prepare(state->clock[i]);
276 csi_clock_name[i]); 278 if (ret < 0) {
277 return -ENXIO; 279 clk_put(state->clock[i]);
280 state->clock[i] = NULL;
281 goto err;
278 } 282 }
279 } 283 }
280 return 0; 284 return 0;
285err:
286 s5pcsis_clk_put(state);
287 dev_err(dev, "failed to get clock: %s\n", csi_clock_name[i]);
288 return -ENXIO;
281} 289}
282 290
283static int s5pcsis_s_power(struct v4l2_subdev *sd, int on) 291static int s5pcsis_s_power(struct v4l2_subdev *sd, int on)
@@ -480,12 +488,11 @@ static int __devinit s5pcsis_probe(struct platform_device *pdev)
480{ 488{
481 struct s5p_platform_mipi_csis *pdata; 489 struct s5p_platform_mipi_csis *pdata;
482 struct resource *mem_res; 490 struct resource *mem_res;
483 struct resource *regs_res;
484 struct csis_state *state; 491 struct csis_state *state;
485 int ret = -ENOMEM; 492 int ret = -ENOMEM;
486 int i; 493 int i;
487 494
488 state = kzalloc(sizeof(*state), GFP_KERNEL); 495 state = devm_kzalloc(&pdev->dev, sizeof(*state), GFP_KERNEL);
489 if (!state) 496 if (!state)
490 return -ENOMEM; 497 return -ENOMEM;
491 498
@@ -495,52 +502,27 @@ static int __devinit s5pcsis_probe(struct platform_device *pdev)
495 pdata = pdev->dev.platform_data; 502 pdata = pdev->dev.platform_data;
496 if (pdata == NULL || pdata->phy_enable == NULL) { 503 if (pdata == NULL || pdata->phy_enable == NULL) {
497 dev_err(&pdev->dev, "Platform data not fully specified\n"); 504 dev_err(&pdev->dev, "Platform data not fully specified\n");
498 goto e_free; 505 return -EINVAL;
499 } 506 }
500 507
501 if ((pdev->id == 1 && pdata->lanes > CSIS1_MAX_LANES) || 508 if ((pdev->id == 1 && pdata->lanes > CSIS1_MAX_LANES) ||
502 pdata->lanes > CSIS0_MAX_LANES) { 509 pdata->lanes > CSIS0_MAX_LANES) {
503 ret = -EINVAL;
504 dev_err(&pdev->dev, "Unsupported number of data lanes: %d\n", 510 dev_err(&pdev->dev, "Unsupported number of data lanes: %d\n",
505 pdata->lanes); 511 pdata->lanes);
506 goto e_free; 512 return -EINVAL;
507 } 513 }
508 514
509 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 515 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
510 if (!mem_res) { 516 state->regs = devm_request_and_ioremap(&pdev->dev, mem_res);
511 dev_err(&pdev->dev, "Failed to get IO memory region\n"); 517 if (state->regs == NULL) {
512 goto e_free; 518 dev_err(&pdev->dev, "Failed to request and remap io memory\n");
519 return -ENXIO;
513 } 520 }
514 521
515 regs_res = request_mem_region(mem_res->start, resource_size(mem_res),
516 pdev->name);
517 if (!regs_res) {
518 dev_err(&pdev->dev, "Failed to request IO memory region\n");
519 goto e_free;
520 }
521 state->regs_res = regs_res;
522
523 state->regs = ioremap(mem_res->start, resource_size(mem_res));
524 if (!state->regs) {
525 dev_err(&pdev->dev, "Failed to remap IO region\n");
526 goto e_reqmem;
527 }
528
529 ret = s5pcsis_clk_get(state);
530 if (ret)
531 goto e_unmap;
532
533 clk_enable(state->clock[CSIS_CLK_MUX]);
534 if (pdata->clk_rate)
535 clk_set_rate(state->clock[CSIS_CLK_MUX], pdata->clk_rate);
536 else
537 dev_WARN(&pdev->dev, "No clock frequency specified!\n");
538
539 state->irq = platform_get_irq(pdev, 0); 522 state->irq = platform_get_irq(pdev, 0);
540 if (state->irq < 0) { 523 if (state->irq < 0) {
541 ret = state->irq;
542 dev_err(&pdev->dev, "Failed to get irq\n"); 524 dev_err(&pdev->dev, "Failed to get irq\n");
543 goto e_clkput; 525 return state->irq;
544 } 526 }
545 527
546 for (i = 0; i < CSIS_NUM_SUPPLIES; i++) 528 for (i = 0; i < CSIS_NUM_SUPPLIES; i++)
@@ -549,12 +531,22 @@ static int __devinit s5pcsis_probe(struct platform_device *pdev)
549 ret = regulator_bulk_get(&pdev->dev, CSIS_NUM_SUPPLIES, 531 ret = regulator_bulk_get(&pdev->dev, CSIS_NUM_SUPPLIES,
550 state->supplies); 532 state->supplies);
551 if (ret) 533 if (ret)
534 return ret;
535
536 ret = s5pcsis_clk_get(state);
537 if (ret)
552 goto e_clkput; 538 goto e_clkput;
553 539
554 ret = request_irq(state->irq, s5pcsis_irq_handler, 0, 540 clk_enable(state->clock[CSIS_CLK_MUX]);
555 dev_name(&pdev->dev), state); 541 if (pdata->clk_rate)
542 clk_set_rate(state->clock[CSIS_CLK_MUX], pdata->clk_rate);
543 else
544 dev_WARN(&pdev->dev, "No clock frequency specified!\n");
545
546 ret = devm_request_irq(&pdev->dev, state->irq, s5pcsis_irq_handler,
547 0, dev_name(&pdev->dev), state);
556 if (ret) { 548 if (ret) {
557 dev_err(&pdev->dev, "request_irq failed\n"); 549 dev_err(&pdev->dev, "Interrupt request failed\n");
558 goto e_regput; 550 goto e_regput;
559 } 551 }
560 552
@@ -573,7 +565,7 @@ static int __devinit s5pcsis_probe(struct platform_device *pdev)
573 ret = media_entity_init(&state->sd.entity, 565 ret = media_entity_init(&state->sd.entity,
574 CSIS_PADS_NUM, state->pads, 0); 566 CSIS_PADS_NUM, state->pads, 0);
575 if (ret < 0) 567 if (ret < 0)
576 goto e_irqfree; 568 goto e_clkput;
577 569
578 /* This allows to retrieve the platform device id by the host driver */ 570 /* This allows to retrieve the platform device id by the host driver */
579 v4l2_set_subdevdata(&state->sd, pdev); 571 v4l2_set_subdevdata(&state->sd, pdev);
@@ -582,22 +574,13 @@ static int __devinit s5pcsis_probe(struct platform_device *pdev)
582 platform_set_drvdata(pdev, &state->sd); 574 platform_set_drvdata(pdev, &state->sd);
583 575
584 pm_runtime_enable(&pdev->dev); 576 pm_runtime_enable(&pdev->dev);
585
586 return 0; 577 return 0;
587 578
588e_irqfree:
589 free_irq(state->irq, state);
590e_regput: 579e_regput:
591 regulator_bulk_free(CSIS_NUM_SUPPLIES, state->supplies); 580 regulator_bulk_free(CSIS_NUM_SUPPLIES, state->supplies);
592e_clkput: 581e_clkput:
593 clk_disable(state->clock[CSIS_CLK_MUX]); 582 clk_disable(state->clock[CSIS_CLK_MUX]);
594 s5pcsis_clk_put(state); 583 s5pcsis_clk_put(state);
595e_unmap:
596 iounmap(state->regs);
597e_reqmem:
598 release_mem_region(regs_res->start, resource_size(regs_res));
599e_free:
600 kfree(state);
601 return ret; 584 return ret;
602} 585}
603 586
@@ -699,21 +682,15 @@ static int __devexit s5pcsis_remove(struct platform_device *pdev)
699{ 682{
700 struct v4l2_subdev *sd = platform_get_drvdata(pdev); 683 struct v4l2_subdev *sd = platform_get_drvdata(pdev);
701 struct csis_state *state = sd_to_csis_state(sd); 684 struct csis_state *state = sd_to_csis_state(sd);
702 struct resource *res = state->regs_res;
703 685
704 pm_runtime_disable(&pdev->dev); 686 pm_runtime_disable(&pdev->dev);
705 s5pcsis_suspend(&pdev->dev); 687 s5pcsis_pm_suspend(&pdev->dev, false);
706 clk_disable(state->clock[CSIS_CLK_MUX]); 688 clk_disable(state->clock[CSIS_CLK_MUX]);
707 pm_runtime_set_suspended(&pdev->dev); 689 pm_runtime_set_suspended(&pdev->dev);
708
709 s5pcsis_clk_put(state); 690 s5pcsis_clk_put(state);
710 regulator_bulk_free(CSIS_NUM_SUPPLIES, state->supplies); 691 regulator_bulk_free(CSIS_NUM_SUPPLIES, state->supplies);
711 692
712 media_entity_cleanup(&state->sd.entity); 693 media_entity_cleanup(&state->sd.entity);
713 free_irq(state->irq, state);
714 iounmap(state->regs);
715 release_mem_region(res->start, resource_size(res));
716 kfree(state);
717 694
718 return 0; 695 return 0;
719} 696}
diff --git a/drivers/media/video/s5p-g2d/g2d-hw.c b/drivers/media/video/s5p-g2d/g2d-hw.c
index 39937cf03c88..5b86cbe408e2 100644
--- a/drivers/media/video/s5p-g2d/g2d-hw.c
+++ b/drivers/media/video/s5p-g2d/g2d-hw.c
@@ -77,6 +77,11 @@ void g2d_set_rop4(struct g2d_dev *d, u32 r)
77 w(r, ROP4_REG); 77 w(r, ROP4_REG);
78} 78}
79 79
80void g2d_set_flip(struct g2d_dev *d, u32 r)
81{
82 w(r, SRC_MSK_DIRECT_REG);
83}
84
80u32 g2d_cmd_stretch(u32 e) 85u32 g2d_cmd_stretch(u32 e)
81{ 86{
82 e &= 1; 87 e &= 1;
diff --git a/drivers/media/video/s5p-g2d/g2d.c b/drivers/media/video/s5p-g2d/g2d.c
index febaa673d363..789de74014e5 100644
--- a/drivers/media/video/s5p-g2d/g2d.c
+++ b/drivers/media/video/s5p-g2d/g2d.c
@@ -178,6 +178,9 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl)
178{ 178{
179 struct g2d_ctx *ctx = container_of(ctrl->handler, struct g2d_ctx, 179 struct g2d_ctx *ctx = container_of(ctrl->handler, struct g2d_ctx,
180 ctrl_handler); 180 ctrl_handler);
181 unsigned long flags;
182
183 spin_lock_irqsave(&ctx->dev->ctrl_lock, flags);
181 switch (ctrl->id) { 184 switch (ctrl->id) {
182 case V4L2_CID_COLORFX: 185 case V4L2_CID_COLORFX:
183 if (ctrl->val == V4L2_COLORFX_NEGATIVE) 186 if (ctrl->val == V4L2_COLORFX_NEGATIVE)
@@ -185,10 +188,13 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl)
185 else 188 else
186 ctx->rop = ROP4_COPY; 189 ctx->rop = ROP4_COPY;
187 break; 190 break;
188 default: 191
189 v4l2_err(&ctx->dev->v4l2_dev, "unknown control\n"); 192 case V4L2_CID_HFLIP:
190 return -EINVAL; 193 ctx->flip = ctx->ctrl_hflip->val | (ctx->ctrl_vflip->val << 1);
194 break;
195
191 } 196 }
197 spin_unlock_irqrestore(&ctx->dev->ctrl_lock, flags);
192 return 0; 198 return 0;
193} 199}
194 200
@@ -200,11 +206,13 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx)
200{ 206{
201 struct g2d_dev *dev = ctx->dev; 207 struct g2d_dev *dev = ctx->dev;
202 208
203 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 1); 209 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
204 if (ctx->ctrl_handler.error) { 210
205 v4l2_err(&dev->v4l2_dev, "v4l2_ctrl_handler_init failed\n"); 211 ctx->ctrl_hflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &g2d_ctrl_ops,
206 return ctx->ctrl_handler.error; 212 V4L2_CID_HFLIP, 0, 1, 1, 0);
207 } 213
214 ctx->ctrl_vflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &g2d_ctrl_ops,
215 V4L2_CID_VFLIP, 0, 1, 1, 0);
208 216
209 v4l2_ctrl_new_std_menu( 217 v4l2_ctrl_new_std_menu(
210 &ctx->ctrl_handler, 218 &ctx->ctrl_handler,
@@ -215,10 +223,14 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx)
215 V4L2_COLORFX_NONE); 223 V4L2_COLORFX_NONE);
216 224
217 if (ctx->ctrl_handler.error) { 225 if (ctx->ctrl_handler.error) {
218 v4l2_err(&dev->v4l2_dev, "v4l2_ctrl_handler_init failed\n"); 226 int err = ctx->ctrl_handler.error;
219 return ctx->ctrl_handler.error; 227 v4l2_err(&dev->v4l2_dev, "g2d_setup_ctrls failed\n");
228 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
229 return err;
220 } 230 }
221 231
232 v4l2_ctrl_cluster(2, &ctx->ctrl_hflip);
233
222 return 0; 234 return 0;
223} 235}
224 236
@@ -547,6 +559,7 @@ static void device_run(void *prv)
547 struct g2d_ctx *ctx = prv; 559 struct g2d_ctx *ctx = prv;
548 struct g2d_dev *dev = ctx->dev; 560 struct g2d_dev *dev = ctx->dev;
549 struct vb2_buffer *src, *dst; 561 struct vb2_buffer *src, *dst;
562 unsigned long flags;
550 u32 cmd = 0; 563 u32 cmd = 0;
551 564
552 dev->curr = ctx; 565 dev->curr = ctx;
@@ -557,6 +570,8 @@ static void device_run(void *prv)
557 clk_enable(dev->gate); 570 clk_enable(dev->gate);
558 g2d_reset(dev); 571 g2d_reset(dev);
559 572
573 spin_lock_irqsave(&dev->ctrl_lock, flags);
574
560 g2d_set_src_size(dev, &ctx->in); 575 g2d_set_src_size(dev, &ctx->in);
561 g2d_set_src_addr(dev, vb2_dma_contig_plane_dma_addr(src, 0)); 576 g2d_set_src_addr(dev, vb2_dma_contig_plane_dma_addr(src, 0));
562 577
@@ -564,11 +579,15 @@ static void device_run(void *prv)
564 g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0)); 579 g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0));
565 580
566 g2d_set_rop4(dev, ctx->rop); 581 g2d_set_rop4(dev, ctx->rop);
582 g2d_set_flip(dev, ctx->flip);
583
567 if (ctx->in.c_width != ctx->out.c_width || 584 if (ctx->in.c_width != ctx->out.c_width ||
568 ctx->in.c_height != ctx->out.c_height) 585 ctx->in.c_height != ctx->out.c_height)
569 cmd |= g2d_cmd_stretch(1); 586 cmd |= g2d_cmd_stretch(1);
570 g2d_set_cmd(dev, cmd); 587 g2d_set_cmd(dev, cmd);
571 g2d_start(dev); 588 g2d_start(dev);
589
590 spin_unlock_irqrestore(&dev->ctrl_lock, flags);
572} 591}
573 592
574static irqreturn_t g2d_isr(int irq, void *prv) 593static irqreturn_t g2d_isr(int irq, void *prv)
@@ -658,7 +677,7 @@ static int g2d_probe(struct platform_device *pdev)
658 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 677 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
659 if (!dev) 678 if (!dev)
660 return -ENOMEM; 679 return -ENOMEM;
661 spin_lock_init(&dev->irqlock); 680 spin_lock_init(&dev->ctrl_lock);
662 mutex_init(&dev->mutex); 681 mutex_init(&dev->mutex);
663 atomic_set(&dev->num_inst, 0); 682 atomic_set(&dev->num_inst, 0);
664 init_waitqueue_head(&dev->irq_queue); 683 init_waitqueue_head(&dev->irq_queue);
@@ -693,18 +712,30 @@ static int g2d_probe(struct platform_device *pdev)
693 goto unmap_regs; 712 goto unmap_regs;
694 } 713 }
695 714
715 ret = clk_prepare(dev->clk);
716 if (ret) {
717 dev_err(&pdev->dev, "failed to prepare g2d clock\n");
718 goto put_clk;
719 }
720
696 dev->gate = clk_get(&pdev->dev, "fimg2d"); 721 dev->gate = clk_get(&pdev->dev, "fimg2d");
697 if (IS_ERR_OR_NULL(dev->gate)) { 722 if (IS_ERR_OR_NULL(dev->gate)) {
698 dev_err(&pdev->dev, "failed to get g2d clock gate\n"); 723 dev_err(&pdev->dev, "failed to get g2d clock gate\n");
699 ret = -ENXIO; 724 ret = -ENXIO;
700 goto put_clk; 725 goto unprep_clk;
726 }
727
728 ret = clk_prepare(dev->gate);
729 if (ret) {
730 dev_err(&pdev->dev, "failed to prepare g2d clock gate\n");
731 goto put_clk_gate;
701 } 732 }
702 733
703 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 734 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
704 if (!res) { 735 if (!res) {
705 dev_err(&pdev->dev, "failed to find IRQ\n"); 736 dev_err(&pdev->dev, "failed to find IRQ\n");
706 ret = -ENXIO; 737 ret = -ENXIO;
707 goto put_clk_gate; 738 goto unprep_clk_gate;
708 } 739 }
709 740
710 dev->irq = res->start; 741 dev->irq = res->start;
@@ -764,8 +795,12 @@ alloc_ctx_cleanup:
764 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); 795 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
765rel_irq: 796rel_irq:
766 free_irq(dev->irq, dev); 797 free_irq(dev->irq, dev);
798unprep_clk_gate:
799 clk_unprepare(dev->gate);
767put_clk_gate: 800put_clk_gate:
768 clk_put(dev->gate); 801 clk_put(dev->gate);
802unprep_clk:
803 clk_unprepare(dev->clk);
769put_clk: 804put_clk:
770 clk_put(dev->clk); 805 clk_put(dev->clk);
771unmap_regs: 806unmap_regs:
@@ -787,7 +822,9 @@ static int g2d_remove(struct platform_device *pdev)
787 v4l2_device_unregister(&dev->v4l2_dev); 822 v4l2_device_unregister(&dev->v4l2_dev);
788 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); 823 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
789 free_irq(dev->irq, dev); 824 free_irq(dev->irq, dev);
825 clk_unprepare(dev->gate);
790 clk_put(dev->gate); 826 clk_put(dev->gate);
827 clk_unprepare(dev->clk);
791 clk_put(dev->clk); 828 clk_put(dev->clk);
792 iounmap(dev->regs); 829 iounmap(dev->regs);
793 release_resource(dev->res_regs); 830 release_resource(dev->res_regs);
diff --git a/drivers/media/video/s5p-g2d/g2d.h b/drivers/media/video/s5p-g2d/g2d.h
index 5eae90107bf8..1b82065aeaef 100644
--- a/drivers/media/video/s5p-g2d/g2d.h
+++ b/drivers/media/video/s5p-g2d/g2d.h
@@ -20,7 +20,7 @@ struct g2d_dev {
20 struct v4l2_m2m_dev *m2m_dev; 20 struct v4l2_m2m_dev *m2m_dev;
21 struct video_device *vfd; 21 struct video_device *vfd;
22 struct mutex mutex; 22 struct mutex mutex;
23 spinlock_t irqlock; 23 spinlock_t ctrl_lock;
24 atomic_t num_inst; 24 atomic_t num_inst;
25 struct vb2_alloc_ctx *alloc_ctx; 25 struct vb2_alloc_ctx *alloc_ctx;
26 struct resource *res_regs; 26 struct resource *res_regs;
@@ -57,8 +57,11 @@ struct g2d_ctx {
57 struct v4l2_m2m_ctx *m2m_ctx; 57 struct v4l2_m2m_ctx *m2m_ctx;
58 struct g2d_frame in; 58 struct g2d_frame in;
59 struct g2d_frame out; 59 struct g2d_frame out;
60 struct v4l2_ctrl *ctrl_hflip;
61 struct v4l2_ctrl *ctrl_vflip;
60 struct v4l2_ctrl_handler ctrl_handler; 62 struct v4l2_ctrl_handler ctrl_handler;
61 u32 rop; 63 u32 rop;
64 u32 flip;
62}; 65};
63 66
64struct g2d_fmt { 67struct g2d_fmt {
@@ -77,6 +80,7 @@ void g2d_set_dst_addr(struct g2d_dev *d, dma_addr_t a);
77void g2d_start(struct g2d_dev *d); 80void g2d_start(struct g2d_dev *d);
78void g2d_clear_int(struct g2d_dev *d); 81void g2d_clear_int(struct g2d_dev *d);
79void g2d_set_rop4(struct g2d_dev *d, u32 r); 82void g2d_set_rop4(struct g2d_dev *d, u32 r);
83void g2d_set_flip(struct g2d_dev *d, u32 r);
80u32 g2d_cmd_stretch(u32 e); 84u32 g2d_cmd_stretch(u32 e);
81void g2d_set_cmd(struct g2d_dev *d, u32 c); 85void g2d_set_cmd(struct g2d_dev *d, u32 c);
82 86
diff --git a/drivers/media/video/s5p-jpeg/jpeg-core.c b/drivers/media/video/s5p-jpeg/jpeg-core.c
index 1105a8749c8b..5a49c307f9c1 100644
--- a/drivers/media/video/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/video/s5p-jpeg/jpeg-core.c
@@ -32,10 +32,9 @@
32 32
33static struct s5p_jpeg_fmt formats_enc[] = { 33static struct s5p_jpeg_fmt formats_enc[] = {
34 { 34 {
35 .name = "YUV 4:2:0 planar, YCbCr", 35 .name = "JPEG JFIF",
36 .fourcc = V4L2_PIX_FMT_YUV420, 36 .fourcc = V4L2_PIX_FMT_JPEG,
37 .depth = 12, 37 .colplanes = 1,
38 .colplanes = 3,
39 .types = MEM2MEM_CAPTURE, 38 .types = MEM2MEM_CAPTURE,
40 }, 39 },
41 { 40 {
@@ -43,7 +42,7 @@ static struct s5p_jpeg_fmt formats_enc[] = {
43 .fourcc = V4L2_PIX_FMT_YUYV, 42 .fourcc = V4L2_PIX_FMT_YUYV,
44 .depth = 16, 43 .depth = 16,
45 .colplanes = 1, 44 .colplanes = 1,
46 .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT, 45 .types = MEM2MEM_OUTPUT,
47 }, 46 },
48 { 47 {
49 .name = "RGB565", 48 .name = "RGB565",
@@ -203,6 +202,16 @@ static const unsigned char hactblg0[162] = {
203 0xf9, 0xfa 202 0xf9, 0xfa
204}; 203};
205 204
205static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
206{
207 return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
208}
209
210static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh)
211{
212 return container_of(fh, struct s5p_jpeg_ctx, fh);
213}
214
206static inline void jpeg_set_qtbl(void __iomem *regs, const unsigned char *qtbl, 215static inline void jpeg_set_qtbl(void __iomem *regs, const unsigned char *qtbl,
207 unsigned long tab, int len) 216 unsigned long tab, int len)
208{ 217{
@@ -269,6 +278,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
269 struct vb2_queue *dst_vq); 278 struct vb2_queue *dst_vq);
270static struct s5p_jpeg_fmt *s5p_jpeg_find_format(unsigned int mode, 279static struct s5p_jpeg_fmt *s5p_jpeg_find_format(unsigned int mode,
271 __u32 pixelformat); 280 __u32 pixelformat);
281static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
272 282
273static int s5p_jpeg_open(struct file *file) 283static int s5p_jpeg_open(struct file *file)
274{ 284{
@@ -276,12 +286,18 @@ static int s5p_jpeg_open(struct file *file)
276 struct video_device *vfd = video_devdata(file); 286 struct video_device *vfd = video_devdata(file);
277 struct s5p_jpeg_ctx *ctx; 287 struct s5p_jpeg_ctx *ctx;
278 struct s5p_jpeg_fmt *out_fmt; 288 struct s5p_jpeg_fmt *out_fmt;
289 int ret = 0;
279 290
280 ctx = kzalloc(sizeof *ctx, GFP_KERNEL); 291 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
281 if (!ctx) 292 if (!ctx)
282 return -ENOMEM; 293 return -ENOMEM;
283 294
284 file->private_data = ctx; 295 v4l2_fh_init(&ctx->fh, vfd);
296 /* Use separate control handler per file handle */
297 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
298 file->private_data = &ctx->fh;
299 v4l2_fh_add(&ctx->fh);
300
285 ctx->jpeg = jpeg; 301 ctx->jpeg = jpeg;
286 if (vfd == jpeg->vfd_encoder) { 302 if (vfd == jpeg->vfd_encoder) {
287 ctx->mode = S5P_JPEG_ENCODE; 303 ctx->mode = S5P_JPEG_ENCODE;
@@ -291,24 +307,35 @@ static int s5p_jpeg_open(struct file *file)
291 out_fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_JPEG); 307 out_fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_JPEG);
292 } 308 }
293 309
310 ret = s5p_jpeg_controls_create(ctx);
311 if (ret < 0)
312 goto error;
313
294 ctx->m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init); 314 ctx->m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
295 if (IS_ERR(ctx->m2m_ctx)) { 315 if (IS_ERR(ctx->m2m_ctx)) {
296 int err = PTR_ERR(ctx->m2m_ctx); 316 ret = PTR_ERR(ctx->m2m_ctx);
297 kfree(ctx); 317 goto error;
298 return err;
299 } 318 }
300 319
301 ctx->out_q.fmt = out_fmt; 320 ctx->out_q.fmt = out_fmt;
302 ctx->cap_q.fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_YUYV); 321 ctx->cap_q.fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_YUYV);
303
304 return 0; 322 return 0;
323
324error:
325 v4l2_fh_del(&ctx->fh);
326 v4l2_fh_exit(&ctx->fh);
327 kfree(ctx);
328 return ret;
305} 329}
306 330
307static int s5p_jpeg_release(struct file *file) 331static int s5p_jpeg_release(struct file *file)
308{ 332{
309 struct s5p_jpeg_ctx *ctx = file->private_data; 333 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
310 334
311 v4l2_m2m_ctx_release(ctx->m2m_ctx); 335 v4l2_m2m_ctx_release(ctx->m2m_ctx);
336 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
337 v4l2_fh_del(&ctx->fh);
338 v4l2_fh_exit(&ctx->fh);
312 kfree(ctx); 339 kfree(ctx);
313 340
314 return 0; 341 return 0;
@@ -317,14 +344,14 @@ static int s5p_jpeg_release(struct file *file)
317static unsigned int s5p_jpeg_poll(struct file *file, 344static unsigned int s5p_jpeg_poll(struct file *file,
318 struct poll_table_struct *wait) 345 struct poll_table_struct *wait)
319{ 346{
320 struct s5p_jpeg_ctx *ctx = file->private_data; 347 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
321 348
322 return v4l2_m2m_poll(file, ctx->m2m_ctx, wait); 349 return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
323} 350}
324 351
325static int s5p_jpeg_mmap(struct file *file, struct vm_area_struct *vma) 352static int s5p_jpeg_mmap(struct file *file, struct vm_area_struct *vma)
326{ 353{
327 struct s5p_jpeg_ctx *ctx = file->private_data; 354 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
328 355
329 return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma); 356 return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
330} 357}
@@ -448,7 +475,7 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
448static int s5p_jpeg_querycap(struct file *file, void *priv, 475static int s5p_jpeg_querycap(struct file *file, void *priv,
449 struct v4l2_capability *cap) 476 struct v4l2_capability *cap)
450{ 477{
451 struct s5p_jpeg_ctx *ctx = priv; 478 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
452 479
453 if (ctx->mode == S5P_JPEG_ENCODE) { 480 if (ctx->mode == S5P_JPEG_ENCODE) {
454 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " encoder", 481 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " encoder",
@@ -497,9 +524,7 @@ static int enum_fmt(struct s5p_jpeg_fmt *formats, int n,
497static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv, 524static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
498 struct v4l2_fmtdesc *f) 525 struct v4l2_fmtdesc *f)
499{ 526{
500 struct s5p_jpeg_ctx *ctx; 527 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
501
502 ctx = priv;
503 528
504 if (ctx->mode == S5P_JPEG_ENCODE) 529 if (ctx->mode == S5P_JPEG_ENCODE)
505 return enum_fmt(formats_enc, NUM_FORMATS_ENC, f, 530 return enum_fmt(formats_enc, NUM_FORMATS_ENC, f,
@@ -511,9 +536,7 @@ static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
511static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv, 536static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
512 struct v4l2_fmtdesc *f) 537 struct v4l2_fmtdesc *f)
513{ 538{
514 struct s5p_jpeg_ctx *ctx; 539 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
515
516 ctx = priv;
517 540
518 if (ctx->mode == S5P_JPEG_ENCODE) 541 if (ctx->mode == S5P_JPEG_ENCODE)
519 return enum_fmt(formats_enc, NUM_FORMATS_ENC, f, 542 return enum_fmt(formats_enc, NUM_FORMATS_ENC, f,
@@ -538,7 +561,7 @@ static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
538 struct vb2_queue *vq; 561 struct vb2_queue *vq;
539 struct s5p_jpeg_q_data *q_data = NULL; 562 struct s5p_jpeg_q_data *q_data = NULL;
540 struct v4l2_pix_format *pix = &f->fmt.pix; 563 struct v4l2_pix_format *pix = &f->fmt.pix;
541 struct s5p_jpeg_ctx *ct = priv; 564 struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
542 565
543 vq = v4l2_m2m_get_vq(ct->m2m_ctx, f->type); 566 vq = v4l2_m2m_get_vq(ct->m2m_ctx, f->type);
544 if (!vq) 567 if (!vq)
@@ -659,8 +682,8 @@ static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
659static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv, 682static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
660 struct v4l2_format *f) 683 struct v4l2_format *f)
661{ 684{
685 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
662 struct s5p_jpeg_fmt *fmt; 686 struct s5p_jpeg_fmt *fmt;
663 struct s5p_jpeg_ctx *ctx = priv;
664 687
665 fmt = s5p_jpeg_find_format(ctx->mode, f->fmt.pix.pixelformat); 688 fmt = s5p_jpeg_find_format(ctx->mode, f->fmt.pix.pixelformat);
666 if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) { 689 if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) {
@@ -676,8 +699,8 @@ static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
676static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv, 699static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
677 struct v4l2_format *f) 700 struct v4l2_format *f)
678{ 701{
702 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
679 struct s5p_jpeg_fmt *fmt; 703 struct s5p_jpeg_fmt *fmt;
680 struct s5p_jpeg_ctx *ctx = priv;
681 704
682 fmt = s5p_jpeg_find_format(ctx->mode, f->fmt.pix.pixelformat); 705 fmt = s5p_jpeg_find_format(ctx->mode, f->fmt.pix.pixelformat);
683 if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) { 706 if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) {
@@ -728,7 +751,7 @@ static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
728 if (ret) 751 if (ret)
729 return ret; 752 return ret;
730 753
731 return s5p_jpeg_s_fmt(priv, f); 754 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
732} 755}
733 756
734static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv, 757static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
@@ -740,13 +763,13 @@ static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
740 if (ret) 763 if (ret)
741 return ret; 764 return ret;
742 765
743 return s5p_jpeg_s_fmt(priv, f); 766 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
744} 767}
745 768
746static int s5p_jpeg_reqbufs(struct file *file, void *priv, 769static int s5p_jpeg_reqbufs(struct file *file, void *priv,
747 struct v4l2_requestbuffers *reqbufs) 770 struct v4l2_requestbuffers *reqbufs)
748{ 771{
749 struct s5p_jpeg_ctx *ctx = priv; 772 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
750 773
751 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); 774 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
752} 775}
@@ -754,14 +777,14 @@ static int s5p_jpeg_reqbufs(struct file *file, void *priv,
754static int s5p_jpeg_querybuf(struct file *file, void *priv, 777static int s5p_jpeg_querybuf(struct file *file, void *priv,
755 struct v4l2_buffer *buf) 778 struct v4l2_buffer *buf)
756{ 779{
757 struct s5p_jpeg_ctx *ctx = priv; 780 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
758 781
759 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); 782 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
760} 783}
761 784
762static int s5p_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) 785static int s5p_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
763{ 786{
764 struct s5p_jpeg_ctx *ctx = priv; 787 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
765 788
766 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); 789 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
767} 790}
@@ -769,7 +792,7 @@ static int s5p_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
769static int s5p_jpeg_dqbuf(struct file *file, void *priv, 792static int s5p_jpeg_dqbuf(struct file *file, void *priv,
770 struct v4l2_buffer *buf) 793 struct v4l2_buffer *buf)
771{ 794{
772 struct s5p_jpeg_ctx *ctx = priv; 795 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
773 796
774 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); 797 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
775} 798}
@@ -777,7 +800,7 @@ static int s5p_jpeg_dqbuf(struct file *file, void *priv,
777static int s5p_jpeg_streamon(struct file *file, void *priv, 800static int s5p_jpeg_streamon(struct file *file, void *priv,
778 enum v4l2_buf_type type) 801 enum v4l2_buf_type type)
779{ 802{
780 struct s5p_jpeg_ctx *ctx = priv; 803 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
781 804
782 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); 805 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
783} 806}
@@ -785,7 +808,7 @@ static int s5p_jpeg_streamon(struct file *file, void *priv,
785static int s5p_jpeg_streamoff(struct file *file, void *priv, 808static int s5p_jpeg_streamoff(struct file *file, void *priv,
786 enum v4l2_buf_type type) 809 enum v4l2_buf_type type)
787{ 810{
788 struct s5p_jpeg_ctx *ctx = priv; 811 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
789 812
790 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type); 813 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
791} 814}
@@ -793,7 +816,7 @@ static int s5p_jpeg_streamoff(struct file *file, void *priv,
793int s5p_jpeg_g_selection(struct file *file, void *priv, 816int s5p_jpeg_g_selection(struct file *file, void *priv,
794 struct v4l2_selection *s) 817 struct v4l2_selection *s)
795{ 818{
796 struct s5p_jpeg_ctx *ctx = priv; 819 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
797 820
798 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && 821 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
799 s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 822 s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -822,33 +845,89 @@ int s5p_jpeg_g_selection(struct file *file, void *priv,
822 return 0; 845 return 0;
823} 846}
824 847
825static int s5p_jpeg_g_jpegcomp(struct file *file, void *priv, 848/*
826 struct v4l2_jpegcompression *compr) 849 * V4L2 controls
850 */
851
852static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
827{ 853{
828 struct s5p_jpeg_ctx *ctx = priv; 854 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
855 struct s5p_jpeg *jpeg = ctx->jpeg;
856 unsigned long flags;
829 857
830 if (ctx->mode == S5P_JPEG_DECODE) 858 switch (ctrl->id) {
831 return -ENOTTY; 859 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
860 spin_lock_irqsave(&jpeg->slock, flags);
832 861
833 memset(compr, 0, sizeof(*compr)); 862 WARN_ON(ctx->subsampling > S5P_SUBSAMPLING_MODE_GRAY);
834 compr->quality = ctx->compr_quality; 863 if (ctx->subsampling > 2)
864 ctrl->val = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
865 else
866 ctrl->val = ctx->subsampling;
867 spin_unlock_irqrestore(&jpeg->slock, flags);
868 break;
869 }
835 870
836 return 0; 871 return 0;
837} 872}
838 873
839static int s5p_jpeg_s_jpegcomp(struct file *file, void *priv, 874static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
840 struct v4l2_jpegcompression *compr)
841{ 875{
842 struct s5p_jpeg_ctx *ctx = priv; 876 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
877 unsigned long flags;
843 878
844 if (ctx->mode == S5P_JPEG_DECODE) 879 spin_lock_irqsave(&ctx->jpeg->slock, flags);
845 return -ENOTTY;
846 880
847 compr->quality = clamp(compr->quality, S5P_JPEG_COMPR_QUAL_BEST, 881 switch (ctrl->id) {
848 S5P_JPEG_COMPR_QUAL_WORST); 882 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
883 ctx->compr_quality = S5P_JPEG_COMPR_QUAL_WORST - ctrl->val;
884 break;
885 case V4L2_CID_JPEG_RESTART_INTERVAL:
886 ctx->restart_interval = ctrl->val;
887 break;
888 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
889 ctx->subsampling = ctrl->val;
890 break;
891 }
849 892
850 ctx->compr_quality = S5P_JPEG_COMPR_QUAL_WORST - compr->quality; 893 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
894 return 0;
895}
896
897static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
898 .g_volatile_ctrl = s5p_jpeg_g_volatile_ctrl,
899 .s_ctrl = s5p_jpeg_s_ctrl,
900};
851 901
902static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
903{
904 unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
905 struct v4l2_ctrl *ctrl;
906
907 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
908
909 if (ctx->mode == S5P_JPEG_ENCODE) {
910 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
911 V4L2_CID_JPEG_COMPRESSION_QUALITY,
912 0, 3, 1, 3);
913
914 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
915 V4L2_CID_JPEG_RESTART_INTERVAL,
916 0, 3, 0xffff, 0);
917 mask = ~0x06; /* 422, 420 */
918 }
919
920 ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
921 V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
922 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask,
923 V4L2_JPEG_CHROMA_SUBSAMPLING_422);
924
925 if (ctx->ctrl_handler.error)
926 return ctx->ctrl_handler.error;
927
928 if (ctx->mode == S5P_JPEG_DECODE)
929 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
930 V4L2_CTRL_FLAG_READ_ONLY;
852 return 0; 931 return 0;
853} 932}
854 933
@@ -877,9 +956,6 @@ static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
877 .vidioc_streamoff = s5p_jpeg_streamoff, 956 .vidioc_streamoff = s5p_jpeg_streamoff,
878 957
879 .vidioc_g_selection = s5p_jpeg_g_selection, 958 .vidioc_g_selection = s5p_jpeg_g_selection,
880
881 .vidioc_g_jpegcomp = s5p_jpeg_g_jpegcomp,
882 .vidioc_s_jpegcomp = s5p_jpeg_s_jpegcomp,
883}; 959};
884 960
885/* 961/*
@@ -908,13 +984,8 @@ static void s5p_jpeg_device_run(void *priv)
908 jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_565); 984 jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_565);
909 else 985 else
910 jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_422); 986 jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_422);
911 if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV) 987 jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
912 jpeg_subsampling_mode(jpeg->regs, 988 jpeg_dri(jpeg->regs, ctx->restart_interval);
913 S5P_JPEG_SUBSAMPLING_422);
914 else
915 jpeg_subsampling_mode(jpeg->regs,
916 S5P_JPEG_SUBSAMPLING_420);
917 jpeg_dri(jpeg->regs, 0);
918 jpeg_x(jpeg->regs, ctx->out_q.w); 989 jpeg_x(jpeg->regs, ctx->out_q.w);
919 jpeg_y(jpeg->regs, ctx->out_q.h); 990 jpeg_y(jpeg->regs, ctx->out_q.h);
920 jpeg_imgadr(jpeg->regs, src_addr); 991 jpeg_imgadr(jpeg->regs, src_addr);
@@ -953,14 +1024,18 @@ static void s5p_jpeg_device_run(void *priv)
953 jpeg_htbl_dc(jpeg->regs, 2); 1024 jpeg_htbl_dc(jpeg->regs, 2);
954 jpeg_htbl_ac(jpeg->regs, 3); 1025 jpeg_htbl_ac(jpeg->regs, 3);
955 jpeg_htbl_dc(jpeg->regs, 3); 1026 jpeg_htbl_dc(jpeg->regs, 3);
956 } else { 1027 } else { /* S5P_JPEG_DECODE */
957 jpeg_rst_int_enable(jpeg->regs, true); 1028 jpeg_rst_int_enable(jpeg->regs, true);
958 jpeg_data_num_int_enable(jpeg->regs, true); 1029 jpeg_data_num_int_enable(jpeg->regs, true);
959 jpeg_final_mcu_num_int_enable(jpeg->regs, true); 1030 jpeg_final_mcu_num_int_enable(jpeg->regs, true);
960 jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422); 1031 if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
1032 jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
1033 else
1034 jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
961 jpeg_jpgadr(jpeg->regs, src_addr); 1035 jpeg_jpgadr(jpeg->regs, src_addr);
962 jpeg_imgadr(jpeg->regs, dst_addr); 1036 jpeg_imgadr(jpeg->regs, dst_addr);
963 } 1037 }
1038
964 jpeg_start(jpeg->regs); 1039 jpeg_start(jpeg->regs);
965} 1040}
966 1041
@@ -1162,6 +1237,8 @@ static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
1162 bool timer_elapsed = false; 1237 bool timer_elapsed = false;
1163 bool op_completed = false; 1238 bool op_completed = false;
1164 1239
1240 spin_lock(&jpeg->slock);
1241
1165 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); 1242 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1166 1243
1167 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx); 1244 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
@@ -1192,6 +1269,9 @@ static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
1192 v4l2_m2m_buf_done(dst_buf, state); 1269 v4l2_m2m_buf_done(dst_buf, state);
1193 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->m2m_ctx); 1270 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->m2m_ctx);
1194 1271
1272 curr_ctx->subsampling = jpeg_get_subsampling_mode(jpeg->regs);
1273 spin_unlock(&jpeg->slock);
1274
1195 jpeg_clear_int(jpeg->regs); 1275 jpeg_clear_int(jpeg->regs);
1196 1276
1197 return IRQ_HANDLED; 1277 return IRQ_HANDLED;
@@ -1215,6 +1295,7 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
1215 return -ENOMEM; 1295 return -ENOMEM;
1216 1296
1217 mutex_init(&jpeg->lock); 1297 mutex_init(&jpeg->lock);
1298 spin_lock_init(&jpeg->slock);
1218 jpeg->dev = &pdev->dev; 1299 jpeg->dev = &pdev->dev;
1219 1300
1220 /* memory-mapped registers */ 1301 /* memory-mapped registers */
diff --git a/drivers/media/video/s5p-jpeg/jpeg-core.h b/drivers/media/video/s5p-jpeg/jpeg-core.h
index facad6114f5e..38d7367f7a6d 100644
--- a/drivers/media/video/s5p-jpeg/jpeg-core.h
+++ b/drivers/media/video/s5p-jpeg/jpeg-core.h
@@ -14,6 +14,8 @@
14#define JPEG_CORE_H_ 14#define JPEG_CORE_H_
15 15
16#include <media/v4l2-device.h> 16#include <media/v4l2-device.h>
17#include <media/v4l2-fh.h>
18#include <media/v4l2-ctrls.h>
17 19
18#define S5P_JPEG_M2M_NAME "s5p-jpeg" 20#define S5P_JPEG_M2M_NAME "s5p-jpeg"
19 21
@@ -47,6 +49,7 @@
47/** 49/**
48 * struct s5p_jpeg - JPEG IP abstraction 50 * struct s5p_jpeg - JPEG IP abstraction
49 * @lock: the mutex protecting this structure 51 * @lock: the mutex protecting this structure
52 * @slock: spinlock protecting the device contexts
50 * @v4l2_dev: v4l2 device for mem2mem mode 53 * @v4l2_dev: v4l2 device for mem2mem mode
51 * @vfd_encoder: video device node for encoder mem2mem mode 54 * @vfd_encoder: video device node for encoder mem2mem mode
52 * @vfd_decoder: video device node for decoder mem2mem mode 55 * @vfd_decoder: video device node for decoder mem2mem mode
@@ -60,6 +63,7 @@
60 */ 63 */
61struct s5p_jpeg { 64struct s5p_jpeg {
62 struct mutex lock; 65 struct mutex lock;
66 struct spinlock slock;
63 67
64 struct v4l2_device v4l2_dev; 68 struct v4l2_device v4l2_dev;
65 struct video_device *vfd_encoder; 69 struct video_device *vfd_encoder;
@@ -117,15 +121,20 @@ struct s5p_jpeg_q_data {
117 * @out_q: source (output) queue information 121 * @out_q: source (output) queue information
118 * @cap_fmt: destination (capture) queue queue information 122 * @cap_fmt: destination (capture) queue queue information
119 * @hdr_parsed: set if header has been parsed during decompression 123 * @hdr_parsed: set if header has been parsed during decompression
124 * @ctrl_handler: controls handler
120 */ 125 */
121struct s5p_jpeg_ctx { 126struct s5p_jpeg_ctx {
122 struct s5p_jpeg *jpeg; 127 struct s5p_jpeg *jpeg;
123 unsigned int mode; 128 unsigned int mode;
124 unsigned int compr_quality; 129 unsigned short compr_quality;
130 unsigned short restart_interval;
131 unsigned short subsampling;
125 struct v4l2_m2m_ctx *m2m_ctx; 132 struct v4l2_m2m_ctx *m2m_ctx;
126 struct s5p_jpeg_q_data out_q; 133 struct s5p_jpeg_q_data out_q;
127 struct s5p_jpeg_q_data cap_q; 134 struct s5p_jpeg_q_data cap_q;
135 struct v4l2_fh fh;
128 bool hdr_parsed; 136 bool hdr_parsed;
137 struct v4l2_ctrl_handler ctrl_handler;
129}; 138};
130 139
131/** 140/**
diff --git a/drivers/media/video/s5p-jpeg/jpeg-hw.h b/drivers/media/video/s5p-jpeg/jpeg-hw.h
index e10c744e9f23..f12f0fdbde7c 100644
--- a/drivers/media/video/s5p-jpeg/jpeg-hw.h
+++ b/drivers/media/video/s5p-jpeg/jpeg-hw.h
@@ -13,6 +13,7 @@
13#define JPEG_HW_H_ 13#define JPEG_HW_H_
14 14
15#include <linux/io.h> 15#include <linux/io.h>
16#include <linux/videodev2.h>
16 17
17#include "jpeg-hw.h" 18#include "jpeg-hw.h"
18#include "jpeg-regs.h" 19#include "jpeg-regs.h"
@@ -25,8 +26,6 @@
25#define S5P_JPEG_DECODE 1 26#define S5P_JPEG_DECODE 1
26#define S5P_JPEG_RAW_IN_565 0 27#define S5P_JPEG_RAW_IN_565 0
27#define S5P_JPEG_RAW_IN_422 1 28#define S5P_JPEG_RAW_IN_422 1
28#define S5P_JPEG_SUBSAMPLING_422 0
29#define S5P_JPEG_SUBSAMPLING_420 1
30#define S5P_JPEG_RAW_OUT_422 0 29#define S5P_JPEG_RAW_OUT_422 0
31#define S5P_JPEG_RAW_OUT_420 1 30#define S5P_JPEG_RAW_OUT_420 1
32 31
@@ -91,21 +90,26 @@ static inline void jpeg_proc_mode(void __iomem *regs, unsigned long mode)
91 writel(reg, regs + S5P_JPGMOD); 90 writel(reg, regs + S5P_JPGMOD);
92} 91}
93 92
94static inline void jpeg_subsampling_mode(void __iomem *regs, unsigned long mode) 93static inline void jpeg_subsampling_mode(void __iomem *regs, unsigned int mode)
95{ 94{
96 unsigned long reg, m; 95 unsigned long reg, m;
97 96
98 m = S5P_SUBSAMPLING_MODE_422; 97 if (mode == V4L2_JPEG_CHROMA_SUBSAMPLING_420)
99 if (mode == S5P_JPEG_SUBSAMPLING_422)
100 m = S5P_SUBSAMPLING_MODE_422;
101 else if (mode == S5P_JPEG_SUBSAMPLING_420)
102 m = S5P_SUBSAMPLING_MODE_420; 98 m = S5P_SUBSAMPLING_MODE_420;
99 else
100 m = S5P_SUBSAMPLING_MODE_422;
101
103 reg = readl(regs + S5P_JPGMOD); 102 reg = readl(regs + S5P_JPGMOD);
104 reg &= ~S5P_SUBSAMPLING_MODE_MASK; 103 reg &= ~S5P_SUBSAMPLING_MODE_MASK;
105 reg |= m; 104 reg |= m;
106 writel(reg, regs + S5P_JPGMOD); 105 writel(reg, regs + S5P_JPGMOD);
107} 106}
108 107
108static inline unsigned int jpeg_get_subsampling_mode(void __iomem *regs)
109{
110 return readl(regs + S5P_JPGMOD) & S5P_SUBSAMPLING_MODE_MASK;
111}
112
109static inline void jpeg_dri(void __iomem *regs, unsigned int dri) 113static inline void jpeg_dri(void __iomem *regs, unsigned int dri)
110{ 114{
111 unsigned long reg; 115 unsigned long reg;
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_pm.c b/drivers/media/video/s5p-mfc/s5p_mfc_pm.c
index f6a3035c4fb7..738a607be43c 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_pm.c
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_pm.c
@@ -41,15 +41,29 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev)
41 pm->clock_gate = clk_get(&dev->plat_dev->dev, MFC_GATE_CLK_NAME); 41 pm->clock_gate = clk_get(&dev->plat_dev->dev, MFC_GATE_CLK_NAME);
42 if (IS_ERR(pm->clock_gate)) { 42 if (IS_ERR(pm->clock_gate)) {
43 mfc_err("Failed to get clock-gating control\n"); 43 mfc_err("Failed to get clock-gating control\n");
44 ret = -ENOENT; 44 ret = PTR_ERR(pm->clock_gate);
45 goto err_g_ip_clk; 45 goto err_g_ip_clk;
46 } 46 }
47
48 ret = clk_prepare(pm->clock_gate);
49 if (ret) {
50 mfc_err("Failed to preapre clock-gating control\n");
51 goto err_p_ip_clk;
52 }
53
47 pm->clock = clk_get(&dev->plat_dev->dev, MFC_CLKNAME); 54 pm->clock = clk_get(&dev->plat_dev->dev, MFC_CLKNAME);
48 if (IS_ERR(pm->clock)) { 55 if (IS_ERR(pm->clock)) {
49 mfc_err("Failed to get MFC clock\n"); 56 mfc_err("Failed to get MFC clock\n");
50 ret = -ENOENT; 57 ret = PTR_ERR(pm->clock);
51 goto err_g_ip_clk_2; 58 goto err_g_ip_clk_2;
52 } 59 }
60
61 ret = clk_prepare(pm->clock);
62 if (ret) {
63 mfc_err("Failed to prepare MFC clock\n");
64 goto err_p_ip_clk_2;
65 }
66
53 atomic_set(&pm->power, 0); 67 atomic_set(&pm->power, 0);
54#ifdef CONFIG_PM_RUNTIME 68#ifdef CONFIG_PM_RUNTIME
55 pm->device = &dev->plat_dev->dev; 69 pm->device = &dev->plat_dev->dev;
@@ -59,7 +73,11 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev)
59 atomic_set(&clk_ref, 0); 73 atomic_set(&clk_ref, 0);
60#endif 74#endif
61 return 0; 75 return 0;
76err_p_ip_clk_2:
77 clk_put(pm->clock);
62err_g_ip_clk_2: 78err_g_ip_clk_2:
79 clk_unprepare(pm->clock_gate);
80err_p_ip_clk:
63 clk_put(pm->clock_gate); 81 clk_put(pm->clock_gate);
64err_g_ip_clk: 82err_g_ip_clk:
65 return ret; 83 return ret;
@@ -67,7 +85,9 @@ err_g_ip_clk:
67 85
68void s5p_mfc_final_pm(struct s5p_mfc_dev *dev) 86void s5p_mfc_final_pm(struct s5p_mfc_dev *dev)
69{ 87{
88 clk_unprepare(pm->clock_gate);
70 clk_put(pm->clock_gate); 89 clk_put(pm->clock_gate);
90 clk_unprepare(pm->clock);
71 clk_put(pm->clock); 91 clk_put(pm->clock);
72#ifdef CONFIG_PM_RUNTIME 92#ifdef CONFIG_PM_RUNTIME
73 pm_runtime_disable(pm->device); 93 pm_runtime_disable(pm->device);
diff --git a/drivers/media/video/s5p-tv/Kconfig b/drivers/media/video/s5p-tv/Kconfig
index f2a09779ec8f..f248b2856720 100644
--- a/drivers/media/video/s5p-tv/Kconfig
+++ b/drivers/media/video/s5p-tv/Kconfig
@@ -46,6 +46,16 @@ config VIDEO_SAMSUNG_S5P_HDMIPHY
46 as module. It is an I2C driver, that exposes a V4L2 46 as module. It is an I2C driver, that exposes a V4L2
47 subdev for use by other drivers. 47 subdev for use by other drivers.
48 48
49config VIDEO_SAMSUNG_S5P_SII9234
50 tristate "Samsung SII9234 Driver"
51 depends on VIDEO_DEV && VIDEO_V4L2 && I2C
52 depends on VIDEO_SAMSUNG_S5P_TV
53 help
54 Say Y here if you want support for the MHL interface
55 in S5P Samsung SoC. The driver can be compiled
56 as module. It is an I2C driver, that exposes a V4L2
57 subdev for use by other drivers.
58
49config VIDEO_SAMSUNG_S5P_SDO 59config VIDEO_SAMSUNG_S5P_SDO
50 tristate "Samsung Analog TV Driver" 60 tristate "Samsung Analog TV Driver"
51 depends on VIDEO_DEV && VIDEO_V4L2 61 depends on VIDEO_DEV && VIDEO_V4L2
diff --git a/drivers/media/video/s5p-tv/Makefile b/drivers/media/video/s5p-tv/Makefile
index 37e4c17663b4..f49e756a2fde 100644
--- a/drivers/media/video/s5p-tv/Makefile
+++ b/drivers/media/video/s5p-tv/Makefile
@@ -8,6 +8,8 @@
8 8
9obj-$(CONFIG_VIDEO_SAMSUNG_S5P_HDMIPHY) += s5p-hdmiphy.o 9obj-$(CONFIG_VIDEO_SAMSUNG_S5P_HDMIPHY) += s5p-hdmiphy.o
10s5p-hdmiphy-y += hdmiphy_drv.o 10s5p-hdmiphy-y += hdmiphy_drv.o
11obj-$(CONFIG_VIDEO_SAMSUNG_S5P_SII9234) += s5p-sii9234.o
12s5p-sii9234-y += sii9234_drv.o
11obj-$(CONFIG_VIDEO_SAMSUNG_S5P_HDMI) += s5p-hdmi.o 13obj-$(CONFIG_VIDEO_SAMSUNG_S5P_HDMI) += s5p-hdmi.o
12s5p-hdmi-y += hdmi_drv.o 14s5p-hdmi-y += hdmi_drv.o
13obj-$(CONFIG_VIDEO_SAMSUNG_S5P_SDO) += s5p-sdo.o 15obj-$(CONFIG_VIDEO_SAMSUNG_S5P_SDO) += s5p-sdo.o
diff --git a/drivers/media/video/s5p-tv/hdmi_drv.c b/drivers/media/video/s5p-tv/hdmi_drv.c
index 8b41a0410ab1..4865d25a0e57 100644
--- a/drivers/media/video/s5p-tv/hdmi_drv.c
+++ b/drivers/media/video/s5p-tv/hdmi_drv.c
@@ -30,6 +30,7 @@
30#include <linux/clk.h> 30#include <linux/clk.h>
31#include <linux/regulator/consumer.h> 31#include <linux/regulator/consumer.h>
32 32
33#include <media/s5p_hdmi.h>
33#include <media/v4l2-common.h> 34#include <media/v4l2-common.h>
34#include <media/v4l2-dev.h> 35#include <media/v4l2-dev.h>
35#include <media/v4l2-device.h> 36#include <media/v4l2-device.h>
@@ -66,6 +67,8 @@ struct hdmi_device {
66 struct v4l2_device v4l2_dev; 67 struct v4l2_device v4l2_dev;
67 /** subdev of HDMIPHY interface */ 68 /** subdev of HDMIPHY interface */
68 struct v4l2_subdev *phy_sd; 69 struct v4l2_subdev *phy_sd;
70 /** subdev of MHL interface */
71 struct v4l2_subdev *mhl_sd;
69 /** configuration of current graphic mode */ 72 /** configuration of current graphic mode */
70 const struct hdmi_preset_conf *cur_conf; 73 const struct hdmi_preset_conf *cur_conf;
71 /** current preset */ 74 /** current preset */
@@ -74,10 +77,6 @@ struct hdmi_device {
74 struct hdmi_resources res; 77 struct hdmi_resources res;
75}; 78};
76 79
77struct hdmi_driver_data {
78 int hdmiphy_bus;
79};
80
81struct hdmi_tg_regs { 80struct hdmi_tg_regs {
82 u8 cmd; 81 u8 cmd;
83 u8 h_fsz_l; 82 u8 h_fsz_l;
@@ -129,23 +128,11 @@ struct hdmi_preset_conf {
129 struct v4l2_mbus_framefmt mbus_fmt; 128 struct v4l2_mbus_framefmt mbus_fmt;
130}; 129};
131 130
132/* I2C module and id for HDMIPHY */
133static struct i2c_board_info hdmiphy_info = {
134 I2C_BOARD_INFO("hdmiphy", 0x38),
135};
136
137static struct hdmi_driver_data hdmi_driver_data[] = {
138 { .hdmiphy_bus = 3 },
139 { .hdmiphy_bus = 8 },
140};
141
142static struct platform_device_id hdmi_driver_types[] = { 131static struct platform_device_id hdmi_driver_types[] = {
143 { 132 {
144 .name = "s5pv210-hdmi", 133 .name = "s5pv210-hdmi",
145 .driver_data = (unsigned long)&hdmi_driver_data[0],
146 }, { 134 }, {
147 .name = "exynos4-hdmi", 135 .name = "exynos4-hdmi",
148 .driver_data = (unsigned long)&hdmi_driver_data[1],
149 }, { 136 }, {
150 /* end node */ 137 /* end node */
151 } 138 }
@@ -587,7 +574,15 @@ static int hdmi_streamon(struct hdmi_device *hdev)
587 if (tries == 0) { 574 if (tries == 0) {
588 dev_err(dev, "hdmiphy's pll could not reach steady state.\n"); 575 dev_err(dev, "hdmiphy's pll could not reach steady state.\n");
589 v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0); 576 v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0);
590 hdmi_dumpregs(hdev, "s_stream"); 577 hdmi_dumpregs(hdev, "hdmiphy - s_stream");
578 return -EIO;
579 }
580
581 /* starting MHL */
582 ret = v4l2_subdev_call(hdev->mhl_sd, video, s_stream, 1);
583 if (hdev->mhl_sd && ret) {
584 v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0);
585 hdmi_dumpregs(hdev, "mhl - s_stream");
591 return -EIO; 586 return -EIO;
592 } 587 }
593 588
@@ -618,6 +613,7 @@ static int hdmi_streamoff(struct hdmi_device *hdev)
618 clk_set_parent(res->sclk_hdmi, res->sclk_pixel); 613 clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
619 clk_enable(res->sclk_hdmi); 614 clk_enable(res->sclk_hdmi);
620 615
616 v4l2_subdev_call(hdev->mhl_sd, video, s_stream, 0);
621 v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0); 617 v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0);
622 618
623 hdmi_dumpregs(hdev, "streamoff"); 619 hdmi_dumpregs(hdev, "streamoff");
@@ -739,6 +735,7 @@ static int hdmi_runtime_suspend(struct device *dev)
739 struct hdmi_device *hdev = sd_to_hdmi_dev(sd); 735 struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
740 736
741 dev_dbg(dev, "%s\n", __func__); 737 dev_dbg(dev, "%s\n", __func__);
738 v4l2_subdev_call(hdev->mhl_sd, core, s_power, 0);
742 hdmi_resource_poweroff(&hdev->res); 739 hdmi_resource_poweroff(&hdev->res);
743 return 0; 740 return 0;
744} 741}
@@ -757,6 +754,11 @@ static int hdmi_runtime_resume(struct device *dev)
757 if (ret) 754 if (ret)
758 goto fail; 755 goto fail;
759 756
757 /* starting MHL */
758 ret = v4l2_subdev_call(hdev->mhl_sd, core, s_power, 1);
759 if (hdev->mhl_sd && ret)
760 goto fail;
761
760 dev_dbg(dev, "poweron succeed\n"); 762 dev_dbg(dev, "poweron succeed\n");
761 763
762 return 0; 764 return 0;
@@ -867,15 +869,21 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
867{ 869{
868 struct device *dev = &pdev->dev; 870 struct device *dev = &pdev->dev;
869 struct resource *res; 871 struct resource *res;
870 struct i2c_adapter *phy_adapter; 872 struct i2c_adapter *adapter;
871 struct v4l2_subdev *sd; 873 struct v4l2_subdev *sd;
872 struct hdmi_device *hdmi_dev = NULL; 874 struct hdmi_device *hdmi_dev = NULL;
873 struct hdmi_driver_data *drv_data; 875 struct s5p_hdmi_platform_data *pdata = dev->platform_data;
874 int ret; 876 int ret;
875 877
876 dev_dbg(dev, "probe start\n"); 878 dev_dbg(dev, "probe start\n");
877 879
878 hdmi_dev = kzalloc(sizeof(*hdmi_dev), GFP_KERNEL); 880 if (!pdata) {
881 dev_err(dev, "platform data is missing\n");
882 ret = -ENODEV;
883 goto fail;
884 }
885
886 hdmi_dev = devm_kzalloc(&pdev->dev, sizeof(*hdmi_dev), GFP_KERNEL);
879 if (!hdmi_dev) { 887 if (!hdmi_dev) {
880 dev_err(dev, "out of memory\n"); 888 dev_err(dev, "out of memory\n");
881 ret = -ENOMEM; 889 ret = -ENOMEM;
@@ -886,7 +894,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
886 894
887 ret = hdmi_resources_init(hdmi_dev); 895 ret = hdmi_resources_init(hdmi_dev);
888 if (ret) 896 if (ret)
889 goto fail_hdev; 897 goto fail;
890 898
891 /* mapping HDMI registers */ 899 /* mapping HDMI registers */
892 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 900 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -896,24 +904,26 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
896 goto fail_init; 904 goto fail_init;
897 } 905 }
898 906
899 hdmi_dev->regs = ioremap(res->start, resource_size(res)); 907 hdmi_dev->regs = devm_ioremap(&pdev->dev, res->start,
908 resource_size(res));
900 if (hdmi_dev->regs == NULL) { 909 if (hdmi_dev->regs == NULL) {
901 dev_err(dev, "register mapping failed.\n"); 910 dev_err(dev, "register mapping failed.\n");
902 ret = -ENXIO; 911 ret = -ENXIO;
903 goto fail_hdev; 912 goto fail_init;
904 } 913 }
905 914
906 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 915 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
907 if (res == NULL) { 916 if (res == NULL) {
908 dev_err(dev, "get interrupt resource failed.\n"); 917 dev_err(dev, "get interrupt resource failed.\n");
909 ret = -ENXIO; 918 ret = -ENXIO;
910 goto fail_regs; 919 goto fail_init;
911 } 920 }
912 921
913 ret = request_irq(res->start, hdmi_irq_handler, 0, "hdmi", hdmi_dev); 922 ret = devm_request_irq(&pdev->dev, res->start, hdmi_irq_handler, 0,
923 "hdmi", hdmi_dev);
914 if (ret) { 924 if (ret) {
915 dev_err(dev, "request interrupt failed.\n"); 925 dev_err(dev, "request interrupt failed.\n");
916 goto fail_regs; 926 goto fail_init;
917 } 927 }
918 hdmi_dev->irq = res->start; 928 hdmi_dev->irq = res->start;
919 929
@@ -924,28 +934,54 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
924 ret = v4l2_device_register(NULL, &hdmi_dev->v4l2_dev); 934 ret = v4l2_device_register(NULL, &hdmi_dev->v4l2_dev);
925 if (ret) { 935 if (ret) {
926 dev_err(dev, "could not register v4l2 device.\n"); 936 dev_err(dev, "could not register v4l2 device.\n");
927 goto fail_irq; 937 goto fail_init;
928 } 938 }
929 939
930 drv_data = (struct hdmi_driver_data *) 940 /* testing if hdmiphy info is present */
931 platform_get_device_id(pdev)->driver_data; 941 if (!pdata->hdmiphy_info) {
932 phy_adapter = i2c_get_adapter(drv_data->hdmiphy_bus); 942 dev_err(dev, "hdmiphy info is missing in platform data\n");
933 if (phy_adapter == NULL) { 943 ret = -ENXIO;
934 dev_err(dev, "adapter request failed\n"); 944 goto fail_vdev;
945 }
946
947 adapter = i2c_get_adapter(pdata->hdmiphy_bus);
948 if (adapter == NULL) {
949 dev_err(dev, "hdmiphy adapter request failed\n");
935 ret = -ENXIO; 950 ret = -ENXIO;
936 goto fail_vdev; 951 goto fail_vdev;
937 } 952 }
938 953
939 hdmi_dev->phy_sd = v4l2_i2c_new_subdev_board(&hdmi_dev->v4l2_dev, 954 hdmi_dev->phy_sd = v4l2_i2c_new_subdev_board(&hdmi_dev->v4l2_dev,
940 phy_adapter, &hdmiphy_info, NULL); 955 adapter, pdata->hdmiphy_info, NULL);
941 /* on failure or not adapter is no longer useful */ 956 /* on failure or not adapter is no longer useful */
942 i2c_put_adapter(phy_adapter); 957 i2c_put_adapter(adapter);
943 if (hdmi_dev->phy_sd == NULL) { 958 if (hdmi_dev->phy_sd == NULL) {
944 dev_err(dev, "missing subdev for hdmiphy\n"); 959 dev_err(dev, "missing subdev for hdmiphy\n");
945 ret = -ENODEV; 960 ret = -ENODEV;
946 goto fail_vdev; 961 goto fail_vdev;
947 } 962 }
948 963
964 /* initialization of MHL interface if present */
965 if (pdata->mhl_info) {
966 adapter = i2c_get_adapter(pdata->mhl_bus);
967 if (adapter == NULL) {
968 dev_err(dev, "MHL adapter request failed\n");
969 ret = -ENXIO;
970 goto fail_vdev;
971 }
972
973 hdmi_dev->mhl_sd = v4l2_i2c_new_subdev_board(
974 &hdmi_dev->v4l2_dev, adapter,
975 pdata->mhl_info, NULL);
976 /* on failure or not adapter is no longer useful */
977 i2c_put_adapter(adapter);
978 if (hdmi_dev->mhl_sd == NULL) {
979 dev_err(dev, "missing subdev for MHL\n");
980 ret = -ENODEV;
981 goto fail_vdev;
982 }
983 }
984
949 clk_enable(hdmi_dev->res.hdmi); 985 clk_enable(hdmi_dev->res.hdmi);
950 986
951 pm_runtime_enable(dev); 987 pm_runtime_enable(dev);
@@ -962,25 +998,16 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
962 /* storing subdev for call that have only access to struct device */ 998 /* storing subdev for call that have only access to struct device */
963 dev_set_drvdata(dev, sd); 999 dev_set_drvdata(dev, sd);
964 1000
965 dev_info(dev, "probe sucessful\n"); 1001 dev_info(dev, "probe successful\n");
966 1002
967 return 0; 1003 return 0;
968 1004
969fail_vdev: 1005fail_vdev:
970 v4l2_device_unregister(&hdmi_dev->v4l2_dev); 1006 v4l2_device_unregister(&hdmi_dev->v4l2_dev);
971 1007
972fail_irq:
973 free_irq(hdmi_dev->irq, hdmi_dev);
974
975fail_regs:
976 iounmap(hdmi_dev->regs);
977
978fail_init: 1008fail_init:
979 hdmi_resources_cleanup(hdmi_dev); 1009 hdmi_resources_cleanup(hdmi_dev);
980 1010
981fail_hdev:
982 kfree(hdmi_dev);
983
984fail: 1011fail:
985 dev_err(dev, "probe failed\n"); 1012 dev_err(dev, "probe failed\n");
986 return ret; 1013 return ret;
@@ -996,11 +1023,8 @@ static int __devexit hdmi_remove(struct platform_device *pdev)
996 clk_disable(hdmi_dev->res.hdmi); 1023 clk_disable(hdmi_dev->res.hdmi);
997 v4l2_device_unregister(&hdmi_dev->v4l2_dev); 1024 v4l2_device_unregister(&hdmi_dev->v4l2_dev);
998 disable_irq(hdmi_dev->irq); 1025 disable_irq(hdmi_dev->irq);
999 free_irq(hdmi_dev->irq, hdmi_dev);
1000 iounmap(hdmi_dev->regs);
1001 hdmi_resources_cleanup(hdmi_dev); 1026 hdmi_resources_cleanup(hdmi_dev);
1002 kfree(hdmi_dev); 1027 dev_info(dev, "remove successful\n");
1003 dev_info(dev, "remove sucessful\n");
1004 1028
1005 return 0; 1029 return 0;
1006} 1030}
diff --git a/drivers/media/video/s5p-tv/hdmiphy_drv.c b/drivers/media/video/s5p-tv/hdmiphy_drv.c
index 6693f4aff108..0afef77747e5 100644
--- a/drivers/media/video/s5p-tv/hdmiphy_drv.c
+++ b/drivers/media/video/s5p-tv/hdmiphy_drv.c
@@ -175,14 +175,4 @@ static struct i2c_driver hdmiphy_driver = {
175 .id_table = hdmiphy_id, 175 .id_table = hdmiphy_id,
176}; 176};
177 177
178static int __init hdmiphy_init(void) 178module_i2c_driver(hdmiphy_driver);
179{
180 return i2c_add_driver(&hdmiphy_driver);
181}
182module_init(hdmiphy_init);
183
184static void __exit hdmiphy_exit(void)
185{
186 i2c_del_driver(&hdmiphy_driver);
187}
188module_exit(hdmiphy_exit);
diff --git a/drivers/media/video/s5p-tv/mixer_drv.c b/drivers/media/video/s5p-tv/mixer_drv.c
index 00643094b221..a2c0c25ad130 100644
--- a/drivers/media/video/s5p-tv/mixer_drv.c
+++ b/drivers/media/video/s5p-tv/mixer_drv.c
@@ -444,7 +444,7 @@ static int __devexit mxr_remove(struct platform_device *pdev)
444 444
445 kfree(mdev); 445 kfree(mdev);
446 446
447 dev_info(dev, "remove sucessful\n"); 447 dev_info(dev, "remove successful\n");
448 return 0; 448 return 0;
449} 449}
450 450
diff --git a/drivers/media/video/s5p-tv/sdo_drv.c b/drivers/media/video/s5p-tv/sdo_drv.c
index 059e7749ce95..f6bca2c20e89 100644
--- a/drivers/media/video/s5p-tv/sdo_drv.c
+++ b/drivers/media/video/s5p-tv/sdo_drv.c
@@ -301,7 +301,7 @@ static int __devinit sdo_probe(struct platform_device *pdev)
301 struct clk *sclk_vpll; 301 struct clk *sclk_vpll;
302 302
303 dev_info(dev, "probe start\n"); 303 dev_info(dev, "probe start\n");
304 sdev = kzalloc(sizeof *sdev, GFP_KERNEL); 304 sdev = devm_kzalloc(&pdev->dev, sizeof *sdev, GFP_KERNEL);
305 if (!sdev) { 305 if (!sdev) {
306 dev_err(dev, "not enough memory.\n"); 306 dev_err(dev, "not enough memory.\n");
307 ret = -ENOMEM; 307 ret = -ENOMEM;
@@ -314,14 +314,14 @@ static int __devinit sdo_probe(struct platform_device *pdev)
314 if (res == NULL) { 314 if (res == NULL) {
315 dev_err(dev, "get memory resource failed.\n"); 315 dev_err(dev, "get memory resource failed.\n");
316 ret = -ENXIO; 316 ret = -ENXIO;
317 goto fail_sdev; 317 goto fail;
318 } 318 }
319 319
320 sdev->regs = ioremap(res->start, resource_size(res)); 320 sdev->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
321 if (sdev->regs == NULL) { 321 if (sdev->regs == NULL) {
322 dev_err(dev, "register mapping failed.\n"); 322 dev_err(dev, "register mapping failed.\n");
323 ret = -ENXIO; 323 ret = -ENXIO;
324 goto fail_sdev; 324 goto fail;
325 } 325 }
326 326
327 /* acquiring interrupt */ 327 /* acquiring interrupt */
@@ -329,12 +329,13 @@ static int __devinit sdo_probe(struct platform_device *pdev)
329 if (res == NULL) { 329 if (res == NULL) {
330 dev_err(dev, "get interrupt resource failed.\n"); 330 dev_err(dev, "get interrupt resource failed.\n");
331 ret = -ENXIO; 331 ret = -ENXIO;
332 goto fail_regs; 332 goto fail;
333 } 333 }
334 ret = request_irq(res->start, sdo_irq_handler, 0, "s5p-sdo", sdev); 334 ret = devm_request_irq(&pdev->dev, res->start, sdo_irq_handler, 0,
335 "s5p-sdo", sdev);
335 if (ret) { 336 if (ret) {
336 dev_err(dev, "request interrupt failed.\n"); 337 dev_err(dev, "request interrupt failed.\n");
337 goto fail_regs; 338 goto fail;
338 } 339 }
339 sdev->irq = res->start; 340 sdev->irq = res->start;
340 341
@@ -343,7 +344,7 @@ static int __devinit sdo_probe(struct platform_device *pdev)
343 if (IS_ERR_OR_NULL(sdev->sclk_dac)) { 344 if (IS_ERR_OR_NULL(sdev->sclk_dac)) {
344 dev_err(dev, "failed to get clock 'sclk_dac'\n"); 345 dev_err(dev, "failed to get clock 'sclk_dac'\n");
345 ret = -ENXIO; 346 ret = -ENXIO;
346 goto fail_irq; 347 goto fail;
347 } 348 }
348 sdev->dac = clk_get(dev, "dac"); 349 sdev->dac = clk_get(dev, "dac");
349 if (IS_ERR_OR_NULL(sdev->dac)) { 350 if (IS_ERR_OR_NULL(sdev->dac)) {
@@ -415,12 +416,6 @@ fail_dac:
415 clk_put(sdev->dac); 416 clk_put(sdev->dac);
416fail_sclk_dac: 417fail_sclk_dac:
417 clk_put(sdev->sclk_dac); 418 clk_put(sdev->sclk_dac);
418fail_irq:
419 free_irq(sdev->irq, sdev);
420fail_regs:
421 iounmap(sdev->regs);
422fail_sdev:
423 kfree(sdev);
424fail: 419fail:
425 dev_info(dev, "probe failed\n"); 420 dev_info(dev, "probe failed\n");
426 return ret; 421 return ret;
@@ -439,9 +434,6 @@ static int __devexit sdo_remove(struct platform_device *pdev)
439 clk_put(sdev->dacphy); 434 clk_put(sdev->dacphy);
440 clk_put(sdev->dac); 435 clk_put(sdev->dac);
441 clk_put(sdev->sclk_dac); 436 clk_put(sdev->sclk_dac);
442 free_irq(sdev->irq, sdev);
443 iounmap(sdev->regs);
444 kfree(sdev);
445 437
446 dev_info(&pdev->dev, "remove successful\n"); 438 dev_info(&pdev->dev, "remove successful\n");
447 return 0; 439 return 0;
diff --git a/drivers/media/video/s5p-tv/sii9234_drv.c b/drivers/media/video/s5p-tv/sii9234_drv.c
new file mode 100644
index 000000000000..0f31eccd7b80
--- /dev/null
+++ b/drivers/media/video/s5p-tv/sii9234_drv.c
@@ -0,0 +1,432 @@
1/*
2 * Samsung MHL interface driver
3 *
4 * Copyright (C) 2011 Samsung Electronics Co.Ltd
5 * Author: Tomasz Stanislawski <t.stanislaws@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/delay.h>
14#include <linux/err.h>
15#include <linux/freezer.h>
16#include <linux/gpio.h>
17#include <linux/i2c.h>
18#include <linux/interrupt.h>
19#include <linux/irq.h>
20#include <linux/kthread.h>
21#include <linux/module.h>
22#include <linux/pm_runtime.h>
23#include <linux/regulator/machine.h>
24#include <linux/slab.h>
25
26#include <mach/gpio.h>
27#include <plat/gpio-cfg.h>
28
29#include <media/sii9234.h>
30#include <media/v4l2-subdev.h>
31
32MODULE_AUTHOR("Tomasz Stanislawski <t.stanislaws@samsung.com>");
33MODULE_DESCRIPTION("Samsung MHL interface driver");
34MODULE_LICENSE("GPL");
35
36struct sii9234_context {
37 struct i2c_client *client;
38 struct regulator *power;
39 int gpio_n_reset;
40 struct v4l2_subdev sd;
41};
42
43static inline struct sii9234_context *sd_to_context(struct v4l2_subdev *sd)
44{
45 return container_of(sd, struct sii9234_context, sd);
46}
47
48static inline int sii9234_readb(struct i2c_client *client, int addr)
49{
50 return i2c_smbus_read_byte_data(client, addr);
51}
52
53static inline int sii9234_writeb(struct i2c_client *client, int addr, int value)
54{
55 return i2c_smbus_write_byte_data(client, addr, value);
56}
57
58static inline int sii9234_writeb_mask(struct i2c_client *client, int addr,
59 int value, int mask)
60{
61 int ret;
62
63 ret = i2c_smbus_read_byte_data(client, addr);
64 if (ret < 0)
65 return ret;
66 ret = (ret & ~mask) | (value & mask);
67 return i2c_smbus_write_byte_data(client, addr, ret);
68}
69
70static inline int sii9234_readb_idx(struct i2c_client *client, int addr)
71{
72 int ret;
73 ret = i2c_smbus_write_byte_data(client, 0xbc, addr >> 8);
74 if (ret < 0)
75 return ret;
76 ret = i2c_smbus_write_byte_data(client, 0xbd, addr & 0xff);
77 if (ret < 0)
78 return ret;
79 return i2c_smbus_read_byte_data(client, 0xbe);
80}
81
82static inline int sii9234_writeb_idx(struct i2c_client *client, int addr,
83 int value)
84{
85 int ret;
86 ret = i2c_smbus_write_byte_data(client, 0xbc, addr >> 8);
87 if (ret < 0)
88 return ret;
89 ret = i2c_smbus_write_byte_data(client, 0xbd, addr & 0xff);
90 if (ret < 0)
91 return ret;
92 ret = i2c_smbus_write_byte_data(client, 0xbe, value);
93 return ret;
94}
95
96static inline int sii9234_writeb_idx_mask(struct i2c_client *client, int addr,
97 int value, int mask)
98{
99 int ret;
100
101 ret = sii9234_readb_idx(client, addr);
102 if (ret < 0)
103 return ret;
104 ret = (ret & ~mask) | (value & mask);
105 return sii9234_writeb_idx(client, addr, ret);
106}
107
108static int sii9234_reset(struct sii9234_context *ctx)
109{
110 struct i2c_client *client = ctx->client;
111 struct device *dev = &client->dev;
112 int ret, tries;
113
114 gpio_direction_output(ctx->gpio_n_reset, 1);
115 mdelay(1);
116 gpio_direction_output(ctx->gpio_n_reset, 0);
117 mdelay(1);
118 gpio_direction_output(ctx->gpio_n_reset, 1);
119 mdelay(1);
120
121 /* going to TTPI mode */
122 ret = sii9234_writeb(client, 0xc7, 0);
123 if (ret < 0) {
124 dev_err(dev, "failed to set TTPI mode\n");
125 return ret;
126 }
127 for (tries = 0; tries < 100 ; ++tries) {
128 ret = sii9234_readb(client, 0x1b);
129 if (ret > 0)
130 break;
131 if (ret < 0) {
132 dev_err(dev, "failed to reset device\n");
133 return -EIO;
134 }
135 mdelay(1);
136 }
137 if (tries == 100) {
138 dev_err(dev, "maximal number of tries reached\n");
139 return -EIO;
140 }
141
142 return 0;
143}
144
145static int sii9234_verify_version(struct i2c_client *client)
146{
147 struct device *dev = &client->dev;
148 int family, rev, tpi_rev, dev_id, sub_id, hdcp, id;
149
150 family = sii9234_readb(client, 0x1b);
151 rev = sii9234_readb(client, 0x1c) & 0x0f;
152 tpi_rev = sii9234_readb(client, 0x1d) & 0x7f;
153 dev_id = sii9234_readb_idx(client, 0x0103);
154 sub_id = sii9234_readb_idx(client, 0x0102);
155 hdcp = sii9234_readb(client, 0x30);
156
157 if (family < 0 || rev < 0 || tpi_rev < 0 || dev_id < 0 ||
158 sub_id < 0 || hdcp < 0) {
159 dev_err(dev, "failed to read chip's version\n");
160 return -EIO;
161 }
162
163 id = (dev_id << 8) | sub_id;
164
165 dev_info(dev, "chip: SiL%02x family: %02x, rev: %02x\n",
166 id, family, rev);
167 dev_info(dev, "tpi_rev:%02x, hdcp: %02x\n", tpi_rev, hdcp);
168 if (id != 0x9234) {
169 dev_err(dev, "not supported chip\n");
170 return -ENODEV;
171 }
172
173 return 0;
174}
175
176static u8 data[][3] = {
177/* setup from driver created by doonsoo45.kim */
178 { 0x01, 0x05, 0x04 }, /* Enable Auto soft reset on SCDT = 0 */
179 { 0x01, 0x08, 0x35 }, /* Power Up TMDS Tx Core */
180 { 0x01, 0x0d, 0x1c }, /* HDMI Transcode mode enable */
181 { 0x01, 0x2b, 0x01 }, /* Enable HDCP Compliance workaround */
182 { 0x01, 0x79, 0x40 }, /* daniel test...MHL_INT */
183 { 0x01, 0x80, 0x34 }, /* Enable Rx PLL Clock Value */
184 { 0x01, 0x90, 0x27 }, /* Enable CBUS discovery */
185 { 0x01, 0x91, 0xe5 }, /* Skip RGND detection */
186 { 0x01, 0x92, 0x46 }, /* Force MHD mode */
187 { 0x01, 0x93, 0xdc }, /* Disable CBUS pull-up during RGND measurement */
188 { 0x01, 0x94, 0x66 }, /* 1.8V CBUS VTH & GND threshold */
189 { 0x01, 0x95, 0x31 }, /* RGND block & single discovery attempt */
190 { 0x01, 0x96, 0x22 }, /* use 1K and 2K setting */
191 { 0x01, 0xa0, 0x10 }, /* SIMG: Term mode */
192 { 0x01, 0xa1, 0xfc }, /* Disable internal Mobile HD driver */
193 { 0x01, 0xa3, 0xfa }, /* SIMG: Output Swing default EB, 3x Clk Mult */
194 { 0x01, 0xa5, 0x80 }, /* SIMG: RGND Hysterisis, 3x mode for Beast */
195 { 0x01, 0xa6, 0x0c }, /* SIMG: Swing Offset */
196 { 0x02, 0x3d, 0x3f }, /* Power up CVCC 1.2V core */
197 { 0x03, 0x00, 0x00 }, /* SIMG: correcting HW default */
198 { 0x03, 0x11, 0x01 }, /* Enable TxPLL Clock */
199 { 0x03, 0x12, 0x15 }, /* Enable Tx Clock Path & Equalizer */
200 { 0x03, 0x13, 0x60 }, /* SIMG: Set termination value */
201 { 0x03, 0x14, 0xf0 }, /* SIMG: Change CKDT level */
202 { 0x03, 0x17, 0x07 }, /* SIMG: PLL Calrefsel */
203 { 0x03, 0x1a, 0x20 }, /* VCO Cal */
204 { 0x03, 0x22, 0xe0 }, /* SIMG: Auto EQ */
205 { 0x03, 0x23, 0xc0 }, /* SIMG: Auto EQ */
206 { 0x03, 0x24, 0xa0 }, /* SIMG: Auto EQ */
207 { 0x03, 0x25, 0x80 }, /* SIMG: Auto EQ */
208 { 0x03, 0x26, 0x60 }, /* SIMG: Auto EQ */
209 { 0x03, 0x27, 0x40 }, /* SIMG: Auto EQ */
210 { 0x03, 0x28, 0x20 }, /* SIMG: Auto EQ */
211 { 0x03, 0x29, 0x00 }, /* SIMG: Auto EQ */
212 { 0x03, 0x31, 0x0b }, /* SIMG: Rx PLL BW value from I2C BW ~ 4MHz */
213 { 0x03, 0x45, 0x06 }, /* SIMG: DPLL Mode */
214 { 0x03, 0x4b, 0x06 }, /* SIMG: Correcting HW default */
215 { 0x03, 0x4c, 0xa0 }, /* Manual zone control */
216 { 0x03, 0x4d, 0x02 }, /* SIMG: PLL Mode Value (order is important) */
217};
218
219static int sii9234_set_internal(struct sii9234_context *ctx)
220{
221 struct i2c_client *client = ctx->client;
222 int i, ret;
223
224 for (i = 0; i < ARRAY_SIZE(data); ++i) {
225 int addr = (data[i][0] << 8) | data[i][1];
226 ret = sii9234_writeb_idx(client, addr, data[i][2]);
227 if (ret < 0)
228 return ret;
229 }
230 return 0;
231}
232
233static int sii9234_runtime_suspend(struct device *dev)
234{
235 struct v4l2_subdev *sd = dev_get_drvdata(dev);
236 struct sii9234_context *ctx = sd_to_context(sd);
237 struct i2c_client *client = ctx->client;
238
239 dev_info(dev, "suspend start\n");
240
241 sii9234_writeb_mask(client, 0x1e, 3, 3);
242 regulator_disable(ctx->power);
243
244 return 0;
245}
246
247static int sii9234_runtime_resume(struct device *dev)
248{
249 struct v4l2_subdev *sd = dev_get_drvdata(dev);
250 struct sii9234_context *ctx = sd_to_context(sd);
251 struct i2c_client *client = ctx->client;
252 int ret;
253
254 dev_info(dev, "resume start\n");
255 regulator_enable(ctx->power);
256
257 ret = sii9234_reset(ctx);
258 if (ret)
259 goto fail;
260
261 /* enable tpi */
262 ret = sii9234_writeb_mask(client, 0x1e, 1, 0);
263 if (ret < 0)
264 goto fail;
265 ret = sii9234_set_internal(ctx);
266 if (ret < 0)
267 goto fail;
268
269 return 0;
270
271fail:
272 dev_err(dev, "failed to resume\n");
273 regulator_disable(ctx->power);
274
275 return ret;
276}
277
278static const struct dev_pm_ops sii9234_pm_ops = {
279 .runtime_suspend = sii9234_runtime_suspend,
280 .runtime_resume = sii9234_runtime_resume,
281};
282
283static int sii9234_s_power(struct v4l2_subdev *sd, int on)
284{
285 struct sii9234_context *ctx = sd_to_context(sd);
286 int ret;
287
288 if (on)
289 ret = pm_runtime_get_sync(&ctx->client->dev);
290 else
291 ret = pm_runtime_put(&ctx->client->dev);
292 /* only values < 0 indicate errors */
293 return IS_ERR_VALUE(ret) ? ret : 0;
294}
295
296static int sii9234_s_stream(struct v4l2_subdev *sd, int enable)
297{
298 struct sii9234_context *ctx = sd_to_context(sd);
299
300 /* (dis/en)able TDMS output */
301 sii9234_writeb_mask(ctx->client, 0x1a, enable ? 0 : ~0 , 1 << 4);
302 return 0;
303}
304
305static const struct v4l2_subdev_core_ops sii9234_core_ops = {
306 .s_power = sii9234_s_power,
307};
308
309static const struct v4l2_subdev_video_ops sii9234_video_ops = {
310 .s_stream = sii9234_s_stream,
311};
312
313static const struct v4l2_subdev_ops sii9234_ops = {
314 .core = &sii9234_core_ops,
315 .video = &sii9234_video_ops,
316};
317
318static int __devinit sii9234_probe(struct i2c_client *client,
319 const struct i2c_device_id *id)
320{
321 struct device *dev = &client->dev;
322 struct sii9234_platform_data *pdata = dev->platform_data;
323 struct sii9234_context *ctx;
324 int ret;
325
326 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
327 if (!ctx) {
328 dev_err(dev, "out of memory\n");
329 ret = -ENOMEM;
330 goto fail;
331 }
332 ctx->client = client;
333
334 ctx->power = regulator_get(dev, "hdmi-en");
335 if (IS_ERR(ctx->power)) {
336 dev_err(dev, "failed to acquire regulator hdmi-en\n");
337 ret = PTR_ERR(ctx->power);
338 goto fail_ctx;
339 }
340
341 ctx->gpio_n_reset = pdata->gpio_n_reset;
342 ret = gpio_request(ctx->gpio_n_reset, "MHL_RST");
343 if (ret) {
344 dev_err(dev, "failed to acquire MHL_RST gpio\n");
345 goto fail_power;
346 }
347
348 v4l2_i2c_subdev_init(&ctx->sd, client, &sii9234_ops);
349
350 pm_runtime_enable(dev);
351
352 /* enable device */
353 ret = pm_runtime_get_sync(dev);
354 if (ret)
355 goto fail_pm;
356
357 /* verify chip version */
358 ret = sii9234_verify_version(client);
359 if (ret)
360 goto fail_pm_get;
361
362 /* stop processing */
363 pm_runtime_put(dev);
364
365 dev_info(dev, "probe successful\n");
366
367 return 0;
368
369fail_pm_get:
370 pm_runtime_put_sync(dev);
371
372fail_pm:
373 pm_runtime_disable(dev);
374 gpio_free(ctx->gpio_n_reset);
375
376fail_power:
377 regulator_put(ctx->power);
378
379fail_ctx:
380 kfree(ctx);
381
382fail:
383 dev_err(dev, "probe failed\n");
384
385 return ret;
386}
387
388static int __devexit sii9234_remove(struct i2c_client *client)
389{
390 struct device *dev = &client->dev;
391 struct v4l2_subdev *sd = i2c_get_clientdata(client);
392 struct sii9234_context *ctx = sd_to_context(sd);
393
394 pm_runtime_disable(dev);
395 gpio_free(ctx->gpio_n_reset);
396 regulator_put(ctx->power);
397 kfree(ctx);
398
399 dev_info(dev, "remove successful\n");
400
401 return 0;
402}
403
404
405static const struct i2c_device_id sii9234_id[] = {
406 { "SII9234", 0 },
407 { },
408};
409
410MODULE_DEVICE_TABLE(i2c, sii9234_id);
411static struct i2c_driver sii9234_driver = {
412 .driver = {
413 .name = "sii9234",
414 .owner = THIS_MODULE,
415 .pm = &sii9234_pm_ops,
416 },
417 .probe = sii9234_probe,
418 .remove = __devexit_p(sii9234_remove),
419 .id_table = sii9234_id,
420};
421
422static int __init sii9234_init(void)
423{
424 return i2c_add_driver(&sii9234_driver);
425}
426module_init(sii9234_init);
427
428static void __exit sii9234_exit(void)
429{
430 i2c_del_driver(&sii9234_driver);
431}
432module_exit(sii9234_exit);
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
index 99a2ac16f9e5..0caac50d7cf4 100644
--- a/drivers/media/video/saa6588.c
+++ b/drivers/media/video/saa6588.c
@@ -539,15 +539,4 @@ static struct i2c_driver saa6588_driver = {
539 .id_table = saa6588_id, 539 .id_table = saa6588_id,
540}; 540};
541 541
542static __init int init_saa6588(void) 542module_i2c_driver(saa6588_driver);
543{
544 return i2c_add_driver(&saa6588_driver);
545}
546
547static __exit void exit_saa6588(void)
548{
549 i2c_del_driver(&saa6588_driver);
550}
551
552module_init(init_saa6588);
553module_exit(exit_saa6588);
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
index 99664205ef4e..51cd4c8f0520 100644
--- a/drivers/media/video/saa7110.c
+++ b/drivers/media/video/saa7110.c
@@ -491,15 +491,4 @@ static struct i2c_driver saa7110_driver = {
491 .id_table = saa7110_id, 491 .id_table = saa7110_id,
492}; 492};
493 493
494static __init int init_saa7110(void) 494module_i2c_driver(saa7110_driver);
495{
496 return i2c_add_driver(&saa7110_driver);
497}
498
499static __exit void exit_saa7110(void)
500{
501 i2c_del_driver(&saa7110_driver);
502}
503
504module_init(init_saa7110);
505module_exit(exit_saa7110);
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 0ef5484696b6..2107336cd836 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -1724,15 +1724,4 @@ static struct i2c_driver saa711x_driver = {
1724 .id_table = saa711x_id, 1724 .id_table = saa711x_id,
1725}; 1725};
1726 1726
1727static __init int init_saa711x(void) 1727module_i2c_driver(saa711x_driver);
1728{
1729 return i2c_add_driver(&saa711x_driver);
1730}
1731
1732static __exit void exit_saa711x(void)
1733{
1734 i2c_del_driver(&saa711x_driver);
1735}
1736
1737module_init(init_saa711x);
1738module_exit(exit_saa711x);
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index ad964616c9d2..39c90b08eea8 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -852,15 +852,4 @@ static struct i2c_driver saa7127_driver = {
852 .id_table = saa7127_id, 852 .id_table = saa7127_id,
853}; 853};
854 854
855static __init int init_saa7127(void) 855module_i2c_driver(saa7127_driver);
856{
857 return i2c_add_driver(&saa7127_driver);
858}
859
860static __exit void exit_saa7127(void)
861{
862 i2c_del_driver(&saa7127_driver);
863}
864
865module_init(init_saa7127);
866module_exit(exit_saa7127);
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile
index a646ccf51696..da3899329f52 100644
--- a/drivers/media/video/saa7134/Makefile
+++ b/drivers/media/video/saa7134/Makefile
@@ -10,7 +10,7 @@ obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o
10 10
11obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o 11obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
12 12
13ccflags-y += -Idrivers/media/video 13ccflags-y += -I$(srctree)/drivers/media/video
14ccflags-y += -Idrivers/media/common/tuners 14ccflags-y += -I$(srctree)/drivers/media/common/tuners
15ccflags-y += -Idrivers/media/dvb/dvb-core 15ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
16ccflags-y += -Idrivers/media/dvb/frontends 16ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index f9f29cc93a8a..f147b05bd860 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -1001,18 +1001,7 @@ static struct i2c_driver saa6752hs_driver = {
1001 .id_table = saa6752hs_id, 1001 .id_table = saa6752hs_id,
1002}; 1002};
1003 1003
1004static __init int init_saa6752hs(void) 1004module_i2c_driver(saa6752hs_driver);
1005{
1006 return i2c_add_driver(&saa6752hs_driver);
1007}
1008
1009static __exit void exit_saa6752hs(void)
1010{
1011 i2c_del_driver(&saa6752hs_driver);
1012}
1013
1014module_init(init_saa6752hs);
1015module_exit(exit_saa6752hs);
1016 1005
1017/* 1006/*
1018 * Overrides for Emacs so that we follow Linus's tabbing style. 1007 * Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 065d0f6be4a0..53aae5968ffb 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -33,6 +33,7 @@
33#include "tea5767.h" 33#include "tea5767.h"
34#include "tda18271.h" 34#include "tda18271.h"
35#include "xc5000.h" 35#include "xc5000.h"
36#include "s5h1411.h"
36 37
37/* commly used strings */ 38/* commly used strings */
38static char name_mute[] = "mute"; 39static char name_mute[] = "mute";
@@ -5712,6 +5713,36 @@ struct saa7134_board saa7134_boards[] = {
5712 .amux = LINE1, 5713 .amux = LINE1,
5713 } }, 5714 } },
5714 }, 5715 },
5716 [SAA7134_BOARD_KWORLD_PC150U] = {
5717 .name = "Kworld PC150-U",
5718 .audio_clock = 0x00187de7,
5719 .tuner_type = TUNER_PHILIPS_TDA8290,
5720 .radio_type = UNSET,
5721 .tuner_addr = ADDR_UNSET,
5722 .radio_addr = ADDR_UNSET,
5723 .mpeg = SAA7134_MPEG_DVB,
5724 .gpiomask = 1 << 21,
5725 .ts_type = SAA7134_MPEG_TS_PARALLEL,
5726 .inputs = { {
5727 .name = name_tv,
5728 .vmux = 1,
5729 .amux = TV,
5730 .tv = 1,
5731 }, {
5732 .name = name_comp,
5733 .vmux = 3,
5734 .amux = LINE1,
5735 }, {
5736 .name = name_svideo,
5737 .vmux = 8,
5738 .amux = LINE2,
5739 } },
5740 .radio = {
5741 .name = name_radio,
5742 .amux = TV,
5743 .gpio = 0x0000000,
5744 },
5745 },
5715 5746
5716}; 5747};
5717 5748
@@ -6306,6 +6337,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
6306 .driver_data = SAA7134_BOARD_KWORLD_ATSC110, /* ATSC 115 */ 6337 .driver_data = SAA7134_BOARD_KWORLD_ATSC110, /* ATSC 115 */
6307 },{ 6338 },{
6308 .vendor = PCI_VENDOR_ID_PHILIPS, 6339 .vendor = PCI_VENDOR_ID_PHILIPS,
6340 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA7135HL */
6341 .subvendor = 0x17de,
6342 .subdevice = 0xa134,
6343 .driver_data = SAA7134_BOARD_KWORLD_PC150U,
6344 }, {
6345 .vendor = PCI_VENDOR_ID_PHILIPS,
6309 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 6346 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
6310 .subvendor = 0x1461, 6347 .subvendor = 0x1461,
6311 .subdevice = 0x7360, 6348 .subdevice = 0x7360,
@@ -7134,6 +7171,23 @@ static inline int saa7134_kworld_sbtvd_toggle_agc(struct saa7134_dev *dev,
7134 return 0; 7171 return 0;
7135} 7172}
7136 7173
7174static int saa7134_kworld_pc150u_toggle_agc(struct saa7134_dev *dev,
7175 enum tda18271_mode mode)
7176{
7177 switch (mode) {
7178 case TDA18271_ANALOG:
7179 saa7134_set_gpio(dev, 18, 0);
7180 break;
7181 case TDA18271_DIGITAL:
7182 saa7134_set_gpio(dev, 18, 1);
7183 msleep(30);
7184 break;
7185 default:
7186 return -EINVAL;
7187 }
7188 return 0;
7189}
7190
7137static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev, 7191static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev,
7138 int command, int arg) 7192 int command, int arg)
7139{ 7193{
@@ -7150,6 +7204,9 @@ static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev,
7150 case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG: 7204 case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
7151 ret = saa7134_kworld_sbtvd_toggle_agc(dev, arg); 7205 ret = saa7134_kworld_sbtvd_toggle_agc(dev, arg);
7152 break; 7206 break;
7207 case SAA7134_BOARD_KWORLD_PC150U:
7208 ret = saa7134_kworld_pc150u_toggle_agc(dev, arg);
7209 break;
7153 default: 7210 default:
7154 break; 7211 break;
7155 } 7212 }
@@ -7171,6 +7228,7 @@ static int saa7134_tda8290_callback(struct saa7134_dev *dev,
7171 case SAA7134_BOARD_HAUPPAUGE_HVR1120: 7228 case SAA7134_BOARD_HAUPPAUGE_HVR1120:
7172 case SAA7134_BOARD_AVERMEDIA_M733A: 7229 case SAA7134_BOARD_AVERMEDIA_M733A:
7173 case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG: 7230 case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
7231 case SAA7134_BOARD_KWORLD_PC150U:
7174 case SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2: 7232 case SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2:
7175 /* tda8290 + tda18271 */ 7233 /* tda8290 + tda18271 */
7176 ret = saa7134_tda8290_18271_callback(dev, command, arg); 7234 ret = saa7134_tda8290_18271_callback(dev, command, arg);
@@ -7452,6 +7510,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
7452 case SAA7134_BOARD_BEHOLD_X7: 7510 case SAA7134_BOARD_BEHOLD_X7:
7453 case SAA7134_BOARD_BEHOLD_H7: 7511 case SAA7134_BOARD_BEHOLD_H7:
7454 case SAA7134_BOARD_BEHOLD_A7: 7512 case SAA7134_BOARD_BEHOLD_A7:
7513 case SAA7134_BOARD_KWORLD_PC150U:
7455 dev->has_remote = SAA7134_REMOTE_I2C; 7514 dev->has_remote = SAA7134_REMOTE_I2C;
7456 break; 7515 break;
7457 case SAA7134_BOARD_AVERMEDIA_A169_B: 7516 case SAA7134_BOARD_AVERMEDIA_A169_B:
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 089fa0fb5c94..aaa5c97a7216 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -61,6 +61,7 @@
61#include "zl10036.h" 61#include "zl10036.h"
62#include "zl10039.h" 62#include "zl10039.h"
63#include "mt312.h" 63#include "mt312.h"
64#include "s5h1411.h"
64 65
65MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 66MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
66MODULE_LICENSE("GPL"); 67MODULE_LICENSE("GPL");
@@ -1158,6 +1159,33 @@ static struct tda18271_config prohdtv_pro2_tda18271_config = {
1158 .output_opt = TDA18271_OUTPUT_LT_OFF, 1159 .output_opt = TDA18271_OUTPUT_LT_OFF,
1159}; 1160};
1160 1161
1162static struct tda18271_std_map kworld_tda18271_std_map = {
1163 .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 3,
1164 .if_lvl = 6, .rfagc_top = 0x37 },
1165 .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0,
1166 .if_lvl = 6, .rfagc_top = 0x37 },
1167};
1168
1169static struct tda18271_config kworld_pc150u_tda18271_config = {
1170 .std_map = &kworld_tda18271_std_map,
1171 .gate = TDA18271_GATE_ANALOG,
1172 .output_opt = TDA18271_OUTPUT_LT_OFF,
1173 .config = 3, /* Use tuner callback for AGC */
1174 .rf_cal_on_startup = 1
1175};
1176
1177static struct s5h1411_config kworld_s5h1411_config = {
1178 .output_mode = S5H1411_PARALLEL_OUTPUT,
1179 .gpio = S5H1411_GPIO_OFF,
1180 .qam_if = S5H1411_IF_4000,
1181 .vsb_if = S5H1411_IF_3250,
1182 .inversion = S5H1411_INVERSION_ON,
1183 .status_mode = S5H1411_DEMODLOCKING,
1184 .mpeg_timing =
1185 S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
1186};
1187
1188
1161/* ================================================================== 1189/* ==================================================================
1162 * Core code 1190 * Core code
1163 */ 1191 */
@@ -1438,6 +1466,22 @@ static int dvb_init(struct saa7134_dev *dev)
1438 &dev->i2c_adap, 0x61, 1466 &dev->i2c_adap, 0x61,
1439 TUNER_PHILIPS_TUV1236D); 1467 TUNER_PHILIPS_TUV1236D);
1440 break; 1468 break;
1469 case SAA7134_BOARD_KWORLD_PC150U:
1470 saa7134_set_gpio(dev, 18, 1); /* Switch to digital mode */
1471 saa7134_tuner_callback(dev, 0,
1472 TDA18271_CALLBACK_CMD_AGC_ENABLE, 1);
1473 fe0->dvb.frontend = dvb_attach(s5h1411_attach,
1474 &kworld_s5h1411_config,
1475 &dev->i2c_adap);
1476 if (fe0->dvb.frontend != NULL) {
1477 dvb_attach(tda829x_attach, fe0->dvb.frontend,
1478 &dev->i2c_adap, 0x4b,
1479 &tda829x_no_probe);
1480 dvb_attach(tda18271_attach, fe0->dvb.frontend,
1481 0x60, &dev->i2c_adap,
1482 &kworld_pc150u_tda18271_config);
1483 }
1484 break;
1441 case SAA7134_BOARD_FLYDVBS_LR300: 1485 case SAA7134_BOARD_FLYDVBS_LR300:
1442 fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, 1486 fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
1443 &dev->i2c_adap); 1487 &dev->i2c_adap);
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index 2d3f6d265bbf..a176ec3285e0 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -254,7 +254,9 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
254 addr = msgs[i].addr << 1; 254 addr = msgs[i].addr << 1;
255 if (msgs[i].flags & I2C_M_RD) 255 if (msgs[i].flags & I2C_M_RD)
256 addr |= 1; 256 addr |= 1;
257 if (i > 0 && msgs[i].flags & I2C_M_RD && msgs[i].addr != 0x40) { 257 if (i > 0 && msgs[i].flags &
258 I2C_M_RD && msgs[i].addr != 0x40 &&
259 msgs[i].addr != 0x19) {
258 /* workaround for a saa7134 i2c bug 260 /* workaround for a saa7134 i2c bug
259 * needed to talk to the mt352 demux 261 * needed to talk to the mt352 demux
260 * thanks to pinnacle for the hint */ 262 * thanks to pinnacle for the hint */
@@ -279,6 +281,16 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
279 d1printk("%02x", rc); 281 d1printk("%02x", rc);
280 msgs[i].buf[byte] = rc; 282 msgs[i].buf[byte] = rc;
281 } 283 }
284 /* discard mysterious extra byte when reading
285 from Samsung S5H1411. i2c bus gets error
286 if we do not. */
287 if (0x19 == msgs[i].addr) {
288 d1printk(" ?");
289 rc = i2c_recv_byte(dev);
290 if (rc < 0)
291 goto err;
292 d1printk("%02x", rc);
293 }
282 } else { 294 } else {
283 /* write bytes */ 295 /* write bytes */
284 d2printk("write bytes\n"); 296 d2printk("write bytes\n");
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 22ecd7297d2d..48d2878699b7 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -210,6 +210,54 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key,
210 return 1; 210 return 1;
211} 211}
212 212
213/* copied and modified from get_key_msi_tvanywhere_plus() */
214static int get_key_kworld_pc150u(struct IR_i2c *ir, u32 *ir_key,
215 u32 *ir_raw)
216{
217 unsigned char b;
218 unsigned int gpio;
219
220 /* <dev> is needed to access GPIO. Used by the saa_readl macro. */
221 struct saa7134_dev *dev = ir->c->adapter->algo_data;
222 if (dev == NULL) {
223 i2cdprintk("get_key_kworld_pc150u: "
224 "ir->c->adapter->algo_data is NULL!\n");
225 return -EIO;
226 }
227
228 /* rising SAA7134_GPIO_GPRESCAN reads the status */
229
230 saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
231 saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
232
233 gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
234
235 /* GPIO&0x100 is pulsed low when a button is pressed. Don't do
236 I2C receive if gpio&0x100 is not low. */
237
238 if (gpio & 0x100)
239 return 0; /* No button press */
240
241 /* GPIO says there is a button press. Get it. */
242
243 if (1 != i2c_master_recv(ir->c, &b, 1)) {
244 i2cdprintk("read error\n");
245 return -EIO;
246 }
247
248 /* No button press */
249
250 if (b == 0xff)
251 return 0;
252
253 /* Button pressed */
254
255 dprintk("get_key_kworld_pc150u: Key = 0x%02X\n", b);
256 *ir_key = b;
257 *ir_raw = b;
258 return 1;
259}
260
213static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) 261static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
214{ 262{
215 unsigned char b; 263 unsigned char b;
@@ -901,6 +949,21 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
901 msg_msi.addr, dev->i2c_adap.name, 949 msg_msi.addr, dev->i2c_adap.name,
902 (1 == rc) ? "yes" : "no"); 950 (1 == rc) ? "yes" : "no");
903 break; 951 break;
952 case SAA7134_BOARD_KWORLD_PC150U:
953 /* copied and modified from MSI TV@nywhere Plus */
954 dev->init_data.name = "Kworld PC150-U";
955 dev->init_data.get_key = get_key_kworld_pc150u;
956 dev->init_data.ir_codes = RC_MAP_KWORLD_PC150U;
957 info.addr = 0x30;
958 /* MSI TV@nywhere Plus controller doesn't seem to
959 respond to probes unless we read something from
960 an existing device. Weird...
961 REVISIT: might no longer be needed */
962 rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1);
963 dprintk("probe 0x%02x @ %s: %s\n",
964 msg_msi.addr, dev->i2c_adap.name,
965 (1 == rc) ? "yes" : "no");
966 break;
904 case SAA7134_BOARD_HAUPPAUGE_HVR1110: 967 case SAA7134_BOARD_HAUPPAUGE_HVR1110:
905 dev->init_data.name = "HVR 1110"; 968 dev->init_data.name = "HVR 1110";
906 dev->init_data.get_key = get_key_hvr1110; 969 dev->init_data.get_key = get_key_hvr1110;
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 42fba4f93c72..f625060e6a0f 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -126,8 +126,8 @@ struct saa7134_card_ir {
126 unsigned users; 126 unsigned users;
127 127
128 u32 polling; 128 u32 polling;
129 u32 last_gpio; 129 u32 last_gpio;
130 u32 mask_keycode, mask_keydown, mask_keyup; 130 u32 mask_keycode, mask_keydown, mask_keyup;
131 131
132 bool running; 132 bool running;
133 bool active; 133 bool active;
@@ -331,6 +331,7 @@ struct saa7134_card_ir {
331#define SAA7134_BOARD_BEHOLD_501 186 331#define SAA7134_BOARD_BEHOLD_501 186
332#define SAA7134_BOARD_BEHOLD_503FM 187 332#define SAA7134_BOARD_BEHOLD_503FM 187
333#define SAA7134_BOARD_SENSORAY811_911 188 333#define SAA7134_BOARD_SENSORAY811_911 188
334#define SAA7134_BOARD_KWORLD_PC150U 189
334 335
335#define SAA7134_MAXBOARDS 32 336#define SAA7134_MAXBOARDS 32
336#define SAA7134_INPUT_MAX 8 337#define SAA7134_INPUT_MAX 8
diff --git a/drivers/media/video/saa7164/Makefile b/drivers/media/video/saa7164/Makefile
index ecd5811dc486..068443af30c8 100644
--- a/drivers/media/video/saa7164/Makefile
+++ b/drivers/media/video/saa7164/Makefile
@@ -4,9 +4,9 @@ saa7164-objs := saa7164-cards.o saa7164-core.o saa7164-i2c.o saa7164-dvb.o \
4 4
5obj-$(CONFIG_VIDEO_SAA7164) += saa7164.o 5obj-$(CONFIG_VIDEO_SAA7164) += saa7164.o
6 6
7ccflags-y += -Idrivers/media/video 7ccflags-y += -I$(srctree)/drivers/media/video
8ccflags-y += -Idrivers/media/common/tuners 8ccflags-y += -I$(srctree)/drivers/media/common/tuners
9ccflags-y += -Idrivers/media/dvb/dvb-core 9ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core
10ccflags-y += -Idrivers/media/dvb/frontends 10ccflags-y += -I$(srctree)/drivers/media/dvb/frontends
11 11
12ccflags-y += $(extra-cflags-y) $(extra-cflags-m) 12ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/saa7164/saa7164-encoder.c b/drivers/media/video/saa7164/saa7164-encoder.c
index 2fd38a01887f..a9ed686ad08a 100644
--- a/drivers/media/video/saa7164/saa7164-encoder.c
+++ b/drivers/media/video/saa7164/saa7164-encoder.c
@@ -791,11 +791,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
791 return 0; 791 return 0;
792} 792}
793 793
794static int vidioc_log_status(struct file *file, void *priv)
795{
796 return 0;
797}
798
799static int fill_queryctrl(struct saa7164_encoder_params *params, 794static int fill_queryctrl(struct saa7164_encoder_params *params,
800 struct v4l2_queryctrl *c) 795 struct v4l2_queryctrl *c)
801{ 796{
@@ -1347,7 +1342,6 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
1347 .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls, 1342 .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
1348 .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls, 1343 .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
1349 .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls, 1344 .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
1350 .vidioc_log_status = vidioc_log_status,
1351 .vidioc_queryctrl = vidioc_queryctrl, 1345 .vidioc_queryctrl = vidioc_queryctrl,
1352 .vidioc_g_chip_ident = saa7164_g_chip_ident, 1346 .vidioc_g_chip_ident = saa7164_g_chip_ident,
1353#ifdef CONFIG_VIDEO_ADV_DEBUG 1347#ifdef CONFIG_VIDEO_ADV_DEBUG
diff --git a/drivers/media/video/saa7164/saa7164-vbi.c b/drivers/media/video/saa7164/saa7164-vbi.c
index e2e034158718..273cf807401c 100644
--- a/drivers/media/video/saa7164/saa7164-vbi.c
+++ b/drivers/media/video/saa7164/saa7164-vbi.c
@@ -730,11 +730,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
730 return 0; 730 return 0;
731} 731}
732 732
733static int vidioc_log_status(struct file *file, void *priv)
734{
735 return 0;
736}
737
738static int fill_queryctrl(struct saa7164_vbi_params *params, 733static int fill_queryctrl(struct saa7164_vbi_params *params,
739 struct v4l2_queryctrl *c) 734 struct v4l2_queryctrl *c)
740{ 735{
@@ -1256,7 +1251,6 @@ static const struct v4l2_ioctl_ops vbi_ioctl_ops = {
1256 .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls, 1251 .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
1257 .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls, 1252 .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
1258 .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls, 1253 .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
1259 .vidioc_log_status = vidioc_log_status,
1260 .vidioc_queryctrl = vidioc_queryctrl, 1254 .vidioc_queryctrl = vidioc_queryctrl,
1261#if 0 1255#if 0
1262 .vidioc_g_chip_ident = saa7164_g_chip_ident, 1256 .vidioc_g_chip_ident = saa7164_g_chip_ident,
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c
index b6172c2c517e..1e84466515aa 100644
--- a/drivers/media/video/saa717x.c
+++ b/drivers/media/video/saa717x.c
@@ -1375,15 +1375,4 @@ static struct i2c_driver saa717x_driver = {
1375 .id_table = saa717x_id, 1375 .id_table = saa717x_id,
1376}; 1376};
1377 1377
1378static __init int init_saa717x(void) 1378module_i2c_driver(saa717x_driver);
1379{
1380 return i2c_add_driver(&saa717x_driver);
1381}
1382
1383static __exit void exit_saa717x(void)
1384{
1385 i2c_del_driver(&saa717x_driver);
1386}
1387
1388module_init(init_saa717x);
1389module_exit(exit_saa717x);
diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c
index 96f56c2f11f3..2c6b65c76e2b 100644
--- a/drivers/media/video/saa7185.c
+++ b/drivers/media/video/saa7185.c
@@ -374,15 +374,4 @@ static struct i2c_driver saa7185_driver = {
374 .id_table = saa7185_id, 374 .id_table = saa7185_id,
375}; 375};
376 376
377static __init int init_saa7185(void) 377module_i2c_driver(saa7185_driver);
378{
379 return i2c_add_driver(&saa7185_driver);
380}
381
382static __exit void exit_saa7185(void)
383{
384 i2c_del_driver(&saa7185_driver);
385}
386
387module_init(init_saa7185);
388module_exit(exit_saa7185);
diff --git a/drivers/media/video/saa7191.c b/drivers/media/video/saa7191.c
index 211fa25a1239..d7d1670e0ca3 100644
--- a/drivers/media/video/saa7191.c
+++ b/drivers/media/video/saa7191.c
@@ -656,15 +656,4 @@ static struct i2c_driver saa7191_driver = {
656 .id_table = saa7191_id, 656 .id_table = saa7191_id,
657}; 657};
658 658
659static __init int init_saa7191(void) 659module_i2c_driver(saa7191_driver);
660{
661 return i2c_add_driver(&saa7191_driver);
662}
663
664static __exit void exit_saa7191(void)
665{
666 i2c_del_driver(&saa7191_driver);
667}
668
669module_init(init_saa7191);
670module_exit(exit_saa7191);
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index f854d85a387c..424dfacd263a 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -112,6 +112,10 @@ struct sh_mobile_ceu_dev {
112 112
113 u32 cflcr; 113 u32 cflcr;
114 114
115 /* static max sizes either from platform data or default */
116 int max_width;
117 int max_height;
118
115 enum v4l2_field field; 119 enum v4l2_field field;
116 int sequence; 120 int sequence;
117 121
@@ -1081,7 +1085,15 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int
1081 if (ret < 0) 1085 if (ret < 0)
1082 return ret; 1086 return ret;
1083 1087
1084 while ((mf.width > 2560 || mf.height > 1920) && shift < 4) { 1088 /*
1089 * All currently existing CEU implementations support 2560x1920
1090 * or larger frames. If the sensor is proposing too big a frame,
1091 * don't bother with possibly supportred by the CEU larger
1092 * sizes, just try VGA multiples. If needed, this can be
1093 * adjusted in the future.
1094 */
1095 while ((mf.width > pcdev->max_width ||
1096 mf.height > pcdev->max_height) && shift < 4) {
1085 /* Try 2560x1920, 1280x960, 640x480, 320x240 */ 1097 /* Try 2560x1920, 1280x960, 640x480, 320x240 */
1086 mf.width = 2560 >> shift; 1098 mf.width = 2560 >> shift;
1087 mf.height = 1920 >> shift; 1099 mf.height = 1920 >> shift;
@@ -1377,6 +1389,8 @@ static int client_s_crop(struct soc_camera_device *icd, struct v4l2_crop *crop,
1377static int client_s_fmt(struct soc_camera_device *icd, 1389static int client_s_fmt(struct soc_camera_device *icd,
1378 struct v4l2_mbus_framefmt *mf, bool ceu_can_scale) 1390 struct v4l2_mbus_framefmt *mf, bool ceu_can_scale)
1379{ 1391{
1392 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1393 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1380 struct sh_mobile_ceu_cam *cam = icd->host_priv; 1394 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1381 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1395 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1382 struct device *dev = icd->parent; 1396 struct device *dev = icd->parent;
@@ -1410,8 +1424,8 @@ static int client_s_fmt(struct soc_camera_device *icd,
1410 if (ret < 0) 1424 if (ret < 0)
1411 return ret; 1425 return ret;
1412 1426
1413 max_width = min(cap.bounds.width, 2560); 1427 max_width = min(cap.bounds.width, pcdev->max_width);
1414 max_height = min(cap.bounds.height, 1920); 1428 max_height = min(cap.bounds.height, pcdev->max_height);
1415 1429
1416 /* Camera set a format, but geometry is not precise, try to improve */ 1430 /* Camera set a format, but geometry is not precise, try to improve */
1417 tmp_w = mf->width; 1431 tmp_w = mf->width;
@@ -1551,7 +1565,7 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
1551 if (ret < 0) 1565 if (ret < 0)
1552 return ret; 1566 return ret;
1553 1567
1554 if (mf.width > 2560 || mf.height > 1920) 1568 if (mf.width > pcdev->max_width || mf.height > pcdev->max_height)
1555 return -EINVAL; 1569 return -EINVAL;
1556 1570
1557 /* 4. Calculate camera scales */ 1571 /* 4. Calculate camera scales */
@@ -1834,6 +1848,8 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
1834static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, 1848static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1835 struct v4l2_format *f) 1849 struct v4l2_format *f)
1836{ 1850{
1851 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1852 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1837 const struct soc_camera_format_xlate *xlate; 1853 const struct soc_camera_format_xlate *xlate;
1838 struct v4l2_pix_format *pix = &f->fmt.pix; 1854 struct v4l2_pix_format *pix = &f->fmt.pix;
1839 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1855 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
@@ -1854,8 +1870,8 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1854 /* FIXME: calculate using depth and bus width */ 1870 /* FIXME: calculate using depth and bus width */
1855 1871
1856 /* CFSZR requires height and width to be 4-pixel aligned */ 1872 /* CFSZR requires height and width to be 4-pixel aligned */
1857 v4l_bound_align_image(&pix->width, 2, 2560, 2, 1873 v4l_bound_align_image(&pix->width, 2, pcdev->max_width, 2,
1858 &pix->height, 4, 1920, 2, 0); 1874 &pix->height, 4, pcdev->max_height, 2, 0);
1859 1875
1860 width = pix->width; 1876 width = pix->width;
1861 height = pix->height; 1877 height = pix->height;
@@ -1890,8 +1906,8 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1890 * requested a bigger rectangle, it will not return a 1906 * requested a bigger rectangle, it will not return a
1891 * smaller one. 1907 * smaller one.
1892 */ 1908 */
1893 mf.width = 2560; 1909 mf.width = pcdev->max_width;
1894 mf.height = 1920; 1910 mf.height = pcdev->max_height;
1895 ret = v4l2_device_call_until_err(sd->v4l2_dev, 1911 ret = v4l2_device_call_until_err(sd->v4l2_dev,
1896 soc_camera_grp_id(icd), video, 1912 soc_camera_grp_id(icd), video,
1897 try_mbus_fmt, &mf); 1913 try_mbus_fmt, &mf);
@@ -2082,6 +2098,9 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
2082 goto exit_kfree; 2098 goto exit_kfree;
2083 } 2099 }
2084 2100
2101 pcdev->max_width = pcdev->pdata->max_width ? : 2560;
2102 pcdev->max_height = pcdev->pdata->max_height ? : 1920;
2103
2085 base = ioremap_nocache(res->start, resource_size(res)); 2104 base = ioremap_nocache(res->start, resource_size(res));
2086 if (!base) { 2105 if (!base) {
2087 err = -ENXIO; 2106 err = -ENXIO;
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index b82710745ba8..eb25756a07af 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -526,10 +526,6 @@ static int soc_camera_open(struct file *file)
526 }, 526 },
527 }; 527 };
528 528
529 ret = soc_camera_power_on(icd, icl);
530 if (ret < 0)
531 goto epower;
532
533 /* The camera could have been already on, try to reset */ 529 /* The camera could have been already on, try to reset */
534 if (icl->reset) 530 if (icl->reset)
535 icl->reset(icd->pdev); 531 icl->reset(icd->pdev);
@@ -540,6 +536,10 @@ static int soc_camera_open(struct file *file)
540 goto eiciadd; 536 goto eiciadd;
541 } 537 }
542 538
539 ret = soc_camera_power_on(icd, icl);
540 if (ret < 0)
541 goto epower;
542
543 pm_runtime_enable(&icd->vdev->dev); 543 pm_runtime_enable(&icd->vdev->dev);
544 ret = pm_runtime_resume(&icd->vdev->dev); 544 ret = pm_runtime_resume(&icd->vdev->dev);
545 if (ret < 0 && ret != -ENOSYS) 545 if (ret < 0 && ret != -ENOSYS)
@@ -578,10 +578,10 @@ einitvb:
578esfmt: 578esfmt:
579 pm_runtime_disable(&icd->vdev->dev); 579 pm_runtime_disable(&icd->vdev->dev);
580eresume: 580eresume:
581 ici->ops->remove(icd);
582eiciadd:
583 soc_camera_power_off(icd, icl); 581 soc_camera_power_off(icd, icl);
584epower: 582epower:
583 ici->ops->remove(icd);
584eiciadd:
585 icd->use_count--; 585 icd->use_count--;
586 module_put(ici->ops->owner); 586 module_put(ici->ops->owner);
587 587
@@ -1050,6 +1050,14 @@ static int soc_camera_probe(struct soc_camera_device *icd)
1050 if (ret < 0) 1050 if (ret < 0)
1051 goto ereg; 1051 goto ereg;
1052 1052
1053 /* The camera could have been already on, try to reset */
1054 if (icl->reset)
1055 icl->reset(icd->pdev);
1056
1057 ret = ici->ops->add(icd);
1058 if (ret < 0)
1059 goto eadd;
1060
1053 /* 1061 /*
1054 * This will not yet call v4l2_subdev_core_ops::s_power(1), because the 1062 * 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 1063 * subdevice has not been initialised yet. We'll have to call it once
@@ -1060,14 +1068,6 @@ static int soc_camera_probe(struct soc_camera_device *icd)
1060 if (ret < 0) 1068 if (ret < 0)
1061 goto epower; 1069 goto epower;
1062 1070
1063 /* The camera could have been already on, try to reset */
1064 if (icl->reset)
1065 icl->reset(icd->pdev);
1066
1067 ret = ici->ops->add(icd);
1068 if (ret < 0)
1069 goto eadd;
1070
1071 /* Must have icd->vdev before registering the device */ 1071 /* Must have icd->vdev before registering the device */
1072 ret = video_dev_create(icd); 1072 ret = video_dev_create(icd);
1073 if (ret < 0) 1073 if (ret < 0)
@@ -1165,10 +1165,10 @@ eadddev:
1165 video_device_release(icd->vdev); 1165 video_device_release(icd->vdev);
1166 icd->vdev = NULL; 1166 icd->vdev = NULL;
1167evdc: 1167evdc:
1168 ici->ops->remove(icd);
1169eadd:
1170 soc_camera_power_off(icd, icl); 1168 soc_camera_power_off(icd, icl);
1171epower: 1169epower:
1170 ici->ops->remove(icd);
1171eadd:
1172 regulator_bulk_free(icl->num_regulators, icl->regulators); 1172 regulator_bulk_free(icl->num_regulators, icl->regulators);
1173ereg: 1173ereg:
1174 v4l2_ctrl_handler_free(&icd->ctrl_handler); 1174 v4l2_ctrl_handler_free(&icd->ctrl_handler);
diff --git a/drivers/media/video/sr030pc30.c b/drivers/media/video/sr030pc30.c
index d1b07aceaf94..e9d95bda2ab1 100644
--- a/drivers/media/video/sr030pc30.c
+++ b/drivers/media/video/sr030pc30.c
@@ -864,18 +864,7 @@ static struct i2c_driver sr030pc30_i2c_driver = {
864 .id_table = sr030pc30_id, 864 .id_table = sr030pc30_id,
865}; 865};
866 866
867static int __init sr030pc30_init(void) 867module_i2c_driver(sr030pc30_i2c_driver);
868{
869 return i2c_add_driver(&sr030pc30_i2c_driver);
870}
871
872static void __exit sr030pc30_exit(void)
873{
874 i2c_del_driver(&sr030pc30_i2c_driver);
875}
876
877module_init(sr030pc30_init);
878module_exit(sr030pc30_exit);
879 868
880MODULE_DESCRIPTION("Siliconfile SR030PC30 camera driver"); 869MODULE_DESCRIPTION("Siliconfile SR030PC30 camera driver");
881MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>"); 870MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index bd218545da9c..f7707e65761e 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -482,15 +482,4 @@ static struct i2c_driver tda7432_driver = {
482 .id_table = tda7432_id, 482 .id_table = tda7432_id,
483}; 483};
484 484
485static __init int init_tda7432(void) 485module_i2c_driver(tda7432_driver);
486{
487 return i2c_add_driver(&tda7432_driver);
488}
489
490static __exit void exit_tda7432(void)
491{
492 i2c_del_driver(&tda7432_driver);
493}
494
495module_init(init_tda7432);
496module_exit(exit_tda7432);
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c
index 22fa8202d5ca..465d7086babf 100644
--- a/drivers/media/video/tda9840.c
+++ b/drivers/media/video/tda9840.c
@@ -208,15 +208,4 @@ static struct i2c_driver tda9840_driver = {
208 .id_table = tda9840_id, 208 .id_table = tda9840_id,
209}; 209};
210 210
211static __init int init_tda9840(void) 211module_i2c_driver(tda9840_driver);
212{
213 return i2c_add_driver(&tda9840_driver);
214}
215
216static __exit void exit_tda9840(void)
217{
218 i2c_del_driver(&tda9840_driver);
219}
220
221module_init(init_tda9840);
222module_exit(exit_tda9840);
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c
index 827425c5b866..d1d6ea1dd273 100644
--- a/drivers/media/video/tea6415c.c
+++ b/drivers/media/video/tea6415c.c
@@ -184,15 +184,4 @@ static struct i2c_driver tea6415c_driver = {
184 .id_table = tea6415c_id, 184 .id_table = tea6415c_id,
185}; 185};
186 186
187static __init int init_tea6415c(void) 187module_i2c_driver(tea6415c_driver);
188{
189 return i2c_add_driver(&tea6415c_driver);
190}
191
192static __exit void exit_tea6415c(void)
193{
194 i2c_del_driver(&tea6415c_driver);
195}
196
197module_init(init_tea6415c);
198module_exit(exit_tea6415c);
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c
index f350b6c24500..38757217a074 100644
--- a/drivers/media/video/tea6420.c
+++ b/drivers/media/video/tea6420.c
@@ -166,15 +166,4 @@ static struct i2c_driver tea6420_driver = {
166 .id_table = tea6420_id, 166 .id_table = tea6420_id,
167}; 167};
168 168
169static __init int init_tea6420(void) 169module_i2c_driver(tea6420_driver);
170{
171 return i2c_add_driver(&tea6420_driver);
172}
173
174static __exit void exit_tea6420(void)
175{
176 i2c_del_driver(&tea6420_driver);
177}
178
179module_init(init_tea6420);
180module_exit(exit_tea6420);
diff --git a/drivers/media/video/ths7303.c b/drivers/media/video/ths7303.c
index 61b1dd118364..e5c0eedebc58 100644
--- a/drivers/media/video/ths7303.c
+++ b/drivers/media/video/ths7303.c
@@ -137,16 +137,4 @@ static struct i2c_driver ths7303_driver = {
137 .id_table = ths7303_id, 137 .id_table = ths7303_id,
138}; 138};
139 139
140static int __init ths7303_init(void) 140module_i2c_driver(ths7303_driver);
141{
142 return i2c_add_driver(&ths7303_driver);
143}
144
145static void __exit ths7303_exit(void)
146{
147 i2c_del_driver(&ths7303_driver);
148}
149
150module_init(ths7303_init);
151module_exit(ths7303_exit);
152
diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c
index 286ec7e7062a..809a75a558ee 100644
--- a/drivers/media/video/tlv320aic23b.c
+++ b/drivers/media/video/tlv320aic23b.c
@@ -227,15 +227,4 @@ static struct i2c_driver tlv320aic23b_driver = {
227 .id_table = tlv320aic23b_id, 227 .id_table = tlv320aic23b_id,
228}; 228};
229 229
230static __init int init_tlv320aic23b(void) 230module_i2c_driver(tlv320aic23b_driver);
231{
232 return i2c_add_driver(&tlv320aic23b_driver);
233}
234
235static __exit void exit_tlv320aic23b(void)
236{
237 i2c_del_driver(&tlv320aic23b_driver);
238}
239
240module_init(init_tlv320aic23b);
241module_exit(exit_tlv320aic23b);
diff --git a/drivers/media/video/tm6000/tm6000-input.c b/drivers/media/video/tm6000/tm6000-input.c
index 7844607dd45a..859eb90e4d56 100644
--- a/drivers/media/video/tm6000/tm6000-input.c
+++ b/drivers/media/video/tm6000/tm6000-input.c
@@ -481,8 +481,6 @@ int tm6000_ir_fini(struct tm6000_core *dev)
481 481
482 dprintk(2, "%s\n",__func__); 482 dprintk(2, "%s\n",__func__);
483 483
484 rc_unregister_device(ir->rc);
485
486 if (!ir->polling) 484 if (!ir->polling)
487 __tm6000_ir_int_stop(ir->rc); 485 __tm6000_ir_int_stop(ir->rc);
488 486
@@ -492,6 +490,7 @@ int tm6000_ir_fini(struct tm6000_core *dev)
492 tm6000_flash_led(dev, 0); 490 tm6000_flash_led(dev, 0);
493 ir->pwled = 0; 491 ir->pwled = 0;
494 492
493 rc_unregister_device(ir->rc);
495 494
496 kfree(ir); 495 kfree(ir);
497 dev->ir = NULL; 496 dev->ir = NULL;
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 4059ea178c2d..a5c6397ad591 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -380,6 +380,21 @@ static void set_type(struct i2c_client *c, unsigned int type,
380 tune_now = 0; 380 tune_now = 0;
381 break; 381 break;
382 } 382 }
383 case TUNER_XC5000C:
384 {
385 struct xc5000_config xc5000c_cfg = {
386 .i2c_address = t->i2c->addr,
387 /* if_khz will be set at dvb_attach() */
388 .if_khz = 0,
389 .chip_id = XC5000C,
390 };
391
392 if (!dvb_attach(xc5000_attach,
393 &t->fe, t->i2c->adapter, &xc5000c_cfg))
394 goto attach_failed;
395 tune_now = 0;
396 break;
397 }
383 case TUNER_NXP_TDA18271: 398 case TUNER_NXP_TDA18271:
384 { 399 {
385 struct tda18271_config cfg = { 400 struct tda18271_config cfg = {
@@ -1314,18 +1329,7 @@ static struct i2c_driver tuner_driver = {
1314 .id_table = tuner_id, 1329 .id_table = tuner_id,
1315}; 1330};
1316 1331
1317static __init int init_tuner(void) 1332module_i2c_driver(tuner_driver);
1318{
1319 return i2c_add_driver(&tuner_driver);
1320}
1321
1322static __exit void exit_tuner(void)
1323{
1324 i2c_del_driver(&tuner_driver);
1325}
1326
1327module_init(init_tuner);
1328module_exit(exit_tuner);
1329 1333
1330MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners"); 1334MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners");
1331MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer"); 1335MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index f22dbef9b95b..c5b1a7365e4f 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -2078,15 +2078,4 @@ static struct i2c_driver tvaudio_driver = {
2078 .id_table = tvaudio_id, 2078 .id_table = tvaudio_id,
2079}; 2079};
2080 2080
2081static __init int init_tvaudio(void) 2081module_i2c_driver(tvaudio_driver);
2082{
2083 return i2c_add_driver(&tvaudio_driver);
2084}
2085
2086static __exit void exit_tvaudio(void)
2087{
2088 i2c_del_driver(&tvaudio_driver);
2089}
2090
2091module_init(init_tvaudio);
2092module_exit(exit_tvaudio);
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 6103d1b1081e..3b6cf034976a 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -286,8 +286,16 @@ hauppauge_tuner[] =
286 { TUNER_ABSENT, "MaxLinear 301"}, 286 { TUNER_ABSENT, "MaxLinear 301"},
287 { TUNER_ABSENT, "Mirics MSi001"}, 287 { TUNER_ABSENT, "Mirics MSi001"},
288 { TUNER_ABSENT, "MaxLinear MxL241SF"}, 288 { TUNER_ABSENT, "MaxLinear MxL241SF"},
289 { TUNER_ABSENT, "Xceive XC5000C"}, 289 { TUNER_XC5000C, "Xceive XC5000C"},
290 { TUNER_ABSENT, "Montage M68TS2020"}, 290 { TUNER_ABSENT, "Montage M68TS2020"},
291 { TUNER_ABSENT, "Siano SMS1530"},
292 { TUNER_ABSENT, "Dibcom 7090"},
293 { TUNER_ABSENT, "Xceive XC5200C"},
294 { TUNER_ABSENT, "NXP 18273"},
295 { TUNER_ABSENT, "Montage M88TS2022"},
296 /* 180-189 */
297 { TUNER_ABSENT, "NXP 18272M"},
298 { TUNER_ABSENT, "NXP 18272S"},
291}; 299};
292 300
293/* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are 301/* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index dd26cacd0556..cd615c1d6011 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -1163,15 +1163,4 @@ static struct i2c_driver tvp514x_driver = {
1163 .id_table = tvp514x_id, 1163 .id_table = tvp514x_id,
1164}; 1164};
1165 1165
1166static int __init tvp514x_init(void) 1166module_i2c_driver(tvp514x_driver);
1167{
1168 return i2c_add_driver(&tvp514x_driver);
1169}
1170
1171static void __exit tvp514x_exit(void)
1172{
1173 i2c_del_driver(&tvp514x_driver);
1174}
1175
1176module_init(tvp514x_init);
1177module_exit(tvp514x_exit);
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 6be9910a6e24..1326e11cf4a9 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -17,6 +17,13 @@
17 17
18#include "tvp5150_reg.h" 18#include "tvp5150_reg.h"
19 19
20#define TVP5150_H_MAX 720
21#define TVP5150_V_MAX_525_60 480
22#define TVP5150_V_MAX_OTHERS 576
23#define TVP5150_MAX_CROP_LEFT 511
24#define TVP5150_MAX_CROP_TOP 127
25#define TVP5150_CROP_SHIFT 2
26
20MODULE_DESCRIPTION("Texas Instruments TVP5150A video decoder driver"); 27MODULE_DESCRIPTION("Texas Instruments TVP5150A video decoder driver");
21MODULE_AUTHOR("Mauro Carvalho Chehab"); 28MODULE_AUTHOR("Mauro Carvalho Chehab");
22MODULE_LICENSE("GPL"); 29MODULE_LICENSE("GPL");
@@ -29,6 +36,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)");
29struct tvp5150 { 36struct tvp5150 {
30 struct v4l2_subdev sd; 37 struct v4l2_subdev sd;
31 struct v4l2_ctrl_handler hdl; 38 struct v4l2_ctrl_handler hdl;
39 struct v4l2_rect rect;
32 40
33 v4l2_std_id norm; /* Current set standard */ 41 v4l2_std_id norm; /* Current set standard */
34 u32 input; 42 u32 input;
@@ -732,6 +740,13 @@ static int tvp5150_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
732 if (decoder->norm == std) 740 if (decoder->norm == std)
733 return 0; 741 return 0;
734 742
743 /* Change cropping height limits */
744 if (std & V4L2_STD_525_60)
745 decoder->rect.height = TVP5150_V_MAX_525_60;
746 else
747 decoder->rect.height = TVP5150_V_MAX_OTHERS;
748
749
735 return tvp5150_set_std(sd, std); 750 return tvp5150_set_std(sd, std);
736} 751}
737 752
@@ -828,11 +843,8 @@ static int tvp5150_mbus_fmt(struct v4l2_subdev *sd,
828 else 843 else
829 std = decoder->norm; 844 std = decoder->norm;
830 845
831 f->width = 720; 846 f->width = decoder->rect.width;
832 if (std & V4L2_STD_525_60) 847 f->height = decoder->rect.height;
833 f->height = 480;
834 else
835 f->height = 576;
836 848
837 f->code = V4L2_MBUS_FMT_YUYV8_2X8; 849 f->code = V4L2_MBUS_FMT_YUYV8_2X8;
838 f->field = V4L2_FIELD_SEQ_TB; 850 f->field = V4L2_FIELD_SEQ_TB;
@@ -843,6 +855,99 @@ static int tvp5150_mbus_fmt(struct v4l2_subdev *sd,
843 return 0; 855 return 0;
844} 856}
845 857
858static int tvp5150_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
859{
860 struct v4l2_rect rect = a->c;
861 struct tvp5150 *decoder = to_tvp5150(sd);
862 v4l2_std_id std;
863 int hmax;
864
865 v4l2_dbg(1, debug, sd, "%s left=%d, top=%d, width=%d, height=%d\n",
866 __func__, rect.left, rect.top, rect.width, rect.height);
867
868 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
869 return -EINVAL;
870
871 /* tvp5150 has some special limits */
872 rect.left = clamp(rect.left, 0, TVP5150_MAX_CROP_LEFT);
873 rect.width = clamp(rect.width,
874 TVP5150_H_MAX - TVP5150_MAX_CROP_LEFT - rect.left,
875 TVP5150_H_MAX - rect.left);
876 rect.top = clamp(rect.top, 0, TVP5150_MAX_CROP_TOP);
877
878 /* Calculate height based on current standard */
879 if (decoder->norm == V4L2_STD_ALL)
880 std = tvp5150_read_std(sd);
881 else
882 std = decoder->norm;
883
884 if (std & V4L2_STD_525_60)
885 hmax = TVP5150_V_MAX_525_60;
886 else
887 hmax = TVP5150_V_MAX_OTHERS;
888
889 rect.height = clamp(rect.height,
890 hmax - TVP5150_MAX_CROP_TOP - rect.top,
891 hmax - rect.top);
892
893 tvp5150_write(sd, TVP5150_VERT_BLANKING_START, rect.top);
894 tvp5150_write(sd, TVP5150_VERT_BLANKING_STOP,
895 rect.top + rect.height - hmax);
896 tvp5150_write(sd, TVP5150_ACT_VD_CROP_ST_MSB,
897 rect.left >> TVP5150_CROP_SHIFT);
898 tvp5150_write(sd, TVP5150_ACT_VD_CROP_ST_LSB,
899 rect.left | (1 << TVP5150_CROP_SHIFT));
900 tvp5150_write(sd, TVP5150_ACT_VD_CROP_STP_MSB,
901 (rect.left + rect.width - TVP5150_MAX_CROP_LEFT) >>
902 TVP5150_CROP_SHIFT);
903 tvp5150_write(sd, TVP5150_ACT_VD_CROP_STP_LSB,
904 rect.left + rect.width - TVP5150_MAX_CROP_LEFT);
905
906 decoder->rect = rect;
907
908 return 0;
909}
910
911static int tvp5150_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
912{
913 struct tvp5150 *decoder = container_of(sd, struct tvp5150, sd);
914
915 a->c = decoder->rect;
916 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
917
918 return 0;
919}
920
921static int tvp5150_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
922{
923 struct tvp5150 *decoder = container_of(sd, struct tvp5150, sd);
924 v4l2_std_id std;
925
926 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
927 return -EINVAL;
928
929 a->bounds.left = 0;
930 a->bounds.top = 0;
931 a->bounds.width = TVP5150_H_MAX;
932
933 /* Calculate height based on current standard */
934 if (decoder->norm == V4L2_STD_ALL)
935 std = tvp5150_read_std(sd);
936 else
937 std = decoder->norm;
938
939 if (std & V4L2_STD_525_60)
940 a->bounds.height = TVP5150_V_MAX_525_60;
941 else
942 a->bounds.height = TVP5150_V_MAX_OTHERS;
943
944 a->defrect = a->bounds;
945 a->pixelaspect.numerator = 1;
946 a->pixelaspect.denominator = 1;
947
948 return 0;
949}
950
846/**************************************************************************** 951/****************************************************************************
847 I2C Command 952 I2C Command
848 ****************************************************************************/ 953 ****************************************************************************/
@@ -998,6 +1103,10 @@ static const struct v4l2_subdev_video_ops tvp5150_video_ops = {
998 .enum_mbus_fmt = tvp5150_enum_mbus_fmt, 1103 .enum_mbus_fmt = tvp5150_enum_mbus_fmt,
999 .s_mbus_fmt = tvp5150_mbus_fmt, 1104 .s_mbus_fmt = tvp5150_mbus_fmt,
1000 .try_mbus_fmt = tvp5150_mbus_fmt, 1105 .try_mbus_fmt = tvp5150_mbus_fmt,
1106 .g_mbus_fmt = tvp5150_mbus_fmt,
1107 .s_crop = tvp5150_s_crop,
1108 .g_crop = tvp5150_g_crop,
1109 .cropcap = tvp5150_cropcap,
1001}; 1110};
1002 1111
1003static const struct v4l2_subdev_vbi_ops tvp5150_vbi_ops = { 1112static const struct v4l2_subdev_vbi_ops tvp5150_vbi_ops = {
@@ -1083,6 +1192,15 @@ static int tvp5150_probe(struct i2c_client *c,
1083 } 1192 }
1084 v4l2_ctrl_handler_setup(&core->hdl); 1193 v4l2_ctrl_handler_setup(&core->hdl);
1085 1194
1195 /* Default is no cropping */
1196 core->rect.top = 0;
1197 if (tvp5150_read_std(sd) & V4L2_STD_525_60)
1198 core->rect.height = TVP5150_V_MAX_525_60;
1199 else
1200 core->rect.height = TVP5150_V_MAX_OTHERS;
1201 core->rect.left = 0;
1202 core->rect.width = TVP5150_H_MAX;
1203
1086 if (debug > 1) 1204 if (debug > 1)
1087 tvp5150_log_status(sd); 1205 tvp5150_log_status(sd);
1088 return 0; 1206 return 0;
@@ -1121,15 +1239,4 @@ static struct i2c_driver tvp5150_driver = {
1121 .id_table = tvp5150_id, 1239 .id_table = tvp5150_id,
1122}; 1240};
1123 1241
1124static __init int init_tvp5150(void) 1242module_i2c_driver(tvp5150_driver);
1125{
1126 return i2c_add_driver(&tvp5150_driver);
1127}
1128
1129static __exit void exit_tvp5150(void)
1130{
1131 i2c_del_driver(&tvp5150_driver);
1132}
1133
1134module_init(init_tvp5150);
1135module_exit(exit_tvp5150);
diff --git a/drivers/media/video/tvp7002.c b/drivers/media/video/tvp7002.c
index 236c559d5f51..d7676d85c4df 100644
--- a/drivers/media/video/tvp7002.c
+++ b/drivers/media/video/tvp7002.c
@@ -1069,27 +1069,4 @@ static struct i2c_driver tvp7002_driver = {
1069 .id_table = tvp7002_id, 1069 .id_table = tvp7002_id,
1070}; 1070};
1071 1071
1072/* 1072module_i2c_driver(tvp7002_driver);
1073 * tvp7002_init - Initialize driver via I2C interface
1074 *
1075 * Register the TVP7002 driver.
1076 * Return 0 on success or error code on failure.
1077 */
1078static int __init tvp7002_init(void)
1079{
1080 return i2c_add_driver(&tvp7002_driver);
1081}
1082
1083/*
1084 * tvp7002_exit - Remove driver via I2C interface
1085 *
1086 * Unregister the TVP7002 driver.
1087 * Returns nothing.
1088 */
1089static void __exit tvp7002_exit(void)
1090{
1091 i2c_del_driver(&tvp7002_driver);
1092}
1093
1094module_init(tvp7002_init);
1095module_exit(tvp7002_exit);
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c
index a514fa61116c..8768efb8508a 100644
--- a/drivers/media/video/tw9910.c
+++ b/drivers/media/video/tw9910.c
@@ -951,21 +951,7 @@ static struct i2c_driver tw9910_i2c_driver = {
951 .id_table = tw9910_id, 951 .id_table = tw9910_id,
952}; 952};
953 953
954/* 954module_i2c_driver(tw9910_i2c_driver);
955 * module function
956 */
957static int __init tw9910_module_init(void)
958{
959 return i2c_add_driver(&tw9910_i2c_driver);
960}
961
962static void __exit tw9910_module_exit(void)
963{
964 i2c_del_driver(&tw9910_i2c_driver);
965}
966
967module_init(tw9910_module_init);
968module_exit(tw9910_module_exit);
969 955
970MODULE_DESCRIPTION("SoC Camera driver for tw9910"); 956MODULE_DESCRIPTION("SoC Camera driver for tw9910");
971MODULE_AUTHOR("Kuninori Morimoto"); 957MODULE_AUTHOR("Kuninori Morimoto");
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c
index 1aab96a88203..1e7446542091 100644
--- a/drivers/media/video/upd64031a.c
+++ b/drivers/media/video/upd64031a.c
@@ -271,15 +271,4 @@ static struct i2c_driver upd64031a_driver = {
271 .id_table = upd64031a_id, 271 .id_table = upd64031a_id,
272}; 272};
273 273
274static __init int init_upd64031a(void) 274module_i2c_driver(upd64031a_driver);
275{
276 return i2c_add_driver(&upd64031a_driver);
277}
278
279static __exit void exit_upd64031a(void)
280{
281 i2c_del_driver(&upd64031a_driver);
282}
283
284module_init(init_upd64031a);
285module_exit(exit_upd64031a);
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c
index 65d065aa6091..75d6acc62018 100644
--- a/drivers/media/video/upd64083.c
+++ b/drivers/media/video/upd64083.c
@@ -243,15 +243,4 @@ static struct i2c_driver upd64083_driver = {
243 .id_table = upd64083_id, 243 .id_table = upd64083_id,
244}; 244};
245 245
246static __init int init_upd64083(void) 246module_i2c_driver(upd64083_driver);
247{
248 return i2c_add_driver(&upd64083_driver);
249}
250
251static __exit void exit_upd64083(void)
252{
253 i2c_del_driver(&upd64083_driver);
254}
255
256module_init(init_upd64083);
257module_exit(exit_upd64083);
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index a240d43d15d1..1d131720b6d7 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -23,6 +23,7 @@
23 * codec can't handle MJPEG data. 23 * codec can't handle MJPEG data.
24 */ 24 */
25 25
26#include <linux/atomic.h>
26#include <linux/kernel.h> 27#include <linux/kernel.h>
27#include <linux/list.h> 28#include <linux/list.h>
28#include <linux/module.h> 29#include <linux/module.h>
@@ -32,7 +33,6 @@
32#include <linux/vmalloc.h> 33#include <linux/vmalloc.h>
33#include <linux/wait.h> 34#include <linux/wait.h>
34#include <linux/version.h> 35#include <linux/version.h>
35#include <asm/atomic.h>
36#include <asm/unaligned.h> 36#include <asm/unaligned.h>
37 37
38#include <media/v4l2-common.h> 38#include <media/v4l2-common.h>
@@ -2139,6 +2139,15 @@ static struct usb_device_id uvc_ids[] = {
2139 .bInterfaceSubClass = 1, 2139 .bInterfaceSubClass = 1,
2140 .bInterfaceProtocol = 0, 2140 .bInterfaceProtocol = 0,
2141 .driver_info = UVC_QUIRK_PROBE_MINMAX }, 2141 .driver_info = UVC_QUIRK_PROBE_MINMAX },
2142 /* Dell XPS m1530 */
2143 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2144 | USB_DEVICE_ID_MATCH_INT_INFO,
2145 .idVendor = 0x05a9,
2146 .idProduct = 0x2640,
2147 .bInterfaceClass = USB_CLASS_VIDEO,
2148 .bInterfaceSubClass = 1,
2149 .bInterfaceProtocol = 0,
2150 .driver_info = UVC_QUIRK_PROBE_DEF },
2142 /* Apple Built-In iSight */ 2151 /* Apple Built-In iSight */
2143 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 2152 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2144 | USB_DEVICE_ID_MATCH_INT_INFO, 2153 | USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index 518f77d3a4d8..8f54e24e3f35 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -126,7 +126,7 @@ void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type,
126 int drop_corrupted) 126 int drop_corrupted)
127{ 127{
128 queue->queue.type = type; 128 queue->queue.type = type;
129 queue->queue.io_modes = VB2_MMAP; 129 queue->queue.io_modes = VB2_MMAP | VB2_USERPTR;
130 queue->queue.drv_priv = queue; 130 queue->queue.drv_priv = queue;
131 queue->queue.buf_struct_size = sizeof(struct uvc_buffer); 131 queue->queue.buf_struct_size = sizeof(struct uvc_buffer);
132 queue->queue.ops = &uvc_queue_qops; 132 queue->queue.ops = &uvc_queue_qops;
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 2ae4f880ea05..ff2cdddf9bc6 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -11,6 +11,7 @@
11 * 11 *
12 */ 12 */
13 13
14#include <linux/compat.h>
14#include <linux/kernel.h> 15#include <linux/kernel.h>
15#include <linux/version.h> 16#include <linux/version.h>
16#include <linux/list.h> 17#include <linux/list.h>
@@ -1012,7 +1013,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1012 1013
1013 default: 1014 default:
1014 uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n", cmd); 1015 uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n", cmd);
1015 return -EINVAL; 1016 return -ENOTTY;
1016 } 1017 }
1017 1018
1018 return ret; 1019 return ret;
@@ -1030,6 +1031,207 @@ static long uvc_v4l2_ioctl(struct file *file,
1030 return video_usercopy(file, cmd, arg, uvc_v4l2_do_ioctl); 1031 return video_usercopy(file, cmd, arg, uvc_v4l2_do_ioctl);
1031} 1032}
1032 1033
1034#ifdef CONFIG_COMPAT
1035struct uvc_xu_control_mapping32 {
1036 __u32 id;
1037 __u8 name[32];
1038 __u8 entity[16];
1039 __u8 selector;
1040
1041 __u8 size;
1042 __u8 offset;
1043 __u32 v4l2_type;
1044 __u32 data_type;
1045
1046 compat_caddr_t menu_info;
1047 __u32 menu_count;
1048
1049 __u32 reserved[4];
1050};
1051
1052static int uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping *kp,
1053 const struct uvc_xu_control_mapping32 __user *up)
1054{
1055 struct uvc_menu_info __user *umenus;
1056 struct uvc_menu_info __user *kmenus;
1057 compat_caddr_t p;
1058
1059 if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
1060 __copy_from_user(kp, up, offsetof(typeof(*up), menu_info)) ||
1061 __get_user(kp->menu_count, &up->menu_count))
1062 return -EFAULT;
1063
1064 memset(kp->reserved, 0, sizeof(kp->reserved));
1065
1066 if (kp->menu_count == 0) {
1067 kp->menu_info = NULL;
1068 return 0;
1069 }
1070
1071 if (__get_user(p, &up->menu_info))
1072 return -EFAULT;
1073 umenus = compat_ptr(p);
1074 if (!access_ok(VERIFY_READ, umenus, kp->menu_count * sizeof(*umenus)))
1075 return -EFAULT;
1076
1077 kmenus = compat_alloc_user_space(kp->menu_count * sizeof(*kmenus));
1078 if (kmenus == NULL)
1079 return -EFAULT;
1080 kp->menu_info = kmenus;
1081
1082 if (copy_in_user(kmenus, umenus, kp->menu_count * sizeof(*umenus)))
1083 return -EFAULT;
1084
1085 return 0;
1086}
1087
1088static int uvc_v4l2_put_xu_mapping(const struct uvc_xu_control_mapping *kp,
1089 struct uvc_xu_control_mapping32 __user *up)
1090{
1091 struct uvc_menu_info __user *umenus;
1092 struct uvc_menu_info __user *kmenus = kp->menu_info;
1093 compat_caddr_t p;
1094
1095 if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
1096 __copy_to_user(up, kp, offsetof(typeof(*up), menu_info)) ||
1097 __put_user(kp->menu_count, &up->menu_count))
1098 return -EFAULT;
1099
1100 __clear_user(up->reserved, sizeof(up->reserved));
1101
1102 if (kp->menu_count == 0)
1103 return 0;
1104
1105 if (get_user(p, &up->menu_info))
1106 return -EFAULT;
1107 umenus = compat_ptr(p);
1108 if (!access_ok(VERIFY_WRITE, umenus, kp->menu_count * sizeof(*umenus)))
1109 return -EFAULT;
1110
1111 if (copy_in_user(umenus, kmenus, kp->menu_count * sizeof(*umenus)))
1112 return -EFAULT;
1113
1114 return 0;
1115}
1116
1117struct uvc_xu_control_query32 {
1118 __u8 unit;
1119 __u8 selector;
1120 __u8 query;
1121 __u16 size;
1122 compat_caddr_t data;
1123};
1124
1125static int uvc_v4l2_get_xu_query(struct uvc_xu_control_query *kp,
1126 const struct uvc_xu_control_query32 __user *up)
1127{
1128 u8 __user *udata;
1129 u8 __user *kdata;
1130 compat_caddr_t p;
1131
1132 if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
1133 __copy_from_user(kp, up, offsetof(typeof(*up), data)))
1134 return -EFAULT;
1135
1136 if (kp->size == 0) {
1137 kp->data = NULL;
1138 return 0;
1139 }
1140
1141 if (__get_user(p, &up->data))
1142 return -EFAULT;
1143 udata = compat_ptr(p);
1144 if (!access_ok(VERIFY_READ, udata, kp->size))
1145 return -EFAULT;
1146
1147 kdata = compat_alloc_user_space(kp->size);
1148 if (kdata == NULL)
1149 return -EFAULT;
1150 kp->data = kdata;
1151
1152 if (copy_in_user(kdata, udata, kp->size))
1153 return -EFAULT;
1154
1155 return 0;
1156}
1157
1158static int uvc_v4l2_put_xu_query(const struct uvc_xu_control_query *kp,
1159 struct uvc_xu_control_query32 __user *up)
1160{
1161 u8 __user *udata;
1162 u8 __user *kdata = kp->data;
1163 compat_caddr_t p;
1164
1165 if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
1166 __copy_to_user(up, kp, offsetof(typeof(*up), data)))
1167 return -EFAULT;
1168
1169 if (kp->size == 0)
1170 return 0;
1171
1172 if (get_user(p, &up->data))
1173 return -EFAULT;
1174 udata = compat_ptr(p);
1175 if (!access_ok(VERIFY_READ, udata, kp->size))
1176 return -EFAULT;
1177
1178 if (copy_in_user(udata, kdata, kp->size))
1179 return -EFAULT;
1180
1181 return 0;
1182}
1183
1184#define UVCIOC_CTRL_MAP32 _IOWR('u', 0x20, struct uvc_xu_control_mapping32)
1185#define UVCIOC_CTRL_QUERY32 _IOWR('u', 0x21, struct uvc_xu_control_query32)
1186
1187static long uvc_v4l2_compat_ioctl32(struct file *file,
1188 unsigned int cmd, unsigned long arg)
1189{
1190 union {
1191 struct uvc_xu_control_mapping xmap;
1192 struct uvc_xu_control_query xqry;
1193 } karg;
1194 void __user *up = compat_ptr(arg);
1195 mm_segment_t old_fs;
1196 long ret;
1197
1198 switch (cmd) {
1199 case UVCIOC_CTRL_MAP32:
1200 cmd = UVCIOC_CTRL_MAP;
1201 ret = uvc_v4l2_get_xu_mapping(&karg.xmap, up);
1202 break;
1203
1204 case UVCIOC_CTRL_QUERY32:
1205 cmd = UVCIOC_CTRL_QUERY;
1206 ret = uvc_v4l2_get_xu_query(&karg.xqry, up);
1207 break;
1208
1209 default:
1210 return -ENOIOCTLCMD;
1211 }
1212
1213 old_fs = get_fs();
1214 set_fs(KERNEL_DS);
1215 ret = uvc_v4l2_ioctl(file, cmd, (unsigned long)&karg);
1216 set_fs(old_fs);
1217
1218 if (ret < 0)
1219 return ret;
1220
1221 switch (cmd) {
1222 case UVCIOC_CTRL_MAP:
1223 ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up);
1224 break;
1225
1226 case UVCIOC_CTRL_QUERY:
1227 ret = uvc_v4l2_put_xu_query(&karg.xqry, up);
1228 break;
1229 }
1230
1231 return ret;
1232}
1233#endif
1234
1033static ssize_t uvc_v4l2_read(struct file *file, char __user *data, 1235static ssize_t uvc_v4l2_read(struct file *file, char __user *data,
1034 size_t count, loff_t *ppos) 1236 size_t count, loff_t *ppos)
1035{ 1237{
@@ -1076,6 +1278,9 @@ const struct v4l2_file_operations uvc_fops = {
1076 .open = uvc_v4l2_open, 1278 .open = uvc_v4l2_open,
1077 .release = uvc_v4l2_release, 1279 .release = uvc_v4l2_release,
1078 .unlocked_ioctl = uvc_v4l2_ioctl, 1280 .unlocked_ioctl = uvc_v4l2_ioctl,
1281#ifdef CONFIG_COMPAT
1282 .compat_ioctl32 = uvc_v4l2_compat_ioctl32,
1283#endif
1079 .read = uvc_v4l2_read, 1284 .read = uvc_v4l2_read,
1080 .mmap = uvc_v4l2_mmap, 1285 .mmap = uvc_v4l2_mmap,
1081 .poll = uvc_v4l2_poll, 1286 .poll = uvc_v4l2_poll,
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index af4419e6c658..2829d256e4b7 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -14,12 +14,11 @@
14 */ 14 */
15 15
16#include <linux/compat.h> 16#include <linux/compat.h>
17#include <linux/videodev2.h>
18#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/videodev2.h>
19#include <media/v4l2-dev.h>
19#include <media/v4l2-ioctl.h> 20#include <media/v4l2-ioctl.h>
20 21
21#ifdef CONFIG_COMPAT
22
23static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 22static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
24{ 23{
25 long ret = -ENOIOCTLCMD; 24 long ret = -ENOIOCTLCMD;
@@ -937,6 +936,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
937 936
938long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) 937long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
939{ 938{
939 struct video_device *vdev = video_devdata(file);
940 long ret = -ENOIOCTLCMD; 940 long ret = -ENOIOCTLCMD;
941 941
942 if (!file->f_op->unlocked_ioctl) 942 if (!file->f_op->unlocked_ioctl)
@@ -1005,6 +1005,8 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
1005 case VIDIOC_G_ENC_INDEX: 1005 case VIDIOC_G_ENC_INDEX:
1006 case VIDIOC_ENCODER_CMD: 1006 case VIDIOC_ENCODER_CMD:
1007 case VIDIOC_TRY_ENCODER_CMD: 1007 case VIDIOC_TRY_ENCODER_CMD:
1008 case VIDIOC_DECODER_CMD:
1009 case VIDIOC_TRY_DECODER_CMD:
1008 case VIDIOC_DBG_S_REGISTER: 1010 case VIDIOC_DBG_S_REGISTER:
1009 case VIDIOC_DBG_G_REGISTER: 1011 case VIDIOC_DBG_G_REGISTER:
1010 case VIDIOC_DBG_G_CHIP_IDENT: 1012 case VIDIOC_DBG_G_CHIP_IDENT:
@@ -1025,14 +1027,16 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
1025 break; 1027 break;
1026 1028
1027 default: 1029 default:
1028 printk(KERN_WARNING "compat_ioctl32: " 1030 if (vdev->fops->compat_ioctl32)
1029 "unknown ioctl '%c', dir=%d, #%d (0x%08x)\n", 1031 ret = vdev->fops->compat_ioctl32(file, cmd, arg);
1030 _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd), cmd); 1032
1033 if (ret == -ENOIOCTLCMD)
1034 printk(KERN_WARNING "compat_ioctl32: "
1035 "unknown ioctl '%c', dir=%d, #%d (0x%08x)\n",
1036 _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd),
1037 cmd);
1031 break; 1038 break;
1032 } 1039 }
1033 return ret; 1040 return ret;
1034} 1041}
1035EXPORT_SYMBOL_GPL(v4l2_compat_ioctl32); 1042EXPORT_SYMBOL_GPL(v4l2_compat_ioctl32);
1036#endif
1037
1038MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index cccd42be718a..18015c0a8d31 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -175,6 +175,15 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
175 "16-bit CRC", 175 "16-bit CRC",
176 NULL 176 NULL
177 }; 177 };
178 static const char * const mpeg_audio_dec_playback[] = {
179 "Auto",
180 "Stereo",
181 "Left",
182 "Right",
183 "Mono",
184 "Swapped Stereo",
185 NULL
186 };
178 static const char * const mpeg_video_encoding[] = { 187 static const char * const mpeg_video_encoding[] = {
179 "MPEG-1", 188 "MPEG-1",
180 "MPEG-2", 189 "MPEG-2",
@@ -236,8 +245,8 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
236 }; 245 };
237 static const char * const tune_preemphasis[] = { 246 static const char * const tune_preemphasis[] = {
238 "No Preemphasis", 247 "No Preemphasis",
239 "50 useconds", 248 "50 Microseconds",
240 "75 useconds", 249 "75 Microseconds",
241 NULL, 250 NULL,
242 }; 251 };
243 static const char * const header_mode[] = { 252 static const char * const header_mode[] = {
@@ -334,7 +343,7 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
334 }; 343 };
335 static const char * const mpeg4_profile[] = { 344 static const char * const mpeg4_profile[] = {
336 "Simple", 345 "Simple",
337 "Adcanved Simple", 346 "Advanced Simple",
338 "Core", 347 "Core",
339 "Simple Scalable", 348 "Simple Scalable",
340 "Advanced Coding Efficency", 349 "Advanced Coding Efficency",
@@ -353,6 +362,16 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
353 NULL, 362 NULL,
354 }; 363 };
355 364
365 static const char * const jpeg_chroma_subsampling[] = {
366 "4:4:4",
367 "4:2:2",
368 "4:2:0",
369 "4:1:1",
370 "4:1:0",
371 "Gray",
372 NULL,
373 };
374
356 switch (id) { 375 switch (id) {
357 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: 376 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
358 return mpeg_audio_sampling_freq; 377 return mpeg_audio_sampling_freq;
@@ -374,6 +393,9 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
374 return mpeg_audio_emphasis; 393 return mpeg_audio_emphasis;
375 case V4L2_CID_MPEG_AUDIO_CRC: 394 case V4L2_CID_MPEG_AUDIO_CRC:
376 return mpeg_audio_crc; 395 return mpeg_audio_crc;
396 case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK:
397 case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK:
398 return mpeg_audio_dec_playback;
377 case V4L2_CID_MPEG_VIDEO_ENCODING: 399 case V4L2_CID_MPEG_VIDEO_ENCODING:
378 return mpeg_video_encoding; 400 return mpeg_video_encoding;
379 case V4L2_CID_MPEG_VIDEO_ASPECT: 401 case V4L2_CID_MPEG_VIDEO_ASPECT:
@@ -414,6 +436,9 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
414 return mpeg_mpeg4_level; 436 return mpeg_mpeg4_level;
415 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: 437 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
416 return mpeg4_profile; 438 return mpeg4_profile;
439 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
440 return jpeg_chroma_subsampling;
441
417 default: 442 default:
418 return NULL; 443 return NULL;
419 } 444 }
@@ -492,6 +517,8 @@ const char *v4l2_ctrl_get_name(u32 id)
492 case V4L2_CID_MPEG_AUDIO_MUTE: return "Audio Mute"; 517 case V4L2_CID_MPEG_AUDIO_MUTE: return "Audio Mute";
493 case V4L2_CID_MPEG_AUDIO_AAC_BITRATE: return "Audio AAC Bitrate"; 518 case V4L2_CID_MPEG_AUDIO_AAC_BITRATE: return "Audio AAC Bitrate";
494 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: return "Audio AC-3 Bitrate"; 519 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: return "Audio AC-3 Bitrate";
520 case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK: return "Audio Playback";
521 case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK: return "Audio Multilingual Playback";
495 case V4L2_CID_MPEG_VIDEO_ENCODING: return "Video Encoding"; 522 case V4L2_CID_MPEG_VIDEO_ENCODING: return "Video Encoding";
496 case V4L2_CID_MPEG_VIDEO_ASPECT: return "Video Aspect"; 523 case V4L2_CID_MPEG_VIDEO_ASPECT: return "Video Aspect";
497 case V4L2_CID_MPEG_VIDEO_B_FRAMES: return "Video B Frames"; 524 case V4L2_CID_MPEG_VIDEO_B_FRAMES: return "Video B Frames";
@@ -546,6 +573,8 @@ const char *v4l2_ctrl_get_name(u32 id)
546 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: return "Number of MBs in a Slice"; 573 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: return "Number of MBs in a Slice";
547 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: return "Slice Partitioning Method"; 574 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: return "Slice Partitioning Method";
548 case V4L2_CID_MPEG_VIDEO_VBV_SIZE: return "VBV Buffer Size"; 575 case V4L2_CID_MPEG_VIDEO_VBV_SIZE: return "VBV Buffer Size";
576 case V4L2_CID_MPEG_VIDEO_DEC_PTS: return "Video Decoder PTS";
577 case V4L2_CID_MPEG_VIDEO_DEC_FRAME: return "Video Decoder Frame Count";
549 578
550 /* CAMERA controls */ 579 /* CAMERA controls */
551 /* Keep the order of the 'case's the same as in videodev2.h! */ 580 /* Keep the order of the 'case's the same as in videodev2.h! */
@@ -607,6 +636,14 @@ const char *v4l2_ctrl_get_name(u32 id)
607 case V4L2_CID_FLASH_CHARGE: return "Charge"; 636 case V4L2_CID_FLASH_CHARGE: return "Charge";
608 case V4L2_CID_FLASH_READY: return "Ready to Strobe"; 637 case V4L2_CID_FLASH_READY: return "Ready to Strobe";
609 638
639 /* JPEG encoder controls */
640 /* Keep the order of the 'case's the same as in videodev2.h! */
641 case V4L2_CID_JPEG_CLASS: return "JPEG Compression Controls";
642 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: return "Chroma Subsampling";
643 case V4L2_CID_JPEG_RESTART_INTERVAL: return "Restart Interval";
644 case V4L2_CID_JPEG_COMPRESSION_QUALITY: return "Compression Quality";
645 case V4L2_CID_JPEG_ACTIVE_MARKER: return "Active Markers";
646
610 default: 647 default:
611 return NULL; 648 return NULL;
612 } 649 }
@@ -674,6 +711,8 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
674 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: 711 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
675 case V4L2_CID_MPEG_AUDIO_EMPHASIS: 712 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
676 case V4L2_CID_MPEG_AUDIO_CRC: 713 case V4L2_CID_MPEG_AUDIO_CRC:
714 case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK:
715 case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK:
677 case V4L2_CID_MPEG_VIDEO_ENCODING: 716 case V4L2_CID_MPEG_VIDEO_ENCODING:
678 case V4L2_CID_MPEG_VIDEO_ASPECT: 717 case V4L2_CID_MPEG_VIDEO_ASPECT:
679 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: 718 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
@@ -693,6 +732,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
693 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: 732 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
694 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: 733 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
695 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: 734 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
735 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
696 *type = V4L2_CTRL_TYPE_MENU; 736 *type = V4L2_CTRL_TYPE_MENU;
697 break; 737 break;
698 case V4L2_CID_RDS_TX_PS_NAME: 738 case V4L2_CID_RDS_TX_PS_NAME:
@@ -704,6 +744,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
704 case V4L2_CID_MPEG_CLASS: 744 case V4L2_CID_MPEG_CLASS:
705 case V4L2_CID_FM_TX_CLASS: 745 case V4L2_CID_FM_TX_CLASS:
706 case V4L2_CID_FLASH_CLASS: 746 case V4L2_CID_FLASH_CLASS:
747 case V4L2_CID_JPEG_CLASS:
707 *type = V4L2_CTRL_TYPE_CTRL_CLASS; 748 *type = V4L2_CTRL_TYPE_CTRL_CLASS;
708 /* You can neither read not write these */ 749 /* You can neither read not write these */
709 *flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY; 750 *flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY;
@@ -717,6 +758,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
717 *max = 0xFFFFFF; 758 *max = 0xFFFFFF;
718 break; 759 break;
719 case V4L2_CID_FLASH_FAULT: 760 case V4L2_CID_FLASH_FAULT:
761 case V4L2_CID_JPEG_ACTIVE_MARKER:
720 *type = V4L2_CTRL_TYPE_BITMASK; 762 *type = V4L2_CTRL_TYPE_BITMASK;
721 break; 763 break;
722 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: 764 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
@@ -724,6 +766,11 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
724 *type = V4L2_CTRL_TYPE_INTEGER; 766 *type = V4L2_CTRL_TYPE_INTEGER;
725 *flags |= V4L2_CTRL_FLAG_READ_ONLY; 767 *flags |= V4L2_CTRL_FLAG_READ_ONLY;
726 break; 768 break;
769 case V4L2_CID_MPEG_VIDEO_DEC_FRAME:
770 case V4L2_CID_MPEG_VIDEO_DEC_PTS:
771 *type = V4L2_CTRL_TYPE_INTEGER64;
772 *flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_VOLATILE;
773 break;
727 default: 774 default:
728 *type = V4L2_CTRL_TYPE_INTEGER; 775 *type = V4L2_CTRL_TYPE_INTEGER;
729 break; 776 break;
@@ -1470,7 +1517,7 @@ EXPORT_SYMBOL(v4l2_ctrl_add_ctrl);
1470int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl, 1517int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
1471 struct v4l2_ctrl_handler *add) 1518 struct v4l2_ctrl_handler *add)
1472{ 1519{
1473 struct v4l2_ctrl *ctrl; 1520 struct v4l2_ctrl_ref *ref;
1474 int ret = 0; 1521 int ret = 0;
1475 1522
1476 /* Do nothing if either handler is NULL or if they are the same */ 1523 /* Do nothing if either handler is NULL or if they are the same */
@@ -1479,7 +1526,9 @@ int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
1479 if (hdl->error) 1526 if (hdl->error)
1480 return hdl->error; 1527 return hdl->error;
1481 mutex_lock(&add->lock); 1528 mutex_lock(&add->lock);
1482 list_for_each_entry(ctrl, &add->ctrls, node) { 1529 list_for_each_entry(ref, &add->ctrl_refs, node) {
1530 struct v4l2_ctrl *ctrl = ref->ctrl;
1531
1483 /* Skip handler-private controls. */ 1532 /* Skip handler-private controls. */
1484 if (ctrl->is_private) 1533 if (ctrl->is_private)
1485 continue; 1534 continue;
@@ -2359,3 +2408,35 @@ void v4l2_ctrl_del_event(struct v4l2_ctrl *ctrl,
2359 v4l2_ctrl_unlock(ctrl); 2408 v4l2_ctrl_unlock(ctrl);
2360} 2409}
2361EXPORT_SYMBOL(v4l2_ctrl_del_event); 2410EXPORT_SYMBOL(v4l2_ctrl_del_event);
2411
2412int v4l2_ctrl_log_status(struct file *file, void *fh)
2413{
2414 struct video_device *vfd = video_devdata(file);
2415 struct v4l2_fh *vfh = file->private_data;
2416
2417 if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) && vfd->v4l2_dev)
2418 v4l2_ctrl_handler_log_status(vfh->ctrl_handler,
2419 vfd->v4l2_dev->name);
2420 return 0;
2421}
2422EXPORT_SYMBOL(v4l2_ctrl_log_status);
2423
2424int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh,
2425 struct v4l2_event_subscription *sub)
2426{
2427 if (sub->type == V4L2_EVENT_CTRL)
2428 return v4l2_event_subscribe(fh, sub, 0);
2429 return -EINVAL;
2430}
2431EXPORT_SYMBOL(v4l2_ctrl_subscribe_event);
2432
2433unsigned int v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait)
2434{
2435 struct v4l2_fh *fh = file->private_data;
2436
2437 if (v4l2_event_pending(fh))
2438 return POLLPRI;
2439 poll_wait(file, &fh->wait, wait);
2440 return 0;
2441}
2442EXPORT_SYMBOL(v4l2_ctrl_poll);
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 96e9615663e9..041804b73ebd 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -788,7 +788,7 @@ static void __exit videodev_exit(void)
788 unregister_chrdev_region(dev, VIDEO_NUM_DEVICES); 788 unregister_chrdev_region(dev, VIDEO_NUM_DEVICES);
789} 789}
790 790
791module_init(videodev_init) 791subsys_initcall(videodev_init);
792module_exit(videodev_exit) 792module_exit(videodev_exit)
793 793
794MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>"); 794MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 3f623859a337..5b2ec1fd2d0a 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -260,6 +260,8 @@ static const char *v4l2_ioctls[] = {
260 [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD", 260 [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD",
261 [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD", 261 [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD",
262 262
263 [_IOC_NR(VIDIOC_DECODER_CMD)] = "VIDIOC_DECODER_CMD",
264 [_IOC_NR(VIDIOC_TRY_DECODER_CMD)] = "VIDIOC_TRY_DECODER_CMD",
263 [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER", 265 [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER",
264 [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER", 266 [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER",
265 267
@@ -540,10 +542,12 @@ static long __video_do_ioctl(struct file *file,
540 if (!ret) 542 if (!ret)
541 dbgarg(cmd, "driver=%s, card=%s, bus=%s, " 543 dbgarg(cmd, "driver=%s, card=%s, bus=%s, "
542 "version=0x%08x, " 544 "version=0x%08x, "
543 "capabilities=0x%08x\n", 545 "capabilities=0x%08x, "
546 "device_caps=0x%08x\n",
544 cap->driver, cap->card, cap->bus_info, 547 cap->driver, cap->card, cap->bus_info,
545 cap->version, 548 cap->version,
546 cap->capabilities); 549 cap->capabilities,
550 cap->device_caps);
547 break; 551 break;
548 } 552 }
549 553
@@ -1762,6 +1766,32 @@ static long __video_do_ioctl(struct file *file,
1762 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); 1766 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
1763 break; 1767 break;
1764 } 1768 }
1769 case VIDIOC_DECODER_CMD:
1770 {
1771 struct v4l2_decoder_cmd *p = arg;
1772
1773 if (!ops->vidioc_decoder_cmd)
1774 break;
1775 if (ret_prio) {
1776 ret = ret_prio;
1777 break;
1778 }
1779 ret = ops->vidioc_decoder_cmd(file, fh, p);
1780 if (!ret)
1781 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
1782 break;
1783 }
1784 case VIDIOC_TRY_DECODER_CMD:
1785 {
1786 struct v4l2_decoder_cmd *p = arg;
1787
1788 if (!ops->vidioc_try_decoder_cmd)
1789 break;
1790 ret = ops->vidioc_try_decoder_cmd(file, fh, p);
1791 if (!ret)
1792 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
1793 break;
1794 }
1765 case VIDIOC_G_PARM: 1795 case VIDIOC_G_PARM:
1766 { 1796 {
1767 struct v4l2_streamparm *p = arg; 1797 struct v4l2_streamparm *p = arg;
@@ -1909,7 +1939,13 @@ static long __video_do_ioctl(struct file *file,
1909 { 1939 {
1910 if (!ops->vidioc_log_status) 1940 if (!ops->vidioc_log_status)
1911 break; 1941 break;
1942 if (vfd->v4l2_dev)
1943 pr_info("%s: ================= START STATUS =================\n",
1944 vfd->v4l2_dev->name);
1912 ret = ops->vidioc_log_status(file, fh); 1945 ret = ops->vidioc_log_status(file, fh);
1946 if (vfd->v4l2_dev)
1947 pr_info("%s: ================== END STATUS ==================\n",
1948 vfd->v4l2_dev->name);
1913 break; 1949 break;
1914 } 1950 }
1915#ifdef CONFIG_VIDEO_ADV_DEBUG 1951#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -2419,7 +2455,7 @@ video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
2419 /* Handles IOCTL */ 2455 /* Handles IOCTL */
2420 err = func(file, cmd, parg); 2456 err = func(file, cmd, parg);
2421 if (err == -ENOIOCTLCMD) 2457 if (err == -ENOIOCTLCMD)
2422 err = -EINVAL; 2458 err = -ENOTTY;
2423 2459
2424 if (has_array_args) { 2460 if (has_array_args) {
2425 *kernel_ptr = user_ptr; 2461 *kernel_ptr = user_ptr;
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c
index 41d118ee2de6..6fe88e965a8c 100644
--- a/drivers/media/video/v4l2-subdev.c
+++ b/drivers/media/video/v4l2-subdev.c
@@ -194,8 +194,16 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
194 } 194 }
195#endif 195#endif
196 196
197 case VIDIOC_LOG_STATUS: 197 case VIDIOC_LOG_STATUS: {
198 return v4l2_subdev_call(sd, core, log_status); 198 int ret;
199
200 pr_info("%s: ================= START STATUS =================\n",
201 sd->name);
202 ret = v4l2_subdev_call(sd, core, log_status);
203 pr_info("%s: ================== END STATUS ==================\n",
204 sd->name);
205 return ret;
206 }
199 207
200#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) 208#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
201 case VIDIOC_SUBDEV_G_FMT: { 209 case VIDIOC_SUBDEV_G_FMT: {
diff --git a/drivers/media/video/videobuf2-vmalloc.c b/drivers/media/video/videobuf2-vmalloc.c
index 4e789a178f8a..6b5ca6c70a46 100644
--- a/drivers/media/video/videobuf2-vmalloc.c
+++ b/drivers/media/video/videobuf2-vmalloc.c
@@ -10,6 +10,7 @@
10 * the Free Software Foundation. 10 * the Free Software Foundation.
11 */ 11 */
12 12
13#include <linux/io.h>
13#include <linux/module.h> 14#include <linux/module.h>
14#include <linux/mm.h> 15#include <linux/mm.h>
15#include <linux/sched.h> 16#include <linux/sched.h>
@@ -22,6 +23,7 @@
22struct vb2_vmalloc_buf { 23struct vb2_vmalloc_buf {
23 void *vaddr; 24 void *vaddr;
24 struct page **pages; 25 struct page **pages;
26 struct vm_area_struct *vma;
25 int write; 27 int write;
26 unsigned long size; 28 unsigned long size;
27 unsigned int n_pages; 29 unsigned int n_pages;
@@ -71,6 +73,8 @@ static void *vb2_vmalloc_get_userptr(void *alloc_ctx, unsigned long vaddr,
71 struct vb2_vmalloc_buf *buf; 73 struct vb2_vmalloc_buf *buf;
72 unsigned long first, last; 74 unsigned long first, last;
73 int n_pages, offset; 75 int n_pages, offset;
76 struct vm_area_struct *vma;
77 dma_addr_t physp;
74 78
75 buf = kzalloc(sizeof(*buf), GFP_KERNEL); 79 buf = kzalloc(sizeof(*buf), GFP_KERNEL);
76 if (!buf) 80 if (!buf)
@@ -80,23 +84,37 @@ static void *vb2_vmalloc_get_userptr(void *alloc_ctx, unsigned long vaddr,
80 offset = vaddr & ~PAGE_MASK; 84 offset = vaddr & ~PAGE_MASK;
81 buf->size = size; 85 buf->size = size;
82 86
83 first = vaddr >> PAGE_SHIFT;
84 last = (vaddr + size - 1) >> PAGE_SHIFT;
85 buf->n_pages = last - first + 1;
86 buf->pages = kzalloc(buf->n_pages * sizeof(struct page *), GFP_KERNEL);
87 if (!buf->pages)
88 goto fail_pages_array_alloc;
89 87
90 /* current->mm->mmap_sem is taken by videobuf2 core */ 88 vma = find_vma(current->mm, vaddr);
91 n_pages = get_user_pages(current, current->mm, vaddr & PAGE_MASK, 89 if (vma && (vma->vm_flags & VM_PFNMAP) && (vma->vm_pgoff)) {
92 buf->n_pages, write, 1, /* force */ 90 if (vb2_get_contig_userptr(vaddr, size, &vma, &physp))
93 buf->pages, NULL); 91 goto fail_pages_array_alloc;
94 if (n_pages != buf->n_pages) 92 buf->vma = vma;
95 goto fail_get_user_pages; 93 buf->vaddr = ioremap_nocache(physp, size);
96 94 if (!buf->vaddr)
97 buf->vaddr = vm_map_ram(buf->pages, buf->n_pages, -1, PAGE_KERNEL); 95 goto fail_pages_array_alloc;
98 if (!buf->vaddr) 96 } else {
99 goto fail_get_user_pages; 97 first = vaddr >> PAGE_SHIFT;
98 last = (vaddr + size - 1) >> PAGE_SHIFT;
99 buf->n_pages = last - first + 1;
100 buf->pages = kzalloc(buf->n_pages * sizeof(struct page *),
101 GFP_KERNEL);
102 if (!buf->pages)
103 goto fail_pages_array_alloc;
104
105 /* current->mm->mmap_sem is taken by videobuf2 core */
106 n_pages = get_user_pages(current, current->mm,
107 vaddr & PAGE_MASK, buf->n_pages,
108 write, 1, /* force */
109 buf->pages, NULL);
110 if (n_pages != buf->n_pages)
111 goto fail_get_user_pages;
112
113 buf->vaddr = vm_map_ram(buf->pages, buf->n_pages, -1,
114 PAGE_KERNEL);
115 if (!buf->vaddr)
116 goto fail_get_user_pages;
117 }
100 118
101 buf->vaddr += offset; 119 buf->vaddr += offset;
102 return buf; 120 return buf;
@@ -120,14 +138,20 @@ static void vb2_vmalloc_put_userptr(void *buf_priv)
120 unsigned long vaddr = (unsigned long)buf->vaddr & PAGE_MASK; 138 unsigned long vaddr = (unsigned long)buf->vaddr & PAGE_MASK;
121 unsigned int i; 139 unsigned int i;
122 140
123 if (vaddr) 141 if (buf->pages) {
124 vm_unmap_ram((void *)vaddr, buf->n_pages); 142 if (vaddr)
125 for (i = 0; i < buf->n_pages; ++i) { 143 vm_unmap_ram((void *)vaddr, buf->n_pages);
126 if (buf->write) 144 for (i = 0; i < buf->n_pages; ++i) {
127 set_page_dirty_lock(buf->pages[i]); 145 if (buf->write)
128 put_page(buf->pages[i]); 146 set_page_dirty_lock(buf->pages[i]);
147 put_page(buf->pages[i]);
148 }
149 kfree(buf->pages);
150 } else {
151 if (buf->vma)
152 vb2_put_vma(buf->vma);
153 iounmap(buf->vaddr);
129 } 154 }
130 kfree(buf->pages);
131 kfree(buf); 155 kfree(buf);
132} 156}
133 157
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 7d754fbcccbf..5e8b0710105b 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -819,8 +819,9 @@ static int vidioc_querycap(struct file *file, void *priv,
819 strcpy(cap->driver, "vivi"); 819 strcpy(cap->driver, "vivi");
820 strcpy(cap->card, "vivi"); 820 strcpy(cap->card, "vivi");
821 strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info)); 821 strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
822 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | \ 822 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
823 V4L2_CAP_READWRITE; 823 V4L2_CAP_READWRITE;
824 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
824 return 0; 825 return 0;
825} 826}
826 827
@@ -958,14 +959,6 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
958 return vb2_streamoff(&dev->vb_vidq, i); 959 return vb2_streamoff(&dev->vb_vidq, i);
959} 960}
960 961
961static int vidioc_log_status(struct file *file, void *priv)
962{
963 struct vivi_dev *dev = video_drvdata(file);
964
965 v4l2_ctrl_handler_log_status(&dev->ctrl_handler, dev->v4l2_dev.name);
966 return 0;
967}
968
969static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i) 962static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
970{ 963{
971 return 0; 964 return 0;
@@ -1008,17 +1001,6 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1008 return 0; 1001 return 0;
1009} 1002}
1010 1003
1011static int vidioc_subscribe_event(struct v4l2_fh *fh,
1012 struct v4l2_event_subscription *sub)
1013{
1014 switch (sub->type) {
1015 case V4L2_EVENT_CTRL:
1016 return v4l2_event_subscribe(fh, sub, 0);
1017 default:
1018 return -EINVAL;
1019 }
1020}
1021
1022/* --- controls ---------------------------------------------- */ 1004/* --- controls ---------------------------------------------- */
1023 1005
1024static int vivi_g_volatile_ctrl(struct v4l2_ctrl *ctrl) 1006static int vivi_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
@@ -1209,8 +1191,8 @@ static const struct v4l2_ioctl_ops vivi_ioctl_ops = {
1209 .vidioc_s_input = vidioc_s_input, 1191 .vidioc_s_input = vidioc_s_input,
1210 .vidioc_streamon = vidioc_streamon, 1192 .vidioc_streamon = vidioc_streamon,
1211 .vidioc_streamoff = vidioc_streamoff, 1193 .vidioc_streamoff = vidioc_streamoff,
1212 .vidioc_log_status = vidioc_log_status, 1194 .vidioc_log_status = v4l2_ctrl_log_status,
1213 .vidioc_subscribe_event = vidioc_subscribe_event, 1195 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1214 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 1196 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1215}; 1197};
1216 1198
diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c
index c15efb6e7771..7cfbc9d94a48 100644
--- a/drivers/media/video/vp27smpx.c
+++ b/drivers/media/video/vp27smpx.c
@@ -208,15 +208,4 @@ static struct i2c_driver vp27smpx_driver = {
208 .id_table = vp27smpx_id, 208 .id_table = vp27smpx_id,
209}; 209};
210 210
211static __init int init_vp27smpx(void) 211module_i2c_driver(vp27smpx_driver);
212{
213 return i2c_add_driver(&vp27smpx_driver);
214}
215
216static __exit void exit_vp27smpx(void)
217{
218 i2c_del_driver(&vp27smpx_driver);
219}
220
221module_init(init_vp27smpx);
222module_exit(exit_vp27smpx);
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
index e5cad6ff64a1..2f67b4c5c823 100644
--- a/drivers/media/video/vpx3220.c
+++ b/drivers/media/video/vpx3220.c
@@ -588,15 +588,4 @@ static struct i2c_driver vpx3220_driver = {
588 .id_table = vpx3220_id, 588 .id_table = vpx3220_id,
589}; 589};
590 590
591static __init int init_vpx3220(void) 591module_i2c_driver(vpx3220_driver);
592{
593 return i2c_add_driver(&vpx3220_driver);
594}
595
596static __exit void exit_vpx3220(void)
597{
598 i2c_del_driver(&vpx3220_driver);
599}
600
601module_init(init_vpx3220);
602module_exit(exit_vpx3220);
diff --git a/drivers/media/video/vs6624.c b/drivers/media/video/vs6624.c
new file mode 100644
index 000000000000..42ae9dc9c574
--- /dev/null
+++ b/drivers/media/video/vs6624.c
@@ -0,0 +1,928 @@
1/*
2 * vs6624.c ST VS6624 CMOS image sensor driver
3 *
4 * Copyright (c) 2011 Analog Devices Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * 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/delay.h>
21#include <linux/errno.h>
22#include <linux/gpio.h>
23#include <linux/i2c.h>
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/slab.h>
27#include <linux/types.h>
28#include <linux/videodev2.h>
29
30#include <media/v4l2-chip-ident.h>
31#include <media/v4l2-ctrls.h>
32#include <media/v4l2-device.h>
33#include <media/v4l2-mediabus.h>
34
35#include "vs6624_regs.h"
36
37#define VGA_WIDTH 640
38#define VGA_HEIGHT 480
39#define QVGA_WIDTH 320
40#define QVGA_HEIGHT 240
41#define QQVGA_WIDTH 160
42#define QQVGA_HEIGHT 120
43#define CIF_WIDTH 352
44#define CIF_HEIGHT 288
45#define QCIF_WIDTH 176
46#define QCIF_HEIGHT 144
47#define QQCIF_WIDTH 88
48#define QQCIF_HEIGHT 72
49
50#define MAX_FRAME_RATE 30
51
52struct vs6624 {
53 struct v4l2_subdev sd;
54 struct v4l2_ctrl_handler hdl;
55 struct v4l2_fract frame_rate;
56 struct v4l2_mbus_framefmt fmt;
57 unsigned ce_pin;
58};
59
60static const struct vs6624_format {
61 enum v4l2_mbus_pixelcode mbus_code;
62 enum v4l2_colorspace colorspace;
63} vs6624_formats[] = {
64 {
65 .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8,
66 .colorspace = V4L2_COLORSPACE_JPEG,
67 },
68 {
69 .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
70 .colorspace = V4L2_COLORSPACE_JPEG,
71 },
72 {
73 .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE,
74 .colorspace = V4L2_COLORSPACE_SRGB,
75 },
76};
77
78static struct v4l2_mbus_framefmt vs6624_default_fmt = {
79 .width = VGA_WIDTH,
80 .height = VGA_HEIGHT,
81 .code = V4L2_MBUS_FMT_UYVY8_2X8,
82 .field = V4L2_FIELD_NONE,
83 .colorspace = V4L2_COLORSPACE_JPEG,
84};
85
86static const u16 vs6624_p1[] = {
87 0x8104, 0x03,
88 0x8105, 0x01,
89 0xc900, 0x03,
90 0xc904, 0x47,
91 0xc905, 0x10,
92 0xc906, 0x80,
93 0xc907, 0x3a,
94 0x903a, 0x02,
95 0x903b, 0x47,
96 0x903c, 0x15,
97 0xc908, 0x31,
98 0xc909, 0xdc,
99 0xc90a, 0x80,
100 0xc90b, 0x44,
101 0x9044, 0x02,
102 0x9045, 0x31,
103 0x9046, 0xe2,
104 0xc90c, 0x07,
105 0xc90d, 0xe0,
106 0xc90e, 0x80,
107 0xc90f, 0x47,
108 0x9047, 0x90,
109 0x9048, 0x83,
110 0x9049, 0x81,
111 0x904a, 0xe0,
112 0x904b, 0x60,
113 0x904c, 0x08,
114 0x904d, 0x90,
115 0x904e, 0xc0,
116 0x904f, 0x43,
117 0x9050, 0x74,
118 0x9051, 0x01,
119 0x9052, 0xf0,
120 0x9053, 0x80,
121 0x9054, 0x05,
122 0x9055, 0xE4,
123 0x9056, 0x90,
124 0x9057, 0xc0,
125 0x9058, 0x43,
126 0x9059, 0xf0,
127 0x905a, 0x02,
128 0x905b, 0x07,
129 0x905c, 0xec,
130 0xc910, 0x5d,
131 0xc911, 0xca,
132 0xc912, 0x80,
133 0xc913, 0x5d,
134 0x905d, 0xa3,
135 0x905e, 0x04,
136 0x905f, 0xf0,
137 0x9060, 0xa3,
138 0x9061, 0x04,
139 0x9062, 0xf0,
140 0x9063, 0x22,
141 0xc914, 0x72,
142 0xc915, 0x92,
143 0xc916, 0x80,
144 0xc917, 0x64,
145 0x9064, 0x74,
146 0x9065, 0x01,
147 0x9066, 0x02,
148 0x9067, 0x72,
149 0x9068, 0x95,
150 0xc918, 0x47,
151 0xc919, 0xf2,
152 0xc91a, 0x81,
153 0xc91b, 0x69,
154 0x9169, 0x74,
155 0x916a, 0x02,
156 0x916b, 0xf0,
157 0x916c, 0xec,
158 0x916d, 0xb4,
159 0x916e, 0x10,
160 0x916f, 0x0a,
161 0x9170, 0x90,
162 0x9171, 0x80,
163 0x9172, 0x16,
164 0x9173, 0xe0,
165 0x9174, 0x70,
166 0x9175, 0x04,
167 0x9176, 0x90,
168 0x9177, 0xd3,
169 0x9178, 0xc4,
170 0x9179, 0xf0,
171 0x917a, 0x22,
172 0xc91c, 0x0a,
173 0xc91d, 0xbe,
174 0xc91e, 0x80,
175 0xc91f, 0x73,
176 0x9073, 0xfc,
177 0x9074, 0xa3,
178 0x9075, 0xe0,
179 0x9076, 0xf5,
180 0x9077, 0x82,
181 0x9078, 0x8c,
182 0x9079, 0x83,
183 0x907a, 0xa3,
184 0x907b, 0xa3,
185 0x907c, 0xe0,
186 0x907d, 0xfc,
187 0x907e, 0xa3,
188 0x907f, 0xe0,
189 0x9080, 0xc3,
190 0x9081, 0x9f,
191 0x9082, 0xff,
192 0x9083, 0xec,
193 0x9084, 0x9e,
194 0x9085, 0xfe,
195 0x9086, 0x02,
196 0x9087, 0x0a,
197 0x9088, 0xea,
198 0xc920, 0x47,
199 0xc921, 0x38,
200 0xc922, 0x80,
201 0xc923, 0x89,
202 0x9089, 0xec,
203 0x908a, 0xd3,
204 0x908b, 0x94,
205 0x908c, 0x20,
206 0x908d, 0x40,
207 0x908e, 0x01,
208 0x908f, 0x1c,
209 0x9090, 0x90,
210 0x9091, 0xd3,
211 0x9092, 0xd4,
212 0x9093, 0xec,
213 0x9094, 0xf0,
214 0x9095, 0x02,
215 0x9096, 0x47,
216 0x9097, 0x3d,
217 0xc924, 0x45,
218 0xc925, 0xca,
219 0xc926, 0x80,
220 0xc927, 0x98,
221 0x9098, 0x12,
222 0x9099, 0x77,
223 0x909a, 0xd6,
224 0x909b, 0x02,
225 0x909c, 0x45,
226 0x909d, 0xcd,
227 0xc928, 0x20,
228 0xc929, 0xd5,
229 0xc92a, 0x80,
230 0xc92b, 0x9e,
231 0x909e, 0x90,
232 0x909f, 0x82,
233 0x90a0, 0x18,
234 0x90a1, 0xe0,
235 0x90a2, 0xb4,
236 0x90a3, 0x03,
237 0x90a4, 0x0e,
238 0x90a5, 0x90,
239 0x90a6, 0x83,
240 0x90a7, 0xbf,
241 0x90a8, 0xe0,
242 0x90a9, 0x60,
243 0x90aa, 0x08,
244 0x90ab, 0x90,
245 0x90ac, 0x81,
246 0x90ad, 0xfc,
247 0x90ae, 0xe0,
248 0x90af, 0xff,
249 0x90b0, 0xc3,
250 0x90b1, 0x13,
251 0x90b2, 0xf0,
252 0x90b3, 0x90,
253 0x90b4, 0x81,
254 0x90b5, 0xfc,
255 0x90b6, 0xe0,
256 0x90b7, 0xff,
257 0x90b8, 0x02,
258 0x90b9, 0x20,
259 0x90ba, 0xda,
260 0xc92c, 0x70,
261 0xc92d, 0xbc,
262 0xc92e, 0x80,
263 0xc92f, 0xbb,
264 0x90bb, 0x90,
265 0x90bc, 0x82,
266 0x90bd, 0x18,
267 0x90be, 0xe0,
268 0x90bf, 0xb4,
269 0x90c0, 0x03,
270 0x90c1, 0x06,
271 0x90c2, 0x90,
272 0x90c3, 0xc1,
273 0x90c4, 0x06,
274 0x90c5, 0x74,
275 0x90c6, 0x05,
276 0x90c7, 0xf0,
277 0x90c8, 0x90,
278 0x90c9, 0xd3,
279 0x90ca, 0xa0,
280 0x90cb, 0x02,
281 0x90cc, 0x70,
282 0x90cd, 0xbf,
283 0xc930, 0x72,
284 0xc931, 0x21,
285 0xc932, 0x81,
286 0xc933, 0x3b,
287 0x913b, 0x7d,
288 0x913c, 0x02,
289 0x913d, 0x7f,
290 0x913e, 0x7b,
291 0x913f, 0x02,
292 0x9140, 0x72,
293 0x9141, 0x25,
294 0xc934, 0x28,
295 0xc935, 0xae,
296 0xc936, 0x80,
297 0xc937, 0xd2,
298 0x90d2, 0xf0,
299 0x90d3, 0x90,
300 0x90d4, 0xd2,
301 0x90d5, 0x0a,
302 0x90d6, 0x02,
303 0x90d7, 0x28,
304 0x90d8, 0xb4,
305 0xc938, 0x28,
306 0xc939, 0xb1,
307 0xc93a, 0x80,
308 0xc93b, 0xd9,
309 0x90d9, 0x90,
310 0x90da, 0x83,
311 0x90db, 0xba,
312 0x90dc, 0xe0,
313 0x90dd, 0xff,
314 0x90de, 0x90,
315 0x90df, 0xd2,
316 0x90e0, 0x08,
317 0x90e1, 0xe0,
318 0x90e2, 0xe4,
319 0x90e3, 0xef,
320 0x90e4, 0xf0,
321 0x90e5, 0xa3,
322 0x90e6, 0xe0,
323 0x90e7, 0x74,
324 0x90e8, 0xff,
325 0x90e9, 0xf0,
326 0x90ea, 0x90,
327 0x90eb, 0xd2,
328 0x90ec, 0x0a,
329 0x90ed, 0x02,
330 0x90ee, 0x28,
331 0x90ef, 0xb4,
332 0xc93c, 0x29,
333 0xc93d, 0x79,
334 0xc93e, 0x80,
335 0xc93f, 0xf0,
336 0x90f0, 0xf0,
337 0x90f1, 0x90,
338 0x90f2, 0xd2,
339 0x90f3, 0x0e,
340 0x90f4, 0x02,
341 0x90f5, 0x29,
342 0x90f6, 0x7f,
343 0xc940, 0x29,
344 0xc941, 0x7c,
345 0xc942, 0x80,
346 0xc943, 0xf7,
347 0x90f7, 0x90,
348 0x90f8, 0x83,
349 0x90f9, 0xba,
350 0x90fa, 0xe0,
351 0x90fb, 0xff,
352 0x90fc, 0x90,
353 0x90fd, 0xd2,
354 0x90fe, 0x0c,
355 0x90ff, 0xe0,
356 0x9100, 0xe4,
357 0x9101, 0xef,
358 0x9102, 0xf0,
359 0x9103, 0xa3,
360 0x9104, 0xe0,
361 0x9105, 0x74,
362 0x9106, 0xff,
363 0x9107, 0xf0,
364 0x9108, 0x90,
365 0x9109, 0xd2,
366 0x910a, 0x0e,
367 0x910b, 0x02,
368 0x910c, 0x29,
369 0x910d, 0x7f,
370 0xc944, 0x2a,
371 0xc945, 0x42,
372 0xc946, 0x81,
373 0xc947, 0x0e,
374 0x910e, 0xf0,
375 0x910f, 0x90,
376 0x9110, 0xd2,
377 0x9111, 0x12,
378 0x9112, 0x02,
379 0x9113, 0x2a,
380 0x9114, 0x48,
381 0xc948, 0x2a,
382 0xc949, 0x45,
383 0xc94a, 0x81,
384 0xc94b, 0x15,
385 0x9115, 0x90,
386 0x9116, 0x83,
387 0x9117, 0xba,
388 0x9118, 0xe0,
389 0x9119, 0xff,
390 0x911a, 0x90,
391 0x911b, 0xd2,
392 0x911c, 0x10,
393 0x911d, 0xe0,
394 0x911e, 0xe4,
395 0x911f, 0xef,
396 0x9120, 0xf0,
397 0x9121, 0xa3,
398 0x9122, 0xe0,
399 0x9123, 0x74,
400 0x9124, 0xff,
401 0x9125, 0xf0,
402 0x9126, 0x90,
403 0x9127, 0xd2,
404 0x9128, 0x12,
405 0x9129, 0x02,
406 0x912a, 0x2a,
407 0x912b, 0x48,
408 0xc900, 0x01,
409 0x0000, 0x00,
410};
411
412static const u16 vs6624_p2[] = {
413 0x806f, 0x01,
414 0x058c, 0x01,
415 0x0000, 0x00,
416};
417
418static const u16 vs6624_run_setup[] = {
419 0x1d18, 0x00, /* Enableconstrainedwhitebalance */
420 VS6624_PEAK_MIN_OUT_G_MSB, 0x3c, /* Damper PeakGain Output MSB */
421 VS6624_PEAK_MIN_OUT_G_LSB, 0x66, /* Damper PeakGain Output LSB */
422 VS6624_CM_LOW_THR_MSB, 0x65, /* Damper Low MSB */
423 VS6624_CM_LOW_THR_LSB, 0xd1, /* Damper Low LSB */
424 VS6624_CM_HIGH_THR_MSB, 0x66, /* Damper High MSB */
425 VS6624_CM_HIGH_THR_LSB, 0x62, /* Damper High LSB */
426 VS6624_CM_MIN_OUT_MSB, 0x00, /* Damper Min output MSB */
427 VS6624_CM_MIN_OUT_LSB, 0x00, /* Damper Min output LSB */
428 VS6624_NORA_DISABLE, 0x00, /* Nora fDisable */
429 VS6624_NORA_USAGE, 0x04, /* Nora usage */
430 VS6624_NORA_LOW_THR_MSB, 0x63, /* Damper Low MSB Changed 0x63 to 0x65 */
431 VS6624_NORA_LOW_THR_LSB, 0xd1, /* Damper Low LSB */
432 VS6624_NORA_HIGH_THR_MSB, 0x68, /* Damper High MSB */
433 VS6624_NORA_HIGH_THR_LSB, 0xdd, /* Damper High LSB */
434 VS6624_NORA_MIN_OUT_MSB, 0x3a, /* Damper Min output MSB */
435 VS6624_NORA_MIN_OUT_LSB, 0x00, /* Damper Min output LSB */
436 VS6624_F2B_DISABLE, 0x00, /* Disable */
437 0x1d8a, 0x30, /* MAXWeightHigh */
438 0x1d91, 0x62, /* fpDamperLowThresholdHigh MSB */
439 0x1d92, 0x4a, /* fpDamperLowThresholdHigh LSB */
440 0x1d95, 0x65, /* fpDamperHighThresholdHigh MSB */
441 0x1d96, 0x0e, /* fpDamperHighThresholdHigh LSB */
442 0x1da1, 0x3a, /* fpMinimumDamperOutputLow MSB */
443 0x1da2, 0xb8, /* fpMinimumDamperOutputLow LSB */
444 0x1e08, 0x06, /* MAXWeightLow */
445 0x1e0a, 0x0a, /* MAXWeightHigh */
446 0x1601, 0x3a, /* Red A MSB */
447 0x1602, 0x14, /* Red A LSB */
448 0x1605, 0x3b, /* Blue A MSB */
449 0x1606, 0x85, /* BLue A LSB */
450 0x1609, 0x3b, /* RED B MSB */
451 0x160a, 0x85, /* RED B LSB */
452 0x160d, 0x3a, /* Blue B MSB */
453 0x160e, 0x14, /* Blue B LSB */
454 0x1611, 0x30, /* Max Distance from Locus MSB */
455 0x1612, 0x8f, /* Max Distance from Locus MSB */
456 0x1614, 0x01, /* Enable constrainer */
457 0x0000, 0x00,
458};
459
460static const u16 vs6624_default[] = {
461 VS6624_CONTRAST0, 0x84,
462 VS6624_SATURATION0, 0x75,
463 VS6624_GAMMA0, 0x11,
464 VS6624_CONTRAST1, 0x84,
465 VS6624_SATURATION1, 0x75,
466 VS6624_GAMMA1, 0x11,
467 VS6624_MAN_RG, 0x80,
468 VS6624_MAN_GG, 0x80,
469 VS6624_MAN_BG, 0x80,
470 VS6624_WB_MODE, 0x1,
471 VS6624_EXPO_COMPENSATION, 0xfe,
472 VS6624_EXPO_METER, 0x0,
473 VS6624_LIGHT_FREQ, 0x64,
474 VS6624_PEAK_GAIN, 0xe,
475 VS6624_PEAK_LOW_THR, 0x28,
476 VS6624_HMIRROR0, 0x0,
477 VS6624_VFLIP0, 0x0,
478 VS6624_ZOOM_HSTEP0_MSB, 0x0,
479 VS6624_ZOOM_HSTEP0_LSB, 0x1,
480 VS6624_ZOOM_VSTEP0_MSB, 0x0,
481 VS6624_ZOOM_VSTEP0_LSB, 0x1,
482 VS6624_PAN_HSTEP0_MSB, 0x0,
483 VS6624_PAN_HSTEP0_LSB, 0xf,
484 VS6624_PAN_VSTEP0_MSB, 0x0,
485 VS6624_PAN_VSTEP0_LSB, 0xf,
486 VS6624_SENSOR_MODE, 0x1,
487 VS6624_SYNC_CODE_SETUP, 0x21,
488 VS6624_DISABLE_FR_DAMPER, 0x0,
489 VS6624_FR_DEN, 0x1,
490 VS6624_FR_NUM_LSB, 0xf,
491 VS6624_INIT_PIPE_SETUP, 0x0,
492 VS6624_IMG_FMT0, 0x0,
493 VS6624_YUV_SETUP, 0x1,
494 VS6624_IMAGE_SIZE0, 0x2,
495 0x0000, 0x00,
496};
497
498static inline struct vs6624 *to_vs6624(struct v4l2_subdev *sd)
499{
500 return container_of(sd, struct vs6624, sd);
501}
502static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
503{
504 return &container_of(ctrl->handler, struct vs6624, hdl)->sd;
505}
506
507static int vs6624_read(struct v4l2_subdev *sd, u16 index)
508{
509 struct i2c_client *client = v4l2_get_subdevdata(sd);
510 u8 buf[2];
511
512 buf[0] = index >> 8;
513 buf[1] = index;
514 i2c_master_send(client, buf, 2);
515 i2c_master_recv(client, buf, 1);
516
517 return buf[0];
518}
519
520static int vs6624_write(struct v4l2_subdev *sd, u16 index,
521 u8 value)
522{
523 struct i2c_client *client = v4l2_get_subdevdata(sd);
524 u8 buf[3];
525
526 buf[0] = index >> 8;
527 buf[1] = index;
528 buf[2] = value;
529
530 return i2c_master_send(client, buf, 3);
531}
532
533static int vs6624_writeregs(struct v4l2_subdev *sd, const u16 *regs)
534{
535 u16 reg;
536 u8 data;
537
538 while (*regs != 0x00) {
539 reg = *regs++;
540 data = *regs++;
541
542 vs6624_write(sd, reg, data);
543 }
544 return 0;
545}
546
547static int vs6624_s_ctrl(struct v4l2_ctrl *ctrl)
548{
549 struct v4l2_subdev *sd = to_sd(ctrl);
550
551 switch (ctrl->id) {
552 case V4L2_CID_CONTRAST:
553 vs6624_write(sd, VS6624_CONTRAST0, ctrl->val);
554 break;
555 case V4L2_CID_SATURATION:
556 vs6624_write(sd, VS6624_SATURATION0, ctrl->val);
557 break;
558 case V4L2_CID_HFLIP:
559 vs6624_write(sd, VS6624_HMIRROR0, ctrl->val);
560 break;
561 case V4L2_CID_VFLIP:
562 vs6624_write(sd, VS6624_VFLIP0, ctrl->val);
563 break;
564 default:
565 return -EINVAL;
566 }
567
568 return 0;
569}
570
571static int vs6624_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
572 enum v4l2_mbus_pixelcode *code)
573{
574 if (index >= ARRAY_SIZE(vs6624_formats))
575 return -EINVAL;
576
577 *code = vs6624_formats[index].mbus_code;
578 return 0;
579}
580
581static int vs6624_try_mbus_fmt(struct v4l2_subdev *sd,
582 struct v4l2_mbus_framefmt *fmt)
583{
584 int index;
585
586 for (index = 0; index < ARRAY_SIZE(vs6624_formats); index++)
587 if (vs6624_formats[index].mbus_code == fmt->code)
588 break;
589 if (index >= ARRAY_SIZE(vs6624_formats)) {
590 /* default to first format */
591 index = 0;
592 fmt->code = vs6624_formats[0].mbus_code;
593 }
594
595 /* sensor mode is VGA */
596 if (fmt->width > VGA_WIDTH)
597 fmt->width = VGA_WIDTH;
598 if (fmt->height > VGA_HEIGHT)
599 fmt->height = VGA_HEIGHT;
600 fmt->width = fmt->width & (~3);
601 fmt->height = fmt->height & (~3);
602 fmt->field = V4L2_FIELD_NONE;
603 fmt->colorspace = vs6624_formats[index].colorspace;
604 return 0;
605}
606
607static int vs6624_s_mbus_fmt(struct v4l2_subdev *sd,
608 struct v4l2_mbus_framefmt *fmt)
609{
610 struct vs6624 *sensor = to_vs6624(sd);
611 int ret;
612
613 ret = vs6624_try_mbus_fmt(sd, fmt);
614 if (ret)
615 return ret;
616
617 /* set image format */
618 switch (fmt->code) {
619 case V4L2_MBUS_FMT_UYVY8_2X8:
620 vs6624_write(sd, VS6624_IMG_FMT0, 0x0);
621 vs6624_write(sd, VS6624_YUV_SETUP, 0x1);
622 break;
623 case V4L2_MBUS_FMT_YUYV8_2X8:
624 vs6624_write(sd, VS6624_IMG_FMT0, 0x0);
625 vs6624_write(sd, VS6624_YUV_SETUP, 0x3);
626 break;
627 case V4L2_MBUS_FMT_RGB565_2X8_LE:
628 vs6624_write(sd, VS6624_IMG_FMT0, 0x4);
629 vs6624_write(sd, VS6624_RGB_SETUP, 0x0);
630 break;
631 default:
632 return -EINVAL;
633 }
634
635 /* set image size */
636 if ((fmt->width == VGA_WIDTH) && (fmt->height == VGA_HEIGHT))
637 vs6624_write(sd, VS6624_IMAGE_SIZE0, 0x2);
638 else if ((fmt->width == QVGA_WIDTH) && (fmt->height == QVGA_HEIGHT))
639 vs6624_write(sd, VS6624_IMAGE_SIZE0, 0x4);
640 else if ((fmt->width == QQVGA_WIDTH) && (fmt->height == QQVGA_HEIGHT))
641 vs6624_write(sd, VS6624_IMAGE_SIZE0, 0x6);
642 else if ((fmt->width == CIF_WIDTH) && (fmt->height == CIF_HEIGHT))
643 vs6624_write(sd, VS6624_IMAGE_SIZE0, 0x3);
644 else if ((fmt->width == QCIF_WIDTH) && (fmt->height == QCIF_HEIGHT))
645 vs6624_write(sd, VS6624_IMAGE_SIZE0, 0x5);
646 else if ((fmt->width == QQCIF_WIDTH) && (fmt->height == QQCIF_HEIGHT))
647 vs6624_write(sd, VS6624_IMAGE_SIZE0, 0x7);
648 else {
649 vs6624_write(sd, VS6624_IMAGE_SIZE0, 0x8);
650 vs6624_write(sd, VS6624_MAN_HSIZE0_MSB, fmt->width >> 8);
651 vs6624_write(sd, VS6624_MAN_HSIZE0_LSB, fmt->width & 0xFF);
652 vs6624_write(sd, VS6624_MAN_VSIZE0_MSB, fmt->height >> 8);
653 vs6624_write(sd, VS6624_MAN_VSIZE0_LSB, fmt->height & 0xFF);
654 vs6624_write(sd, VS6624_CROP_CTRL0, 0x1);
655 }
656
657 sensor->fmt = *fmt;
658
659 return 0;
660}
661
662static int vs6624_g_mbus_fmt(struct v4l2_subdev *sd,
663 struct v4l2_mbus_framefmt *fmt)
664{
665 struct vs6624 *sensor = to_vs6624(sd);
666
667 *fmt = sensor->fmt;
668 return 0;
669}
670
671static int vs6624_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
672{
673 struct vs6624 *sensor = to_vs6624(sd);
674 struct v4l2_captureparm *cp = &parms->parm.capture;
675
676 if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
677 return -EINVAL;
678
679 memset(cp, 0, sizeof(*cp));
680 cp->capability = V4L2_CAP_TIMEPERFRAME;
681 cp->timeperframe.numerator = sensor->frame_rate.denominator;
682 cp->timeperframe.denominator = sensor->frame_rate.numerator;
683 return 0;
684}
685
686static int vs6624_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
687{
688 struct vs6624 *sensor = to_vs6624(sd);
689 struct v4l2_captureparm *cp = &parms->parm.capture;
690 struct v4l2_fract *tpf = &cp->timeperframe;
691
692 if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
693 return -EINVAL;
694 if (cp->extendedmode != 0)
695 return -EINVAL;
696
697 if (tpf->numerator == 0 || tpf->denominator == 0
698 || (tpf->denominator > tpf->numerator * MAX_FRAME_RATE)) {
699 /* reset to max frame rate */
700 tpf->numerator = 1;
701 tpf->denominator = MAX_FRAME_RATE;
702 }
703 sensor->frame_rate.numerator = tpf->denominator;
704 sensor->frame_rate.denominator = tpf->numerator;
705 vs6624_write(sd, VS6624_DISABLE_FR_DAMPER, 0x0);
706 vs6624_write(sd, VS6624_FR_NUM_MSB,
707 sensor->frame_rate.numerator >> 8);
708 vs6624_write(sd, VS6624_FR_NUM_LSB,
709 sensor->frame_rate.numerator & 0xFF);
710 vs6624_write(sd, VS6624_FR_DEN,
711 sensor->frame_rate.denominator & 0xFF);
712 return 0;
713}
714
715static int vs6624_s_stream(struct v4l2_subdev *sd, int enable)
716{
717 if (enable)
718 vs6624_write(sd, VS6624_USER_CMD, 0x2);
719 else
720 vs6624_write(sd, VS6624_USER_CMD, 0x4);
721 udelay(100);
722 return 0;
723}
724
725static int vs6624_g_chip_ident(struct v4l2_subdev *sd,
726 struct v4l2_dbg_chip_ident *chip)
727{
728 int rev;
729 struct i2c_client *client = v4l2_get_subdevdata(sd);
730
731 rev = (vs6624_read(sd, VS6624_FW_VSN_MAJOR) << 8)
732 | vs6624_read(sd, VS6624_FW_VSN_MINOR);
733
734 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_VS6624, rev);
735}
736
737#ifdef CONFIG_VIDEO_ADV_DEBUG
738static int vs6624_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
739{
740 struct i2c_client *client = v4l2_get_subdevdata(sd);
741
742 if (!v4l2_chip_match_i2c_client(client, &reg->match))
743 return -EINVAL;
744 if (!capable(CAP_SYS_ADMIN))
745 return -EPERM;
746 reg->val = vs6624_read(sd, reg->reg & 0xffff);
747 reg->size = 1;
748 return 0;
749}
750
751static int vs6624_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
752{
753 struct i2c_client *client = v4l2_get_subdevdata(sd);
754
755 if (!v4l2_chip_match_i2c_client(client, &reg->match))
756 return -EINVAL;
757 if (!capable(CAP_SYS_ADMIN))
758 return -EPERM;
759 vs6624_write(sd, reg->reg & 0xffff, reg->val & 0xff);
760 return 0;
761}
762#endif
763
764static const struct v4l2_ctrl_ops vs6624_ctrl_ops = {
765 .s_ctrl = vs6624_s_ctrl,
766};
767
768static const struct v4l2_subdev_core_ops vs6624_core_ops = {
769 .g_chip_ident = vs6624_g_chip_ident,
770#ifdef CONFIG_VIDEO_ADV_DEBUG
771 .g_register = vs6624_g_register,
772 .s_register = vs6624_s_register,
773#endif
774};
775
776static const struct v4l2_subdev_video_ops vs6624_video_ops = {
777 .enum_mbus_fmt = vs6624_enum_mbus_fmt,
778 .try_mbus_fmt = vs6624_try_mbus_fmt,
779 .s_mbus_fmt = vs6624_s_mbus_fmt,
780 .g_mbus_fmt = vs6624_g_mbus_fmt,
781 .s_parm = vs6624_s_parm,
782 .g_parm = vs6624_g_parm,
783 .s_stream = vs6624_s_stream,
784};
785
786static const struct v4l2_subdev_ops vs6624_ops = {
787 .core = &vs6624_core_ops,
788 .video = &vs6624_video_ops,
789};
790
791static int __devinit vs6624_probe(struct i2c_client *client,
792 const struct i2c_device_id *id)
793{
794 struct vs6624 *sensor;
795 struct v4l2_subdev *sd;
796 struct v4l2_ctrl_handler *hdl;
797 const unsigned *ce;
798 int ret;
799
800 /* Check if the adapter supports the needed features */
801 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
802 return -EIO;
803
804 ce = client->dev.platform_data;
805 if (ce == NULL)
806 return -EINVAL;
807
808 ret = gpio_request(*ce, "VS6624 Chip Enable");
809 if (ret) {
810 v4l_err(client, "failed to request GPIO %d\n", *ce);
811 return ret;
812 }
813 gpio_direction_output(*ce, 1);
814 /* wait 100ms before any further i2c writes are performed */
815 mdelay(100);
816
817 sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
818 if (sensor == NULL) {
819 gpio_free(*ce);
820 return -ENOMEM;
821 }
822
823 sd = &sensor->sd;
824 v4l2_i2c_subdev_init(sd, client, &vs6624_ops);
825
826 vs6624_writeregs(sd, vs6624_p1);
827 vs6624_write(sd, VS6624_MICRO_EN, 0x2);
828 vs6624_write(sd, VS6624_DIO_EN, 0x1);
829 mdelay(10);
830 vs6624_writeregs(sd, vs6624_p2);
831
832 vs6624_writeregs(sd, vs6624_default);
833 vs6624_write(sd, VS6624_HSYNC_SETUP, 0xF);
834 vs6624_writeregs(sd, vs6624_run_setup);
835
836 /* set frame rate */
837 sensor->frame_rate.numerator = MAX_FRAME_RATE;
838 sensor->frame_rate.denominator = 1;
839 vs6624_write(sd, VS6624_DISABLE_FR_DAMPER, 0x0);
840 vs6624_write(sd, VS6624_FR_NUM_MSB,
841 sensor->frame_rate.numerator >> 8);
842 vs6624_write(sd, VS6624_FR_NUM_LSB,
843 sensor->frame_rate.numerator & 0xFF);
844 vs6624_write(sd, VS6624_FR_DEN,
845 sensor->frame_rate.denominator & 0xFF);
846
847 sensor->fmt = vs6624_default_fmt;
848 sensor->ce_pin = *ce;
849
850 v4l_info(client, "chip found @ 0x%02x (%s)\n",
851 client->addr << 1, client->adapter->name);
852
853 hdl = &sensor->hdl;
854 v4l2_ctrl_handler_init(hdl, 4);
855 v4l2_ctrl_new_std(hdl, &vs6624_ctrl_ops,
856 V4L2_CID_CONTRAST, 0, 0xFF, 1, 0x87);
857 v4l2_ctrl_new_std(hdl, &vs6624_ctrl_ops,
858 V4L2_CID_SATURATION, 0, 0xFF, 1, 0x78);
859 v4l2_ctrl_new_std(hdl, &vs6624_ctrl_ops,
860 V4L2_CID_HFLIP, 0, 1, 1, 0);
861 v4l2_ctrl_new_std(hdl, &vs6624_ctrl_ops,
862 V4L2_CID_VFLIP, 0, 1, 1, 0);
863 /* hook the control handler into the driver */
864 sd->ctrl_handler = hdl;
865 if (hdl->error) {
866 int err = hdl->error;
867
868 v4l2_ctrl_handler_free(hdl);
869 kfree(sensor);
870 gpio_free(*ce);
871 return err;
872 }
873
874 /* initialize the hardware to the default control values */
875 ret = v4l2_ctrl_handler_setup(hdl);
876 if (ret) {
877 v4l2_ctrl_handler_free(hdl);
878 kfree(sensor);
879 gpio_free(*ce);
880 }
881 return ret;
882}
883
884static int __devexit vs6624_remove(struct i2c_client *client)
885{
886 struct v4l2_subdev *sd = i2c_get_clientdata(client);
887 struct vs6624 *sensor = to_vs6624(sd);
888
889 v4l2_device_unregister_subdev(sd);
890 v4l2_ctrl_handler_free(sd->ctrl_handler);
891 gpio_free(sensor->ce_pin);
892 kfree(sensor);
893 return 0;
894}
895
896static const struct i2c_device_id vs6624_id[] = {
897 {"vs6624", 0},
898 {},
899};
900
901MODULE_DEVICE_TABLE(i2c, vs6624_id);
902
903static struct i2c_driver vs6624_driver = {
904 .driver = {
905 .owner = THIS_MODULE,
906 .name = "vs6624",
907 },
908 .probe = vs6624_probe,
909 .remove = __devexit_p(vs6624_remove),
910 .id_table = vs6624_id,
911};
912
913static __init int vs6624_init(void)
914{
915 return i2c_add_driver(&vs6624_driver);
916}
917
918static __exit void vs6624_exit(void)
919{
920 i2c_del_driver(&vs6624_driver);
921}
922
923module_init(vs6624_init);
924module_exit(vs6624_exit);
925
926MODULE_DESCRIPTION("VS6624 sensor driver");
927MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>");
928MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/vs6624_regs.h b/drivers/media/video/vs6624_regs.h
new file mode 100644
index 000000000000..6ba2ee25827e
--- /dev/null
+++ b/drivers/media/video/vs6624_regs.h
@@ -0,0 +1,337 @@
1/*
2 * vs6624 - ST VS6624 CMOS image sensor registers
3 *
4 * Copyright (c) 2011 Analog Devices Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * 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#ifndef _VS6624_REGS_H_
21#define _VS6624_REGS_H_
22
23/* low level control registers */
24#define VS6624_MICRO_EN 0xC003 /* power enable for all MCU clock */
25#define VS6624_DIO_EN 0xC044 /* enable digital I/O */
26/* device parameters */
27#define VS6624_DEV_ID_MSB 0x0001 /* device id MSB */
28#define VS6624_DEV_ID_LSB 0x0002 /* device id LSB */
29#define VS6624_FW_VSN_MAJOR 0x0004 /* firmware version major */
30#define VS6624_FW_VSN_MINOR 0x0006 /* firmware version minor */
31#define VS6624_PATCH_VSN_MAJOR 0x0008 /* patch version major */
32#define VS6624_PATCH_VSN_MINOR 0x000A /* patch version minor */
33/* host interface manager control */
34#define VS6624_USER_CMD 0x0180 /* user level control of operating states */
35/* host interface manager status */
36#define VS6624_STATE 0x0202 /* current state of the mode manager */
37/* run mode control */
38#define VS6624_METER_ON 0x0280 /* if false AE and AWB are disabled */
39/* mode setup */
40#define VS6624_ACTIVE_PIPE_SETUP 0x0302 /* select the active bank for non view live mode */
41#define VS6624_SENSOR_MODE 0x0308 /* select the different sensor mode */
42/* pipe setup bank0 */
43#define VS6624_IMAGE_SIZE0 0x0380 /* required output dimension */
44#define VS6624_MAN_HSIZE0_MSB 0x0383 /* input required manual H size MSB */
45#define VS6624_MAN_HSIZE0_LSB 0x0384 /* input required manual H size LSB */
46#define VS6624_MAN_VSIZE0_MSB 0x0387 /* input required manual V size MSB */
47#define VS6624_MAN_VSIZE0_LSB 0x0388 /* input required manual V size LSB */
48#define VS6624_ZOOM_HSTEP0_MSB 0x038B /* set the zoom H step MSB */
49#define VS6624_ZOOM_HSTEP0_LSB 0x038C /* set the zoom H step LSB */
50#define VS6624_ZOOM_VSTEP0_MSB 0x038F /* set the zoom V step MSB */
51#define VS6624_ZOOM_VSTEP0_LSB 0x0390 /* set the zoom V step LSB */
52#define VS6624_ZOOM_CTRL0 0x0392 /* control zoon in, out and stop */
53#define VS6624_PAN_HSTEP0_MSB 0x0395 /* set the pan H step MSB */
54#define VS6624_PAN_HSTEP0_LSB 0x0396 /* set the pan H step LSB */
55#define VS6624_PAN_VSTEP0_MSB 0x0399 /* set the pan V step MSB */
56#define VS6624_PAN_VSTEP0_LSB 0x039A /* set the pan V step LSB */
57#define VS6624_PAN_CTRL0 0x039C /* control pan operation */
58#define VS6624_CROP_CTRL0 0x039E /* select cropping mode */
59#define VS6624_CROP_HSTART0_MSB 0x03A1 /* set the cropping H start address MSB */
60#define VS6624_CROP_HSTART0_LSB 0x03A2 /* set the cropping H start address LSB */
61#define VS6624_CROP_HSIZE0_MSB 0x03A5 /* set the cropping H size MSB */
62#define VS6624_CROP_HSIZE0_LSB 0x03A6 /* set the cropping H size LSB */
63#define VS6624_CROP_VSTART0_MSB 0x03A9 /* set the cropping V start address MSB */
64#define VS6624_CROP_VSTART0_LSB 0x03AA /* set the cropping V start address LSB */
65#define VS6624_CROP_VSIZE0_MSB 0x03AD /* set the cropping V size MSB */
66#define VS6624_CROP_VSIZE0_LSB 0x03AE /* set the cropping V size LSB */
67#define VS6624_IMG_FMT0 0x03B0 /* select required output image format */
68#define VS6624_BAYER_OUT_ALIGN0 0x03B2 /* set bayer output alignment */
69#define VS6624_CONTRAST0 0x03B4 /* contrast control for output */
70#define VS6624_SATURATION0 0x03B6 /* saturation control for output */
71#define VS6624_GAMMA0 0x03B8 /* gamma settings */
72#define VS6624_HMIRROR0 0x03BA /* horizontal image orientation flip */
73#define VS6624_VFLIP0 0x03BC /* vertical image orientation flip */
74#define VS6624_CHANNEL_ID0 0x03BE /* logical DMA channel number */
75/* pipe setup bank1 */
76#define VS6624_IMAGE_SIZE1 0x0400 /* required output dimension */
77#define VS6624_MAN_HSIZE1_MSB 0x0403 /* input required manual H size MSB */
78#define VS6624_MAN_HSIZE1_LSB 0x0404 /* input required manual H size LSB */
79#define VS6624_MAN_VSIZE1_MSB 0x0407 /* input required manual V size MSB */
80#define VS6624_MAN_VSIZE1_LSB 0x0408 /* input required manual V size LSB */
81#define VS6624_ZOOM_HSTEP1_MSB 0x040B /* set the zoom H step MSB */
82#define VS6624_ZOOM_HSTEP1_LSB 0x040C /* set the zoom H step LSB */
83#define VS6624_ZOOM_VSTEP1_MSB 0x040F /* set the zoom V step MSB */
84#define VS6624_ZOOM_VSTEP1_LSB 0x0410 /* set the zoom V step LSB */
85#define VS6624_ZOOM_CTRL1 0x0412 /* control zoon in, out and stop */
86#define VS6624_PAN_HSTEP1_MSB 0x0415 /* set the pan H step MSB */
87#define VS6624_PAN_HSTEP1_LSB 0x0416 /* set the pan H step LSB */
88#define VS6624_PAN_VSTEP1_MSB 0x0419 /* set the pan V step MSB */
89#define VS6624_PAN_VSTEP1_LSB 0x041A /* set the pan V step LSB */
90#define VS6624_PAN_CTRL1 0x041C /* control pan operation */
91#define VS6624_CROP_CTRL1 0x041E /* select cropping mode */
92#define VS6624_CROP_HSTART1_MSB 0x0421 /* set the cropping H start address MSB */
93#define VS6624_CROP_HSTART1_LSB 0x0422 /* set the cropping H start address LSB */
94#define VS6624_CROP_HSIZE1_MSB 0x0425 /* set the cropping H size MSB */
95#define VS6624_CROP_HSIZE1_LSB 0x0426 /* set the cropping H size LSB */
96#define VS6624_CROP_VSTART1_MSB 0x0429 /* set the cropping V start address MSB */
97#define VS6624_CROP_VSTART1_LSB 0x042A /* set the cropping V start address LSB */
98#define VS6624_CROP_VSIZE1_MSB 0x042D /* set the cropping V size MSB */
99#define VS6624_CROP_VSIZE1_LSB 0x042E /* set the cropping V size LSB */
100#define VS6624_IMG_FMT1 0x0430 /* select required output image format */
101#define VS6624_BAYER_OUT_ALIGN1 0x0432 /* set bayer output alignment */
102#define VS6624_CONTRAST1 0x0434 /* contrast control for output */
103#define VS6624_SATURATION1 0x0436 /* saturation control for output */
104#define VS6624_GAMMA1 0x0438 /* gamma settings */
105#define VS6624_HMIRROR1 0x043A /* horizontal image orientation flip */
106#define VS6624_VFLIP1 0x043C /* vertical image orientation flip */
107#define VS6624_CHANNEL_ID1 0x043E /* logical DMA channel number */
108/* view live control */
109#define VS6624_VIEW_LIVE_EN 0x0480 /* enable view live mode */
110#define VS6624_INIT_PIPE_SETUP 0x0482 /* select initial pipe setup bank */
111/* view live status */
112#define VS6624_CUR_PIPE_SETUP 0x0500 /* indicates most recently applied setup bank */
113/* power management */
114#define VS6624_TIME_TO_POWER_DOWN 0x0580 /* automatically transition time to stop mode */
115/* video timing parameter host inputs */
116#define VS6624_EXT_CLK_FREQ_NUM_MSB 0x0605 /* external clock frequency numerator MSB */
117#define VS6624_EXT_CLK_FREQ_NUM_LSB 0x0606 /* external clock frequency numerator LSB */
118#define VS6624_EXT_CLK_FREQ_DEN 0x0608 /* external clock frequency denominator */
119/* video timing control */
120#define VS6624_SYS_CLK_MODE 0x0880 /* decides system clock frequency */
121/* frame dimension parameter host inputs */
122#define VS6624_LIGHT_FREQ 0x0C80 /* AC frequency used for flicker free time */
123#define VS6624_FLICKER_COMPAT 0x0C82 /* flicker compatible frame length */
124/* static frame rate control */
125#define VS6624_FR_NUM_MSB 0x0D81 /* desired frame rate numerator MSB */
126#define VS6624_FR_NUM_LSB 0x0D82 /* desired frame rate numerator LSB */
127#define VS6624_FR_DEN 0x0D84 /* desired frame rate denominator */
128/* automatic frame rate control */
129#define VS6624_DISABLE_FR_DAMPER 0x0E80 /* defines frame rate mode */
130#define VS6624_MIN_DAMPER_OUT_MSB 0x0E8C /* minimum frame rate MSB */
131#define VS6624_MIN_DAMPER_OUT_LSB 0x0E8A /* minimum frame rate LSB */
132/* exposure controls */
133#define VS6624_EXPO_MODE 0x1180 /* exposure mode */
134#define VS6624_EXPO_METER 0x1182 /* weights to be associated with the zones */
135#define VS6624_EXPO_TIME_NUM 0x1184 /* exposure time numerator */
136#define VS6624_EXPO_TIME_DEN 0x1186 /* exposure time denominator */
137#define VS6624_EXPO_TIME_MSB 0x1189 /* exposure time for the Manual Mode MSB */
138#define VS6624_EXPO_TIME_LSB 0x118A /* exposure time for the Manual Mode LSB */
139#define VS6624_EXPO_COMPENSATION 0x1190 /* exposure compensation */
140#define VS6624_DIRECT_COARSE_MSB 0x1195 /* coarse integration lines for Direct Mode MSB */
141#define VS6624_DIRECT_COARSE_LSB 0x1196 /* coarse integration lines for Direct Mode LSB */
142#define VS6624_DIRECT_FINE_MSB 0x1199 /* fine integration pixels for Direct Mode MSB */
143#define VS6624_DIRECT_FINE_LSB 0x119A /* fine integration pixels for Direct Mode LSB */
144#define VS6624_DIRECT_ANAL_GAIN_MSB 0x119D /* analog gain for Direct Mode MSB */
145#define VS6624_DIRECT_ANAL_GAIN_LSB 0x119E /* analog gain for Direct Mode LSB */
146#define VS6624_DIRECT_DIGI_GAIN_MSB 0x11A1 /* digital gain for Direct Mode MSB */
147#define VS6624_DIRECT_DIGI_GAIN_LSB 0x11A2 /* digital gain for Direct Mode LSB */
148#define VS6624_FLASH_COARSE_MSB 0x11A5 /* coarse integration lines for Flash Gun Mode MSB */
149#define VS6624_FLASH_COARSE_LSB 0x11A6 /* coarse integration lines for Flash Gun Mode LSB */
150#define VS6624_FLASH_FINE_MSB 0x11A9 /* fine integration pixels for Flash Gun Mode MSB */
151#define VS6624_FLASH_FINE_LSB 0x11AA /* fine integration pixels for Flash Gun Mode LSB */
152#define VS6624_FLASH_ANAL_GAIN_MSB 0x11AD /* analog gain for Flash Gun Mode MSB */
153#define VS6624_FLASH_ANAL_GAIN_LSB 0x11AE /* analog gain for Flash Gun Mode LSB */
154#define VS6624_FLASH_DIGI_GAIN_MSB 0x11B1 /* digital gain for Flash Gun Mode MSB */
155#define VS6624_FLASH_DIGI_GAIN_LSB 0x11B2 /* digital gain for Flash Gun Mode LSB */
156#define VS6624_FREEZE_AE 0x11B4 /* freeze auto exposure */
157#define VS6624_MAX_INT_TIME_MSB 0x11B7 /* user maximum integration time MSB */
158#define VS6624_MAX_INT_TIME_LSB 0x11B8 /* user maximum integration time LSB */
159#define VS6624_FLASH_AG_THR_MSB 0x11BB /* recommend flash gun analog gain threshold MSB */
160#define VS6624_FLASH_AG_THR_LSB 0x11BC /* recommend flash gun analog gain threshold LSB */
161#define VS6624_ANTI_FLICKER_MODE 0x11C0 /* anti flicker mode */
162/* white balance control */
163#define VS6624_WB_MODE 0x1480 /* set white balance mode */
164#define VS6624_MAN_RG 0x1482 /* user setting for red channel gain */
165#define VS6624_MAN_GG 0x1484 /* user setting for green channel gain */
166#define VS6624_MAN_BG 0x1486 /* user setting for blue channel gain */
167#define VS6624_FLASH_RG_MSB 0x148B /* red gain for Flash Gun MSB */
168#define VS6624_FLASH_RG_LSB 0x148C /* red gain for Flash Gun LSB */
169#define VS6624_FLASH_GG_MSB 0x148F /* green gain for Flash Gun MSB */
170#define VS6624_FLASH_GG_LSB 0x1490 /* green gain for Flash Gun LSB */
171#define VS6624_FLASH_BG_MSB 0x1493 /* blue gain for Flash Gun MSB */
172#define VS6624_FLASH_BG_LSB 0x1494 /* blue gain for Flash Gun LSB */
173/* sensor setup */
174#define VS6624_BC_OFFSET 0x1990 /* Black Correction Offset */
175/* image stability */
176#define VS6624_STABLE_WB 0x1900 /* white balance stable */
177#define VS6624_STABLE_EXPO 0x1902 /* exposure stable */
178#define VS6624_STABLE 0x1906 /* system stable */
179/* flash control */
180#define VS6624_FLASH_MODE 0x1A80 /* flash mode */
181#define VS6624_FLASH_OFF_LINE_MSB 0x1A83 /* off line at flash pulse mode MSB */
182#define VS6624_FLASH_OFF_LINE_LSB 0x1A84 /* off line at flash pulse mode LSB */
183/* flash status */
184#define VS6624_FLASH_RECOM 0x1B00 /* flash gun is recommended */
185#define VS6624_FLASH_GRAB_COMPLETE 0x1B02 /* flash gun image has been grabbed */
186/* scythe filter controls */
187#define VS6624_SCYTHE_FILTER 0x1D80 /* disable scythe defect correction */
188/* jack filter controls */
189#define VS6624_JACK_FILTER 0x1E00 /* disable jack defect correction */
190/* demosaic control */
191#define VS6624_ANTI_ALIAS_FILTER 0x1E80 /* anti alias filter suppress */
192/* color matrix dampers */
193#define VS6624_CM_DISABLE 0x1F00 /* disable color matrix damper */
194#define VS6624_CM_LOW_THR_MSB 0x1F03 /* low threshold for exposure MSB */
195#define VS6624_CM_LOW_THR_LSB 0x1F04 /* low threshold for exposure LSB */
196#define VS6624_CM_HIGH_THR_MSB 0x1F07 /* high threshold for exposure MSB */
197#define VS6624_CM_HIGH_THR_LSB 0x1F08 /* high threshold for exposure LSB */
198#define VS6624_CM_MIN_OUT_MSB 0x1F0B /* minimum possible damper output MSB */
199#define VS6624_CM_MIN_OUT_LSB 0x1F0C /* minimum possible damper output LSB */
200/* peaking control */
201#define VS6624_PEAK_GAIN 0x2000 /* controls peaking gain */
202#define VS6624_PEAK_G_DISABLE 0x2002 /* disable peak gain damping */
203#define VS6624_PEAK_LOW_THR_G_MSB 0x2005 /* low threshold for exposure for gain MSB */
204#define VS6624_PEAK_LOW_THR_G_LSB 0x2006 /* low threshold for exposure for gain LSB */
205#define VS6624_PEAK_HIGH_THR_G_MSB 0x2009 /* high threshold for exposure for gain MSB */
206#define VS6624_PEAK_HIGH_THR_G_LSB 0x200A /* high threshold for exposure for gain LSB */
207#define VS6624_PEAK_MIN_OUT_G_MSB 0x200D /* minimum damper output for gain MSB */
208#define VS6624_PEAK_MIN_OUT_G_LSB 0x200E /* minimum damper output for gain LSB */
209#define VS6624_PEAK_LOW_THR 0x2010 /* adjust degree of coring */
210#define VS6624_PEAK_C_DISABLE 0x2012 /* disable coring damping */
211#define VS6624_PEAK_HIGH_THR 0x2014 /* adjust maximum gain */
212#define VS6624_PEAK_LOW_THR_C_MSB 0x2017 /* low threshold for exposure for coring MSB */
213#define VS6624_PEAK_LOW_THR_C_LSB 0x2018 /* low threshold for exposure for coring LSB */
214#define VS6624_PEAK_HIGH_THR_C_MSB 0x201B /* high threshold for exposure for coring MSB */
215#define VS6624_PEAK_HIGH_THR_C_LSB 0x201C /* high threshold for exposure for coring LSB */
216#define VS6624_PEAK_MIN_OUT_C_MSB 0x201F /* minimum damper output for coring MSB */
217#define VS6624_PEAK_MIN_OUT_C_LSB 0x2020 /* minimum damper output for coring LSB */
218/* pipe 0 RGB to YUV matrix manual control */
219#define VS6624_RYM0_MAN_CTRL 0x2180 /* enable manual RGB to YUV matrix */
220#define VS6624_RYM0_W00_MSB 0x2183 /* row 0 column 0 of YUV matrix MSB */
221#define VS6624_RYM0_W00_LSB 0x2184 /* row 0 column 0 of YUV matrix LSB */
222#define VS6624_RYM0_W01_MSB 0x2187 /* row 0 column 1 of YUV matrix MSB */
223#define VS6624_RYM0_W01_LSB 0x2188 /* row 0 column 1 of YUV matrix LSB */
224#define VS6624_RYM0_W02_MSB 0x218C /* row 0 column 2 of YUV matrix MSB */
225#define VS6624_RYM0_W02_LSB 0x218D /* row 0 column 2 of YUV matrix LSB */
226#define VS6624_RYM0_W10_MSB 0x2190 /* row 1 column 0 of YUV matrix MSB */
227#define VS6624_RYM0_W10_LSB 0x218F /* row 1 column 0 of YUV matrix LSB */
228#define VS6624_RYM0_W11_MSB 0x2193 /* row 1 column 1 of YUV matrix MSB */
229#define VS6624_RYM0_W11_LSB 0x2194 /* row 1 column 1 of YUV matrix LSB */
230#define VS6624_RYM0_W12_MSB 0x2197 /* row 1 column 2 of YUV matrix MSB */
231#define VS6624_RYM0_W12_LSB 0x2198 /* row 1 column 2 of YUV matrix LSB */
232#define VS6624_RYM0_W20_MSB 0x219B /* row 2 column 0 of YUV matrix MSB */
233#define VS6624_RYM0_W20_LSB 0x219C /* row 2 column 0 of YUV matrix LSB */
234#define VS6624_RYM0_W21_MSB 0x21A0 /* row 2 column 1 of YUV matrix MSB */
235#define VS6624_RYM0_W21_LSB 0x219F /* row 2 column 1 of YUV matrix LSB */
236#define VS6624_RYM0_W22_MSB 0x21A3 /* row 2 column 2 of YUV matrix MSB */
237#define VS6624_RYM0_W22_LSB 0x21A4 /* row 2 column 2 of YUV matrix LSB */
238#define VS6624_RYM0_YINY_MSB 0x21A7 /* Y in Y MSB */
239#define VS6624_RYM0_YINY_LSB 0x21A8 /* Y in Y LSB */
240#define VS6624_RYM0_YINCB_MSB 0x21AB /* Y in Cb MSB */
241#define VS6624_RYM0_YINCB_LSB 0x21AC /* Y in Cb LSB */
242#define VS6624_RYM0_YINCR_MSB 0x21B0 /* Y in Cr MSB */
243#define VS6624_RYM0_YINCR_LSB 0x21AF /* Y in Cr LSB */
244/* pipe 1 RGB to YUV matrix manual control */
245#define VS6624_RYM1_MAN_CTRL 0x2200 /* enable manual RGB to YUV matrix */
246#define VS6624_RYM1_W00_MSB 0x2203 /* row 0 column 0 of YUV matrix MSB */
247#define VS6624_RYM1_W00_LSB 0x2204 /* row 0 column 0 of YUV matrix LSB */
248#define VS6624_RYM1_W01_MSB 0x2207 /* row 0 column 1 of YUV matrix MSB */
249#define VS6624_RYM1_W01_LSB 0x2208 /* row 0 column 1 of YUV matrix LSB */
250#define VS6624_RYM1_W02_MSB 0x220C /* row 0 column 2 of YUV matrix MSB */
251#define VS6624_RYM1_W02_LSB 0x220D /* row 0 column 2 of YUV matrix LSB */
252#define VS6624_RYM1_W10_MSB 0x2210 /* row 1 column 0 of YUV matrix MSB */
253#define VS6624_RYM1_W10_LSB 0x220F /* row 1 column 0 of YUV matrix LSB */
254#define VS6624_RYM1_W11_MSB 0x2213 /* row 1 column 1 of YUV matrix MSB */
255#define VS6624_RYM1_W11_LSB 0x2214 /* row 1 column 1 of YUV matrix LSB */
256#define VS6624_RYM1_W12_MSB 0x2217 /* row 1 column 2 of YUV matrix MSB */
257#define VS6624_RYM1_W12_LSB 0x2218 /* row 1 column 2 of YUV matrix LSB */
258#define VS6624_RYM1_W20_MSB 0x221B /* row 2 column 0 of YUV matrix MSB */
259#define VS6624_RYM1_W20_LSB 0x221C /* row 2 column 0 of YUV matrix LSB */
260#define VS6624_RYM1_W21_MSB 0x2220 /* row 2 column 1 of YUV matrix MSB */
261#define VS6624_RYM1_W21_LSB 0x221F /* row 2 column 1 of YUV matrix LSB */
262#define VS6624_RYM1_W22_MSB 0x2223 /* row 2 column 2 of YUV matrix MSB */
263#define VS6624_RYM1_W22_LSB 0x2224 /* row 2 column 2 of YUV matrix LSB */
264#define VS6624_RYM1_YINY_MSB 0x2227 /* Y in Y MSB */
265#define VS6624_RYM1_YINY_LSB 0x2228 /* Y in Y LSB */
266#define VS6624_RYM1_YINCB_MSB 0x222B /* Y in Cb MSB */
267#define VS6624_RYM1_YINCB_LSB 0x222C /* Y in Cb LSB */
268#define VS6624_RYM1_YINCR_MSB 0x2220 /* Y in Cr MSB */
269#define VS6624_RYM1_YINCR_LSB 0x222F /* Y in Cr LSB */
270/* pipe 0 gamma manual control */
271#define VS6624_GAMMA_MAN_CTRL0 0x2280 /* enable manual gamma setup */
272#define VS6624_GAMMA_PEAK_R0 0x2282 /* peaked red channel gamma value */
273#define VS6624_GAMMA_PEAK_G0 0x2284 /* peaked green channel gamma value */
274#define VS6624_GAMMA_PEAK_B0 0x2286 /* peaked blue channel gamma value */
275#define VS6624_GAMMA_UNPEAK_R0 0x2288 /* unpeaked red channel gamma value */
276#define VS6624_GAMMA_UNPEAK_G0 0x228A /* unpeaked green channel gamma value */
277#define VS6624_GAMMA_UNPEAK_B0 0x228C /* unpeaked blue channel gamma value */
278/* pipe 1 gamma manual control */
279#define VS6624_GAMMA_MAN_CTRL1 0x2300 /* enable manual gamma setup */
280#define VS6624_GAMMA_PEAK_R1 0x2302 /* peaked red channel gamma value */
281#define VS6624_GAMMA_PEAK_G1 0x2304 /* peaked green channel gamma value */
282#define VS6624_GAMMA_PEAK_B1 0x2306 /* peaked blue channel gamma value */
283#define VS6624_GAMMA_UNPEAK_R1 0x2308 /* unpeaked red channel gamma value */
284#define VS6624_GAMMA_UNPEAK_G1 0x230A /* unpeaked green channel gamma value */
285#define VS6624_GAMMA_UNPEAK_B1 0x230C /* unpeaked blue channel gamma value */
286/* fade to black */
287#define VS6624_F2B_DISABLE 0x2480 /* disable fade to black */
288#define VS6624_F2B_BLACK_VAL_MSB 0x2483 /* black value MSB */
289#define VS6624_F2B_BLACK_VAL_LSB 0x2484 /* black value LSB */
290#define VS6624_F2B_LOW_THR_MSB 0x2487 /* low threshold for exposure MSB */
291#define VS6624_F2B_LOW_THR_LSB 0x2488 /* low threshold for exposure LSB */
292#define VS6624_F2B_HIGH_THR_MSB 0x248B /* high threshold for exposure MSB */
293#define VS6624_F2B_HIGH_THR_LSB 0x248C /* high threshold for exposure LSB */
294#define VS6624_F2B_MIN_OUT_MSB 0x248F /* minimum damper output MSB */
295#define VS6624_F2B_MIN_OUT_LSB 0x2490 /* minimum damper output LSB */
296/* output formatter control */
297#define VS6624_CODE_CK_EN 0x2580 /* code check enable */
298#define VS6624_BLANK_FMT 0x2582 /* blank format */
299#define VS6624_SYNC_CODE_SETUP 0x2584 /* sync code setup */
300#define VS6624_HSYNC_SETUP 0x2586 /* H sync setup */
301#define VS6624_VSYNC_SETUP 0x2588 /* V sync setup */
302#define VS6624_PCLK_SETUP 0x258A /* PCLK setup */
303#define VS6624_PCLK_EN 0x258C /* PCLK enable */
304#define VS6624_OPF_SP_SETUP 0x258E /* output formatter sp setup */
305#define VS6624_BLANK_DATA_MSB 0x2590 /* blank data MSB */
306#define VS6624_BLANK_DATA_LSB 0x2592 /* blank data LSB */
307#define VS6624_RGB_SETUP 0x2594 /* RGB setup */
308#define VS6624_YUV_SETUP 0x2596 /* YUV setup */
309#define VS6624_VSYNC_RIS_COARSE_H 0x2598 /* V sync rising coarse high */
310#define VS6624_VSYNC_RIS_COARSE_L 0x259A /* V sync rising coarse low */
311#define VS6624_VSYNC_RIS_FINE_H 0x259C /* V sync rising fine high */
312#define VS6624_VSYNC_RIS_FINE_L 0x259E /* V sync rising fine low */
313#define VS6624_VSYNC_FALL_COARSE_H 0x25A0 /* V sync falling coarse high */
314#define VS6624_VSYNC_FALL_COARSE_L 0x25A2 /* V sync falling coarse low */
315#define VS6624_VSYNC_FALL_FINE_H 0x25A4 /* V sync falling fine high */
316#define VS6624_VSYNC_FALL_FINE_L 0x25A6 /* V sync falling fine low */
317#define VS6624_HSYNC_RIS_H 0x25A8 /* H sync rising high */
318#define VS6624_HSYNC_RIS_L 0x25AA /* H sync rising low */
319#define VS6624_HSYNC_FALL_H 0x25AC /* H sync falling high */
320#define VS6624_HSYNC_FALL_L 0x25AE /* H sync falling low */
321#define VS6624_OUT_IF 0x25B0 /* output interface */
322#define VS6624_CCP_EXT_DATA 0x25B2 /* CCP extra data */
323/* NoRA controls */
324#define VS6624_NORA_DISABLE 0x2600 /* NoRA control mode */
325#define VS6624_NORA_USAGE 0x2602 /* usage */
326#define VS6624_NORA_SPLIT_KN 0x2604 /* split kn */
327#define VS6624_NORA_SPLIT_NI 0x2606 /* split ni */
328#define VS6624_NORA_TIGHT_G 0x2608 /* tight green */
329#define VS6624_NORA_DISABLE_NP 0x260A /* disable noro promoting */
330#define VS6624_NORA_LOW_THR_MSB 0x260D /* low threshold for exposure MSB */
331#define VS6624_NORA_LOW_THR_LSB 0x260E /* low threshold for exposure LSB */
332#define VS6624_NORA_HIGH_THR_MSB 0x2611 /* high threshold for exposure MSB */
333#define VS6624_NORA_HIGH_THR_LSB 0x2612 /* high threshold for exposure LSB */
334#define VS6624_NORA_MIN_OUT_MSB 0x2615 /* minimum damper output MSB */
335#define VS6624_NORA_MIN_OUT_LSB 0x2616 /* minimum damper output LSB */
336
337#endif
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index 453dbbd1e6e8..7fd7ac567e1a 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -129,9 +129,9 @@ MODULE_LICENSE("GPL");
129MODULE_VERSION("0.33.1"); 129MODULE_VERSION("0.33.1");
130 130
131#ifdef MODULE 131#ifdef MODULE
132static const char *pardev[] = {[0 ... W9966_MAXCAMS] = ""}; 132static char *pardev[] = {[0 ... W9966_MAXCAMS] = ""};
133#else 133#else
134static const char *pardev[] = {[0 ... W9966_MAXCAMS] = "aggressive"}; 134static char *pardev[] = {[0 ... W9966_MAXCAMS] = "aggressive"};
135#endif 135#endif
136module_param_array(pardev, charp, NULL, 0); 136module_param_array(pardev, charp, NULL, 0);
137MODULE_PARM_DESC(pardev, "pardev: where to search for\n" 137MODULE_PARM_DESC(pardev, "pardev: where to search for\n"
diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c
index a22f765e968a..3bb99e93febe 100644
--- a/drivers/media/video/wm8739.c
+++ b/drivers/media/video/wm8739.c
@@ -291,15 +291,4 @@ static struct i2c_driver wm8739_driver = {
291 .id_table = wm8739_id, 291 .id_table = wm8739_id,
292}; 292};
293 293
294static __init int init_wm8739(void) 294module_i2c_driver(wm8739_driver);
295{
296 return i2c_add_driver(&wm8739_driver);
297}
298
299static __exit void exit_wm8739(void)
300{
301 i2c_del_driver(&wm8739_driver);
302}
303
304module_init(init_wm8739);
305module_exit(exit_wm8739);
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index 9cedb1e69b58..bee77ea9f49e 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -339,15 +339,4 @@ static struct i2c_driver wm8775_driver = {
339 .id_table = wm8775_id, 339 .id_table = wm8775_id,
340}; 340};
341 341
342static __init int init_wm8775(void) 342module_i2c_driver(wm8775_driver);
343{
344 return i2c_add_driver(&wm8775_driver);
345}
346
347static __exit void exit_wm8775(void)
348{
349 i2c_del_driver(&wm8775_driver);
350}
351
352module_init(init_wm8775);
353module_exit(exit_wm8775);