aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-15 12:22:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-15 12:22:18 -0400
commit043fe50f8085c12651c96f04576eae4d8a22f3d8 (patch)
tree214b4f985ce7d3b1a4961620e2c2f4f5f06e1c35 /drivers
parent227423904c709a8e60245c97081bbeb4fb500655 (diff)
parentea47689e74a1637fac4f5fc44890f3662c976849 (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (213 commits) V4L/DVB (12720): em28xx-cards: Add vendor/product id for Kworld DVD Maker 2 V4L/DVB (12713): em28xx: Cleanups at ir_i2c handler V4L/DVB (12712): em28xx: properly load ir-kbd-i2c when needed V4L/DVB (12701): saa7134: ir-kbd-i2c init data needs a persistent object V4L/DVB (12699): cx18: ir-kbd-i2c initialization data should point to a persistent object V4L/DVB (12698): em28xx: ir-kbd-i2c init data needs a persistent object V4L/DVB (12707): gspca - sn9c20x: Add SXGA support to MT9M111 V4L/DVB (12706): gspca - sn9c20x: disable exposure/gain controls for MT9M111 sensors. V4L/DVB (12705): gspca - sn9c20x: Add SXGA support to SOI968 V4L/DVB (12703): gspca - sn9c20x: Reduces size of object V4L/DVB (12704): gspca - sn9c20x: Fix exposure on SOI968 sensors V4L/DVB (12696): gspca - sonixj / sn9c102: Two drivers for 0c45:60fc and 0c45:613e. V4L/DVB (12695): gspca - vc032x: Do the LED work with the sensor hv7131r. V4L/DVB (12694): gspca - vc032x: Change the start exchanges of the sensor hv7131r. V4L/DVB (12693): gspca - sunplus: The brightness is signed. V4L/DVB (12692): gspca - sunplus: Optimize code. V4L/DVB (12691): gspca - sonixj: Don't use mdelay(). V4L/DVB (12690): gspca - pac7311: Webcam 06f8:3009 added. V4L/DVB (12686): dvb-core: check supported QAM modulations V4L/DVB (12685): dvb-core: check fe->ops.set_frontend return value ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/common/ir-functions.c15
-rw-r--r--drivers/media/common/ir-keymaps.c5022
-rw-r--r--drivers/media/common/tuners/tda18271-fe.c20
-rw-r--r--drivers/media/common/tuners/tda18271-priv.h20
-rw-r--r--drivers/media/common/tuners/tda18271.h3
-rw-r--r--drivers/media/common/tuners/tuner-simple.c6
-rw-r--r--drivers/media/common/tuners/tuner-types.c25
-rw-r--r--drivers/media/dvb/Kconfig13
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c218
-rw-r--r--drivers/media/dvb/bt8xx/dst.c2
-rw-r--r--drivers/media/dvb/dm1105/dm1105.c150
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c231
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.h9
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c8
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c35
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.h5
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig6
-rw-r--r--drivers/media/dvb/dvb-usb/a800.c70
-rw-r--r--drivers/media/dvb/dvb-usb/af9005-remote.c76
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c20
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.h460
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.c92
-rw-r--r--drivers/media/dvb/dvb-usb/cinergyT2-core.c74
-rw-r--r--drivers/media/dvb/dvb-usb/cinergyT2-fe.c1
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c260
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c387
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-common.c244
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mc.c10
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.c114
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.c36
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-i2c.c2
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h6
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-remote.c73
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h17
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c403
-rw-r--r--drivers/media/dvb/dvb-usb/m920x.c68
-rw-r--r--drivers/media/dvb/dvb-usb/nova-t-usb2.c97
-rw-r--r--drivers/media/dvb/dvb-usb/opera1.c55
-rw-r--r--drivers/media/dvb/dvb-usb/vp702x.c6
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045.c102
-rw-r--r--drivers/media/dvb/firewire/firedtv-avc.c143
-rw-r--r--drivers/media/dvb/frontends/Kconfig7
-rw-r--r--drivers/media/dvb/frontends/Makefile1
-rw-r--r--drivers/media/dvb/frontends/cx22700.c2
-rw-r--r--drivers/media/dvb/frontends/cx24113.c6
-rw-r--r--drivers/media/dvb/frontends/cx24123.c2
-rw-r--r--drivers/media/dvb/frontends/dib0070.c2
-rw-r--r--drivers/media/dvb/frontends/dib7000p.c2
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c75
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h4
-rw-r--r--drivers/media/dvb/frontends/lgs8gxx.c484
-rw-r--r--drivers/media/dvb/frontends/lgs8gxx.h11
-rw-r--r--drivers/media/dvb/frontends/lgs8gxx_priv.h12
-rw-r--r--drivers/media/dvb/frontends/mt312.c7
-rw-r--r--drivers/media/dvb/frontends/stb6100.c4
-rw-r--r--drivers/media/dvb/frontends/stv0900_core.c8
-rw-r--r--drivers/media/dvb/frontends/stv0900_sw.c2
-rw-r--r--drivers/media/dvb/frontends/stv6110.c48
-rw-r--r--drivers/media/dvb/frontends/stv6110.h2
-rw-r--r--drivers/media/dvb/frontends/tda10021.c2
-rw-r--r--drivers/media/dvb/frontends/tda8261.c4
-rw-r--r--drivers/media/dvb/frontends/ves1820.c2
-rw-r--r--drivers/media/dvb/frontends/zl10036.c2
-rw-r--r--drivers/media/dvb/frontends/zl10039.c308
-rw-r--r--drivers/media/dvb/frontends/zl10039.h40
-rw-r--r--drivers/media/dvb/frontends/zl10353.c14
-rw-r--r--drivers/media/dvb/pluto2/pluto2.c2
-rw-r--r--drivers/media/dvb/ttpci/av7110_v4l.c2
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c6
-rw-r--r--drivers/media/radio/Kconfig59
-rw-r--r--drivers/media/radio/Makefile4
-rw-r--r--drivers/media/radio/radio-cadet.c6
-rw-r--r--drivers/media/radio/radio-si470x.c1863
-rw-r--r--drivers/media/radio/radio-si4713.c367
-rw-r--r--drivers/media/radio/si470x/Kconfig37
-rw-r--r--drivers/media/radio/si470x/Makefile9
-rw-r--r--drivers/media/radio/si470x/radio-si470x-common.c798
-rw-r--r--drivers/media/radio/si470x/radio-si470x-i2c.c401
-rw-r--r--drivers/media/radio/si470x/radio-si470x-usb.c988
-rw-r--r--drivers/media/radio/si470x/radio-si470x.h225
-rw-r--r--drivers/media/radio/si4713-i2c.c2060
-rw-r--r--drivers/media/radio/si4713-i2c.h237
-rw-r--r--drivers/media/video/Kconfig6
-rw-r--r--drivers/media/video/au0828/au0828-dvb.c2
-rw-r--r--drivers/media/video/au0828/au0828-i2c.c1
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c1
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c14
-rw-r--r--drivers/media/video/bt8xx/bttv-i2c.c2
-rw-r--r--drivers/media/video/bt8xx/bttv-input.c27
-rw-r--r--drivers/media/video/cafe_ccic.c1
-rw-r--r--drivers/media/video/cx18/cx18-cards.c8
-rw-r--r--drivers/media/video/cx18/cx18-cards.h18
-rw-r--r--drivers/media/video/cx18/cx18-driver.c41
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c2
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c59
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c2
-rw-r--r--drivers/media/video/cx231xx/cx231xx-conf-reg.h8
-rw-r--r--drivers/media/video/cx231xx/cx231xx-i2c.c1
-rw-r--r--drivers/media/video/cx231xx/cx231xx-video.c4
-rw-r--r--drivers/media/video/cx231xx/cx231xx.h2
-rw-r--r--drivers/media/video/cx23885/cimax2.c1
-rw-r--r--drivers/media/video/cx23885/cx23885-417.c57
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c77
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c30
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c54
-rw-r--r--drivers/media/video/cx23885/cx23885-i2c.c1
-rw-r--r--drivers/media/video/cx23885/cx23885.h14
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c15
-rw-r--r--drivers/media/video/cx25840/cx25840-firmware.c48
-rw-r--r--drivers/media/video/cx88/cx88-cards.c56
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c16
-rw-r--r--drivers/media/video/cx88/cx88-input.c78
-rw-r--r--drivers/media/video/cx88/cx88.h1
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c115
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c1
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c161
-rw-r--r--drivers/media/video/em28xx/em28xx.h8
-rw-r--r--drivers/media/video/gspca/Kconfig21
-rw-r--r--drivers/media/video/gspca/Makefile2
-rw-r--r--drivers/media/video/gspca/conex.c2
-rw-r--r--drivers/media/video/gspca/etoms.c4
-rw-r--r--drivers/media/video/gspca/gspca.c66
-rw-r--r--drivers/media/video/gspca/gspca.h5
-rw-r--r--drivers/media/video/gspca/jeilinj.c388
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.c4
-rw-r--r--drivers/media/video/gspca/mr97310a.c853
-rw-r--r--drivers/media/video/gspca/pac207.c37
-rw-r--r--drivers/media/video/gspca/pac7311.c2
-rw-r--r--drivers/media/video/gspca/sn9c20x.c235
-rw-r--r--drivers/media/video/gspca/sonixj.c40
-rw-r--r--drivers/media/video/gspca/spca501.c2
-rw-r--r--drivers/media/video/gspca/spca506.c2
-rw-r--r--drivers/media/video/gspca/spca508.c59
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c4
-rw-r--r--drivers/media/video/gspca/sunplus.c386
-rw-r--r--drivers/media/video/gspca/t613.c210
-rw-r--r--drivers/media/video/gspca/tv8532.c2
-rw-r--r--drivers/media/video/gspca/vc032x.c1126
-rw-r--r--drivers/media/video/gspca/zc3xx.c2
-rw-r--r--drivers/media/video/hdpvr/hdpvr-control.c24
-rw-r--r--drivers/media/video/hdpvr/hdpvr-core.c12
-rw-r--r--drivers/media/video/hdpvr/hdpvr-i2c.c1
-rw-r--r--drivers/media/video/hdpvr/hdpvr-video.c6
-rw-r--r--drivers/media/video/ir-kbd-i2c.c64
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.c70
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.h3
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c3
-rw-r--r--drivers/media/video/ivtv/ivtv-gpio.c13
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c2
-rw-r--r--drivers/media/video/meye.c3
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-audio.c5
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c1
-rw-r--r--drivers/media/video/pwc/pwc-if.c78
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c2
-rw-r--r--drivers/media/video/pwc/pwc.h7
-rw-r--r--drivers/media/video/saa6588.c60
-rw-r--r--drivers/media/video/saa7134/Kconfig1
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c242
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c213
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c4
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c17
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c120
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c5
-rw-r--r--drivers/media/video/saa7134/saa7134.h9
-rw-r--r--drivers/media/video/sn9c102/sn9c102_devtable.h2
-rw-r--r--drivers/media/video/stk-webcam.c1
-rw-r--r--drivers/media/video/stv680.c9
-rw-r--r--drivers/media/video/tuner-core.c4
-rw-r--r--drivers/media/video/tveeprom.c4
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c255
-rw-r--r--drivers/media/video/uvc/uvc_driver.c570
-rw-r--r--drivers/media/video/uvc/uvc_isight.c7
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c277
-rw-r--r--drivers/media/video/uvc/uvc_video.c434
-rw-r--r--drivers/media/video/uvc/uvcvideo.h278
-rw-r--r--drivers/media/video/v4l1-compat.c5
-rw-r--r--drivers/media/video/v4l2-common.c52
-rw-r--r--drivers/media/video/v4l2-compat-ioctl32.c67
-rw-r--r--drivers/media/video/v4l2-ioctl.c33
-rw-r--r--drivers/media/video/vino.c1
-rw-r--r--drivers/media/video/w9968cf.c1
-rw-r--r--drivers/media/video/zoran/zoran_card.c3
-rw-r--r--drivers/media/video/zr364xx.c1226
184 files changed, 16638 insertions, 8661 deletions
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c
index 16792a68a449..655474b29e21 100644
--- a/drivers/media/common/ir-functions.c
+++ b/drivers/media/common/ir-functions.c
@@ -58,13 +58,24 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
58/* -------------------------------------------------------------------------- */ 58/* -------------------------------------------------------------------------- */
59 59
60void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, 60void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
61 int ir_type, IR_KEYTAB_TYPE *ir_codes) 61 int ir_type, struct ir_scancode_table *ir_codes)
62{ 62{
63 int i; 63 int i;
64 64
65 ir->ir_type = ir_type; 65 ir->ir_type = ir_type;
66
67 memset(ir->ir_codes, sizeof(ir->ir_codes), 0);
68
69 /*
70 * FIXME: This is a temporary workaround to use the new IR tables
71 * with the old approach. Later patches will replace this to a
72 * proper method
73 */
74
66 if (ir_codes) 75 if (ir_codes)
67 memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes)); 76 for (i = 0; i < ir_codes->size; i++)
77 if (ir_codes->scan[i].scancode < IR_KEYTAB_SIZE)
78 ir->ir_codes[ir_codes->scan[i].scancode] = ir_codes->scan[i].keycode;
68 79
69 dev->keycode = ir->ir_codes; 80 dev->keycode = ir->ir_codes;
70 dev->keycodesize = sizeof(IR_KEYTAB_TYPE); 81 dev->keycodesize = sizeof(IR_KEYTAB_TYPE);
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
index 4216328552f6..f6790172736a 100644
--- a/drivers/media/common/ir-keymaps.c
+++ b/drivers/media/common/ir-keymaps.c
@@ -1,8 +1,6 @@
1/* 1/*
2 2 Keytables for supported remote controls, used on drivers/media
3 3 devices.
4 Keytables for supported remote controls. This file is part of
5 video4linux.
6 4
7 This program is free software; you can redistribute it and/or modify 5 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 6 it under the terms of the GNU General Public License as published by
@@ -17,7 +15,13 @@
17 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software 16 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
20 19
20/*
21 * NOTICE FOR DEVELOPERS:
22 * The IR mappings should be as close as possible to what's
23 * specified at:
24 * http://linuxtv.org/wiki/index.php/Remote_Controllers
21 */ 25 */
22#include <linux/module.h> 26#include <linux/module.h>
23 27
@@ -25,589 +29,627 @@
25#include <media/ir-common.h> 29#include <media/ir-common.h>
26 30
27/* empty keytable, can be used as placeholder for not-yet created keytables */ 31/* empty keytable, can be used as placeholder for not-yet created keytables */
28IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = { 32static struct ir_scancode ir_codes_empty[] = {
29 [ 0x2a ] = KEY_COFFEE, 33 { 0x2a, KEY_COFFEE },
30}; 34};
31 35
32EXPORT_SYMBOL_GPL(ir_codes_empty); 36struct ir_scancode_table ir_codes_empty_table = {
37 .scan = ir_codes_empty,
38 .size = ARRAY_SIZE(ir_codes_empty),
39};
40EXPORT_SYMBOL_GPL(ir_codes_empty_table);
33 41
34/* Michal Majchrowicz <mmajchrowicz@gmail.com> */ 42/* Michal Majchrowicz <mmajchrowicz@gmail.com> */
35IR_KEYTAB_TYPE ir_codes_proteus_2309[IR_KEYTAB_SIZE] = { 43static struct ir_scancode ir_codes_proteus_2309[] = {
36 /* numeric */ 44 /* numeric */
37 [ 0x00 ] = KEY_0, 45 { 0x00, KEY_0 },
38 [ 0x01 ] = KEY_1, 46 { 0x01, KEY_1 },
39 [ 0x02 ] = KEY_2, 47 { 0x02, KEY_2 },
40 [ 0x03 ] = KEY_3, 48 { 0x03, KEY_3 },
41 [ 0x04 ] = KEY_4, 49 { 0x04, KEY_4 },
42 [ 0x05 ] = KEY_5, 50 { 0x05, KEY_5 },
43 [ 0x06 ] = KEY_6, 51 { 0x06, KEY_6 },
44 [ 0x07 ] = KEY_7, 52 { 0x07, KEY_7 },
45 [ 0x08 ] = KEY_8, 53 { 0x08, KEY_8 },
46 [ 0x09 ] = KEY_9, 54 { 0x09, KEY_9 },
47 55
48 [ 0x5c ] = KEY_POWER, /* power */ 56 { 0x5c, KEY_POWER }, /* power */
49 [ 0x20 ] = KEY_F, /* full screen */ 57 { 0x20, KEY_ZOOM }, /* full screen */
50 [ 0x0f ] = KEY_BACKSPACE, /* recall */ 58 { 0x0f, KEY_BACKSPACE }, /* recall */
51 [ 0x1b ] = KEY_ENTER, /* mute */ 59 { 0x1b, KEY_ENTER }, /* mute */
52 [ 0x41 ] = KEY_RECORD, /* record */ 60 { 0x41, KEY_RECORD }, /* record */
53 [ 0x43 ] = KEY_STOP, /* stop */ 61 { 0x43, KEY_STOP }, /* stop */
54 [ 0x16 ] = KEY_S, 62 { 0x16, KEY_S },
55 [ 0x1a ] = KEY_Q, /* off */ 63 { 0x1a, KEY_POWER2 }, /* off */
56 [ 0x2e ] = KEY_RED, 64 { 0x2e, KEY_RED },
57 [ 0x1f ] = KEY_DOWN, /* channel - */ 65 { 0x1f, KEY_CHANNELDOWN }, /* channel - */
58 [ 0x1c ] = KEY_UP, /* channel + */ 66 { 0x1c, KEY_CHANNELUP }, /* channel + */
59 [ 0x10 ] = KEY_LEFT, /* volume - */ 67 { 0x10, KEY_VOLUMEDOWN }, /* volume - */
60 [ 0x1e ] = KEY_RIGHT, /* volume + */ 68 { 0x1e, KEY_VOLUMEUP }, /* volume + */
61 [ 0x14 ] = KEY_F1, 69 { 0x14, KEY_F1 },
62}; 70};
63 71
64EXPORT_SYMBOL_GPL(ir_codes_proteus_2309); 72struct ir_scancode_table ir_codes_proteus_2309_table = {
73 .scan = ir_codes_proteus_2309,
74 .size = ARRAY_SIZE(ir_codes_proteus_2309),
75};
76EXPORT_SYMBOL_GPL(ir_codes_proteus_2309_table);
77
65/* Matt Jesson <dvb@jesson.eclipse.co.uk */ 78/* Matt Jesson <dvb@jesson.eclipse.co.uk */
66IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE] = { 79static struct ir_scancode ir_codes_avermedia_dvbt[] = {
67 [ 0x28 ] = KEY_0, //'0' / 'enter' 80 { 0x28, KEY_0 }, /* '0' / 'enter' */
68 [ 0x22 ] = KEY_1, //'1' 81 { 0x22, KEY_1 }, /* '1' */
69 [ 0x12 ] = KEY_2, //'2' / 'up arrow' 82 { 0x12, KEY_2 }, /* '2' / 'up arrow' */
70 [ 0x32 ] = KEY_3, //'3' 83 { 0x32, KEY_3 }, /* '3' */
71 [ 0x24 ] = KEY_4, //'4' / 'left arrow' 84 { 0x24, KEY_4 }, /* '4' / 'left arrow' */
72 [ 0x14 ] = KEY_5, //'5' 85 { 0x14, KEY_5 }, /* '5' */
73 [ 0x34 ] = KEY_6, //'6' / 'right arrow' 86 { 0x34, KEY_6 }, /* '6' / 'right arrow' */
74 [ 0x26 ] = KEY_7, //'7' 87 { 0x26, KEY_7 }, /* '7' */
75 [ 0x16 ] = KEY_8, //'8' / 'down arrow' 88 { 0x16, KEY_8 }, /* '8' / 'down arrow' */
76 [ 0x36 ] = KEY_9, //'9' 89 { 0x36, KEY_9 }, /* '9' */
77 90
78 [ 0x20 ] = KEY_LIST, // 'source' 91 { 0x20, KEY_LIST }, /* 'source' */
79 [ 0x10 ] = KEY_TEXT, // 'teletext' 92 { 0x10, KEY_TEXT }, /* 'teletext' */
80 [ 0x00 ] = KEY_POWER, // 'power' 93 { 0x00, KEY_POWER }, /* 'power' */
81 [ 0x04 ] = KEY_AUDIO, // 'audio' 94 { 0x04, KEY_AUDIO }, /* 'audio' */
82 [ 0x06 ] = KEY_ZOOM, // 'full screen' 95 { 0x06, KEY_ZOOM }, /* 'full screen' */
83 [ 0x18 ] = KEY_VIDEO, // 'display' 96 { 0x18, KEY_VIDEO }, /* 'display' */
84 [ 0x38 ] = KEY_SEARCH, // 'loop' 97 { 0x38, KEY_SEARCH }, /* 'loop' */
85 [ 0x08 ] = KEY_INFO, // 'preview' 98 { 0x08, KEY_INFO }, /* 'preview' */
86 [ 0x2a ] = KEY_REWIND, // 'backward <<' 99 { 0x2a, KEY_REWIND }, /* 'backward <<' */
87 [ 0x1a ] = KEY_FASTFORWARD, // 'forward >>' 100 { 0x1a, KEY_FASTFORWARD }, /* 'forward >>' */
88 [ 0x3a ] = KEY_RECORD, // 'capture' 101 { 0x3a, KEY_RECORD }, /* 'capture' */
89 [ 0x0a ] = KEY_MUTE, // 'mute' 102 { 0x0a, KEY_MUTE }, /* 'mute' */
90 [ 0x2c ] = KEY_RECORD, // 'record' 103 { 0x2c, KEY_RECORD }, /* 'record' */
91 [ 0x1c ] = KEY_PAUSE, // 'pause' 104 { 0x1c, KEY_PAUSE }, /* 'pause' */
92 [ 0x3c ] = KEY_STOP, // 'stop' 105 { 0x3c, KEY_STOP }, /* 'stop' */
93 [ 0x0c ] = KEY_PLAY, // 'play' 106 { 0x0c, KEY_PLAY }, /* 'play' */
94 [ 0x2e ] = KEY_RED, // 'red' 107 { 0x2e, KEY_RED }, /* 'red' */
95 [ 0x01 ] = KEY_BLUE, // 'blue' / 'cancel' 108 { 0x01, KEY_BLUE }, /* 'blue' / 'cancel' */
96 [ 0x0e ] = KEY_YELLOW, // 'yellow' / 'ok' 109 { 0x0e, KEY_YELLOW }, /* 'yellow' / 'ok' */
97 [ 0x21 ] = KEY_GREEN, // 'green' 110 { 0x21, KEY_GREEN }, /* 'green' */
98 [ 0x11 ] = KEY_CHANNELDOWN, // 'channel -' 111 { 0x11, KEY_CHANNELDOWN }, /* 'channel -' */
99 [ 0x31 ] = KEY_CHANNELUP, // 'channel +' 112 { 0x31, KEY_CHANNELUP }, /* 'channel +' */
100 [ 0x1e ] = KEY_VOLUMEDOWN, // 'volume -' 113 { 0x1e, KEY_VOLUMEDOWN }, /* 'volume -' */
101 [ 0x3e ] = KEY_VOLUMEUP, // 'volume +' 114 { 0x3e, KEY_VOLUMEUP }, /* 'volume +' */
102}; 115};
103 116
104EXPORT_SYMBOL_GPL(ir_codes_avermedia_dvbt); 117struct ir_scancode_table ir_codes_avermedia_dvbt_table = {
118 .scan = ir_codes_avermedia_dvbt,
119 .size = ARRAY_SIZE(ir_codes_avermedia_dvbt),
120};
121EXPORT_SYMBOL_GPL(ir_codes_avermedia_dvbt_table);
105 122
106/* Mauro Carvalho Chehab <mchehab@infradead.org> */ 123/* Mauro Carvalho Chehab <mchehab@infradead.org> */
107IR_KEYTAB_TYPE ir_codes_avermedia_m135a[IR_KEYTAB_SIZE] = { 124static struct ir_scancode ir_codes_avermedia_m135a[] = {
108 [0x00] = KEY_POWER2, 125 { 0x00, KEY_POWER2 },
109 [0x2e] = KEY_DOT, /* '.' */ 126 { 0x2e, KEY_DOT }, /* '.' */
110 [0x01] = KEY_MODE, /* TV/FM */ 127 { 0x01, KEY_MODE }, /* TV/FM */
111 128
112 [0x05] = KEY_1, 129 { 0x05, KEY_1 },
113 [0x06] = KEY_2, 130 { 0x06, KEY_2 },
114 [0x07] = KEY_3, 131 { 0x07, KEY_3 },
115 [0x09] = KEY_4, 132 { 0x09, KEY_4 },
116 [0x0a] = KEY_5, 133 { 0x0a, KEY_5 },
117 [0x0b] = KEY_6, 134 { 0x0b, KEY_6 },
118 [0x0d] = KEY_7, 135 { 0x0d, KEY_7 },
119 [0x0e] = KEY_8, 136 { 0x0e, KEY_8 },
120 [0x0f] = KEY_9, 137 { 0x0f, KEY_9 },
121 [0x11] = KEY_0, 138 { 0x11, KEY_0 },
122 139
123 [0x13] = KEY_RIGHT, /* -> */ 140 { 0x13, KEY_RIGHT }, /* -> */
124 [0x12] = KEY_LEFT, /* <- */ 141 { 0x12, KEY_LEFT }, /* <- */
125 142
126 [0x17] = KEY_SLEEP, /* Capturar Imagem */ 143 { 0x17, KEY_SLEEP }, /* Capturar Imagem */
127 [0x10] = KEY_SHUFFLE, /* Amostra */ 144 { 0x10, KEY_SHUFFLE }, /* Amostra */
128 145
129 /* FIXME: The keys bellow aren't ok */ 146 /* FIXME: The keys bellow aren't ok */
130 147
131 [0x43] = KEY_CHANNELUP, 148 { 0x43, KEY_CHANNELUP },
132 [0x42] = KEY_CHANNELDOWN, 149 { 0x42, KEY_CHANNELDOWN },
133 [0x1f] = KEY_VOLUMEUP, 150 { 0x1f, KEY_VOLUMEUP },
134 [0x1e] = KEY_VOLUMEDOWN, 151 { 0x1e, KEY_VOLUMEDOWN },
135 [0x0c] = KEY_ENTER, 152 { 0x0c, KEY_ENTER },
136 153
137 [0x14] = KEY_MUTE, 154 { 0x14, KEY_MUTE },
138 [0x08] = KEY_AUDIO, 155 { 0x08, KEY_AUDIO },
139 156
140 [0x03] = KEY_TEXT, 157 { 0x03, KEY_TEXT },
141 [0x04] = KEY_EPG, 158 { 0x04, KEY_EPG },
142 [0x2b] = KEY_TV2, /* TV2 */ 159 { 0x2b, KEY_TV2 }, /* TV2 */
143 160
144 [0x1d] = KEY_RED, 161 { 0x1d, KEY_RED },
145 [0x1c] = KEY_YELLOW, 162 { 0x1c, KEY_YELLOW },
146 [0x41] = KEY_GREEN, 163 { 0x41, KEY_GREEN },
147 [0x40] = KEY_BLUE, 164 { 0x40, KEY_BLUE },
148 165
149 [0x1a] = KEY_PLAYPAUSE, 166 { 0x1a, KEY_PLAYPAUSE },
150 [0x19] = KEY_RECORD, 167 { 0x19, KEY_RECORD },
151 [0x18] = KEY_PLAY, 168 { 0x18, KEY_PLAY },
152 [0x1b] = KEY_STOP, 169 { 0x1b, KEY_STOP },
153}; 170};
154EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a); 171
172struct ir_scancode_table ir_codes_avermedia_m135a_table = {
173 .scan = ir_codes_avermedia_m135a,
174 .size = ARRAY_SIZE(ir_codes_avermedia_m135a),
175};
176EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a_table);
155 177
156/* Oldrich Jedlicka <oldium.pro@seznam.cz> */ 178/* Oldrich Jedlicka <oldium.pro@seznam.cz> */
157IR_KEYTAB_TYPE ir_codes_avermedia_cardbus[IR_KEYTAB_SIZE] = { 179static struct ir_scancode ir_codes_avermedia_cardbus[] = {
158 [0x00] = KEY_POWER, 180 { 0x00, KEY_POWER },
159 [0x01] = KEY_TUNER, /* TV/FM */ 181 { 0x01, KEY_TUNER }, /* TV/FM */
160 [0x03] = KEY_TEXT, /* Teletext */ 182 { 0x03, KEY_TEXT }, /* Teletext */
161 [0x04] = KEY_EPG, 183 { 0x04, KEY_EPG },
162 [0x05] = KEY_1, 184 { 0x05, KEY_1 },
163 [0x06] = KEY_2, 185 { 0x06, KEY_2 },
164 [0x07] = KEY_3, 186 { 0x07, KEY_3 },
165 [0x08] = KEY_AUDIO, 187 { 0x08, KEY_AUDIO },
166 [0x09] = KEY_4, 188 { 0x09, KEY_4 },
167 [0x0a] = KEY_5, 189 { 0x0a, KEY_5 },
168 [0x0b] = KEY_6, 190 { 0x0b, KEY_6 },
169 [0x0c] = KEY_ZOOM, /* Full screen */ 191 { 0x0c, KEY_ZOOM }, /* Full screen */
170 [0x0d] = KEY_7, 192 { 0x0d, KEY_7 },
171 [0x0e] = KEY_8, 193 { 0x0e, KEY_8 },
172 [0x0f] = KEY_9, 194 { 0x0f, KEY_9 },
173 [0x10] = KEY_PAGEUP, /* 16-CH PREV */ 195 { 0x10, KEY_PAGEUP }, /* 16-CH PREV */
174 [0x11] = KEY_0, 196 { 0x11, KEY_0 },
175 [0x12] = KEY_INFO, 197 { 0x12, KEY_INFO },
176 [0x13] = KEY_AGAIN, /* CH RTN - channel return */ 198 { 0x13, KEY_AGAIN }, /* CH RTN - channel return */
177 [0x14] = KEY_MUTE, 199 { 0x14, KEY_MUTE },
178 [0x15] = KEY_EDIT, /* Autoscan */ 200 { 0x15, KEY_EDIT }, /* Autoscan */
179 [0x17] = KEY_SAVE, /* Screenshot */ 201 { 0x17, KEY_SAVE }, /* Screenshot */
180 [0x18] = KEY_PLAYPAUSE, 202 { 0x18, KEY_PLAYPAUSE },
181 [0x19] = KEY_RECORD, 203 { 0x19, KEY_RECORD },
182 [0x1a] = KEY_PLAY, 204 { 0x1a, KEY_PLAY },
183 [0x1b] = KEY_STOP, 205 { 0x1b, KEY_STOP },
184 [0x1c] = KEY_FASTFORWARD, 206 { 0x1c, KEY_FASTFORWARD },
185 [0x1d] = KEY_REWIND, 207 { 0x1d, KEY_REWIND },
186 [0x1e] = KEY_VOLUMEDOWN, 208 { 0x1e, KEY_VOLUMEDOWN },
187 [0x1f] = KEY_VOLUMEUP, 209 { 0x1f, KEY_VOLUMEUP },
188 [0x22] = KEY_SLEEP, /* Sleep */ 210 { 0x22, KEY_SLEEP }, /* Sleep */
189 [0x23] = KEY_ZOOM, /* Aspect */ 211 { 0x23, KEY_ZOOM }, /* Aspect */
190 [0x26] = KEY_SCREEN, /* Pos */ 212 { 0x26, KEY_SCREEN }, /* Pos */
191 [0x27] = KEY_ANGLE, /* Size */ 213 { 0x27, KEY_ANGLE }, /* Size */
192 [0x28] = KEY_SELECT, /* Select */ 214 { 0x28, KEY_SELECT }, /* Select */
193 [0x29] = KEY_BLUE, /* Blue/Picture */ 215 { 0x29, KEY_BLUE }, /* Blue/Picture */
194 [0x2a] = KEY_BACKSPACE, /* Back */ 216 { 0x2a, KEY_BACKSPACE }, /* Back */
195 [0x2b] = KEY_MEDIA, /* PIP (Picture-in-picture) */ 217 { 0x2b, KEY_MEDIA }, /* PIP (Picture-in-picture) */
196 [0x2c] = KEY_DOWN, 218 { 0x2c, KEY_DOWN },
197 [0x2e] = KEY_DOT, 219 { 0x2e, KEY_DOT },
198 [0x2f] = KEY_TV, /* Live TV */ 220 { 0x2f, KEY_TV }, /* Live TV */
199 [0x32] = KEY_LEFT, 221 { 0x32, KEY_LEFT },
200 [0x33] = KEY_CLEAR, /* Clear */ 222 { 0x33, KEY_CLEAR }, /* Clear */
201 [0x35] = KEY_RED, /* Red/TV */ 223 { 0x35, KEY_RED }, /* Red/TV */
202 [0x36] = KEY_UP, 224 { 0x36, KEY_UP },
203 [0x37] = KEY_HOME, /* Home */ 225 { 0x37, KEY_HOME }, /* Home */
204 [0x39] = KEY_GREEN, /* Green/Video */ 226 { 0x39, KEY_GREEN }, /* Green/Video */
205 [0x3d] = KEY_YELLOW, /* Yellow/Music */ 227 { 0x3d, KEY_YELLOW }, /* Yellow/Music */
206 [0x3e] = KEY_OK, /* Ok */ 228 { 0x3e, KEY_OK }, /* Ok */
207 [0x3f] = KEY_RIGHT, 229 { 0x3f, KEY_RIGHT },
208 [0x40] = KEY_NEXT, /* Next */ 230 { 0x40, KEY_NEXT }, /* Next */
209 [0x41] = KEY_PREVIOUS, /* Previous */ 231 { 0x41, KEY_PREVIOUS }, /* Previous */
210 [0x42] = KEY_CHANNELDOWN, /* Channel down */ 232 { 0x42, KEY_CHANNELDOWN }, /* Channel down */
211 [0x43] = KEY_CHANNELUP /* Channel up */ 233 { 0x43, KEY_CHANNELUP }, /* Channel up */
212}; 234};
213EXPORT_SYMBOL_GPL(ir_codes_avermedia_cardbus); 235
236struct ir_scancode_table ir_codes_avermedia_cardbus_table = {
237 .scan = ir_codes_avermedia_cardbus,
238 .size = ARRAY_SIZE(ir_codes_avermedia_cardbus),
239};
240EXPORT_SYMBOL_GPL(ir_codes_avermedia_cardbus_table);
214 241
215/* Attila Kondoros <attila.kondoros@chello.hu> */ 242/* Attila Kondoros <attila.kondoros@chello.hu> */
216IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = { 243static struct ir_scancode ir_codes_apac_viewcomp[] = {
217 244
218 [ 0x01 ] = KEY_1, 245 { 0x01, KEY_1 },
219 [ 0x02 ] = KEY_2, 246 { 0x02, KEY_2 },
220 [ 0x03 ] = KEY_3, 247 { 0x03, KEY_3 },
221 [ 0x04 ] = KEY_4, 248 { 0x04, KEY_4 },
222 [ 0x05 ] = KEY_5, 249 { 0x05, KEY_5 },
223 [ 0x06 ] = KEY_6, 250 { 0x06, KEY_6 },
224 [ 0x07 ] = KEY_7, 251 { 0x07, KEY_7 },
225 [ 0x08 ] = KEY_8, 252 { 0x08, KEY_8 },
226 [ 0x09 ] = KEY_9, 253 { 0x09, KEY_9 },
227 [ 0x00 ] = KEY_0, 254 { 0x00, KEY_0 },
228 [ 0x17 ] = KEY_LAST, // +100 255 { 0x17, KEY_LAST }, /* +100 */
229 [ 0x0a ] = KEY_LIST, // recall 256 { 0x0a, KEY_LIST }, /* recall */
230 257
231 258
232 [ 0x1c ] = KEY_TUNER, // TV/FM 259 { 0x1c, KEY_TUNER }, /* TV/FM */
233 [ 0x15 ] = KEY_SEARCH, // scan 260 { 0x15, KEY_SEARCH }, /* scan */
234 [ 0x12 ] = KEY_POWER, // power 261 { 0x12, KEY_POWER }, /* power */
235 [ 0x1f ] = KEY_VOLUMEDOWN, // vol up 262 { 0x1f, KEY_VOLUMEDOWN }, /* vol up */
236 [ 0x1b ] = KEY_VOLUMEUP, // vol down 263 { 0x1b, KEY_VOLUMEUP }, /* vol down */
237 [ 0x1e ] = KEY_CHANNELDOWN, // chn up 264 { 0x1e, KEY_CHANNELDOWN }, /* chn up */
238 [ 0x1a ] = KEY_CHANNELUP, // chn down 265 { 0x1a, KEY_CHANNELUP }, /* chn down */
239 266
240 [ 0x11 ] = KEY_VIDEO, // video 267 { 0x11, KEY_VIDEO }, /* video */
241 [ 0x0f ] = KEY_ZOOM, // full screen 268 { 0x0f, KEY_ZOOM }, /* full screen */
242 [ 0x13 ] = KEY_MUTE, // mute/unmute 269 { 0x13, KEY_MUTE }, /* mute/unmute */
243 [ 0x10 ] = KEY_TEXT, // min 270 { 0x10, KEY_TEXT }, /* min */
244 271
245 [ 0x0d ] = KEY_STOP, // freeze 272 { 0x0d, KEY_STOP }, /* freeze */
246 [ 0x0e ] = KEY_RECORD, // record 273 { 0x0e, KEY_RECORD }, /* record */
247 [ 0x1d ] = KEY_PLAYPAUSE, // stop 274 { 0x1d, KEY_PLAYPAUSE }, /* stop */
248 [ 0x19 ] = KEY_PLAY, // play 275 { 0x19, KEY_PLAY }, /* play */
249 276
250 [ 0x16 ] = KEY_GOTO, // osd 277 { 0x16, KEY_GOTO }, /* osd */
251 [ 0x14 ] = KEY_REFRESH, // default 278 { 0x14, KEY_REFRESH }, /* default */
252 [ 0x0c ] = KEY_KPPLUS, // fine tune >>>> 279 { 0x0c, KEY_KPPLUS }, /* fine tune >>>> */
253 [ 0x18 ] = KEY_KPMINUS // fine tune <<<< 280 { 0x18, KEY_KPMINUS }, /* fine tune <<<< */
254}; 281};
255 282
256EXPORT_SYMBOL_GPL(ir_codes_apac_viewcomp); 283struct ir_scancode_table ir_codes_apac_viewcomp_table = {
284 .scan = ir_codes_apac_viewcomp,
285 .size = ARRAY_SIZE(ir_codes_apac_viewcomp),
286};
287EXPORT_SYMBOL_GPL(ir_codes_apac_viewcomp_table);
257 288
258/* ---------------------------------------------------------------------- */ 289/* ---------------------------------------------------------------------- */
259 290
260IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = { 291static struct ir_scancode ir_codes_pixelview[] = {
261 292
262 [ 0x1e ] = KEY_POWER, // power 293 { 0x1e, KEY_POWER }, /* power */
263 [ 0x07 ] = KEY_MEDIA, // source 294 { 0x07, KEY_MEDIA }, /* source */
264 [ 0x1c ] = KEY_SEARCH, // scan 295 { 0x1c, KEY_SEARCH }, /* scan */
265 296
266/* FIXME: duplicate keycodes?
267 *
268 * These four keys seem to share the same GPIO as CH+, CH-, <<< and >>>
269 * The GPIO values are
270 * 6397fb for both "Scan <" and "CH -",
271 * 639ffb for "Scan >" and "CH+",
272 * 6384fb for "Tune <" and "<<<",
273 * 638cfb for "Tune >" and ">>>", regardless of the mask.
274 *
275 * [ 0x17 ] = KEY_BACK, // fm scan <<
276 * [ 0x1f ] = KEY_FORWARD, // fm scan >>
277 *
278 * [ 0x04 ] = KEY_LEFT, // fm tuning <
279 * [ 0x0c ] = KEY_RIGHT, // fm tuning >
280 *
281 * For now, these four keys are disabled. Pressing them will generate
282 * the CH+/CH-/<<</>>> events
283 */
284 297
285 [ 0x03 ] = KEY_TUNER, // TV/FM 298 { 0x03, KEY_TUNER }, /* TV/FM */
286 299
287 [ 0x00 ] = KEY_RECORD, 300 { 0x00, KEY_RECORD },
288 [ 0x08 ] = KEY_STOP, 301 { 0x08, KEY_STOP },
289 [ 0x11 ] = KEY_PLAY, 302 { 0x11, KEY_PLAY },
290 303
291 [ 0x1a ] = KEY_PLAYPAUSE, // freeze 304 { 0x1a, KEY_PLAYPAUSE }, /* freeze */
292 [ 0x19 ] = KEY_ZOOM, // zoom 305 { 0x19, KEY_ZOOM }, /* zoom */
293 [ 0x0f ] = KEY_TEXT, // min 306 { 0x0f, KEY_TEXT }, /* min */
294 307
295 [ 0x01 ] = KEY_1, 308 { 0x01, KEY_1 },
296 [ 0x0b ] = KEY_2, 309 { 0x0b, KEY_2 },
297 [ 0x1b ] = KEY_3, 310 { 0x1b, KEY_3 },
298 [ 0x05 ] = KEY_4, 311 { 0x05, KEY_4 },
299 [ 0x09 ] = KEY_5, 312 { 0x09, KEY_5 },
300 [ 0x15 ] = KEY_6, 313 { 0x15, KEY_6 },
301 [ 0x06 ] = KEY_7, 314 { 0x06, KEY_7 },
302 [ 0x0a ] = KEY_8, 315 { 0x0a, KEY_8 },
303 [ 0x12 ] = KEY_9, 316 { 0x12, KEY_9 },
304 [ 0x02 ] = KEY_0, 317 { 0x02, KEY_0 },
305 [ 0x10 ] = KEY_LAST, // +100 318 { 0x10, KEY_LAST }, /* +100 */
306 [ 0x13 ] = KEY_LIST, // recall 319 { 0x13, KEY_LIST }, /* recall */
307 320
308 [ 0x1f ] = KEY_CHANNELUP, // chn down 321 { 0x1f, KEY_CHANNELUP }, /* chn down */
309 [ 0x17 ] = KEY_CHANNELDOWN, // chn up 322 { 0x17, KEY_CHANNELDOWN }, /* chn up */
310 [ 0x16 ] = KEY_VOLUMEUP, // vol down 323 { 0x16, KEY_VOLUMEUP }, /* vol down */
311 [ 0x14 ] = KEY_VOLUMEDOWN, // vol up 324 { 0x14, KEY_VOLUMEDOWN }, /* vol up */
312 325
313 [ 0x04 ] = KEY_KPMINUS, // <<< 326 { 0x04, KEY_KPMINUS }, /* <<< */
314 [ 0x0e ] = KEY_SETUP, // function 327 { 0x0e, KEY_SETUP }, /* function */
315 [ 0x0c ] = KEY_KPPLUS, // >>> 328 { 0x0c, KEY_KPPLUS }, /* >>> */
316 329
317 [ 0x0d ] = KEY_GOTO, // mts 330 { 0x0d, KEY_GOTO }, /* mts */
318 [ 0x1d ] = KEY_REFRESH, // reset 331 { 0x1d, KEY_REFRESH }, /* reset */
319 [ 0x18 ] = KEY_MUTE // mute/unmute 332 { 0x18, KEY_MUTE }, /* mute/unmute */
320}; 333};
321 334
322EXPORT_SYMBOL_GPL(ir_codes_pixelview); 335struct ir_scancode_table ir_codes_pixelview_table = {
336 .scan = ir_codes_pixelview,
337 .size = ARRAY_SIZE(ir_codes_pixelview),
338};
339EXPORT_SYMBOL_GPL(ir_codes_pixelview_table);
323 340
324/* 341/*
325 Mauro Carvalho Chehab <mchehab@infradead.org> 342 Mauro Carvalho Chehab <mchehab@infradead.org>
326 present on PV MPEG 8000GT 343 present on PV MPEG 8000GT
327 */ 344 */
328IR_KEYTAB_TYPE ir_codes_pixelview_new[IR_KEYTAB_SIZE] = { 345static struct ir_scancode ir_codes_pixelview_new[] = {
329 [0x3c] = KEY_PAUSE, /* Timeshift */ 346 { 0x3c, KEY_TIME }, /* Timeshift */
330 [0x12] = KEY_POWER, 347 { 0x12, KEY_POWER },
331 348
332 [0x3d] = KEY_1, 349 { 0x3d, KEY_1 },
333 [0x38] = KEY_2, 350 { 0x38, KEY_2 },
334 [0x18] = KEY_3, 351 { 0x18, KEY_3 },
335 [0x35] = KEY_4, 352 { 0x35, KEY_4 },
336 [0x39] = KEY_5, 353 { 0x39, KEY_5 },
337 [0x15] = KEY_6, 354 { 0x15, KEY_6 },
338 [0x36] = KEY_7, 355 { 0x36, KEY_7 },
339 [0x3a] = KEY_8, 356 { 0x3a, KEY_8 },
340 [0x1e] = KEY_9, 357 { 0x1e, KEY_9 },
341 [0x3e] = KEY_0, 358 { 0x3e, KEY_0 },
342 359
343 [0x1c] = KEY_AGAIN, /* LOOP */ 360 { 0x1c, KEY_AGAIN }, /* LOOP */
344 [0x3f] = KEY_MEDIA, /* Source */ 361 { 0x3f, KEY_MEDIA }, /* Source */
345 [0x1f] = KEY_LAST, /* +100 */ 362 { 0x1f, KEY_LAST }, /* +100 */
346 [0x1b] = KEY_MUTE, 363 { 0x1b, KEY_MUTE },
347 364
348 [0x17] = KEY_CHANNELDOWN, 365 { 0x17, KEY_CHANNELDOWN },
349 [0x16] = KEY_CHANNELUP, 366 { 0x16, KEY_CHANNELUP },
350 [0x10] = KEY_VOLUMEUP, 367 { 0x10, KEY_VOLUMEUP },
351 [0x14] = KEY_VOLUMEDOWN, 368 { 0x14, KEY_VOLUMEDOWN },
352 [0x13] = KEY_ZOOM, 369 { 0x13, KEY_ZOOM },
353 370
354 [0x19] = KEY_SHUFFLE, /* SNAPSHOT */ 371 { 0x19, KEY_CAMERA }, /* SNAPSHOT */
355 [0x1a] = KEY_SEARCH, /* scan */ 372 { 0x1a, KEY_SEARCH }, /* scan */
356 373
357 [0x37] = KEY_REWIND, /* << */ 374 { 0x37, KEY_REWIND }, /* << */
358 [0x32] = KEY_RECORD, /* o (red) */ 375 { 0x32, KEY_RECORD }, /* o (red) */
359 [0x33] = KEY_FORWARD, /* >> */ 376 { 0x33, KEY_FORWARD }, /* >> */
360 [0x11] = KEY_STOP, /* square */ 377 { 0x11, KEY_STOP }, /* square */
361 [0x3b] = KEY_PLAY, /* > */ 378 { 0x3b, KEY_PLAY }, /* > */
362 [0x30] = KEY_PLAYPAUSE, /* || */ 379 { 0x30, KEY_PLAYPAUSE }, /* || */
363 380
364 [0x31] = KEY_TV, 381 { 0x31, KEY_TV },
365 [0x34] = KEY_RADIO, 382 { 0x34, KEY_RADIO },
366}; 383};
367EXPORT_SYMBOL_GPL(ir_codes_pixelview_new); 384
368 385struct ir_scancode_table ir_codes_pixelview_new_table = {
369IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE] = { 386 .scan = ir_codes_pixelview_new,
370 [ 0x00 ] = KEY_0, 387 .size = ARRAY_SIZE(ir_codes_pixelview_new),
371 [ 0x01 ] = KEY_1, 388};
372 [ 0x02 ] = KEY_2, 389EXPORT_SYMBOL_GPL(ir_codes_pixelview_new_table);
373 [ 0x03 ] = KEY_3, 390
374 [ 0x04 ] = KEY_4, 391static struct ir_scancode ir_codes_nebula[] = {
375 [ 0x05 ] = KEY_5, 392 { 0x00, KEY_0 },
376 [ 0x06 ] = KEY_6, 393 { 0x01, KEY_1 },
377 [ 0x07 ] = KEY_7, 394 { 0x02, KEY_2 },
378 [ 0x08 ] = KEY_8, 395 { 0x03, KEY_3 },
379 [ 0x09 ] = KEY_9, 396 { 0x04, KEY_4 },
380 [ 0x0a ] = KEY_TV, 397 { 0x05, KEY_5 },
381 [ 0x0b ] = KEY_AUX, 398 { 0x06, KEY_6 },
382 [ 0x0c ] = KEY_DVD, 399 { 0x07, KEY_7 },
383 [ 0x0d ] = KEY_POWER, 400 { 0x08, KEY_8 },
384 [ 0x0e ] = KEY_MHP, /* labelled 'Picture' */ 401 { 0x09, KEY_9 },
385 [ 0x0f ] = KEY_AUDIO, 402 { 0x0a, KEY_TV },
386 [ 0x10 ] = KEY_INFO, 403 { 0x0b, KEY_AUX },
387 [ 0x11 ] = KEY_F13, /* 16:9 */ 404 { 0x0c, KEY_DVD },
388 [ 0x12 ] = KEY_F14, /* 14:9 */ 405 { 0x0d, KEY_POWER },
389 [ 0x13 ] = KEY_EPG, 406 { 0x0e, KEY_MHP }, /* labelled 'Picture' */
390 [ 0x14 ] = KEY_EXIT, 407 { 0x0f, KEY_AUDIO },
391 [ 0x15 ] = KEY_MENU, 408 { 0x10, KEY_INFO },
392 [ 0x16 ] = KEY_UP, 409 { 0x11, KEY_F13 }, /* 16:9 */
393 [ 0x17 ] = KEY_DOWN, 410 { 0x12, KEY_F14 }, /* 14:9 */
394 [ 0x18 ] = KEY_LEFT, 411 { 0x13, KEY_EPG },
395 [ 0x19 ] = KEY_RIGHT, 412 { 0x14, KEY_EXIT },
396 [ 0x1a ] = KEY_ENTER, 413 { 0x15, KEY_MENU },
397 [ 0x1b ] = KEY_CHANNELUP, 414 { 0x16, KEY_UP },
398 [ 0x1c ] = KEY_CHANNELDOWN, 415 { 0x17, KEY_DOWN },
399 [ 0x1d ] = KEY_VOLUMEUP, 416 { 0x18, KEY_LEFT },
400 [ 0x1e ] = KEY_VOLUMEDOWN, 417 { 0x19, KEY_RIGHT },
401 [ 0x1f ] = KEY_RED, 418 { 0x1a, KEY_ENTER },
402 [ 0x20 ] = KEY_GREEN, 419 { 0x1b, KEY_CHANNELUP },
403 [ 0x21 ] = KEY_YELLOW, 420 { 0x1c, KEY_CHANNELDOWN },
404 [ 0x22 ] = KEY_BLUE, 421 { 0x1d, KEY_VOLUMEUP },
405 [ 0x23 ] = KEY_SUBTITLE, 422 { 0x1e, KEY_VOLUMEDOWN },
406 [ 0x24 ] = KEY_F15, /* AD */ 423 { 0x1f, KEY_RED },
407 [ 0x25 ] = KEY_TEXT, 424 { 0x20, KEY_GREEN },
408 [ 0x26 ] = KEY_MUTE, 425 { 0x21, KEY_YELLOW },
409 [ 0x27 ] = KEY_REWIND, 426 { 0x22, KEY_BLUE },
410 [ 0x28 ] = KEY_STOP, 427 { 0x23, KEY_SUBTITLE },
411 [ 0x29 ] = KEY_PLAY, 428 { 0x24, KEY_F15 }, /* AD */
412 [ 0x2a ] = KEY_FASTFORWARD, 429 { 0x25, KEY_TEXT },
413 [ 0x2b ] = KEY_F16, /* chapter */ 430 { 0x26, KEY_MUTE },
414 [ 0x2c ] = KEY_PAUSE, 431 { 0x27, KEY_REWIND },
415 [ 0x2d ] = KEY_PLAY, 432 { 0x28, KEY_STOP },
416 [ 0x2e ] = KEY_RECORD, 433 { 0x29, KEY_PLAY },
417 [ 0x2f ] = KEY_F17, /* picture in picture */ 434 { 0x2a, KEY_FASTFORWARD },
418 [ 0x30 ] = KEY_KPPLUS, /* zoom in */ 435 { 0x2b, KEY_F16 }, /* chapter */
419 [ 0x31 ] = KEY_KPMINUS, /* zoom out */ 436 { 0x2c, KEY_PAUSE },
420 [ 0x32 ] = KEY_F18, /* capture */ 437 { 0x2d, KEY_PLAY },
421 [ 0x33 ] = KEY_F19, /* web */ 438 { 0x2e, KEY_RECORD },
422 [ 0x34 ] = KEY_EMAIL, 439 { 0x2f, KEY_F17 }, /* picture in picture */
423 [ 0x35 ] = KEY_PHONE, 440 { 0x30, KEY_KPPLUS }, /* zoom in */
424 [ 0x36 ] = KEY_PC 441 { 0x31, KEY_KPMINUS }, /* zoom out */
425}; 442 { 0x32, KEY_F18 }, /* capture */
426 443 { 0x33, KEY_F19 }, /* web */
427EXPORT_SYMBOL_GPL(ir_codes_nebula); 444 { 0x34, KEY_EMAIL },
445 { 0x35, KEY_PHONE },
446 { 0x36, KEY_PC },
447};
448
449struct ir_scancode_table ir_codes_nebula_table = {
450 .scan = ir_codes_nebula,
451 .size = ARRAY_SIZE(ir_codes_nebula),
452};
453EXPORT_SYMBOL_GPL(ir_codes_nebula_table);
428 454
429/* DigitalNow DNTV Live DVB-T Remote */ 455/* DigitalNow DNTV Live DVB-T Remote */
430IR_KEYTAB_TYPE ir_codes_dntv_live_dvb_t[IR_KEYTAB_SIZE] = { 456static struct ir_scancode ir_codes_dntv_live_dvb_t[] = {
431 [ 0x00 ] = KEY_ESC, /* 'go up a level?' */ 457 { 0x00, KEY_ESC }, /* 'go up a level?' */
432 /* Keys 0 to 9 */ 458 /* Keys 0 to 9 */
433 [ 0x0a ] = KEY_0, 459 { 0x0a, KEY_0 },
434 [ 0x01 ] = KEY_1, 460 { 0x01, KEY_1 },
435 [ 0x02 ] = KEY_2, 461 { 0x02, KEY_2 },
436 [ 0x03 ] = KEY_3, 462 { 0x03, KEY_3 },
437 [ 0x04 ] = KEY_4, 463 { 0x04, KEY_4 },
438 [ 0x05 ] = KEY_5, 464 { 0x05, KEY_5 },
439 [ 0x06 ] = KEY_6, 465 { 0x06, KEY_6 },
440 [ 0x07 ] = KEY_7, 466 { 0x07, KEY_7 },
441 [ 0x08 ] = KEY_8, 467 { 0x08, KEY_8 },
442 [ 0x09 ] = KEY_9, 468 { 0x09, KEY_9 },
443 469
444 [ 0x0b ] = KEY_TUNER, /* tv/fm */ 470 { 0x0b, KEY_TUNER }, /* tv/fm */
445 [ 0x0c ] = KEY_SEARCH, /* scan */ 471 { 0x0c, KEY_SEARCH }, /* scan */
446 [ 0x0d ] = KEY_STOP, 472 { 0x0d, KEY_STOP },
447 [ 0x0e ] = KEY_PAUSE, 473 { 0x0e, KEY_PAUSE },
448 [ 0x0f ] = KEY_LIST, /* source */ 474 { 0x0f, KEY_LIST }, /* source */
449 475
450 [ 0x10 ] = KEY_MUTE, 476 { 0x10, KEY_MUTE },
451 [ 0x11 ] = KEY_REWIND, /* backward << */ 477 { 0x11, KEY_REWIND }, /* backward << */
452 [ 0x12 ] = KEY_POWER, 478 { 0x12, KEY_POWER },
453 [ 0x13 ] = KEY_S, /* snap */ 479 { 0x13, KEY_CAMERA }, /* snap */
454 [ 0x14 ] = KEY_AUDIO, /* stereo */ 480 { 0x14, KEY_AUDIO }, /* stereo */
455 [ 0x15 ] = KEY_CLEAR, /* reset */ 481 { 0x15, KEY_CLEAR }, /* reset */
456 [ 0x16 ] = KEY_PLAY, 482 { 0x16, KEY_PLAY },
457 [ 0x17 ] = KEY_ENTER, 483 { 0x17, KEY_ENTER },
458 [ 0x18 ] = KEY_ZOOM, /* full screen */ 484 { 0x18, KEY_ZOOM }, /* full screen */
459 [ 0x19 ] = KEY_FASTFORWARD, /* forward >> */ 485 { 0x19, KEY_FASTFORWARD }, /* forward >> */
460 [ 0x1a ] = KEY_CHANNELUP, 486 { 0x1a, KEY_CHANNELUP },
461 [ 0x1b ] = KEY_VOLUMEUP, 487 { 0x1b, KEY_VOLUMEUP },
462 [ 0x1c ] = KEY_INFO, /* preview */ 488 { 0x1c, KEY_INFO }, /* preview */
463 [ 0x1d ] = KEY_RECORD, /* record */ 489 { 0x1d, KEY_RECORD }, /* record */
464 [ 0x1e ] = KEY_CHANNELDOWN, 490 { 0x1e, KEY_CHANNELDOWN },
465 [ 0x1f ] = KEY_VOLUMEDOWN, 491 { 0x1f, KEY_VOLUMEDOWN },
466}; 492};
467 493
468EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvb_t); 494struct ir_scancode_table ir_codes_dntv_live_dvb_t_table = {
495 .scan = ir_codes_dntv_live_dvb_t,
496 .size = ARRAY_SIZE(ir_codes_dntv_live_dvb_t),
497};
498EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvb_t_table);
469 499
470/* ---------------------------------------------------------------------- */ 500/* ---------------------------------------------------------------------- */
471 501
472/* IO-DATA BCTV7E Remote */ 502/* IO-DATA BCTV7E Remote */
473IR_KEYTAB_TYPE ir_codes_iodata_bctv7e[IR_KEYTAB_SIZE] = { 503static struct ir_scancode ir_codes_iodata_bctv7e[] = {
474 [ 0x40 ] = KEY_TV, 504 { 0x40, KEY_TV },
475 [ 0x20 ] = KEY_RADIO, /* FM */ 505 { 0x20, KEY_RADIO }, /* FM */
476 [ 0x60 ] = KEY_EPG, 506 { 0x60, KEY_EPG },
477 [ 0x00 ] = KEY_POWER, 507 { 0x00, KEY_POWER },
478 508
479 /* Keys 0 to 9 */ 509 /* Keys 0 to 9 */
480 [ 0x44 ] = KEY_0, /* 10 */ 510 { 0x44, KEY_0 }, /* 10 */
481 [ 0x50 ] = KEY_1, 511 { 0x50, KEY_1 },
482 [ 0x30 ] = KEY_2, 512 { 0x30, KEY_2 },
483 [ 0x70 ] = KEY_3, 513 { 0x70, KEY_3 },
484 [ 0x48 ] = KEY_4, 514 { 0x48, KEY_4 },
485 [ 0x28 ] = KEY_5, 515 { 0x28, KEY_5 },
486 [ 0x68 ] = KEY_6, 516 { 0x68, KEY_6 },
487 [ 0x58 ] = KEY_7, 517 { 0x58, KEY_7 },
488 [ 0x38 ] = KEY_8, 518 { 0x38, KEY_8 },
489 [ 0x78 ] = KEY_9, 519 { 0x78, KEY_9 },
490 520
491 [ 0x10 ] = KEY_L, /* Live */ 521 { 0x10, KEY_L }, /* Live */
492 [ 0x08 ] = KEY_T, /* Time Shift */ 522 { 0x08, KEY_TIME }, /* Time Shift */
493 523
494 [ 0x18 ] = KEY_PLAYPAUSE, /* Play */ 524 { 0x18, KEY_PLAYPAUSE }, /* Play */
495 525
496 [ 0x24 ] = KEY_ENTER, /* 11 */ 526 { 0x24, KEY_ENTER }, /* 11 */
497 [ 0x64 ] = KEY_ESC, /* 12 */ 527 { 0x64, KEY_ESC }, /* 12 */
498 [ 0x04 ] = KEY_M, /* Multi */ 528 { 0x04, KEY_M }, /* Multi */
499 529
500 [ 0x54 ] = KEY_VIDEO, 530 { 0x54, KEY_VIDEO },
501 [ 0x34 ] = KEY_CHANNELUP, 531 { 0x34, KEY_CHANNELUP },
502 [ 0x74 ] = KEY_VOLUMEUP, 532 { 0x74, KEY_VOLUMEUP },
503 [ 0x14 ] = KEY_MUTE, 533 { 0x14, KEY_MUTE },
504 534
505 [ 0x4c ] = KEY_S, /* SVIDEO */ 535 { 0x4c, KEY_VCR }, /* SVIDEO */
506 [ 0x2c ] = KEY_CHANNELDOWN, 536 { 0x2c, KEY_CHANNELDOWN },
507 [ 0x6c ] = KEY_VOLUMEDOWN, 537 { 0x6c, KEY_VOLUMEDOWN },
508 [ 0x0c ] = KEY_ZOOM, 538 { 0x0c, KEY_ZOOM },
509 539
510 [ 0x5c ] = KEY_PAUSE, 540 { 0x5c, KEY_PAUSE },
511 [ 0x3c ] = KEY_C, /* || (red) */ 541 { 0x3c, KEY_RED }, /* || (red) */
512 [ 0x7c ] = KEY_RECORD, /* recording */ 542 { 0x7c, KEY_RECORD }, /* recording */
513 [ 0x1c ] = KEY_STOP, 543 { 0x1c, KEY_STOP },
514 544
515 [ 0x41 ] = KEY_REWIND, /* backward << */ 545 { 0x41, KEY_REWIND }, /* backward << */
516 [ 0x21 ] = KEY_PLAY, 546 { 0x21, KEY_PLAY },
517 [ 0x61 ] = KEY_FASTFORWARD, /* forward >> */ 547 { 0x61, KEY_FASTFORWARD }, /* forward >> */
518 [ 0x01 ] = KEY_NEXT, /* skip >| */ 548 { 0x01, KEY_NEXT }, /* skip >| */
519}; 549};
520 550
521EXPORT_SYMBOL_GPL(ir_codes_iodata_bctv7e); 551struct ir_scancode_table ir_codes_iodata_bctv7e_table = {
552 .scan = ir_codes_iodata_bctv7e,
553 .size = ARRAY_SIZE(ir_codes_iodata_bctv7e),
554};
555EXPORT_SYMBOL_GPL(ir_codes_iodata_bctv7e_table);
522 556
523/* ---------------------------------------------------------------------- */ 557/* ---------------------------------------------------------------------- */
524 558
525/* ADS Tech Instant TV DVB-T PCI Remote */ 559/* ADS Tech Instant TV DVB-T PCI Remote */
526IR_KEYTAB_TYPE ir_codes_adstech_dvb_t_pci[IR_KEYTAB_SIZE] = { 560static struct ir_scancode ir_codes_adstech_dvb_t_pci[] = {
527 /* Keys 0 to 9 */ 561 /* Keys 0 to 9 */
528 [ 0x4d ] = KEY_0, 562 { 0x4d, KEY_0 },
529 [ 0x57 ] = KEY_1, 563 { 0x57, KEY_1 },
530 [ 0x4f ] = KEY_2, 564 { 0x4f, KEY_2 },
531 [ 0x53 ] = KEY_3, 565 { 0x53, KEY_3 },
532 [ 0x56 ] = KEY_4, 566 { 0x56, KEY_4 },
533 [ 0x4e ] = KEY_5, 567 { 0x4e, KEY_5 },
534 [ 0x5e ] = KEY_6, 568 { 0x5e, KEY_6 },
535 [ 0x54 ] = KEY_7, 569 { 0x54, KEY_7 },
536 [ 0x4c ] = KEY_8, 570 { 0x4c, KEY_8 },
537 [ 0x5c ] = KEY_9, 571 { 0x5c, KEY_9 },
538 572
539 [ 0x5b ] = KEY_POWER, 573 { 0x5b, KEY_POWER },
540 [ 0x5f ] = KEY_MUTE, 574 { 0x5f, KEY_MUTE },
541 [ 0x55 ] = KEY_GOTO, 575 { 0x55, KEY_GOTO },
542 [ 0x5d ] = KEY_SEARCH, 576 { 0x5d, KEY_SEARCH },
543 [ 0x17 ] = KEY_EPG, /* Guide */ 577 { 0x17, KEY_EPG }, /* Guide */
544 [ 0x1f ] = KEY_MENU, 578 { 0x1f, KEY_MENU },
545 [ 0x0f ] = KEY_UP, 579 { 0x0f, KEY_UP },
546 [ 0x46 ] = KEY_DOWN, 580 { 0x46, KEY_DOWN },
547 [ 0x16 ] = KEY_LEFT, 581 { 0x16, KEY_LEFT },
548 [ 0x1e ] = KEY_RIGHT, 582 { 0x1e, KEY_RIGHT },
549 [ 0x0e ] = KEY_SELECT, /* Enter */ 583 { 0x0e, KEY_SELECT }, /* Enter */
550 [ 0x5a ] = KEY_INFO, 584 { 0x5a, KEY_INFO },
551 [ 0x52 ] = KEY_EXIT, 585 { 0x52, KEY_EXIT },
552 [ 0x59 ] = KEY_PREVIOUS, 586 { 0x59, KEY_PREVIOUS },
553 [ 0x51 ] = KEY_NEXT, 587 { 0x51, KEY_NEXT },
554 [ 0x58 ] = KEY_REWIND, 588 { 0x58, KEY_REWIND },
555 [ 0x50 ] = KEY_FORWARD, 589 { 0x50, KEY_FORWARD },
556 [ 0x44 ] = KEY_PLAYPAUSE, 590 { 0x44, KEY_PLAYPAUSE },
557 [ 0x07 ] = KEY_STOP, 591 { 0x07, KEY_STOP },
558 [ 0x1b ] = KEY_RECORD, 592 { 0x1b, KEY_RECORD },
559 [ 0x13 ] = KEY_TUNER, /* Live */ 593 { 0x13, KEY_TUNER }, /* Live */
560 [ 0x0a ] = KEY_A, 594 { 0x0a, KEY_A },
561 [ 0x12 ] = KEY_B, 595 { 0x12, KEY_B },
562 [ 0x03 ] = KEY_PROG1, /* 1 */ 596 { 0x03, KEY_PROG1 }, /* 1 */
563 [ 0x01 ] = KEY_PROG2, /* 2 */ 597 { 0x01, KEY_PROG2 }, /* 2 */
564 [ 0x00 ] = KEY_PROG3, /* 3 */ 598 { 0x00, KEY_PROG3 }, /* 3 */
565 [ 0x06 ] = KEY_DVD, 599 { 0x06, KEY_DVD },
566 [ 0x48 ] = KEY_AUX, /* Photo */ 600 { 0x48, KEY_AUX }, /* Photo */
567 [ 0x40 ] = KEY_VIDEO, 601 { 0x40, KEY_VIDEO },
568 [ 0x19 ] = KEY_AUDIO, /* Music */ 602 { 0x19, KEY_AUDIO }, /* Music */
569 [ 0x0b ] = KEY_CHANNELUP, 603 { 0x0b, KEY_CHANNELUP },
570 [ 0x08 ] = KEY_CHANNELDOWN, 604 { 0x08, KEY_CHANNELDOWN },
571 [ 0x15 ] = KEY_VOLUMEUP, 605 { 0x15, KEY_VOLUMEUP },
572 [ 0x1c ] = KEY_VOLUMEDOWN, 606 { 0x1c, KEY_VOLUMEDOWN },
573}; 607};
574 608
575EXPORT_SYMBOL_GPL(ir_codes_adstech_dvb_t_pci); 609struct ir_scancode_table ir_codes_adstech_dvb_t_pci_table = {
610 .scan = ir_codes_adstech_dvb_t_pci,
611 .size = ARRAY_SIZE(ir_codes_adstech_dvb_t_pci),
612};
613EXPORT_SYMBOL_GPL(ir_codes_adstech_dvb_t_pci_table);
576 614
577/* ---------------------------------------------------------------------- */ 615/* ---------------------------------------------------------------------- */
578 616
579/* MSI TV@nywhere MASTER remote */ 617/* MSI TV@nywhere MASTER remote */
580 618
581IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE] = { 619static struct ir_scancode ir_codes_msi_tvanywhere[] = {
582 /* Keys 0 to 9 */ 620 /* Keys 0 to 9 */
583 [ 0x00 ] = KEY_0, 621 { 0x00, KEY_0 },
584 [ 0x01 ] = KEY_1, 622 { 0x01, KEY_1 },
585 [ 0x02 ] = KEY_2, 623 { 0x02, KEY_2 },
586 [ 0x03 ] = KEY_3, 624 { 0x03, KEY_3 },
587 [ 0x04 ] = KEY_4, 625 { 0x04, KEY_4 },
588 [ 0x05 ] = KEY_5, 626 { 0x05, KEY_5 },
589 [ 0x06 ] = KEY_6, 627 { 0x06, KEY_6 },
590 [ 0x07 ] = KEY_7, 628 { 0x07, KEY_7 },
591 [ 0x08 ] = KEY_8, 629 { 0x08, KEY_8 },
592 [ 0x09 ] = KEY_9, 630 { 0x09, KEY_9 },
593 631
594 [ 0x0c ] = KEY_MUTE, 632 { 0x0c, KEY_MUTE },
595 [ 0x0f ] = KEY_SCREEN, /* Full Screen */ 633 { 0x0f, KEY_SCREEN }, /* Full Screen */
596 [ 0x10 ] = KEY_F, /* Funtion */ 634 { 0x10, KEY_FN }, /* Funtion */
597 [ 0x11 ] = KEY_T, /* Time shift */ 635 { 0x11, KEY_TIME }, /* Time shift */
598 [ 0x12 ] = KEY_POWER, 636 { 0x12, KEY_POWER },
599 [ 0x13 ] = KEY_MEDIA, /* MTS */ 637 { 0x13, KEY_MEDIA }, /* MTS */
600 [ 0x14 ] = KEY_SLOW, 638 { 0x14, KEY_SLOW },
601 [ 0x16 ] = KEY_REWIND, /* backward << */ 639 { 0x16, KEY_REWIND }, /* backward << */
602 [ 0x17 ] = KEY_ENTER, /* Return */ 640 { 0x17, KEY_ENTER }, /* Return */
603 [ 0x18 ] = KEY_FASTFORWARD, /* forward >> */ 641 { 0x18, KEY_FASTFORWARD }, /* forward >> */
604 [ 0x1a ] = KEY_CHANNELUP, 642 { 0x1a, KEY_CHANNELUP },
605 [ 0x1b ] = KEY_VOLUMEUP, 643 { 0x1b, KEY_VOLUMEUP },
606 [ 0x1e ] = KEY_CHANNELDOWN, 644 { 0x1e, KEY_CHANNELDOWN },
607 [ 0x1f ] = KEY_VOLUMEDOWN, 645 { 0x1f, KEY_VOLUMEDOWN },
608}; 646};
609 647
610EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere); 648struct ir_scancode_table ir_codes_msi_tvanywhere_table = {
649 .scan = ir_codes_msi_tvanywhere,
650 .size = ARRAY_SIZE(ir_codes_msi_tvanywhere),
651};
652EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_table);
611 653
612/* ---------------------------------------------------------------------- */ 654/* ---------------------------------------------------------------------- */
613 655
@@ -626,7 +668,7 @@ EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere);
626 668
627*/ 669*/
628 670
629IR_KEYTAB_TYPE ir_codes_msi_tvanywhere_plus[IR_KEYTAB_SIZE] = { 671static struct ir_scancode ir_codes_msi_tvanywhere_plus[] = {
630 672
631/* ---- Remote Button Layout ---- 673/* ---- Remote Button Layout ----
632 674
@@ -648,596 +690,645 @@ IR_KEYTAB_TYPE ir_codes_msi_tvanywhere_plus[IR_KEYTAB_SIZE] = {
648 << FUNC >> RESET 690 << FUNC >> RESET
649*/ 691*/
650 692
651 [0x01] = KEY_KP1, /* 1 */ 693 { 0x01, KEY_1 }, /* 1 */
652 [0x0b] = KEY_KP2, /* 2 */ 694 { 0x0b, KEY_2 }, /* 2 */
653 [0x1b] = KEY_KP3, /* 3 */ 695 { 0x1b, KEY_3 }, /* 3 */
654 [0x05] = KEY_KP4, /* 4 */ 696 { 0x05, KEY_4 }, /* 4 */
655 [0x09] = KEY_KP5, /* 5 */ 697 { 0x09, KEY_5 }, /* 5 */
656 [0x15] = KEY_KP6, /* 6 */ 698 { 0x15, KEY_6 }, /* 6 */
657 [0x06] = KEY_KP7, /* 7 */ 699 { 0x06, KEY_7 }, /* 7 */
658 [0x0a] = KEY_KP8, /* 8 */ 700 { 0x0a, KEY_8 }, /* 8 */
659 [0x12] = KEY_KP9, /* 9 */ 701 { 0x12, KEY_9 }, /* 9 */
660 [0x02] = KEY_KP0, /* 0 */ 702 { 0x02, KEY_0 }, /* 0 */
661 [0x10] = KEY_KPPLUS, /* + */ 703 { 0x10, KEY_KPPLUS }, /* + */
662 [0x13] = KEY_AGAIN, /* Recall */ 704 { 0x13, KEY_AGAIN }, /* Recall */
663 705
664 [0x1e] = KEY_POWER, /* Power */ 706 { 0x1e, KEY_POWER }, /* Power */
665 [0x07] = KEY_TUNER, /* Source */ 707 { 0x07, KEY_TUNER }, /* Source */
666 [0x1c] = KEY_SEARCH, /* Scan */ 708 { 0x1c, KEY_SEARCH }, /* Scan */
667 [0x18] = KEY_MUTE, /* Mute */ 709 { 0x18, KEY_MUTE }, /* Mute */
668 710
669 [0x03] = KEY_RADIO, /* TV/FM */ 711 { 0x03, KEY_RADIO }, /* TV/FM */
670 /* The next four keys are duplicates that appear to send the 712 /* The next four keys are duplicates that appear to send the
671 same IR code as Ch+, Ch-, >>, and << . The raw code assigned 713 same IR code as Ch+, Ch-, >>, and << . The raw code assigned
672 to them is the actual code + 0x20 - they will never be 714 to them is the actual code + 0x20 - they will never be
673 detected as such unless some way is discovered to distinguish 715 detected as such unless some way is discovered to distinguish
674 these buttons from those that have the same code. */ 716 these buttons from those that have the same code. */
675 [0x3f] = KEY_RIGHT, /* |> and Ch+ */ 717 { 0x3f, KEY_RIGHT }, /* |> and Ch+ */
676 [0x37] = KEY_LEFT, /* <| and Ch- */ 718 { 0x37, KEY_LEFT }, /* <| and Ch- */
677 [0x2c] = KEY_UP, /* ^^Up and >> */ 719 { 0x2c, KEY_UP }, /* ^^Up and >> */
678 [0x24] = KEY_DOWN, /* vvDn and << */ 720 { 0x24, KEY_DOWN }, /* vvDn and << */
679 721
680 [0x00] = KEY_RECORD, /* Record */ 722 { 0x00, KEY_RECORD }, /* Record */
681 [0x08] = KEY_STOP, /* Stop */ 723 { 0x08, KEY_STOP }, /* Stop */
682 [0x11] = KEY_PLAY, /* Play */ 724 { 0x11, KEY_PLAY }, /* Play */
683 725
684 [0x0f] = KEY_CLOSE, /* Minimize */ 726 { 0x0f, KEY_CLOSE }, /* Minimize */
685 [0x19] = KEY_ZOOM, /* Zoom */ 727 { 0x19, KEY_ZOOM }, /* Zoom */
686 [0x1a] = KEY_SHUFFLE, /* Snapshot */ 728 { 0x1a, KEY_CAMERA }, /* Snapshot */
687 [0x0d] = KEY_LANGUAGE, /* MTS */ 729 { 0x0d, KEY_LANGUAGE }, /* MTS */
688 730
689 [0x14] = KEY_VOLUMEDOWN, /* Vol- */ 731 { 0x14, KEY_VOLUMEDOWN }, /* Vol- */
690 [0x16] = KEY_VOLUMEUP, /* Vol+ */ 732 { 0x16, KEY_VOLUMEUP }, /* Vol+ */
691 [0x17] = KEY_CHANNELDOWN, /* Ch- */ 733 { 0x17, KEY_CHANNELDOWN }, /* Ch- */
692 [0x1f] = KEY_CHANNELUP, /* Ch+ */ 734 { 0x1f, KEY_CHANNELUP }, /* Ch+ */
735
736 { 0x04, KEY_REWIND }, /* << */
737 { 0x0e, KEY_MENU }, /* Function */
738 { 0x0c, KEY_FASTFORWARD }, /* >> */
739 { 0x1d, KEY_RESTART }, /* Reset */
740};
693 741
694 [0x04] = KEY_REWIND, /* << */ 742struct ir_scancode_table ir_codes_msi_tvanywhere_plus_table = {
695 [0x0e] = KEY_MENU, /* Function */ 743 .scan = ir_codes_msi_tvanywhere_plus,
696 [0x0c] = KEY_FASTFORWARD, /* >> */ 744 .size = ARRAY_SIZE(ir_codes_msi_tvanywhere_plus),
697 [0x1d] = KEY_RESTART, /* Reset */
698}; 745};
699EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_plus); 746EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_plus_table);
700 747
701/* ---------------------------------------------------------------------- */ 748/* ---------------------------------------------------------------------- */
702 749
703/* Cinergy 1400 DVB-T */ 750/* Cinergy 1400 DVB-T */
704IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = { 751static struct ir_scancode ir_codes_cinergy_1400[] = {
705 [ 0x01 ] = KEY_POWER, 752 { 0x01, KEY_POWER },
706 [ 0x02 ] = KEY_1, 753 { 0x02, KEY_1 },
707 [ 0x03 ] = KEY_2, 754 { 0x03, KEY_2 },
708 [ 0x04 ] = KEY_3, 755 { 0x04, KEY_3 },
709 [ 0x05 ] = KEY_4, 756 { 0x05, KEY_4 },
710 [ 0x06 ] = KEY_5, 757 { 0x06, KEY_5 },
711 [ 0x07 ] = KEY_6, 758 { 0x07, KEY_6 },
712 [ 0x08 ] = KEY_7, 759 { 0x08, KEY_7 },
713 [ 0x09 ] = KEY_8, 760 { 0x09, KEY_8 },
714 [ 0x0a ] = KEY_9, 761 { 0x0a, KEY_9 },
715 [ 0x0c ] = KEY_0, 762 { 0x0c, KEY_0 },
716 763
717 [ 0x0b ] = KEY_VIDEO, 764 { 0x0b, KEY_VIDEO },
718 [ 0x0d ] = KEY_REFRESH, 765 { 0x0d, KEY_REFRESH },
719 [ 0x0e ] = KEY_SELECT, 766 { 0x0e, KEY_SELECT },
720 [ 0x0f ] = KEY_EPG, 767 { 0x0f, KEY_EPG },
721 [ 0x10 ] = KEY_UP, 768 { 0x10, KEY_UP },
722 [ 0x11 ] = KEY_LEFT, 769 { 0x11, KEY_LEFT },
723 [ 0x12 ] = KEY_OK, 770 { 0x12, KEY_OK },
724 [ 0x13 ] = KEY_RIGHT, 771 { 0x13, KEY_RIGHT },
725 [ 0x14 ] = KEY_DOWN, 772 { 0x14, KEY_DOWN },
726 [ 0x15 ] = KEY_TEXT, 773 { 0x15, KEY_TEXT },
727 [ 0x16 ] = KEY_INFO, 774 { 0x16, KEY_INFO },
728 775
729 [ 0x17 ] = KEY_RED, 776 { 0x17, KEY_RED },
730 [ 0x18 ] = KEY_GREEN, 777 { 0x18, KEY_GREEN },
731 [ 0x19 ] = KEY_YELLOW, 778 { 0x19, KEY_YELLOW },
732 [ 0x1a ] = KEY_BLUE, 779 { 0x1a, KEY_BLUE },
733 780
734 [ 0x1b ] = KEY_CHANNELUP, 781 { 0x1b, KEY_CHANNELUP },
735 [ 0x1c ] = KEY_VOLUMEUP, 782 { 0x1c, KEY_VOLUMEUP },
736 [ 0x1d ] = KEY_MUTE, 783 { 0x1d, KEY_MUTE },
737 [ 0x1e ] = KEY_VOLUMEDOWN, 784 { 0x1e, KEY_VOLUMEDOWN },
738 [ 0x1f ] = KEY_CHANNELDOWN, 785 { 0x1f, KEY_CHANNELDOWN },
739 786
740 [ 0x40 ] = KEY_PAUSE, 787 { 0x40, KEY_PAUSE },
741 [ 0x4c ] = KEY_PLAY, 788 { 0x4c, KEY_PLAY },
742 [ 0x58 ] = KEY_RECORD, 789 { 0x58, KEY_RECORD },
743 [ 0x54 ] = KEY_PREVIOUS, 790 { 0x54, KEY_PREVIOUS },
744 [ 0x48 ] = KEY_STOP, 791 { 0x48, KEY_STOP },
745 [ 0x5c ] = KEY_NEXT, 792 { 0x5c, KEY_NEXT },
746}; 793};
747 794
748EXPORT_SYMBOL_GPL(ir_codes_cinergy_1400); 795struct ir_scancode_table ir_codes_cinergy_1400_table = {
796 .scan = ir_codes_cinergy_1400,
797 .size = ARRAY_SIZE(ir_codes_cinergy_1400),
798};
799EXPORT_SYMBOL_GPL(ir_codes_cinergy_1400_table);
749 800
750/* ---------------------------------------------------------------------- */ 801/* ---------------------------------------------------------------------- */
751 802
752/* AVERTV STUDIO 303 Remote */ 803/* AVERTV STUDIO 303 Remote */
753IR_KEYTAB_TYPE ir_codes_avertv_303[IR_KEYTAB_SIZE] = { 804static struct ir_scancode ir_codes_avertv_303[] = {
754 [ 0x2a ] = KEY_1, 805 { 0x2a, KEY_1 },
755 [ 0x32 ] = KEY_2, 806 { 0x32, KEY_2 },
756 [ 0x3a ] = KEY_3, 807 { 0x3a, KEY_3 },
757 [ 0x4a ] = KEY_4, 808 { 0x4a, KEY_4 },
758 [ 0x52 ] = KEY_5, 809 { 0x52, KEY_5 },
759 [ 0x5a ] = KEY_6, 810 { 0x5a, KEY_6 },
760 [ 0x6a ] = KEY_7, 811 { 0x6a, KEY_7 },
761 [ 0x72 ] = KEY_8, 812 { 0x72, KEY_8 },
762 [ 0x7a ] = KEY_9, 813 { 0x7a, KEY_9 },
763 [ 0x0e ] = KEY_0, 814 { 0x0e, KEY_0 },
764 815
765 [ 0x02 ] = KEY_POWER, 816 { 0x02, KEY_POWER },
766 [ 0x22 ] = KEY_VIDEO, 817 { 0x22, KEY_VIDEO },
767 [ 0x42 ] = KEY_AUDIO, 818 { 0x42, KEY_AUDIO },
768 [ 0x62 ] = KEY_ZOOM, 819 { 0x62, KEY_ZOOM },
769 [ 0x0a ] = KEY_TV, 820 { 0x0a, KEY_TV },
770 [ 0x12 ] = KEY_CD, 821 { 0x12, KEY_CD },
771 [ 0x1a ] = KEY_TEXT, 822 { 0x1a, KEY_TEXT },
772 823
773 [ 0x16 ] = KEY_SUBTITLE, 824 { 0x16, KEY_SUBTITLE },
774 [ 0x1e ] = KEY_REWIND, 825 { 0x1e, KEY_REWIND },
775 [ 0x06 ] = KEY_PRINT, 826 { 0x06, KEY_PRINT },
776 827
777 [ 0x2e ] = KEY_SEARCH, 828 { 0x2e, KEY_SEARCH },
778 [ 0x36 ] = KEY_SLEEP, 829 { 0x36, KEY_SLEEP },
779 [ 0x3e ] = KEY_SHUFFLE, 830 { 0x3e, KEY_SHUFFLE },
780 [ 0x26 ] = KEY_MUTE, 831 { 0x26, KEY_MUTE },
781 832
782 [ 0x4e ] = KEY_RECORD, 833 { 0x4e, KEY_RECORD },
783 [ 0x56 ] = KEY_PAUSE, 834 { 0x56, KEY_PAUSE },
784 [ 0x5e ] = KEY_STOP, 835 { 0x5e, KEY_STOP },
785 [ 0x46 ] = KEY_PLAY, 836 { 0x46, KEY_PLAY },
786 837
787 [ 0x6e ] = KEY_RED, 838 { 0x6e, KEY_RED },
788 [ 0x0b ] = KEY_GREEN, 839 { 0x0b, KEY_GREEN },
789 [ 0x66 ] = KEY_YELLOW, 840 { 0x66, KEY_YELLOW },
790 [ 0x03 ] = KEY_BLUE, 841 { 0x03, KEY_BLUE },
791 842
792 [ 0x76 ] = KEY_LEFT, 843 { 0x76, KEY_LEFT },
793 [ 0x7e ] = KEY_RIGHT, 844 { 0x7e, KEY_RIGHT },
794 [ 0x13 ] = KEY_DOWN, 845 { 0x13, KEY_DOWN },
795 [ 0x1b ] = KEY_UP, 846 { 0x1b, KEY_UP },
796}; 847};
797 848
798EXPORT_SYMBOL_GPL(ir_codes_avertv_303); 849struct ir_scancode_table ir_codes_avertv_303_table = {
850 .scan = ir_codes_avertv_303,
851 .size = ARRAY_SIZE(ir_codes_avertv_303),
852};
853EXPORT_SYMBOL_GPL(ir_codes_avertv_303_table);
799 854
800/* ---------------------------------------------------------------------- */ 855/* ---------------------------------------------------------------------- */
801 856
802/* DigitalNow DNTV Live! DVB-T Pro Remote */ 857/* DigitalNow DNTV Live! DVB-T Pro Remote */
803IR_KEYTAB_TYPE ir_codes_dntv_live_dvbt_pro[IR_KEYTAB_SIZE] = { 858static struct ir_scancode ir_codes_dntv_live_dvbt_pro[] = {
804 [ 0x16 ] = KEY_POWER, 859 { 0x16, KEY_POWER },
805 [ 0x5b ] = KEY_HOME, 860 { 0x5b, KEY_HOME },
806 861
807 [ 0x55 ] = KEY_TV, /* live tv */ 862 { 0x55, KEY_TV }, /* live tv */
808 [ 0x58 ] = KEY_TUNER, /* digital Radio */ 863 { 0x58, KEY_TUNER }, /* digital Radio */
809 [ 0x5a ] = KEY_RADIO, /* FM radio */ 864 { 0x5a, KEY_RADIO }, /* FM radio */
810 [ 0x59 ] = KEY_DVD, /* dvd menu */ 865 { 0x59, KEY_DVD }, /* dvd menu */
811 [ 0x03 ] = KEY_1, 866 { 0x03, KEY_1 },
812 [ 0x01 ] = KEY_2, 867 { 0x01, KEY_2 },
813 [ 0x06 ] = KEY_3, 868 { 0x06, KEY_3 },
814 [ 0x09 ] = KEY_4, 869 { 0x09, KEY_4 },
815 [ 0x1d ] = KEY_5, 870 { 0x1d, KEY_5 },
816 [ 0x1f ] = KEY_6, 871 { 0x1f, KEY_6 },
817 [ 0x0d ] = KEY_7, 872 { 0x0d, KEY_7 },
818 [ 0x19 ] = KEY_8, 873 { 0x19, KEY_8 },
819 [ 0x1b ] = KEY_9, 874 { 0x1b, KEY_9 },
820 [ 0x0c ] = KEY_CANCEL, 875 { 0x0c, KEY_CANCEL },
821 [ 0x15 ] = KEY_0, 876 { 0x15, KEY_0 },
822 [ 0x4a ] = KEY_CLEAR, 877 { 0x4a, KEY_CLEAR },
823 [ 0x13 ] = KEY_BACK, 878 { 0x13, KEY_BACK },
824 [ 0x00 ] = KEY_TAB, 879 { 0x00, KEY_TAB },
825 [ 0x4b ] = KEY_UP, 880 { 0x4b, KEY_UP },
826 [ 0x4e ] = KEY_LEFT, 881 { 0x4e, KEY_LEFT },
827 [ 0x4f ] = KEY_OK, 882 { 0x4f, KEY_OK },
828 [ 0x52 ] = KEY_RIGHT, 883 { 0x52, KEY_RIGHT },
829 [ 0x51 ] = KEY_DOWN, 884 { 0x51, KEY_DOWN },
830 [ 0x1e ] = KEY_VOLUMEUP, 885 { 0x1e, KEY_VOLUMEUP },
831 [ 0x0a ] = KEY_VOLUMEDOWN, 886 { 0x0a, KEY_VOLUMEDOWN },
832 [ 0x02 ] = KEY_CHANNELDOWN, 887 { 0x02, KEY_CHANNELDOWN },
833 [ 0x05 ] = KEY_CHANNELUP, 888 { 0x05, KEY_CHANNELUP },
834 [ 0x11 ] = KEY_RECORD, 889 { 0x11, KEY_RECORD },
835 [ 0x14 ] = KEY_PLAY, 890 { 0x14, KEY_PLAY },
836 [ 0x4c ] = KEY_PAUSE, 891 { 0x4c, KEY_PAUSE },
837 [ 0x1a ] = KEY_STOP, 892 { 0x1a, KEY_STOP },
838 [ 0x40 ] = KEY_REWIND, 893 { 0x40, KEY_REWIND },
839 [ 0x12 ] = KEY_FASTFORWARD, 894 { 0x12, KEY_FASTFORWARD },
840 [ 0x41 ] = KEY_PREVIOUSSONG, /* replay |< */ 895 { 0x41, KEY_PREVIOUSSONG }, /* replay |< */
841 [ 0x42 ] = KEY_NEXTSONG, /* skip >| */ 896 { 0x42, KEY_NEXTSONG }, /* skip >| */
842 [ 0x54 ] = KEY_CAMERA, /* capture */ 897 { 0x54, KEY_CAMERA }, /* capture */
843 [ 0x50 ] = KEY_LANGUAGE, /* sap */ 898 { 0x50, KEY_LANGUAGE }, /* sap */
844 [ 0x47 ] = KEY_TV2, /* pip */ 899 { 0x47, KEY_TV2 }, /* pip */
845 [ 0x4d ] = KEY_SCREEN, 900 { 0x4d, KEY_SCREEN },
846 [ 0x43 ] = KEY_SUBTITLE, 901 { 0x43, KEY_SUBTITLE },
847 [ 0x10 ] = KEY_MUTE, 902 { 0x10, KEY_MUTE },
848 [ 0x49 ] = KEY_AUDIO, /* l/r */ 903 { 0x49, KEY_AUDIO }, /* l/r */
849 [ 0x07 ] = KEY_SLEEP, 904 { 0x07, KEY_SLEEP },
850 [ 0x08 ] = KEY_VIDEO, /* a/v */ 905 { 0x08, KEY_VIDEO }, /* a/v */
851 [ 0x0e ] = KEY_PREVIOUS, /* recall */ 906 { 0x0e, KEY_PREVIOUS }, /* recall */
852 [ 0x45 ] = KEY_ZOOM, /* zoom + */ 907 { 0x45, KEY_ZOOM }, /* zoom + */
853 [ 0x46 ] = KEY_ANGLE, /* zoom - */ 908 { 0x46, KEY_ANGLE }, /* zoom - */
854 [ 0x56 ] = KEY_RED, 909 { 0x56, KEY_RED },
855 [ 0x57 ] = KEY_GREEN, 910 { 0x57, KEY_GREEN },
856 [ 0x5c ] = KEY_YELLOW, 911 { 0x5c, KEY_YELLOW },
857 [ 0x5d ] = KEY_BLUE, 912 { 0x5d, KEY_BLUE },
858}; 913};
859 914
860EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvbt_pro); 915struct ir_scancode_table ir_codes_dntv_live_dvbt_pro_table = {
861 916 .scan = ir_codes_dntv_live_dvbt_pro,
862IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = { 917 .size = ARRAY_SIZE(ir_codes_dntv_live_dvbt_pro),
863 [ 0x01 ] = KEY_CHANNEL, 918};
864 [ 0x02 ] = KEY_SELECT, 919EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvbt_pro_table);
865 [ 0x03 ] = KEY_MUTE, 920
866 [ 0x04 ] = KEY_POWER, 921static struct ir_scancode ir_codes_em_terratec[] = {
867 [ 0x05 ] = KEY_1, 922 { 0x01, KEY_CHANNEL },
868 [ 0x06 ] = KEY_2, 923 { 0x02, KEY_SELECT },
869 [ 0x07 ] = KEY_3, 924 { 0x03, KEY_MUTE },
870 [ 0x08 ] = KEY_CHANNELUP, 925 { 0x04, KEY_POWER },
871 [ 0x09 ] = KEY_4, 926 { 0x05, KEY_1 },
872 [ 0x0a ] = KEY_5, 927 { 0x06, KEY_2 },
873 [ 0x0b ] = KEY_6, 928 { 0x07, KEY_3 },
874 [ 0x0c ] = KEY_CHANNELDOWN, 929 { 0x08, KEY_CHANNELUP },
875 [ 0x0d ] = KEY_7, 930 { 0x09, KEY_4 },
876 [ 0x0e ] = KEY_8, 931 { 0x0a, KEY_5 },
877 [ 0x0f ] = KEY_9, 932 { 0x0b, KEY_6 },
878 [ 0x10 ] = KEY_VOLUMEUP, 933 { 0x0c, KEY_CHANNELDOWN },
879 [ 0x11 ] = KEY_0, 934 { 0x0d, KEY_7 },
880 [ 0x12 ] = KEY_MENU, 935 { 0x0e, KEY_8 },
881 [ 0x13 ] = KEY_PRINT, 936 { 0x0f, KEY_9 },
882 [ 0x14 ] = KEY_VOLUMEDOWN, 937 { 0x10, KEY_VOLUMEUP },
883 [ 0x16 ] = KEY_PAUSE, 938 { 0x11, KEY_0 },
884 [ 0x18 ] = KEY_RECORD, 939 { 0x12, KEY_MENU },
885 [ 0x19 ] = KEY_REWIND, 940 { 0x13, KEY_PRINT },
886 [ 0x1a ] = KEY_PLAY, 941 { 0x14, KEY_VOLUMEDOWN },
887 [ 0x1b ] = KEY_FORWARD, 942 { 0x16, KEY_PAUSE },
888 [ 0x1c ] = KEY_BACKSPACE, 943 { 0x18, KEY_RECORD },
889 [ 0x1e ] = KEY_STOP, 944 { 0x19, KEY_REWIND },
890 [ 0x40 ] = KEY_ZOOM, 945 { 0x1a, KEY_PLAY },
891}; 946 { 0x1b, KEY_FORWARD },
892 947 { 0x1c, KEY_BACKSPACE },
893EXPORT_SYMBOL_GPL(ir_codes_em_terratec); 948 { 0x1e, KEY_STOP },
894 949 { 0x40, KEY_ZOOM },
895IR_KEYTAB_TYPE ir_codes_pinnacle_grey[IR_KEYTAB_SIZE] = { 950};
896 [ 0x3a ] = KEY_0, 951
897 [ 0x31 ] = KEY_1, 952struct ir_scancode_table ir_codes_em_terratec_table = {
898 [ 0x32 ] = KEY_2, 953 .scan = ir_codes_em_terratec,
899 [ 0x33 ] = KEY_3, 954 .size = ARRAY_SIZE(ir_codes_em_terratec),
900 [ 0x34 ] = KEY_4, 955};
901 [ 0x35 ] = KEY_5, 956EXPORT_SYMBOL_GPL(ir_codes_em_terratec_table);
902 [ 0x36 ] = KEY_6, 957
903 [ 0x37 ] = KEY_7, 958static struct ir_scancode ir_codes_pinnacle_grey[] = {
904 [ 0x38 ] = KEY_8, 959 { 0x3a, KEY_0 },
905 [ 0x39 ] = KEY_9, 960 { 0x31, KEY_1 },
906 961 { 0x32, KEY_2 },
907 [ 0x2f ] = KEY_POWER, 962 { 0x33, KEY_3 },
908 963 { 0x34, KEY_4 },
909 [ 0x2e ] = KEY_P, 964 { 0x35, KEY_5 },
910 [ 0x1f ] = KEY_L, 965 { 0x36, KEY_6 },
911 [ 0x2b ] = KEY_I, 966 { 0x37, KEY_7 },
912 967 { 0x38, KEY_8 },
913 [ 0x2d ] = KEY_SCREEN, 968 { 0x39, KEY_9 },
914 [ 0x1e ] = KEY_ZOOM, 969
915 [ 0x1b ] = KEY_VOLUMEUP, 970 { 0x2f, KEY_POWER },
916 [ 0x0f ] = KEY_VOLUMEDOWN, 971
917 [ 0x17 ] = KEY_CHANNELUP, 972 { 0x2e, KEY_P },
918 [ 0x1c ] = KEY_CHANNELDOWN, 973 { 0x1f, KEY_L },
919 [ 0x25 ] = KEY_INFO, 974 { 0x2b, KEY_I },
920 975
921 [ 0x3c ] = KEY_MUTE, 976 { 0x2d, KEY_SCREEN },
922 977 { 0x1e, KEY_ZOOM },
923 [ 0x3d ] = KEY_LEFT, 978 { 0x1b, KEY_VOLUMEUP },
924 [ 0x3b ] = KEY_RIGHT, 979 { 0x0f, KEY_VOLUMEDOWN },
925 980 { 0x17, KEY_CHANNELUP },
926 [ 0x3f ] = KEY_UP, 981 { 0x1c, KEY_CHANNELDOWN },
927 [ 0x3e ] = KEY_DOWN, 982 { 0x25, KEY_INFO },
928 [ 0x1a ] = KEY_ENTER, 983
929 984 { 0x3c, KEY_MUTE },
930 [ 0x1d ] = KEY_MENU, 985
931 [ 0x19 ] = KEY_AGAIN, 986 { 0x3d, KEY_LEFT },
932 [ 0x16 ] = KEY_PREVIOUSSONG, 987 { 0x3b, KEY_RIGHT },
933 [ 0x13 ] = KEY_NEXTSONG, 988
934 [ 0x15 ] = KEY_PAUSE, 989 { 0x3f, KEY_UP },
935 [ 0x0e ] = KEY_REWIND, 990 { 0x3e, KEY_DOWN },
936 [ 0x0d ] = KEY_PLAY, 991 { 0x1a, KEY_ENTER },
937 [ 0x0b ] = KEY_STOP, 992
938 [ 0x07 ] = KEY_FORWARD, 993 { 0x1d, KEY_MENU },
939 [ 0x27 ] = KEY_RECORD, 994 { 0x19, KEY_AGAIN },
940 [ 0x26 ] = KEY_TUNER, 995 { 0x16, KEY_PREVIOUSSONG },
941 [ 0x29 ] = KEY_TEXT, 996 { 0x13, KEY_NEXTSONG },
942 [ 0x2a ] = KEY_MEDIA, 997 { 0x15, KEY_PAUSE },
943 [ 0x18 ] = KEY_EPG, 998 { 0x0e, KEY_REWIND },
944}; 999 { 0x0d, KEY_PLAY },
945 1000 { 0x0b, KEY_STOP },
946EXPORT_SYMBOL_GPL(ir_codes_pinnacle_grey); 1001 { 0x07, KEY_FORWARD },
947 1002 { 0x27, KEY_RECORD },
948IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE] = { 1003 { 0x26, KEY_TUNER },
949 [ 0x0f ] = KEY_0, 1004 { 0x29, KEY_TEXT },
950 [ 0x03 ] = KEY_1, 1005 { 0x2a, KEY_MEDIA },
951 [ 0x04 ] = KEY_2, 1006 { 0x18, KEY_EPG },
952 [ 0x05 ] = KEY_3, 1007};
953 [ 0x07 ] = KEY_4, 1008
954 [ 0x08 ] = KEY_5, 1009struct ir_scancode_table ir_codes_pinnacle_grey_table = {
955 [ 0x09 ] = KEY_6, 1010 .scan = ir_codes_pinnacle_grey,
956 [ 0x0b ] = KEY_7, 1011 .size = ARRAY_SIZE(ir_codes_pinnacle_grey),
957 [ 0x0c ] = KEY_8, 1012};
958 [ 0x0d ] = KEY_9, 1013EXPORT_SYMBOL_GPL(ir_codes_pinnacle_grey_table);
959 1014
960 [ 0x0e ] = KEY_MODE, // Air/Cable 1015static struct ir_scancode ir_codes_flyvideo[] = {
961 [ 0x11 ] = KEY_VIDEO, // Video 1016 { 0x0f, KEY_0 },
962 [ 0x15 ] = KEY_AUDIO, // Audio 1017 { 0x03, KEY_1 },
963 [ 0x00 ] = KEY_POWER, // Power 1018 { 0x04, KEY_2 },
964 [ 0x18 ] = KEY_TUNER, // AV Source 1019 { 0x05, KEY_3 },
965 [ 0x02 ] = KEY_ZOOM, // Fullscreen 1020 { 0x07, KEY_4 },
966 [ 0x1a ] = KEY_LANGUAGE, // Stereo 1021 { 0x08, KEY_5 },
967 [ 0x1b ] = KEY_MUTE, // Mute 1022 { 0x09, KEY_6 },
968 [ 0x14 ] = KEY_VOLUMEUP, // Volume + 1023 { 0x0b, KEY_7 },
969 [ 0x17 ] = KEY_VOLUMEDOWN, // Volume - 1024 { 0x0c, KEY_8 },
970 [ 0x12 ] = KEY_CHANNELUP, // Channel + 1025 { 0x0d, KEY_9 },
971 [ 0x13 ] = KEY_CHANNELDOWN, // Channel - 1026
972 [ 0x06 ] = KEY_AGAIN, // Recall 1027 { 0x0e, KEY_MODE }, /* Air/Cable */
973 [ 0x10 ] = KEY_ENTER, // Enter 1028 { 0x11, KEY_VIDEO }, /* Video */
974 1029 { 0x15, KEY_AUDIO }, /* Audio */
975 [ 0x19 ] = KEY_BACK, // Rewind ( <<< ) 1030 { 0x00, KEY_POWER }, /* Power */
976 [ 0x1f ] = KEY_FORWARD, // Forward ( >>> ) 1031 { 0x18, KEY_TUNER }, /* AV Source */
977 [ 0x0a ] = KEY_ANGLE, // (no label, may be used as the PAUSE button) 1032 { 0x02, KEY_ZOOM }, /* Fullscreen */
978}; 1033 { 0x1a, KEY_LANGUAGE }, /* Stereo */
979 1034 { 0x1b, KEY_MUTE }, /* Mute */
980EXPORT_SYMBOL_GPL(ir_codes_flyvideo); 1035 { 0x14, KEY_VOLUMEUP }, /* Volume + */
981 1036 { 0x17, KEY_VOLUMEDOWN },/* Volume - */
982IR_KEYTAB_TYPE ir_codes_flydvb[IR_KEYTAB_SIZE] = { 1037 { 0x12, KEY_CHANNELUP },/* Channel + */
983 [ 0x01 ] = KEY_ZOOM, // Full Screen 1038 { 0x13, KEY_CHANNELDOWN },/* Channel - */
984 [ 0x00 ] = KEY_POWER, // Power 1039 { 0x06, KEY_AGAIN }, /* Recall */
985 1040 { 0x10, KEY_ENTER }, /* Enter */
986 [ 0x03 ] = KEY_1, 1041
987 [ 0x04 ] = KEY_2, 1042 { 0x19, KEY_BACK }, /* Rewind ( <<< ) */
988 [ 0x05 ] = KEY_3, 1043 { 0x1f, KEY_FORWARD }, /* Forward ( >>> ) */
989 [ 0x07 ] = KEY_4, 1044 { 0x0a, KEY_ANGLE }, /* no label, may be used as the PAUSE button */
990 [ 0x08 ] = KEY_5, 1045};
991 [ 0x09 ] = KEY_6, 1046
992 [ 0x0b ] = KEY_7, 1047struct ir_scancode_table ir_codes_flyvideo_table = {
993 [ 0x0c ] = KEY_8, 1048 .scan = ir_codes_flyvideo,
994 [ 0x0d ] = KEY_9, 1049 .size = ARRAY_SIZE(ir_codes_flyvideo),
995 [ 0x06 ] = KEY_AGAIN, // Recall 1050};
996 [ 0x0f ] = KEY_0, 1051EXPORT_SYMBOL_GPL(ir_codes_flyvideo_table);
997 [ 0x10 ] = KEY_MUTE, // Mute 1052
998 [ 0x02 ] = KEY_RADIO, // TV/Radio 1053static struct ir_scancode ir_codes_flydvb[] = {
999 [ 0x1b ] = KEY_LANGUAGE, // SAP (Second Audio Program) 1054 { 0x01, KEY_ZOOM }, /* Full Screen */
1000 1055 { 0x00, KEY_POWER }, /* Power */
1001 [ 0x14 ] = KEY_VOLUMEUP, // VOL+ 1056
1002 [ 0x17 ] = KEY_VOLUMEDOWN, // VOL- 1057 { 0x03, KEY_1 },
1003 [ 0x12 ] = KEY_CHANNELUP, // CH+ 1058 { 0x04, KEY_2 },
1004 [ 0x13 ] = KEY_CHANNELDOWN, // CH- 1059 { 0x05, KEY_3 },
1005 [ 0x1d ] = KEY_ENTER, // Enter 1060 { 0x07, KEY_4 },
1006 1061 { 0x08, KEY_5 },
1007 [ 0x1a ] = KEY_MODE, // PIP 1062 { 0x09, KEY_6 },
1008 [ 0x18 ] = KEY_TUNER, // Source 1063 { 0x0b, KEY_7 },
1009 1064 { 0x0c, KEY_8 },
1010 [ 0x1e ] = KEY_RECORD, // Record/Pause 1065 { 0x0d, KEY_9 },
1011 [ 0x15 ] = KEY_ANGLE, // Swap (no label on key) 1066 { 0x06, KEY_AGAIN }, /* Recall */
1012 [ 0x1c ] = KEY_PAUSE, // Timeshift/Pause 1067 { 0x0f, KEY_0 },
1013 [ 0x19 ] = KEY_BACK, // Rewind << 1068 { 0x10, KEY_MUTE }, /* Mute */
1014 [ 0x0a ] = KEY_PLAYPAUSE, // Play/Pause 1069 { 0x02, KEY_RADIO }, /* TV/Radio */
1015 [ 0x1f ] = KEY_FORWARD, // Forward >> 1070 { 0x1b, KEY_LANGUAGE }, /* SAP (Second Audio Program) */
1016 [ 0x16 ] = KEY_PREVIOUS, // Back |<< 1071
1017 [ 0x11 ] = KEY_STOP, // Stop 1072 { 0x14, KEY_VOLUMEUP }, /* VOL+ */
1018 [ 0x0e ] = KEY_NEXT, // End >>| 1073 { 0x17, KEY_VOLUMEDOWN }, /* VOL- */
1019}; 1074 { 0x12, KEY_CHANNELUP }, /* CH+ */
1020 1075 { 0x13, KEY_CHANNELDOWN }, /* CH- */
1021EXPORT_SYMBOL_GPL(ir_codes_flydvb); 1076 { 0x1d, KEY_ENTER }, /* Enter */
1022 1077
1023IR_KEYTAB_TYPE ir_codes_cinergy[IR_KEYTAB_SIZE] = { 1078 { 0x1a, KEY_MODE }, /* PIP */
1024 [ 0x00 ] = KEY_0, 1079 { 0x18, KEY_TUNER }, /* Source */
1025 [ 0x01 ] = KEY_1, 1080
1026 [ 0x02 ] = KEY_2, 1081 { 0x1e, KEY_RECORD }, /* Record/Pause */
1027 [ 0x03 ] = KEY_3, 1082 { 0x15, KEY_ANGLE }, /* Swap (no label on key) */
1028 [ 0x04 ] = KEY_4, 1083 { 0x1c, KEY_PAUSE }, /* Timeshift/Pause */
1029 [ 0x05 ] = KEY_5, 1084 { 0x19, KEY_BACK }, /* Rewind << */
1030 [ 0x06 ] = KEY_6, 1085 { 0x0a, KEY_PLAYPAUSE }, /* Play/Pause */
1031 [ 0x07 ] = KEY_7, 1086 { 0x1f, KEY_FORWARD }, /* Forward >> */
1032 [ 0x08 ] = KEY_8, 1087 { 0x16, KEY_PREVIOUS }, /* Back |<< */
1033 [ 0x09 ] = KEY_9, 1088 { 0x11, KEY_STOP }, /* Stop */
1034 1089 { 0x0e, KEY_NEXT }, /* End >>| */
1035 [ 0x0a ] = KEY_POWER, 1090};
1036 [ 0x0b ] = KEY_PROG1, // app 1091
1037 [ 0x0c ] = KEY_ZOOM, // zoom/fullscreen 1092struct ir_scancode_table ir_codes_flydvb_table = {
1038 [ 0x0d ] = KEY_CHANNELUP, // channel 1093 .scan = ir_codes_flydvb,
1039 [ 0x0e ] = KEY_CHANNELDOWN, // channel- 1094 .size = ARRAY_SIZE(ir_codes_flydvb),
1040 [ 0x0f ] = KEY_VOLUMEUP, 1095};
1041 [ 0x10 ] = KEY_VOLUMEDOWN, 1096EXPORT_SYMBOL_GPL(ir_codes_flydvb_table);
1042 [ 0x11 ] = KEY_TUNER, // AV 1097
1043 [ 0x12 ] = KEY_NUMLOCK, // -/-- 1098static struct ir_scancode ir_codes_cinergy[] = {
1044 [ 0x13 ] = KEY_AUDIO, // audio 1099 { 0x00, KEY_0 },
1045 [ 0x14 ] = KEY_MUTE, 1100 { 0x01, KEY_1 },
1046 [ 0x15 ] = KEY_UP, 1101 { 0x02, KEY_2 },
1047 [ 0x16 ] = KEY_DOWN, 1102 { 0x03, KEY_3 },
1048 [ 0x17 ] = KEY_LEFT, 1103 { 0x04, KEY_4 },
1049 [ 0x18 ] = KEY_RIGHT, 1104 { 0x05, KEY_5 },
1050 [ 0x19 ] = BTN_LEFT, 1105 { 0x06, KEY_6 },
1051 [ 0x1a ] = BTN_RIGHT, 1106 { 0x07, KEY_7 },
1052 [ 0x1b ] = KEY_WWW, // text 1107 { 0x08, KEY_8 },
1053 [ 0x1c ] = KEY_REWIND, 1108 { 0x09, KEY_9 },
1054 [ 0x1d ] = KEY_FORWARD, 1109
1055 [ 0x1e ] = KEY_RECORD, 1110 { 0x0a, KEY_POWER },
1056 [ 0x1f ] = KEY_PLAY, 1111 { 0x0b, KEY_PROG1 }, /* app */
1057 [ 0x20 ] = KEY_PREVIOUSSONG, 1112 { 0x0c, KEY_ZOOM }, /* zoom/fullscreen */
1058 [ 0x21 ] = KEY_NEXTSONG, 1113 { 0x0d, KEY_CHANNELUP }, /* channel */
1059 [ 0x22 ] = KEY_PAUSE, 1114 { 0x0e, KEY_CHANNELDOWN }, /* channel- */
1060 [ 0x23 ] = KEY_STOP, 1115 { 0x0f, KEY_VOLUMEUP },
1061}; 1116 { 0x10, KEY_VOLUMEDOWN },
1062 1117 { 0x11, KEY_TUNER }, /* AV */
1063EXPORT_SYMBOL_GPL(ir_codes_cinergy); 1118 { 0x12, KEY_NUMLOCK }, /* -/-- */
1119 { 0x13, KEY_AUDIO }, /* audio */
1120 { 0x14, KEY_MUTE },
1121 { 0x15, KEY_UP },
1122 { 0x16, KEY_DOWN },
1123 { 0x17, KEY_LEFT },
1124 { 0x18, KEY_RIGHT },
1125 { 0x19, BTN_LEFT, },
1126 { 0x1a, BTN_RIGHT, },
1127 { 0x1b, KEY_WWW }, /* text */
1128 { 0x1c, KEY_REWIND },
1129 { 0x1d, KEY_FORWARD },
1130 { 0x1e, KEY_RECORD },
1131 { 0x1f, KEY_PLAY },
1132 { 0x20, KEY_PREVIOUSSONG },
1133 { 0x21, KEY_NEXTSONG },
1134 { 0x22, KEY_PAUSE },
1135 { 0x23, KEY_STOP },
1136};
1137
1138struct ir_scancode_table ir_codes_cinergy_table = {
1139 .scan = ir_codes_cinergy,
1140 .size = ARRAY_SIZE(ir_codes_cinergy),
1141};
1142EXPORT_SYMBOL_GPL(ir_codes_cinergy_table);
1064 1143
1065/* Alfons Geser <a.geser@cox.net> 1144/* Alfons Geser <a.geser@cox.net>
1066 * updates from Job D. R. Borges <jobdrb@ig.com.br> */ 1145 * updates from Job D. R. Borges <jobdrb@ig.com.br> */
1067IR_KEYTAB_TYPE ir_codes_eztv[IR_KEYTAB_SIZE] = { 1146static struct ir_scancode ir_codes_eztv[] = {
1068 [ 0x12 ] = KEY_POWER, 1147 { 0x12, KEY_POWER },
1069 [ 0x01 ] = KEY_TV, // DVR 1148 { 0x01, KEY_TV }, /* DVR */
1070 [ 0x15 ] = KEY_DVD, // DVD 1149 { 0x15, KEY_DVD }, /* DVD */
1071 [ 0x17 ] = KEY_AUDIO, // music 1150 { 0x17, KEY_AUDIO }, /* music */
1072 // DVR mode / DVD mode / music mode 1151 /* DVR mode / DVD mode / music mode */
1073 1152
1074 [ 0x1b ] = KEY_MUTE, // mute 1153 { 0x1b, KEY_MUTE }, /* mute */
1075 [ 0x02 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek 1154 { 0x02, KEY_LANGUAGE }, /* MTS/SAP / audio / autoseek */
1076 [ 0x1e ] = KEY_SUBTITLE, // closed captioning / subtitle / seek 1155 { 0x1e, KEY_SUBTITLE }, /* closed captioning / subtitle / seek */
1077 [ 0x16 ] = KEY_ZOOM, // full screen 1156 { 0x16, KEY_ZOOM }, /* full screen */
1078 [ 0x1c ] = KEY_VIDEO, // video source / eject / delall 1157 { 0x1c, KEY_VIDEO }, /* video source / eject / delall */
1079 [ 0x1d ] = KEY_RESTART, // playback / angle / del 1158 { 0x1d, KEY_RESTART }, /* playback / angle / del */
1080 [ 0x2f ] = KEY_SEARCH, // scan / menu / playlist 1159 { 0x2f, KEY_SEARCH }, /* scan / menu / playlist */
1081 [ 0x30 ] = KEY_CHANNEL, // CH surfing / bookmark / memo 1160 { 0x30, KEY_CHANNEL }, /* CH surfing / bookmark / memo */
1082 1161
1083 [ 0x31 ] = KEY_HELP, // help 1162 { 0x31, KEY_HELP }, /* help */
1084 [ 0x32 ] = KEY_MODE, // num/memo 1163 { 0x32, KEY_MODE }, /* num/memo */
1085 [ 0x33 ] = KEY_ESC, // cancel 1164 { 0x33, KEY_ESC }, /* cancel */
1086 1165
1087 [ 0x0c ] = KEY_UP, // up 1166 { 0x0c, KEY_UP }, /* up */
1088 [ 0x10 ] = KEY_DOWN, // down 1167 { 0x10, KEY_DOWN }, /* down */
1089 [ 0x08 ] = KEY_LEFT, // left 1168 { 0x08, KEY_LEFT }, /* left */
1090 [ 0x04 ] = KEY_RIGHT, // right 1169 { 0x04, KEY_RIGHT }, /* right */
1091 [ 0x03 ] = KEY_SELECT, // select 1170 { 0x03, KEY_SELECT }, /* select */
1092 1171
1093 [ 0x1f ] = KEY_REWIND, // rewind 1172 { 0x1f, KEY_REWIND }, /* rewind */
1094 [ 0x20 ] = KEY_PLAYPAUSE, // play/pause 1173 { 0x20, KEY_PLAYPAUSE },/* play/pause */
1095 [ 0x29 ] = KEY_FORWARD, // forward 1174 { 0x29, KEY_FORWARD }, /* forward */
1096 [ 0x14 ] = KEY_AGAIN, // repeat 1175 { 0x14, KEY_AGAIN }, /* repeat */
1097 [ 0x2b ] = KEY_RECORD, // recording 1176 { 0x2b, KEY_RECORD }, /* recording */
1098 [ 0x2c ] = KEY_STOP, // stop 1177 { 0x2c, KEY_STOP }, /* stop */
1099 [ 0x2d ] = KEY_PLAY, // play 1178 { 0x2d, KEY_PLAY }, /* play */
1100 [ 0x2e ] = KEY_SHUFFLE, // snapshot / shuffle 1179 { 0x2e, KEY_CAMERA }, /* snapshot / shuffle */
1101 1180
1102 [ 0x00 ] = KEY_0, 1181 { 0x00, KEY_0 },
1103 [ 0x05 ] = KEY_1, 1182 { 0x05, KEY_1 },
1104 [ 0x06 ] = KEY_2, 1183 { 0x06, KEY_2 },
1105 [ 0x07 ] = KEY_3, 1184 { 0x07, KEY_3 },
1106 [ 0x09 ] = KEY_4, 1185 { 0x09, KEY_4 },
1107 [ 0x0a ] = KEY_5, 1186 { 0x0a, KEY_5 },
1108 [ 0x0b ] = KEY_6, 1187 { 0x0b, KEY_6 },
1109 [ 0x0d ] = KEY_7, 1188 { 0x0d, KEY_7 },
1110 [ 0x0e ] = KEY_8, 1189 { 0x0e, KEY_8 },
1111 [ 0x0f ] = KEY_9, 1190 { 0x0f, KEY_9 },
1112 1191
1113 [ 0x2a ] = KEY_VOLUMEUP, 1192 { 0x2a, KEY_VOLUMEUP },
1114 [ 0x11 ] = KEY_VOLUMEDOWN, 1193 { 0x11, KEY_VOLUMEDOWN },
1115 [ 0x18 ] = KEY_CHANNELUP, // CH.tracking up 1194 { 0x18, KEY_CHANNELUP },/* CH.tracking up */
1116 [ 0x19 ] = KEY_CHANNELDOWN, // CH.tracking down 1195 { 0x19, KEY_CHANNELDOWN },/* CH.tracking down */
1117 1196
1118 [ 0x13 ] = KEY_ENTER, // enter 1197 { 0x13, KEY_ENTER }, /* enter */
1119 [ 0x21 ] = KEY_DOT, // . (decimal dot) 1198 { 0x21, KEY_DOT }, /* . (decimal dot) */
1120}; 1199};
1121 1200
1122EXPORT_SYMBOL_GPL(ir_codes_eztv); 1201struct ir_scancode_table ir_codes_eztv_table = {
1202 .scan = ir_codes_eztv,
1203 .size = ARRAY_SIZE(ir_codes_eztv),
1204};
1205EXPORT_SYMBOL_GPL(ir_codes_eztv_table);
1123 1206
1124/* Alex Hermann <gaaf@gmx.net> */ 1207/* Alex Hermann <gaaf@gmx.net> */
1125IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE] = { 1208static struct ir_scancode ir_codes_avermedia[] = {
1126 [ 0x28 ] = KEY_1, 1209 { 0x28, KEY_1 },
1127 [ 0x18 ] = KEY_2, 1210 { 0x18, KEY_2 },
1128 [ 0x38 ] = KEY_3, 1211 { 0x38, KEY_3 },
1129 [ 0x24 ] = KEY_4, 1212 { 0x24, KEY_4 },
1130 [ 0x14 ] = KEY_5, 1213 { 0x14, KEY_5 },
1131 [ 0x34 ] = KEY_6, 1214 { 0x34, KEY_6 },
1132 [ 0x2c ] = KEY_7, 1215 { 0x2c, KEY_7 },
1133 [ 0x1c ] = KEY_8, 1216 { 0x1c, KEY_8 },
1134 [ 0x3c ] = KEY_9, 1217 { 0x3c, KEY_9 },
1135 [ 0x22 ] = KEY_0, 1218 { 0x22, KEY_0 },
1136 1219
1137 [ 0x20 ] = KEY_TV, /* TV/FM */ 1220 { 0x20, KEY_TV }, /* TV/FM */
1138 [ 0x10 ] = KEY_CD, /* CD */ 1221 { 0x10, KEY_CD }, /* CD */
1139 [ 0x30 ] = KEY_TEXT, /* TELETEXT */ 1222 { 0x30, KEY_TEXT }, /* TELETEXT */
1140 [ 0x00 ] = KEY_POWER, /* POWER */ 1223 { 0x00, KEY_POWER }, /* POWER */
1141 1224
1142 [ 0x08 ] = KEY_VIDEO, /* VIDEO */ 1225 { 0x08, KEY_VIDEO }, /* VIDEO */
1143 [ 0x04 ] = KEY_AUDIO, /* AUDIO */ 1226 { 0x04, KEY_AUDIO }, /* AUDIO */
1144 [ 0x0c ] = KEY_ZOOM, /* FULL SCREEN */ 1227 { 0x0c, KEY_ZOOM }, /* FULL SCREEN */
1145 1228
1146 [ 0x12 ] = KEY_SUBTITLE, /* DISPLAY */ 1229 { 0x12, KEY_SUBTITLE }, /* DISPLAY */
1147 [ 0x32 ] = KEY_REWIND, /* LOOP */ 1230 { 0x32, KEY_REWIND }, /* LOOP */
1148 [ 0x02 ] = KEY_PRINT, /* PREVIEW */ 1231 { 0x02, KEY_PRINT }, /* PREVIEW */
1149 1232
1150 [ 0x2a ] = KEY_SEARCH, /* AUTOSCAN */ 1233 { 0x2a, KEY_SEARCH }, /* AUTOSCAN */
1151 [ 0x1a ] = KEY_SLEEP, /* FREEZE */ 1234 { 0x1a, KEY_SLEEP }, /* FREEZE */
1152 [ 0x3a ] = KEY_SHUFFLE, /* SNAPSHOT */ 1235 { 0x3a, KEY_CAMERA }, /* SNAPSHOT */
1153 [ 0x0a ] = KEY_MUTE, /* MUTE */ 1236 { 0x0a, KEY_MUTE }, /* MUTE */
1154 1237
1155 [ 0x26 ] = KEY_RECORD, /* RECORD */ 1238 { 0x26, KEY_RECORD }, /* RECORD */
1156 [ 0x16 ] = KEY_PAUSE, /* PAUSE */ 1239 { 0x16, KEY_PAUSE }, /* PAUSE */
1157 [ 0x36 ] = KEY_STOP, /* STOP */ 1240 { 0x36, KEY_STOP }, /* STOP */
1158 [ 0x06 ] = KEY_PLAY, /* PLAY */ 1241 { 0x06, KEY_PLAY }, /* PLAY */
1159 1242
1160 [ 0x2e ] = KEY_RED, /* RED */ 1243 { 0x2e, KEY_RED }, /* RED */
1161 [ 0x21 ] = KEY_GREEN, /* GREEN */ 1244 { 0x21, KEY_GREEN }, /* GREEN */
1162 [ 0x0e ] = KEY_YELLOW, /* YELLOW */ 1245 { 0x0e, KEY_YELLOW }, /* YELLOW */
1163 [ 0x01 ] = KEY_BLUE, /* BLUE */ 1246 { 0x01, KEY_BLUE }, /* BLUE */
1164 1247
1165 [ 0x1e ] = KEY_VOLUMEDOWN, /* VOLUME- */ 1248 { 0x1e, KEY_VOLUMEDOWN }, /* VOLUME- */
1166 [ 0x3e ] = KEY_VOLUMEUP, /* VOLUME+ */ 1249 { 0x3e, KEY_VOLUMEUP }, /* VOLUME+ */
1167 [ 0x11 ] = KEY_CHANNELDOWN, /* CHANNEL/PAGE- */ 1250 { 0x11, KEY_CHANNELDOWN }, /* CHANNEL/PAGE- */
1168 [ 0x31 ] = KEY_CHANNELUP /* CHANNEL/PAGE+ */ 1251 { 0x31, KEY_CHANNELUP } /* CHANNEL/PAGE+ */
1169}; 1252};
1170 1253
1171EXPORT_SYMBOL_GPL(ir_codes_avermedia); 1254struct ir_scancode_table ir_codes_avermedia_table = {
1172 1255 .scan = ir_codes_avermedia,
1173IR_KEYTAB_TYPE ir_codes_videomate_tv_pvr[IR_KEYTAB_SIZE] = { 1256 .size = ARRAY_SIZE(ir_codes_avermedia),
1174 [ 0x14 ] = KEY_MUTE, 1257};
1175 [ 0x24 ] = KEY_ZOOM, 1258EXPORT_SYMBOL_GPL(ir_codes_avermedia_table);
1176 1259
1177 [ 0x01 ] = KEY_DVD, 1260static struct ir_scancode ir_codes_videomate_tv_pvr[] = {
1178 [ 0x23 ] = KEY_RADIO, 1261 { 0x14, KEY_MUTE },
1179 [ 0x00 ] = KEY_TV, 1262 { 0x24, KEY_ZOOM },
1180 1263
1181 [ 0x0a ] = KEY_REWIND, 1264 { 0x01, KEY_DVD },
1182 [ 0x08 ] = KEY_PLAYPAUSE, 1265 { 0x23, KEY_RADIO },
1183 [ 0x0f ] = KEY_FORWARD, 1266 { 0x00, KEY_TV },
1184 1267
1185 [ 0x02 ] = KEY_PREVIOUS, 1268 { 0x0a, KEY_REWIND },
1186 [ 0x07 ] = KEY_STOP, 1269 { 0x08, KEY_PLAYPAUSE },
1187 [ 0x06 ] = KEY_NEXT, 1270 { 0x0f, KEY_FORWARD },
1188 1271
1189 [ 0x0c ] = KEY_UP, 1272 { 0x02, KEY_PREVIOUS },
1190 [ 0x0e ] = KEY_DOWN, 1273 { 0x07, KEY_STOP },
1191 [ 0x0b ] = KEY_LEFT, 1274 { 0x06, KEY_NEXT },
1192 [ 0x0d ] = KEY_RIGHT, 1275
1193 [ 0x11 ] = KEY_OK, 1276 { 0x0c, KEY_UP },
1194 1277 { 0x0e, KEY_DOWN },
1195 [ 0x03 ] = KEY_MENU, 1278 { 0x0b, KEY_LEFT },
1196 [ 0x09 ] = KEY_SETUP, 1279 { 0x0d, KEY_RIGHT },
1197 [ 0x05 ] = KEY_VIDEO, 1280 { 0x11, KEY_OK },
1198 [ 0x22 ] = KEY_CHANNEL, 1281
1199 1282 { 0x03, KEY_MENU },
1200 [ 0x12 ] = KEY_VOLUMEUP, 1283 { 0x09, KEY_SETUP },
1201 [ 0x15 ] = KEY_VOLUMEDOWN, 1284 { 0x05, KEY_VIDEO },
1202 [ 0x10 ] = KEY_CHANNELUP, 1285 { 0x22, KEY_CHANNEL },
1203 [ 0x13 ] = KEY_CHANNELDOWN, 1286
1204 1287 { 0x12, KEY_VOLUMEUP },
1205 [ 0x04 ] = KEY_RECORD, 1288 { 0x15, KEY_VOLUMEDOWN },
1206 1289 { 0x10, KEY_CHANNELUP },
1207 [ 0x16 ] = KEY_1, 1290 { 0x13, KEY_CHANNELDOWN },
1208 [ 0x17 ] = KEY_2, 1291
1209 [ 0x18 ] = KEY_3, 1292 { 0x04, KEY_RECORD },
1210 [ 0x19 ] = KEY_4, 1293
1211 [ 0x1a ] = KEY_5, 1294 { 0x16, KEY_1 },
1212 [ 0x1b ] = KEY_6, 1295 { 0x17, KEY_2 },
1213 [ 0x1c ] = KEY_7, 1296 { 0x18, KEY_3 },
1214 [ 0x1d ] = KEY_8, 1297 { 0x19, KEY_4 },
1215 [ 0x1e ] = KEY_9, 1298 { 0x1a, KEY_5 },
1216 [ 0x1f ] = KEY_0, 1299 { 0x1b, KEY_6 },
1217 1300 { 0x1c, KEY_7 },
1218 [ 0x20 ] = KEY_LANGUAGE, 1301 { 0x1d, KEY_8 },
1219 [ 0x21 ] = KEY_SLEEP, 1302 { 0x1e, KEY_9 },
1220}; 1303 { 0x1f, KEY_0 },
1221 1304
1222EXPORT_SYMBOL_GPL(ir_codes_videomate_tv_pvr); 1305 { 0x20, KEY_LANGUAGE },
1306 { 0x21, KEY_SLEEP },
1307};
1308
1309struct ir_scancode_table ir_codes_videomate_tv_pvr_table = {
1310 .scan = ir_codes_videomate_tv_pvr,
1311 .size = ARRAY_SIZE(ir_codes_videomate_tv_pvr),
1312};
1313EXPORT_SYMBOL_GPL(ir_codes_videomate_tv_pvr_table);
1223 1314
1224/* Michael Tokarev <mjt@tls.msk.ru> 1315/* Michael Tokarev <mjt@tls.msk.ru>
1225 http://www.corpit.ru/mjt/beholdTV/remote_control.jpg 1316 http://www.corpit.ru/mjt/beholdTV/remote_control.jpg
1226 keytable is used by MANLI MTV00[ 0x0c ] and BeholdTV 40[13] at 1317 keytable is used by MANLI MTV00[0x0c] and BeholdTV 40[13] at
1227 least, and probably other cards too. 1318 least, and probably other cards too.
1228 The "ascii-art picture" below (in comments, first row 1319 The "ascii-art picture" below (in comments, first row
1229 is the keycode in hex, and subsequent row(s) shows 1320 is the keycode in hex, and subsequent row(s) shows
1230 the button labels (several variants when appropriate) 1321 the button labels (several variants when appropriate)
1231 helps to descide which keycodes to assign to the buttons. 1322 helps to descide which keycodes to assign to the buttons.
1232 */ 1323 */
1233IR_KEYTAB_TYPE ir_codes_manli[IR_KEYTAB_SIZE] = { 1324static struct ir_scancode ir_codes_manli[] = {
1234 1325
1235 /* 0x1c 0x12 * 1326 /* 0x1c 0x12 *
1236 * FUNCTION POWER * 1327 * FUNCTION POWER *
1237 * FM (|) * 1328 * FM (|) *
1238 * */ 1329 * */
1239 [ 0x1c ] = KEY_RADIO, /*XXX*/ 1330 { 0x1c, KEY_RADIO }, /*XXX*/
1240 [ 0x12 ] = KEY_POWER, 1331 { 0x12, KEY_POWER },
1241 1332
1242 /* 0x01 0x02 0x03 * 1333 /* 0x01 0x02 0x03 *
1243 * 1 2 3 * 1334 * 1 2 3 *
@@ -1248,29 +1339,29 @@ IR_KEYTAB_TYPE ir_codes_manli[IR_KEYTAB_SIZE] = {
1248 * 0x07 0x08 0x09 * 1339 * 0x07 0x08 0x09 *
1249 * 7 8 9 * 1340 * 7 8 9 *
1250 * */ 1341 * */
1251 [ 0x01 ] = KEY_1, 1342 { 0x01, KEY_1 },
1252 [ 0x02 ] = KEY_2, 1343 { 0x02, KEY_2 },
1253 [ 0x03 ] = KEY_3, 1344 { 0x03, KEY_3 },
1254 [ 0x04 ] = KEY_4, 1345 { 0x04, KEY_4 },
1255 [ 0x05 ] = KEY_5, 1346 { 0x05, KEY_5 },
1256 [ 0x06 ] = KEY_6, 1347 { 0x06, KEY_6 },
1257 [ 0x07 ] = KEY_7, 1348 { 0x07, KEY_7 },
1258 [ 0x08 ] = KEY_8, 1349 { 0x08, KEY_8 },
1259 [ 0x09 ] = KEY_9, 1350 { 0x09, KEY_9 },
1260 1351
1261 /* 0x0a 0x00 0x17 * 1352 /* 0x0a 0x00 0x17 *
1262 * RECALL 0 +100 * 1353 * RECALL 0 +100 *
1263 * PLUS * 1354 * PLUS *
1264 * */ 1355 * */
1265 [ 0x0a ] = KEY_AGAIN, /*XXX KEY_REWIND? */ 1356 { 0x0a, KEY_AGAIN }, /*XXX KEY_REWIND? */
1266 [ 0x00 ] = KEY_0, 1357 { 0x00, KEY_0 },
1267 [ 0x17 ] = KEY_DIGITS, /*XXX*/ 1358 { 0x17, KEY_DIGITS }, /*XXX*/
1268 1359
1269 /* 0x14 0x10 * 1360 /* 0x14 0x10 *
1270 * MENU INFO * 1361 * MENU INFO *
1271 * OSD */ 1362 * OSD */
1272 [ 0x14 ] = KEY_MENU, 1363 { 0x14, KEY_MENU },
1273 [ 0x10 ] = KEY_INFO, 1364 { 0x10, KEY_INFO },
1274 1365
1275 /* 0x0b * 1366 /* 0x0b *
1276 * Up * 1367 * Up *
@@ -1281,18 +1372,18 @@ IR_KEYTAB_TYPE ir_codes_manli[IR_KEYTAB_SIZE] = {
1281 * 0x015 * 1372 * 0x015 *
1282 * Down * 1373 * Down *
1283 * */ 1374 * */
1284 [ 0x0b ] = KEY_UP, /*XXX KEY_SCROLLUP? */ 1375 { 0x0b, KEY_UP },
1285 [ 0x18 ] = KEY_LEFT, /*XXX KEY_BACK? */ 1376 { 0x18, KEY_LEFT },
1286 [ 0x16 ] = KEY_OK, /*XXX KEY_SELECT? KEY_ENTER? */ 1377 { 0x16, KEY_OK }, /*XXX KEY_SELECT? KEY_ENTER? */
1287 [ 0x0c ] = KEY_RIGHT, /*XXX KEY_FORWARD? */ 1378 { 0x0c, KEY_RIGHT },
1288 [ 0x15 ] = KEY_DOWN, /*XXX KEY_SCROLLDOWN? */ 1379 { 0x15, KEY_DOWN },
1289 1380
1290 /* 0x11 0x0d * 1381 /* 0x11 0x0d *
1291 * TV/AV MODE * 1382 * TV/AV MODE *
1292 * SOURCE STEREO * 1383 * SOURCE STEREO *
1293 * */ 1384 * */
1294 [ 0x11 ] = KEY_TV, /*XXX*/ 1385 { 0x11, KEY_TV }, /*XXX*/
1295 [ 0x0d ] = KEY_MODE, /*XXX there's no KEY_STEREO */ 1386 { 0x0d, KEY_MODE }, /*XXX there's no KEY_STEREO */
1296 1387
1297 /* 0x0f 0x1b 0x1a * 1388 /* 0x0f 0x1b 0x1a *
1298 * AUDIO Vol+ Chan+ * 1389 * AUDIO Vol+ Chan+ *
@@ -1301,891 +1392,967 @@ IR_KEYTAB_TYPE ir_codes_manli[IR_KEYTAB_SIZE] = {
1301 * 0x0e 0x1f 0x1e * 1392 * 0x0e 0x1f 0x1e *
1302 * SLEEP Vol- Chan- * 1393 * SLEEP Vol- Chan- *
1303 * */ 1394 * */
1304 [ 0x0f ] = KEY_AUDIO, 1395 { 0x0f, KEY_AUDIO },
1305 [ 0x1b ] = KEY_VOLUMEUP, 1396 { 0x1b, KEY_VOLUMEUP },
1306 [ 0x1a ] = KEY_CHANNELUP, 1397 { 0x1a, KEY_CHANNELUP },
1307 [ 0x0e ] = KEY_SLEEP, /*XXX maybe KEY_PAUSE */ 1398 { 0x0e, KEY_TIME },
1308 [ 0x1f ] = KEY_VOLUMEDOWN, 1399 { 0x1f, KEY_VOLUMEDOWN },
1309 [ 0x1e ] = KEY_CHANNELDOWN, 1400 { 0x1e, KEY_CHANNELDOWN },
1310 1401
1311 /* 0x13 0x19 * 1402 /* 0x13 0x19 *
1312 * MUTE SNAPSHOT* 1403 * MUTE SNAPSHOT*
1313 * */ 1404 * */
1314 [ 0x13 ] = KEY_MUTE, 1405 { 0x13, KEY_MUTE },
1315 [ 0x19 ] = KEY_RECORD, /*XXX*/ 1406 { 0x19, KEY_CAMERA },
1316 1407
1317 // 0x1d unused ? 1408 /* 0x1d unused ? */
1318}; 1409};
1319 1410
1320EXPORT_SYMBOL_GPL(ir_codes_manli); 1411struct ir_scancode_table ir_codes_manli_table = {
1412 .scan = ir_codes_manli,
1413 .size = ARRAY_SIZE(ir_codes_manli),
1414};
1415EXPORT_SYMBOL_GPL(ir_codes_manli_table);
1321 1416
1322/* Mike Baikov <mike@baikov.com> */ 1417/* Mike Baikov <mike@baikov.com> */
1323IR_KEYTAB_TYPE ir_codes_gotview7135[IR_KEYTAB_SIZE] = { 1418static struct ir_scancode ir_codes_gotview7135[] = {
1324 1419
1325 [ 0x11 ] = KEY_POWER, 1420 { 0x11, KEY_POWER },
1326 [ 0x35 ] = KEY_TV, 1421 { 0x35, KEY_TV },
1327 [ 0x1b ] = KEY_0, 1422 { 0x1b, KEY_0 },
1328 [ 0x29 ] = KEY_1, 1423 { 0x29, KEY_1 },
1329 [ 0x19 ] = KEY_2, 1424 { 0x19, KEY_2 },
1330 [ 0x39 ] = KEY_3, 1425 { 0x39, KEY_3 },
1331 [ 0x1f ] = KEY_4, 1426 { 0x1f, KEY_4 },
1332 [ 0x2c ] = KEY_5, 1427 { 0x2c, KEY_5 },
1333 [ 0x21 ] = KEY_6, 1428 { 0x21, KEY_6 },
1334 [ 0x24 ] = KEY_7, 1429 { 0x24, KEY_7 },
1335 [ 0x18 ] = KEY_8, 1430 { 0x18, KEY_8 },
1336 [ 0x2b ] = KEY_9, 1431 { 0x2b, KEY_9 },
1337 [ 0x3b ] = KEY_AGAIN, /* LOOP */ 1432 { 0x3b, KEY_AGAIN }, /* LOOP */
1338 [ 0x06 ] = KEY_AUDIO, 1433 { 0x06, KEY_AUDIO },
1339 [ 0x31 ] = KEY_PRINT, /* PREVIEW */ 1434 { 0x31, KEY_PRINT }, /* PREVIEW */
1340 [ 0x3e ] = KEY_VIDEO, 1435 { 0x3e, KEY_VIDEO },
1341 [ 0x10 ] = KEY_CHANNELUP, 1436 { 0x10, KEY_CHANNELUP },
1342 [ 0x20 ] = KEY_CHANNELDOWN, 1437 { 0x20, KEY_CHANNELDOWN },
1343 [ 0x0c ] = KEY_VOLUMEDOWN, 1438 { 0x0c, KEY_VOLUMEDOWN },
1344 [ 0x28 ] = KEY_VOLUMEUP, 1439 { 0x28, KEY_VOLUMEUP },
1345 [ 0x08 ] = KEY_MUTE, 1440 { 0x08, KEY_MUTE },
1346 [ 0x26 ] = KEY_SEARCH, /*SCAN*/ 1441 { 0x26, KEY_SEARCH }, /* SCAN */
1347 [ 0x3f ] = KEY_SHUFFLE, /* SNAPSHOT */ 1442 { 0x3f, KEY_CAMERA }, /* SNAPSHOT */
1348 [ 0x12 ] = KEY_RECORD, 1443 { 0x12, KEY_RECORD },
1349 [ 0x32 ] = KEY_STOP, 1444 { 0x32, KEY_STOP },
1350 [ 0x3c ] = KEY_PLAY, 1445 { 0x3c, KEY_PLAY },
1351 [ 0x1d ] = KEY_REWIND, 1446 { 0x1d, KEY_REWIND },
1352 [ 0x2d ] = KEY_PAUSE, 1447 { 0x2d, KEY_PAUSE },
1353 [ 0x0d ] = KEY_FORWARD, 1448 { 0x0d, KEY_FORWARD },
1354 [ 0x05 ] = KEY_ZOOM, /*FULL*/ 1449 { 0x05, KEY_ZOOM }, /*FULL*/
1355 1450
1356 [ 0x2a ] = KEY_F21, /* LIVE TIMESHIFT */ 1451 { 0x2a, KEY_F21 }, /* LIVE TIMESHIFT */
1357 [ 0x0e ] = KEY_F22, /* MIN TIMESHIFT */ 1452 { 0x0e, KEY_F22 }, /* MIN TIMESHIFT */
1358 [ 0x1e ] = KEY_F23, /* TIMESHIFT */ 1453 { 0x1e, KEY_TIME }, /* TIMESHIFT */
1359 [ 0x38 ] = KEY_F24, /* NORMAL TIMESHIFT */ 1454 { 0x38, KEY_F24 }, /* NORMAL TIMESHIFT */
1360}; 1455};
1361 1456
1362EXPORT_SYMBOL_GPL(ir_codes_gotview7135); 1457struct ir_scancode_table ir_codes_gotview7135_table = {
1363 1458 .scan = ir_codes_gotview7135,
1364IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = { 1459 .size = ARRAY_SIZE(ir_codes_gotview7135),
1365 [ 0x03 ] = KEY_POWER, 1460};
1366 [ 0x6f ] = KEY_MUTE, 1461EXPORT_SYMBOL_GPL(ir_codes_gotview7135_table);
1367 [ 0x10 ] = KEY_BACKSPACE, /* Recall */ 1462
1368 1463static struct ir_scancode ir_codes_purpletv[] = {
1369 [ 0x11 ] = KEY_0, 1464 { 0x03, KEY_POWER },
1370 [ 0x04 ] = KEY_1, 1465 { 0x6f, KEY_MUTE },
1371 [ 0x05 ] = KEY_2, 1466 { 0x10, KEY_BACKSPACE }, /* Recall */
1372 [ 0x06 ] = KEY_3, 1467
1373 [ 0x08 ] = KEY_4, 1468 { 0x11, KEY_0 },
1374 [ 0x09 ] = KEY_5, 1469 { 0x04, KEY_1 },
1375 [ 0x0a ] = KEY_6, 1470 { 0x05, KEY_2 },
1376 [ 0x0c ] = KEY_7, 1471 { 0x06, KEY_3 },
1377 [ 0x0d ] = KEY_8, 1472 { 0x08, KEY_4 },
1378 [ 0x0e ] = KEY_9, 1473 { 0x09, KEY_5 },
1379 [ 0x12 ] = KEY_DOT, /* 100+ */ 1474 { 0x0a, KEY_6 },
1380 1475 { 0x0c, KEY_7 },
1381 [ 0x07 ] = KEY_VOLUMEUP, 1476 { 0x0d, KEY_8 },
1382 [ 0x0b ] = KEY_VOLUMEDOWN, 1477 { 0x0e, KEY_9 },
1383 [ 0x1a ] = KEY_KPPLUS, 1478 { 0x12, KEY_DOT }, /* 100+ */
1384 [ 0x18 ] = KEY_KPMINUS, 1479
1385 [ 0x15 ] = KEY_UP, 1480 { 0x07, KEY_VOLUMEUP },
1386 [ 0x1d ] = KEY_DOWN, 1481 { 0x0b, KEY_VOLUMEDOWN },
1387 [ 0x0f ] = KEY_CHANNELUP, 1482 { 0x1a, KEY_KPPLUS },
1388 [ 0x13 ] = KEY_CHANNELDOWN, 1483 { 0x18, KEY_KPMINUS },
1389 [ 0x48 ] = KEY_ZOOM, 1484 { 0x15, KEY_UP },
1390 1485 { 0x1d, KEY_DOWN },
1391 [ 0x1b ] = KEY_VIDEO, /* Video source */ 1486 { 0x0f, KEY_CHANNELUP },
1392 [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */ 1487 { 0x13, KEY_CHANNELDOWN },
1393 [ 0x19 ] = KEY_SEARCH, /* Auto Scan */ 1488 { 0x48, KEY_ZOOM },
1394 1489
1395 [ 0x4b ] = KEY_RECORD, 1490 { 0x1b, KEY_VIDEO }, /* Video source */
1396 [ 0x46 ] = KEY_PLAY, 1491 { 0x1f, KEY_CAMERA }, /* Snapshot */
1397 [ 0x45 ] = KEY_PAUSE, /* Pause */ 1492 { 0x49, KEY_LANGUAGE }, /* MTS Select */
1398 [ 0x44 ] = KEY_STOP, 1493 { 0x19, KEY_SEARCH }, /* Auto Scan */
1399 [ 0x40 ] = KEY_FORWARD, /* Forward ? */ 1494
1400 [ 0x42 ] = KEY_REWIND, /* Backward ? */ 1495 { 0x4b, KEY_RECORD },
1401 1496 { 0x46, KEY_PLAY },
1402}; 1497 { 0x45, KEY_PAUSE }, /* Pause */
1403 1498 { 0x44, KEY_STOP },
1404EXPORT_SYMBOL_GPL(ir_codes_purpletv); 1499 { 0x43, KEY_TIME }, /* Time Shift */
1500 { 0x17, KEY_CHANNEL }, /* SURF CH */
1501 { 0x40, KEY_FORWARD }, /* Forward ? */
1502 { 0x42, KEY_REWIND }, /* Backward ? */
1503
1504};
1505
1506struct ir_scancode_table ir_codes_purpletv_table = {
1507 .scan = ir_codes_purpletv,
1508 .size = ARRAY_SIZE(ir_codes_purpletv),
1509};
1510EXPORT_SYMBOL_GPL(ir_codes_purpletv_table);
1405 1511
1406/* Mapping for the 28 key remote control as seen at 1512/* Mapping for the 28 key remote control as seen at
1407 http://www.sednacomputer.com/photo/cardbus-tv.jpg 1513 http://www.sednacomputer.com/photo/cardbus-tv.jpg
1408 Pavel Mihaylov <bin@bash.info> 1514 Pavel Mihaylov <bin@bash.info>
1409 Also for the remote bundled with Kozumi KTV-01C card */ 1515 Also for the remote bundled with Kozumi KTV-01C card */
1410IR_KEYTAB_TYPE ir_codes_pctv_sedna[IR_KEYTAB_SIZE] = { 1516static struct ir_scancode ir_codes_pctv_sedna[] = {
1411 [ 0x00 ] = KEY_0, 1517 { 0x00, KEY_0 },
1412 [ 0x01 ] = KEY_1, 1518 { 0x01, KEY_1 },
1413 [ 0x02 ] = KEY_2, 1519 { 0x02, KEY_2 },
1414 [ 0x03 ] = KEY_3, 1520 { 0x03, KEY_3 },
1415 [ 0x04 ] = KEY_4, 1521 { 0x04, KEY_4 },
1416 [ 0x05 ] = KEY_5, 1522 { 0x05, KEY_5 },
1417 [ 0x06 ] = KEY_6, 1523 { 0x06, KEY_6 },
1418 [ 0x07 ] = KEY_7, 1524 { 0x07, KEY_7 },
1419 [ 0x08 ] = KEY_8, 1525 { 0x08, KEY_8 },
1420 [ 0x09 ] = KEY_9, 1526 { 0x09, KEY_9 },
1421 1527
1422 [ 0x0a ] = KEY_AGAIN, /* Recall */ 1528 { 0x0a, KEY_AGAIN }, /* Recall */
1423 [ 0x0b ] = KEY_CHANNELUP, 1529 { 0x0b, KEY_CHANNELUP },
1424 [ 0x0c ] = KEY_VOLUMEUP, 1530 { 0x0c, KEY_VOLUMEUP },
1425 [ 0x0d ] = KEY_MODE, /* Stereo */ 1531 { 0x0d, KEY_MODE }, /* Stereo */
1426 [ 0x0e ] = KEY_STOP, 1532 { 0x0e, KEY_STOP },
1427 [ 0x0f ] = KEY_PREVIOUSSONG, 1533 { 0x0f, KEY_PREVIOUSSONG },
1428 [ 0x10 ] = KEY_ZOOM, 1534 { 0x10, KEY_ZOOM },
1429 [ 0x11 ] = KEY_TUNER, /* Source */ 1535 { 0x11, KEY_TUNER }, /* Source */
1430 [ 0x12 ] = KEY_POWER, 1536 { 0x12, KEY_POWER },
1431 [ 0x13 ] = KEY_MUTE, 1537 { 0x13, KEY_MUTE },
1432 [ 0x15 ] = KEY_CHANNELDOWN, 1538 { 0x15, KEY_CHANNELDOWN },
1433 [ 0x18 ] = KEY_VOLUMEDOWN, 1539 { 0x18, KEY_VOLUMEDOWN },
1434 [ 0x19 ] = KEY_SHUFFLE, /* Snapshot */ 1540 { 0x19, KEY_CAMERA }, /* Snapshot */
1435 [ 0x1a ] = KEY_NEXTSONG, 1541 { 0x1a, KEY_NEXTSONG },
1436 [ 0x1b ] = KEY_TEXT, /* Time Shift */ 1542 { 0x1b, KEY_TIME }, /* Time Shift */
1437 [ 0x1c ] = KEY_RADIO, /* FM Radio */ 1543 { 0x1c, KEY_RADIO }, /* FM Radio */
1438 [ 0x1d ] = KEY_RECORD, 1544 { 0x1d, KEY_RECORD },
1439 [ 0x1e ] = KEY_PAUSE, 1545 { 0x1e, KEY_PAUSE },
1440 /* additional codes for Kozumi's remote */ 1546 /* additional codes for Kozumi's remote */
1441 [0x14] = KEY_INFO, /* OSD */ 1547 { 0x14, KEY_INFO }, /* OSD */
1442 [0x16] = KEY_OK, /* OK */ 1548 { 0x16, KEY_OK }, /* OK */
1443 [0x17] = KEY_DIGITS, /* Plus */ 1549 { 0x17, KEY_DIGITS }, /* Plus */
1444 [0x1f] = KEY_PLAY, /* Play */ 1550 { 0x1f, KEY_PLAY }, /* Play */
1445}; 1551};
1446 1552
1447EXPORT_SYMBOL_GPL(ir_codes_pctv_sedna); 1553struct ir_scancode_table ir_codes_pctv_sedna_table = {
1554 .scan = ir_codes_pctv_sedna,
1555 .size = ARRAY_SIZE(ir_codes_pctv_sedna),
1556};
1557EXPORT_SYMBOL_GPL(ir_codes_pctv_sedna_table);
1448 1558
1449/* Mark Phalan <phalanm@o2.ie> */ 1559/* Mark Phalan <phalanm@o2.ie> */
1450IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = { 1560static struct ir_scancode ir_codes_pv951[] = {
1451 [ 0x00 ] = KEY_0, 1561 { 0x00, KEY_0 },
1452 [ 0x01 ] = KEY_1, 1562 { 0x01, KEY_1 },
1453 [ 0x02 ] = KEY_2, 1563 { 0x02, KEY_2 },
1454 [ 0x03 ] = KEY_3, 1564 { 0x03, KEY_3 },
1455 [ 0x04 ] = KEY_4, 1565 { 0x04, KEY_4 },
1456 [ 0x05 ] = KEY_5, 1566 { 0x05, KEY_5 },
1457 [ 0x06 ] = KEY_6, 1567 { 0x06, KEY_6 },
1458 [ 0x07 ] = KEY_7, 1568 { 0x07, KEY_7 },
1459 [ 0x08 ] = KEY_8, 1569 { 0x08, KEY_8 },
1460 [ 0x09 ] = KEY_9, 1570 { 0x09, KEY_9 },
1461 1571
1462 [ 0x12 ] = KEY_POWER, 1572 { 0x12, KEY_POWER },
1463 [ 0x10 ] = KEY_MUTE, 1573 { 0x10, KEY_MUTE },
1464 [ 0x1f ] = KEY_VOLUMEDOWN, 1574 { 0x1f, KEY_VOLUMEDOWN },
1465 [ 0x1b ] = KEY_VOLUMEUP, 1575 { 0x1b, KEY_VOLUMEUP },
1466 [ 0x1a ] = KEY_CHANNELUP, 1576 { 0x1a, KEY_CHANNELUP },
1467 [ 0x1e ] = KEY_CHANNELDOWN, 1577 { 0x1e, KEY_CHANNELDOWN },
1468 [ 0x0e ] = KEY_PAGEUP, 1578 { 0x0e, KEY_PAGEUP },
1469 [ 0x1d ] = KEY_PAGEDOWN, 1579 { 0x1d, KEY_PAGEDOWN },
1470 [ 0x13 ] = KEY_SOUND, 1580 { 0x13, KEY_SOUND },
1471 1581
1472 [ 0x18 ] = KEY_KPPLUSMINUS, /* CH +/- */ 1582 { 0x18, KEY_KPPLUSMINUS }, /* CH +/- */
1473 [ 0x16 ] = KEY_SUBTITLE, /* CC */ 1583 { 0x16, KEY_SUBTITLE }, /* CC */
1474 [ 0x0d ] = KEY_TEXT, /* TTX */ 1584 { 0x0d, KEY_TEXT }, /* TTX */
1475 [ 0x0b ] = KEY_TV, /* AIR/CBL */ 1585 { 0x0b, KEY_TV }, /* AIR/CBL */
1476 [ 0x11 ] = KEY_PC, /* PC/TV */ 1586 { 0x11, KEY_PC }, /* PC/TV */
1477 [ 0x17 ] = KEY_OK, /* CH RTN */ 1587 { 0x17, KEY_OK }, /* CH RTN */
1478 [ 0x19 ] = KEY_MODE, /* FUNC */ 1588 { 0x19, KEY_MODE }, /* FUNC */
1479 [ 0x0c ] = KEY_SEARCH, /* AUTOSCAN */ 1589 { 0x0c, KEY_SEARCH }, /* AUTOSCAN */
1480 1590
1481 /* Not sure what to do with these ones! */ 1591 /* Not sure what to do with these ones! */
1482 [ 0x0f ] = KEY_SELECT, /* SOURCE */ 1592 { 0x0f, KEY_SELECT }, /* SOURCE */
1483 [ 0x0a ] = KEY_KPPLUS, /* +100 */ 1593 { 0x0a, KEY_KPPLUS }, /* +100 */
1484 [ 0x14 ] = KEY_EQUAL, /* SYNC */ 1594 { 0x14, KEY_EQUAL }, /* SYNC */
1485 [ 0x1c ] = KEY_MEDIA, /* PC/TV */ 1595 { 0x1c, KEY_MEDIA }, /* PC/TV */
1486}; 1596};
1487 1597
1488EXPORT_SYMBOL_GPL(ir_codes_pv951); 1598struct ir_scancode_table ir_codes_pv951_table = {
1599 .scan = ir_codes_pv951,
1600 .size = ARRAY_SIZE(ir_codes_pv951),
1601};
1602EXPORT_SYMBOL_GPL(ir_codes_pv951_table);
1489 1603
1490/* generic RC5 keytable */ 1604/* generic RC5 keytable */
1491/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */ 1605/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
1492/* used by old (black) Hauppauge remotes */ 1606/* used by old (black) Hauppauge remotes */
1493IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE] = { 1607static struct ir_scancode ir_codes_rc5_tv[] = {
1494 /* Keys 0 to 9 */ 1608 /* Keys 0 to 9 */
1495 [ 0x00 ] = KEY_0, 1609 { 0x00, KEY_0 },
1496 [ 0x01 ] = KEY_1, 1610 { 0x01, KEY_1 },
1497 [ 0x02 ] = KEY_2, 1611 { 0x02, KEY_2 },
1498 [ 0x03 ] = KEY_3, 1612 { 0x03, KEY_3 },
1499 [ 0x04 ] = KEY_4, 1613 { 0x04, KEY_4 },
1500 [ 0x05 ] = KEY_5, 1614 { 0x05, KEY_5 },
1501 [ 0x06 ] = KEY_6, 1615 { 0x06, KEY_6 },
1502 [ 0x07 ] = KEY_7, 1616 { 0x07, KEY_7 },
1503 [ 0x08 ] = KEY_8, 1617 { 0x08, KEY_8 },
1504 [ 0x09 ] = KEY_9, 1618 { 0x09, KEY_9 },
1505 1619
1506 [ 0x0b ] = KEY_CHANNEL, /* channel / program (japan: 11) */ 1620 { 0x0b, KEY_CHANNEL }, /* channel / program (japan: 11) */
1507 [ 0x0c ] = KEY_POWER, /* standby */ 1621 { 0x0c, KEY_POWER }, /* standby */
1508 [ 0x0d ] = KEY_MUTE, /* mute / demute */ 1622 { 0x0d, KEY_MUTE }, /* mute / demute */
1509 [ 0x0f ] = KEY_TV, /* display */ 1623 { 0x0f, KEY_TV }, /* display */
1510 [ 0x10 ] = KEY_VOLUMEUP, 1624 { 0x10, KEY_VOLUMEUP },
1511 [ 0x11 ] = KEY_VOLUMEDOWN, 1625 { 0x11, KEY_VOLUMEDOWN },
1512 [ 0x12 ] = KEY_BRIGHTNESSUP, 1626 { 0x12, KEY_BRIGHTNESSUP },
1513 [ 0x13 ] = KEY_BRIGHTNESSDOWN, 1627 { 0x13, KEY_BRIGHTNESSDOWN },
1514 [ 0x1e ] = KEY_SEARCH, /* search + */ 1628 { 0x1e, KEY_SEARCH }, /* search + */
1515 [ 0x20 ] = KEY_CHANNELUP, /* channel / program + */ 1629 { 0x20, KEY_CHANNELUP }, /* channel / program + */
1516 [ 0x21 ] = KEY_CHANNELDOWN, /* channel / program - */ 1630 { 0x21, KEY_CHANNELDOWN }, /* channel / program - */
1517 [ 0x22 ] = KEY_CHANNEL, /* alt / channel */ 1631 { 0x22, KEY_CHANNEL }, /* alt / channel */
1518 [ 0x23 ] = KEY_LANGUAGE, /* 1st / 2nd language */ 1632 { 0x23, KEY_LANGUAGE }, /* 1st / 2nd language */
1519 [ 0x26 ] = KEY_SLEEP, /* sleeptimer */ 1633 { 0x26, KEY_SLEEP }, /* sleeptimer */
1520 [ 0x2e ] = KEY_MENU, /* 2nd controls (USA: menu) */ 1634 { 0x2e, KEY_MENU }, /* 2nd controls (USA: menu) */
1521 [ 0x30 ] = KEY_PAUSE, 1635 { 0x30, KEY_PAUSE },
1522 [ 0x32 ] = KEY_REWIND, 1636 { 0x32, KEY_REWIND },
1523 [ 0x33 ] = KEY_GOTO, 1637 { 0x33, KEY_GOTO },
1524 [ 0x35 ] = KEY_PLAY, 1638 { 0x35, KEY_PLAY },
1525 [ 0x36 ] = KEY_STOP, 1639 { 0x36, KEY_STOP },
1526 [ 0x37 ] = KEY_RECORD, /* recording */ 1640 { 0x37, KEY_RECORD }, /* recording */
1527 [ 0x3c ] = KEY_TEXT, /* teletext submode (Japan: 12) */ 1641 { 0x3c, KEY_TEXT }, /* teletext submode (Japan: 12) */
1528 [ 0x3d ] = KEY_SUSPEND, /* system standby */ 1642 { 0x3d, KEY_SUSPEND }, /* system standby */
1529 1643
1530}; 1644};
1531 1645
1532EXPORT_SYMBOL_GPL(ir_codes_rc5_tv); 1646struct ir_scancode_table ir_codes_rc5_tv_table = {
1647 .scan = ir_codes_rc5_tv,
1648 .size = ARRAY_SIZE(ir_codes_rc5_tv),
1649};
1650EXPORT_SYMBOL_GPL(ir_codes_rc5_tv_table);
1533 1651
1534/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */ 1652/* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */
1535IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { 1653static struct ir_scancode ir_codes_winfast[] = {
1536 /* Keys 0 to 9 */ 1654 /* Keys 0 to 9 */
1537 [ 0x12 ] = KEY_0, 1655 { 0x12, KEY_0 },
1538 [ 0x05 ] = KEY_1, 1656 { 0x05, KEY_1 },
1539 [ 0x06 ] = KEY_2, 1657 { 0x06, KEY_2 },
1540 [ 0x07 ] = KEY_3, 1658 { 0x07, KEY_3 },
1541 [ 0x09 ] = KEY_4, 1659 { 0x09, KEY_4 },
1542 [ 0x0a ] = KEY_5, 1660 { 0x0a, KEY_5 },
1543 [ 0x0b ] = KEY_6, 1661 { 0x0b, KEY_6 },
1544 [ 0x0d ] = KEY_7, 1662 { 0x0d, KEY_7 },
1545 [ 0x0e ] = KEY_8, 1663 { 0x0e, KEY_8 },
1546 [ 0x0f ] = KEY_9, 1664 { 0x0f, KEY_9 },
1547 1665
1548 [ 0x00 ] = KEY_POWER, 1666 { 0x00, KEY_POWER },
1549 [ 0x1b ] = KEY_AUDIO, /* Audio Source */ 1667 { 0x1b, KEY_AUDIO }, /* Audio Source */
1550 [ 0x02 ] = KEY_TUNER, /* TV/FM, not on Y0400052 */ 1668 { 0x02, KEY_TUNER }, /* TV/FM, not on Y0400052 */
1551 [ 0x1e ] = KEY_VIDEO, /* Video Source */ 1669 { 0x1e, KEY_VIDEO }, /* Video Source */
1552 [ 0x16 ] = KEY_INFO, /* Display information */ 1670 { 0x16, KEY_INFO }, /* Display information */
1553 [ 0x04 ] = KEY_VOLUMEUP, 1671 { 0x04, KEY_VOLUMEUP },
1554 [ 0x08 ] = KEY_VOLUMEDOWN, 1672 { 0x08, KEY_VOLUMEDOWN },
1555 [ 0x0c ] = KEY_CHANNELUP, 1673 { 0x0c, KEY_CHANNELUP },
1556 [ 0x10 ] = KEY_CHANNELDOWN, 1674 { 0x10, KEY_CHANNELDOWN },
1557 [ 0x03 ] = KEY_ZOOM, /* fullscreen */ 1675 { 0x03, KEY_ZOOM }, /* fullscreen */
1558 [ 0x1f ] = KEY_TEXT, /* closed caption/teletext */ 1676 { 0x1f, KEY_TEXT }, /* closed caption/teletext */
1559 [ 0x20 ] = KEY_SLEEP, 1677 { 0x20, KEY_SLEEP },
1560 [ 0x29 ] = KEY_CLEAR, /* boss key */ 1678 { 0x29, KEY_CLEAR }, /* boss key */
1561 [ 0x14 ] = KEY_MUTE, 1679 { 0x14, KEY_MUTE },
1562 [ 0x2b ] = KEY_RED, 1680 { 0x2b, KEY_RED },
1563 [ 0x2c ] = KEY_GREEN, 1681 { 0x2c, KEY_GREEN },
1564 [ 0x2d ] = KEY_YELLOW, 1682 { 0x2d, KEY_YELLOW },
1565 [ 0x2e ] = KEY_BLUE, 1683 { 0x2e, KEY_BLUE },
1566 [ 0x18 ] = KEY_KPPLUS, /* fine tune + , not on Y040052 */ 1684 { 0x18, KEY_KPPLUS }, /* fine tune + , not on Y040052 */
1567 [ 0x19 ] = KEY_KPMINUS, /* fine tune - , not on Y040052 */ 1685 { 0x19, KEY_KPMINUS }, /* fine tune - , not on Y040052 */
1568 [ 0x2a ] = KEY_MEDIA, /* PIP (Picture in picture */ 1686 { 0x2a, KEY_MEDIA }, /* PIP (Picture in picture */
1569 [ 0x21 ] = KEY_DOT, 1687 { 0x21, KEY_DOT },
1570 [ 0x13 ] = KEY_ENTER, 1688 { 0x13, KEY_ENTER },
1571 [ 0x11 ] = KEY_LAST, /* Recall (last channel */ 1689 { 0x11, KEY_LAST }, /* Recall (last channel */
1572 [ 0x22 ] = KEY_PREVIOUS, 1690 { 0x22, KEY_PREVIOUS },
1573 [ 0x23 ] = KEY_PLAYPAUSE, 1691 { 0x23, KEY_PLAYPAUSE },
1574 [ 0x24 ] = KEY_NEXT, 1692 { 0x24, KEY_NEXT },
1575 [ 0x25 ] = KEY_ARCHIVE, /* Time Shifting */ 1693 { 0x25, KEY_TIME }, /* Time Shifting */
1576 [ 0x26 ] = KEY_STOP, 1694 { 0x26, KEY_STOP },
1577 [ 0x27 ] = KEY_RECORD, 1695 { 0x27, KEY_RECORD },
1578 [ 0x28 ] = KEY_SAVE, /* Screenshot */ 1696 { 0x28, KEY_SAVE }, /* Screenshot */
1579 [ 0x2f ] = KEY_MENU, 1697 { 0x2f, KEY_MENU },
1580 [ 0x30 ] = KEY_CANCEL, 1698 { 0x30, KEY_CANCEL },
1581 [ 0x31 ] = KEY_CHANNEL, /* Channel Surf */ 1699 { 0x31, KEY_CHANNEL }, /* Channel Surf */
1582 [ 0x32 ] = KEY_SUBTITLE, 1700 { 0x32, KEY_SUBTITLE },
1583 [ 0x33 ] = KEY_LANGUAGE, 1701 { 0x33, KEY_LANGUAGE },
1584 [ 0x34 ] = KEY_REWIND, 1702 { 0x34, KEY_REWIND },
1585 [ 0x35 ] = KEY_FASTFORWARD, 1703 { 0x35, KEY_FASTFORWARD },
1586 [ 0x36 ] = KEY_TV, 1704 { 0x36, KEY_TV },
1587 [ 0x37 ] = KEY_RADIO, /* FM */ 1705 { 0x37, KEY_RADIO }, /* FM */
1588 [ 0x38 ] = KEY_DVD, 1706 { 0x38, KEY_DVD },
1589 1707
1590 [ 0x3e ] = KEY_F21, /* MCE +VOL, on Y04G0033 */ 1708 { 0x3e, KEY_F21 }, /* MCE +VOL, on Y04G0033 */
1591 [ 0x3a ] = KEY_F22, /* MCE -VOL, on Y04G0033 */ 1709 { 0x3a, KEY_F22 }, /* MCE -VOL, on Y04G0033 */
1592 [ 0x3b ] = KEY_F23, /* MCE +CH, on Y04G0033 */ 1710 { 0x3b, KEY_F23 }, /* MCE +CH, on Y04G0033 */
1593 [ 0x3f ] = KEY_F24 /* MCE -CH, on Y04G0033 */ 1711 { 0x3f, KEY_F24 } /* MCE -CH, on Y04G0033 */
1594}; 1712};
1595 1713
1596EXPORT_SYMBOL_GPL(ir_codes_winfast); 1714struct ir_scancode_table ir_codes_winfast_table = {
1597 1715 .scan = ir_codes_winfast,
1598IR_KEYTAB_TYPE ir_codes_pinnacle_color[IR_KEYTAB_SIZE] = { 1716 .size = ARRAY_SIZE(ir_codes_winfast),
1599 [ 0x59 ] = KEY_MUTE, 1717};
1600 [ 0x4a ] = KEY_POWER, 1718EXPORT_SYMBOL_GPL(ir_codes_winfast_table);
1601 1719
1602 [ 0x18 ] = KEY_TEXT, 1720static struct ir_scancode ir_codes_pinnacle_color[] = {
1603 [ 0x26 ] = KEY_TV, 1721 { 0x59, KEY_MUTE },
1604 [ 0x3d ] = KEY_PRINT, 1722 { 0x4a, KEY_POWER },
1605 1723
1606 [ 0x48 ] = KEY_RED, 1724 { 0x18, KEY_TEXT },
1607 [ 0x04 ] = KEY_GREEN, 1725 { 0x26, KEY_TV },
1608 [ 0x11 ] = KEY_YELLOW, 1726 { 0x3d, KEY_PRINT },
1609 [ 0x00 ] = KEY_BLUE, 1727
1610 1728 { 0x48, KEY_RED },
1611 [ 0x2d ] = KEY_VOLUMEUP, 1729 { 0x04, KEY_GREEN },
1612 [ 0x1e ] = KEY_VOLUMEDOWN, 1730 { 0x11, KEY_YELLOW },
1613 1731 { 0x00, KEY_BLUE },
1614 [ 0x49 ] = KEY_MENU, 1732
1615 1733 { 0x2d, KEY_VOLUMEUP },
1616 [ 0x16 ] = KEY_CHANNELUP, 1734 { 0x1e, KEY_VOLUMEDOWN },
1617 [ 0x17 ] = KEY_CHANNELDOWN, 1735
1618 1736 { 0x49, KEY_MENU },
1619 [ 0x20 ] = KEY_UP, 1737
1620 [ 0x21 ] = KEY_DOWN, 1738 { 0x16, KEY_CHANNELUP },
1621 [ 0x22 ] = KEY_LEFT, 1739 { 0x17, KEY_CHANNELDOWN },
1622 [ 0x23 ] = KEY_RIGHT, 1740
1623 [ 0x0d ] = KEY_SELECT, 1741 { 0x20, KEY_UP },
1624 1742 { 0x21, KEY_DOWN },
1625 1743 { 0x22, KEY_LEFT },
1626 1744 { 0x23, KEY_RIGHT },
1627 [ 0x08 ] = KEY_BACK, 1745 { 0x0d, KEY_SELECT },
1628 [ 0x07 ] = KEY_REFRESH, 1746
1629 1747 { 0x08, KEY_BACK },
1630 [ 0x2f ] = KEY_ZOOM, 1748 { 0x07, KEY_REFRESH },
1631 [ 0x29 ] = KEY_RECORD, 1749
1632 1750 { 0x2f, KEY_ZOOM },
1633 [ 0x4b ] = KEY_PAUSE, 1751 { 0x29, KEY_RECORD },
1634 [ 0x4d ] = KEY_REWIND, 1752
1635 [ 0x2e ] = KEY_PLAY, 1753 { 0x4b, KEY_PAUSE },
1636 [ 0x4e ] = KEY_FORWARD, 1754 { 0x4d, KEY_REWIND },
1637 [ 0x53 ] = KEY_PREVIOUS, 1755 { 0x2e, KEY_PLAY },
1638 [ 0x4c ] = KEY_STOP, 1756 { 0x4e, KEY_FORWARD },
1639 [ 0x54 ] = KEY_NEXT, 1757 { 0x53, KEY_PREVIOUS },
1640 1758 { 0x4c, KEY_STOP },
1641 [ 0x69 ] = KEY_0, 1759 { 0x54, KEY_NEXT },
1642 [ 0x6a ] = KEY_1, 1760
1643 [ 0x6b ] = KEY_2, 1761 { 0x69, KEY_0 },
1644 [ 0x6c ] = KEY_3, 1762 { 0x6a, KEY_1 },
1645 [ 0x6d ] = KEY_4, 1763 { 0x6b, KEY_2 },
1646 [ 0x6e ] = KEY_5, 1764 { 0x6c, KEY_3 },
1647 [ 0x6f ] = KEY_6, 1765 { 0x6d, KEY_4 },
1648 [ 0x70 ] = KEY_7, 1766 { 0x6e, KEY_5 },
1649 [ 0x71 ] = KEY_8, 1767 { 0x6f, KEY_6 },
1650 [ 0x72 ] = KEY_9, 1768 { 0x70, KEY_7 },
1651 1769 { 0x71, KEY_8 },
1652 [ 0x74 ] = KEY_CHANNEL, 1770 { 0x72, KEY_9 },
1653 [ 0x0a ] = KEY_BACKSPACE, 1771
1654}; 1772 { 0x74, KEY_CHANNEL },
1655 1773 { 0x0a, KEY_BACKSPACE },
1656EXPORT_SYMBOL_GPL(ir_codes_pinnacle_color); 1774};
1775
1776struct ir_scancode_table ir_codes_pinnacle_color_table = {
1777 .scan = ir_codes_pinnacle_color,
1778 .size = ARRAY_SIZE(ir_codes_pinnacle_color),
1779};
1780EXPORT_SYMBOL_GPL(ir_codes_pinnacle_color_table);
1657 1781
1658/* Hauppauge: the newer, gray remotes (seems there are multiple 1782/* Hauppauge: the newer, gray remotes (seems there are multiple
1659 * slightly different versions), shipped with cx88+ivtv cards. 1783 * slightly different versions), shipped with cx88+ivtv cards.
1660 * almost rc5 coding, but some non-standard keys */ 1784 * almost rc5 coding, but some non-standard keys */
1661IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = { 1785static struct ir_scancode ir_codes_hauppauge_new[] = {
1662 /* Keys 0 to 9 */ 1786 /* Keys 0 to 9 */
1663 [ 0x00 ] = KEY_0, 1787 { 0x00, KEY_0 },
1664 [ 0x01 ] = KEY_1, 1788 { 0x01, KEY_1 },
1665 [ 0x02 ] = KEY_2, 1789 { 0x02, KEY_2 },
1666 [ 0x03 ] = KEY_3, 1790 { 0x03, KEY_3 },
1667 [ 0x04 ] = KEY_4, 1791 { 0x04, KEY_4 },
1668 [ 0x05 ] = KEY_5, 1792 { 0x05, KEY_5 },
1669 [ 0x06 ] = KEY_6, 1793 { 0x06, KEY_6 },
1670 [ 0x07 ] = KEY_7, 1794 { 0x07, KEY_7 },
1671 [ 0x08 ] = KEY_8, 1795 { 0x08, KEY_8 },
1672 [ 0x09 ] = KEY_9, 1796 { 0x09, KEY_9 },
1673 1797
1674 [ 0x0a ] = KEY_TEXT, /* keypad asterisk as well */ 1798 { 0x0a, KEY_TEXT }, /* keypad asterisk as well */
1675 [ 0x0b ] = KEY_RED, /* red button */ 1799 { 0x0b, KEY_RED }, /* red button */
1676 [ 0x0c ] = KEY_RADIO, 1800 { 0x0c, KEY_RADIO },
1677 [ 0x0d ] = KEY_MENU, 1801 { 0x0d, KEY_MENU },
1678 [ 0x0e ] = KEY_SUBTITLE, /* also the # key */ 1802 { 0x0e, KEY_SUBTITLE }, /* also the # key */
1679 [ 0x0f ] = KEY_MUTE, 1803 { 0x0f, KEY_MUTE },
1680 [ 0x10 ] = KEY_VOLUMEUP, 1804 { 0x10, KEY_VOLUMEUP },
1681 [ 0x11 ] = KEY_VOLUMEDOWN, 1805 { 0x11, KEY_VOLUMEDOWN },
1682 [ 0x12 ] = KEY_PREVIOUS, /* previous channel */ 1806 { 0x12, KEY_PREVIOUS }, /* previous channel */
1683 [ 0x14 ] = KEY_UP, 1807 { 0x14, KEY_UP },
1684 [ 0x15 ] = KEY_DOWN, 1808 { 0x15, KEY_DOWN },
1685 [ 0x16 ] = KEY_LEFT, 1809 { 0x16, KEY_LEFT },
1686 [ 0x17 ] = KEY_RIGHT, 1810 { 0x17, KEY_RIGHT },
1687 [ 0x18 ] = KEY_VIDEO, /* Videos */ 1811 { 0x18, KEY_VIDEO }, /* Videos */
1688 [ 0x19 ] = KEY_AUDIO, /* Music */ 1812 { 0x19, KEY_AUDIO }, /* Music */
1689 /* 0x1a: Pictures - presume this means 1813 /* 0x1a: Pictures - presume this means
1690 "Multimedia Home Platform" - 1814 "Multimedia Home Platform" -
1691 no "PICTURES" key in input.h 1815 no "PICTURES" key in input.h
1692 */ 1816 */
1693 [ 0x1a ] = KEY_MHP, 1817 { 0x1a, KEY_MHP },
1694 1818
1695 [ 0x1b ] = KEY_EPG, /* Guide */ 1819 { 0x1b, KEY_EPG }, /* Guide */
1696 [ 0x1c ] = KEY_TV, 1820 { 0x1c, KEY_TV },
1697 [ 0x1e ] = KEY_NEXTSONG, /* skip >| */ 1821 { 0x1e, KEY_NEXTSONG }, /* skip >| */
1698 [ 0x1f ] = KEY_EXIT, /* back/exit */ 1822 { 0x1f, KEY_EXIT }, /* back/exit */
1699 [ 0x20 ] = KEY_CHANNELUP, /* channel / program + */ 1823 { 0x20, KEY_CHANNELUP }, /* channel / program + */
1700 [ 0x21 ] = KEY_CHANNELDOWN, /* channel / program - */ 1824 { 0x21, KEY_CHANNELDOWN }, /* channel / program - */
1701 [ 0x22 ] = KEY_CHANNEL, /* source (old black remote) */ 1825 { 0x22, KEY_CHANNEL }, /* source (old black remote) */
1702 [ 0x24 ] = KEY_PREVIOUSSONG, /* replay |< */ 1826 { 0x24, KEY_PREVIOUSSONG }, /* replay |< */
1703 [ 0x25 ] = KEY_ENTER, /* OK */ 1827 { 0x25, KEY_ENTER }, /* OK */
1704 [ 0x26 ] = KEY_SLEEP, /* minimize (old black remote) */ 1828 { 0x26, KEY_SLEEP }, /* minimize (old black remote) */
1705 [ 0x29 ] = KEY_BLUE, /* blue key */ 1829 { 0x29, KEY_BLUE }, /* blue key */
1706 [ 0x2e ] = KEY_GREEN, /* green button */ 1830 { 0x2e, KEY_GREEN }, /* green button */
1707 [ 0x30 ] = KEY_PAUSE, /* pause */ 1831 { 0x30, KEY_PAUSE }, /* pause */
1708 [ 0x32 ] = KEY_REWIND, /* backward << */ 1832 { 0x32, KEY_REWIND }, /* backward << */
1709 [ 0x34 ] = KEY_FASTFORWARD, /* forward >> */ 1833 { 0x34, KEY_FASTFORWARD }, /* forward >> */
1710 [ 0x35 ] = KEY_PLAY, 1834 { 0x35, KEY_PLAY },
1711 [ 0x36 ] = KEY_STOP, 1835 { 0x36, KEY_STOP },
1712 [ 0x37 ] = KEY_RECORD, /* recording */ 1836 { 0x37, KEY_RECORD }, /* recording */
1713 [ 0x38 ] = KEY_YELLOW, /* yellow key */ 1837 { 0x38, KEY_YELLOW }, /* yellow key */
1714 [ 0x3b ] = KEY_SELECT, /* top right button */ 1838 { 0x3b, KEY_SELECT }, /* top right button */
1715 [ 0x3c ] = KEY_ZOOM, /* full */ 1839 { 0x3c, KEY_ZOOM }, /* full */
1716 [ 0x3d ] = KEY_POWER, /* system power (green button) */ 1840 { 0x3d, KEY_POWER }, /* system power (green button) */
1717}; 1841};
1718 1842
1719EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new); 1843struct ir_scancode_table ir_codes_hauppauge_new_table = {
1720 1844 .scan = ir_codes_hauppauge_new,
1721IR_KEYTAB_TYPE ir_codes_npgtech[IR_KEYTAB_SIZE] = { 1845 .size = ARRAY_SIZE(ir_codes_hauppauge_new),
1722 [ 0x1d ] = KEY_SWITCHVIDEOMODE, /* switch inputs */ 1846};
1723 [ 0x2a ] = KEY_FRONT, 1847EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table);
1724 1848
1725 [ 0x3e ] = KEY_1, 1849static struct ir_scancode ir_codes_npgtech[] = {
1726 [ 0x02 ] = KEY_2, 1850 { 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */
1727 [ 0x06 ] = KEY_3, 1851 { 0x2a, KEY_FRONT },
1728 [ 0x0a ] = KEY_4, 1852
1729 [ 0x0e ] = KEY_5, 1853 { 0x3e, KEY_1 },
1730 [ 0x12 ] = KEY_6, 1854 { 0x02, KEY_2 },
1731 [ 0x16 ] = KEY_7, 1855 { 0x06, KEY_3 },
1732 [ 0x1a ] = KEY_8, 1856 { 0x0a, KEY_4 },
1733 [ 0x1e ] = KEY_9, 1857 { 0x0e, KEY_5 },
1734 [ 0x3a ] = KEY_0, 1858 { 0x12, KEY_6 },
1735 [ 0x22 ] = KEY_NUMLOCK, /* -/-- */ 1859 { 0x16, KEY_7 },
1736 [ 0x20 ] = KEY_REFRESH, 1860 { 0x1a, KEY_8 },
1737 1861 { 0x1e, KEY_9 },
1738 [ 0x03 ] = KEY_BRIGHTNESSDOWN, 1862 { 0x3a, KEY_0 },
1739 [ 0x28 ] = KEY_AUDIO, 1863 { 0x22, KEY_NUMLOCK }, /* -/-- */
1740 [ 0x3c ] = KEY_UP, 1864 { 0x20, KEY_REFRESH },
1741 [ 0x3f ] = KEY_LEFT, 1865
1742 [ 0x2e ] = KEY_MUTE, 1866 { 0x03, KEY_BRIGHTNESSDOWN },
1743 [ 0x3b ] = KEY_RIGHT, 1867 { 0x28, KEY_AUDIO },
1744 [ 0x00 ] = KEY_DOWN, 1868 { 0x3c, KEY_CHANNELUP },
1745 [ 0x07 ] = KEY_BRIGHTNESSUP, 1869 { 0x3f, KEY_VOLUMEDOWN },
1746 [ 0x2c ] = KEY_TEXT, 1870 { 0x2e, KEY_MUTE },
1747 1871 { 0x3b, KEY_VOLUMEUP },
1748 [ 0x37 ] = KEY_RECORD, 1872 { 0x00, KEY_CHANNELDOWN },
1749 [ 0x17 ] = KEY_PLAY, 1873 { 0x07, KEY_BRIGHTNESSUP },
1750 [ 0x13 ] = KEY_PAUSE, 1874 { 0x2c, KEY_TEXT },
1751 [ 0x26 ] = KEY_STOP, 1875
1752 [ 0x18 ] = KEY_FASTFORWARD, 1876 { 0x37, KEY_RECORD },
1753 [ 0x14 ] = KEY_REWIND, 1877 { 0x17, KEY_PLAY },
1754 [ 0x33 ] = KEY_ZOOM, 1878 { 0x13, KEY_PAUSE },
1755 [ 0x32 ] = KEY_KEYBOARD, 1879 { 0x26, KEY_STOP },
1756 [ 0x30 ] = KEY_GOTO, /* Pointing arrow */ 1880 { 0x18, KEY_FASTFORWARD },
1757 [ 0x36 ] = KEY_MACRO, /* Maximize/Minimize (yellow) */ 1881 { 0x14, KEY_REWIND },
1758 [ 0x0b ] = KEY_RADIO, 1882 { 0x33, KEY_ZOOM },
1759 [ 0x10 ] = KEY_POWER, 1883 { 0x32, KEY_KEYBOARD },
1760 1884 { 0x30, KEY_GOTO }, /* Pointing arrow */
1761}; 1885 { 0x36, KEY_MACRO }, /* Maximize/Minimize (yellow) */
1762 1886 { 0x0b, KEY_RADIO },
1763EXPORT_SYMBOL_GPL(ir_codes_npgtech); 1887 { 0x10, KEY_POWER },
1888
1889};
1890
1891struct ir_scancode_table ir_codes_npgtech_table = {
1892 .scan = ir_codes_npgtech,
1893 .size = ARRAY_SIZE(ir_codes_npgtech),
1894};
1895EXPORT_SYMBOL_GPL(ir_codes_npgtech_table);
1764 1896
1765/* Norwood Micro (non-Pro) TV Tuner 1897/* Norwood Micro (non-Pro) TV Tuner
1766 By Peter Naulls <peter@chocky.org> 1898 By Peter Naulls <peter@chocky.org>
1767 Key comments are the functions given in the manual */ 1899 Key comments are the functions given in the manual */
1768IR_KEYTAB_TYPE ir_codes_norwood[IR_KEYTAB_SIZE] = { 1900static struct ir_scancode ir_codes_norwood[] = {
1769 /* Keys 0 to 9 */ 1901 /* Keys 0 to 9 */
1770 [ 0x20 ] = KEY_0, 1902 { 0x20, KEY_0 },
1771 [ 0x21 ] = KEY_1, 1903 { 0x21, KEY_1 },
1772 [ 0x22 ] = KEY_2, 1904 { 0x22, KEY_2 },
1773 [ 0x23 ] = KEY_3, 1905 { 0x23, KEY_3 },
1774 [ 0x24 ] = KEY_4, 1906 { 0x24, KEY_4 },
1775 [ 0x25 ] = KEY_5, 1907 { 0x25, KEY_5 },
1776 [ 0x26 ] = KEY_6, 1908 { 0x26, KEY_6 },
1777 [ 0x27 ] = KEY_7, 1909 { 0x27, KEY_7 },
1778 [ 0x28 ] = KEY_8, 1910 { 0x28, KEY_8 },
1779 [ 0x29 ] = KEY_9, 1911 { 0x29, KEY_9 },
1780 1912
1781 [ 0x78 ] = KEY_TUNER, /* Video Source */ 1913 { 0x78, KEY_TUNER }, /* Video Source */
1782 [ 0x2c ] = KEY_EXIT, /* Open/Close software */ 1914 { 0x2c, KEY_EXIT }, /* Open/Close software */
1783 [ 0x2a ] = KEY_SELECT, /* 2 Digit Select */ 1915 { 0x2a, KEY_SELECT }, /* 2 Digit Select */
1784 [ 0x69 ] = KEY_AGAIN, /* Recall */ 1916 { 0x69, KEY_AGAIN }, /* Recall */
1785 1917
1786 [ 0x32 ] = KEY_BRIGHTNESSUP, /* Brightness increase */ 1918 { 0x32, KEY_BRIGHTNESSUP }, /* Brightness increase */
1787 [ 0x33 ] = KEY_BRIGHTNESSDOWN, /* Brightness decrease */ 1919 { 0x33, KEY_BRIGHTNESSDOWN }, /* Brightness decrease */
1788 [ 0x6b ] = KEY_KPPLUS, /* (not named >>>>>) */ 1920 { 0x6b, KEY_KPPLUS }, /* (not named >>>>>) */
1789 [ 0x6c ] = KEY_KPMINUS, /* (not named <<<<<) */ 1921 { 0x6c, KEY_KPMINUS }, /* (not named <<<<<) */
1790 1922
1791 [ 0x2d ] = KEY_MUTE, /* Mute */ 1923 { 0x2d, KEY_MUTE }, /* Mute */
1792 [ 0x30 ] = KEY_VOLUMEUP, /* Volume up */ 1924 { 0x30, KEY_VOLUMEUP }, /* Volume up */
1793 [ 0x31 ] = KEY_VOLUMEDOWN, /* Volume down */ 1925 { 0x31, KEY_VOLUMEDOWN }, /* Volume down */
1794 [ 0x60 ] = KEY_CHANNELUP, /* Channel up */ 1926 { 0x60, KEY_CHANNELUP }, /* Channel up */
1795 [ 0x61 ] = KEY_CHANNELDOWN, /* Channel down */ 1927 { 0x61, KEY_CHANNELDOWN }, /* Channel down */
1796 1928
1797 [ 0x3f ] = KEY_RECORD, /* Record */ 1929 { 0x3f, KEY_RECORD }, /* Record */
1798 [ 0x37 ] = KEY_PLAY, /* Play */ 1930 { 0x37, KEY_PLAY }, /* Play */
1799 [ 0x36 ] = KEY_PAUSE, /* Pause */ 1931 { 0x36, KEY_PAUSE }, /* Pause */
1800 [ 0x2b ] = KEY_STOP, /* Stop */ 1932 { 0x2b, KEY_STOP }, /* Stop */
1801 [ 0x67 ] = KEY_FASTFORWARD, /* Foward */ 1933 { 0x67, KEY_FASTFORWARD }, /* Foward */
1802 [ 0x66 ] = KEY_REWIND, /* Rewind */ 1934 { 0x66, KEY_REWIND }, /* Rewind */
1803 [ 0x3e ] = KEY_SEARCH, /* Auto Scan */ 1935 { 0x3e, KEY_SEARCH }, /* Auto Scan */
1804 [ 0x2e ] = KEY_CAMERA, /* Capture Video */ 1936 { 0x2e, KEY_CAMERA }, /* Capture Video */
1805 [ 0x6d ] = KEY_MENU, /* Show/Hide Control */ 1937 { 0x6d, KEY_MENU }, /* Show/Hide Control */
1806 [ 0x2f ] = KEY_ZOOM, /* Full Screen */ 1938 { 0x2f, KEY_ZOOM }, /* Full Screen */
1807 [ 0x34 ] = KEY_RADIO, /* FM */ 1939 { 0x34, KEY_RADIO }, /* FM */
1808 [ 0x65 ] = KEY_POWER, /* Computer power */ 1940 { 0x65, KEY_POWER }, /* Computer power */
1809}; 1941};
1810 1942
1811EXPORT_SYMBOL_GPL(ir_codes_norwood); 1943struct ir_scancode_table ir_codes_norwood_table = {
1944 .scan = ir_codes_norwood,
1945 .size = ARRAY_SIZE(ir_codes_norwood),
1946};
1947EXPORT_SYMBOL_GPL(ir_codes_norwood_table);
1812 1948
1813/* From reading the following remotes: 1949/* From reading the following remotes:
1814 * Zenith Universal 7 / TV Mode 807 / VCR Mode 837 1950 * Zenith Universal 7 / TV Mode 807 / VCR Mode 837
1815 * Hauppauge (from NOVA-CI-s box product) 1951 * Hauppauge (from NOVA-CI-s box product)
1816 * This is a "middle of the road" approach, differences are noted 1952 * This is a "middle of the road" approach, differences are noted
1817 */ 1953 */
1818IR_KEYTAB_TYPE ir_codes_budget_ci_old[IR_KEYTAB_SIZE] = { 1954static struct ir_scancode ir_codes_budget_ci_old[] = {
1819 [ 0x00 ] = KEY_0, 1955 { 0x00, KEY_0 },
1820 [ 0x01 ] = KEY_1, 1956 { 0x01, KEY_1 },
1821 [ 0x02 ] = KEY_2, 1957 { 0x02, KEY_2 },
1822 [ 0x03 ] = KEY_3, 1958 { 0x03, KEY_3 },
1823 [ 0x04 ] = KEY_4, 1959 { 0x04, KEY_4 },
1824 [ 0x05 ] = KEY_5, 1960 { 0x05, KEY_5 },
1825 [ 0x06 ] = KEY_6, 1961 { 0x06, KEY_6 },
1826 [ 0x07 ] = KEY_7, 1962 { 0x07, KEY_7 },
1827 [ 0x08 ] = KEY_8, 1963 { 0x08, KEY_8 },
1828 [ 0x09 ] = KEY_9, 1964 { 0x09, KEY_9 },
1829 [ 0x0a ] = KEY_ENTER, 1965 { 0x0a, KEY_ENTER },
1830 [ 0x0b ] = KEY_RED, 1966 { 0x0b, KEY_RED },
1831 [ 0x0c ] = KEY_POWER, /* RADIO on Hauppauge */ 1967 { 0x0c, KEY_POWER }, /* RADIO on Hauppauge */
1832 [ 0x0d ] = KEY_MUTE, 1968 { 0x0d, KEY_MUTE },
1833 [ 0x0f ] = KEY_A, /* TV on Hauppauge */ 1969 { 0x0f, KEY_A }, /* TV on Hauppauge */
1834 [ 0x10 ] = KEY_VOLUMEUP, 1970 { 0x10, KEY_VOLUMEUP },
1835 [ 0x11 ] = KEY_VOLUMEDOWN, 1971 { 0x11, KEY_VOLUMEDOWN },
1836 [ 0x14 ] = KEY_B, 1972 { 0x14, KEY_B },
1837 [ 0x1c ] = KEY_UP, 1973 { 0x1c, KEY_UP },
1838 [ 0x1d ] = KEY_DOWN, 1974 { 0x1d, KEY_DOWN },
1839 [ 0x1e ] = KEY_OPTION, /* RESERVED on Hauppauge */ 1975 { 0x1e, KEY_OPTION }, /* RESERVED on Hauppauge */
1840 [ 0x1f ] = KEY_BREAK, 1976 { 0x1f, KEY_BREAK },
1841 [ 0x20 ] = KEY_CHANNELUP, 1977 { 0x20, KEY_CHANNELUP },
1842 [ 0x21 ] = KEY_CHANNELDOWN, 1978 { 0x21, KEY_CHANNELDOWN },
1843 [ 0x22 ] = KEY_PREVIOUS, /* Prev. Ch on Zenith, SOURCE on Hauppauge */ 1979 { 0x22, KEY_PREVIOUS }, /* Prev Ch on Zenith, SOURCE on Hauppauge */
1844 [ 0x24 ] = KEY_RESTART, 1980 { 0x24, KEY_RESTART },
1845 [ 0x25 ] = KEY_OK, 1981 { 0x25, KEY_OK },
1846 [ 0x26 ] = KEY_CYCLEWINDOWS, /* MINIMIZE on Hauppauge */ 1982 { 0x26, KEY_CYCLEWINDOWS }, /* MINIMIZE on Hauppauge */
1847 [ 0x28 ] = KEY_ENTER, /* VCR mode on Zenith */ 1983 { 0x28, KEY_ENTER }, /* VCR mode on Zenith */
1848 [ 0x29 ] = KEY_PAUSE, 1984 { 0x29, KEY_PAUSE },
1849 [ 0x2b ] = KEY_RIGHT, 1985 { 0x2b, KEY_RIGHT },
1850 [ 0x2c ] = KEY_LEFT, 1986 { 0x2c, KEY_LEFT },
1851 [ 0x2e ] = KEY_MENU, /* FULL SCREEN on Hauppauge */ 1987 { 0x2e, KEY_MENU }, /* FULL SCREEN on Hauppauge */
1852 [ 0x30 ] = KEY_SLOW, 1988 { 0x30, KEY_SLOW },
1853 [ 0x31 ] = KEY_PREVIOUS, /* VCR mode on Zenith */ 1989 { 0x31, KEY_PREVIOUS }, /* VCR mode on Zenith */
1854 [ 0x32 ] = KEY_REWIND, 1990 { 0x32, KEY_REWIND },
1855 [ 0x34 ] = KEY_FASTFORWARD, 1991 { 0x34, KEY_FASTFORWARD },
1856 [ 0x35 ] = KEY_PLAY, 1992 { 0x35, KEY_PLAY },
1857 [ 0x36 ] = KEY_STOP, 1993 { 0x36, KEY_STOP },
1858 [ 0x37 ] = KEY_RECORD, 1994 { 0x37, KEY_RECORD },
1859 [ 0x38 ] = KEY_TUNER, /* TV/VCR on Zenith */ 1995 { 0x38, KEY_TUNER }, /* TV/VCR on Zenith */
1860 [ 0x3a ] = KEY_C, 1996 { 0x3a, KEY_C },
1861 [ 0x3c ] = KEY_EXIT, 1997 { 0x3c, KEY_EXIT },
1862 [ 0x3d ] = KEY_POWER2, 1998 { 0x3d, KEY_POWER2 },
1863 [ 0x3e ] = KEY_TUNER, 1999 { 0x3e, KEY_TUNER },
1864}; 2000};
1865 2001
1866EXPORT_SYMBOL_GPL(ir_codes_budget_ci_old); 2002struct ir_scancode_table ir_codes_budget_ci_old_table = {
2003 .scan = ir_codes_budget_ci_old,
2004 .size = ARRAY_SIZE(ir_codes_budget_ci_old),
2005};
2006EXPORT_SYMBOL_GPL(ir_codes_budget_ci_old_table);
1867 2007
1868/* 2008/*
1869 * Marc Fargas <telenieko@telenieko.com> 2009 * Marc Fargas <telenieko@telenieko.com>
1870 * this is the remote control that comes with the asus p7131 2010 * this is the remote control that comes with the asus p7131
1871 * which has a label saying is "Model PC-39" 2011 * which has a label saying is "Model PC-39"
1872 */ 2012 */
1873IR_KEYTAB_TYPE ir_codes_asus_pc39[IR_KEYTAB_SIZE] = { 2013static struct ir_scancode ir_codes_asus_pc39[] = {
1874 /* Keys 0 to 9 */ 2014 /* Keys 0 to 9 */
1875 [ 0x15 ] = KEY_0, 2015 { 0x15, KEY_0 },
1876 [ 0x29 ] = KEY_1, 2016 { 0x29, KEY_1 },
1877 [ 0x2d ] = KEY_2, 2017 { 0x2d, KEY_2 },
1878 [ 0x2b ] = KEY_3, 2018 { 0x2b, KEY_3 },
1879 [ 0x09 ] = KEY_4, 2019 { 0x09, KEY_4 },
1880 [ 0x0d ] = KEY_5, 2020 { 0x0d, KEY_5 },
1881 [ 0x0b ] = KEY_6, 2021 { 0x0b, KEY_6 },
1882 [ 0x31 ] = KEY_7, 2022 { 0x31, KEY_7 },
1883 [ 0x35 ] = KEY_8, 2023 { 0x35, KEY_8 },
1884 [ 0x33 ] = KEY_9, 2024 { 0x33, KEY_9 },
1885 2025
1886 [ 0x3e ] = KEY_RADIO, /* radio */ 2026 { 0x3e, KEY_RADIO }, /* radio */
1887 [ 0x03 ] = KEY_MENU, /* dvd/menu */ 2027 { 0x03, KEY_MENU }, /* dvd/menu */
1888 [ 0x2a ] = KEY_VOLUMEUP, 2028 { 0x2a, KEY_VOLUMEUP },
1889 [ 0x19 ] = KEY_VOLUMEDOWN, 2029 { 0x19, KEY_VOLUMEDOWN },
1890 [ 0x37 ] = KEY_UP, 2030 { 0x37, KEY_UP },
1891 [ 0x3b ] = KEY_DOWN, 2031 { 0x3b, KEY_DOWN },
1892 [ 0x27 ] = KEY_LEFT, 2032 { 0x27, KEY_LEFT },
1893 [ 0x2f ] = KEY_RIGHT, 2033 { 0x2f, KEY_RIGHT },
1894 [ 0x25 ] = KEY_VIDEO, /* video */ 2034 { 0x25, KEY_VIDEO }, /* video */
1895 [ 0x39 ] = KEY_AUDIO, /* music */ 2035 { 0x39, KEY_AUDIO }, /* music */
1896 2036
1897 [ 0x21 ] = KEY_TV, /* tv */ 2037 { 0x21, KEY_TV }, /* tv */
1898 [ 0x1d ] = KEY_EXIT, /* back */ 2038 { 0x1d, KEY_EXIT }, /* back */
1899 [ 0x0a ] = KEY_CHANNELUP, /* channel / program + */ 2039 { 0x0a, KEY_CHANNELUP }, /* channel / program + */
1900 [ 0x1b ] = KEY_CHANNELDOWN, /* channel / program - */ 2040 { 0x1b, KEY_CHANNELDOWN }, /* channel / program - */
1901 [ 0x1a ] = KEY_ENTER, /* enter */ 2041 { 0x1a, KEY_ENTER }, /* enter */
1902 2042
1903 [ 0x06 ] = KEY_PAUSE, /* play/pause */ 2043 { 0x06, KEY_PAUSE }, /* play/pause */
1904 [ 0x1e ] = KEY_PREVIOUS, /* rew */ 2044 { 0x1e, KEY_PREVIOUS }, /* rew */
1905 [ 0x26 ] = KEY_NEXT, /* forward */ 2045 { 0x26, KEY_NEXT }, /* forward */
1906 [ 0x0e ] = KEY_REWIND, /* backward << */ 2046 { 0x0e, KEY_REWIND }, /* backward << */
1907 [ 0x3a ] = KEY_FASTFORWARD, /* forward >> */ 2047 { 0x3a, KEY_FASTFORWARD }, /* forward >> */
1908 [ 0x36 ] = KEY_STOP, 2048 { 0x36, KEY_STOP },
1909 [ 0x2e ] = KEY_RECORD, /* recording */ 2049 { 0x2e, KEY_RECORD }, /* recording */
1910 [ 0x16 ] = KEY_POWER, /* the button that reads "close" */ 2050 { 0x16, KEY_POWER }, /* the button that reads "close" */
1911 2051
1912 [ 0x11 ] = KEY_ZOOM, /* full screen */ 2052 { 0x11, KEY_ZOOM }, /* full screen */
1913 [ 0x13 ] = KEY_MACRO, /* recall */ 2053 { 0x13, KEY_MACRO }, /* recall */
1914 [ 0x23 ] = KEY_HOME, /* home */ 2054 { 0x23, KEY_HOME }, /* home */
1915 [ 0x05 ] = KEY_PVR, /* picture */ 2055 { 0x05, KEY_PVR }, /* picture */
1916 [ 0x3d ] = KEY_MUTE, /* mute */ 2056 { 0x3d, KEY_MUTE }, /* mute */
1917 [ 0x01 ] = KEY_DVD, /* dvd */ 2057 { 0x01, KEY_DVD }, /* dvd */
1918}; 2058};
1919 2059
1920EXPORT_SYMBOL_GPL(ir_codes_asus_pc39); 2060struct ir_scancode_table ir_codes_asus_pc39_table = {
2061 .scan = ir_codes_asus_pc39,
2062 .size = ARRAY_SIZE(ir_codes_asus_pc39),
2063};
2064EXPORT_SYMBOL_GPL(ir_codes_asus_pc39_table);
1921 2065
1922 2066
1923/* Encore ENLTV-FM - black plastic, white front cover with white glowing buttons 2067/* Encore ENLTV-FM - black plastic, white front cover with white glowing buttons
1924 Juan Pablo Sormani <sorman@gmail.com> */ 2068 Juan Pablo Sormani <sorman@gmail.com> */
1925IR_KEYTAB_TYPE ir_codes_encore_enltv[IR_KEYTAB_SIZE] = { 2069static struct ir_scancode ir_codes_encore_enltv[] = {
1926 2070
1927 /* Power button does nothing, neither in Windows app, 2071 /* Power button does nothing, neither in Windows app,
1928 although it sends data (used for BIOS wakeup?) */ 2072 although it sends data (used for BIOS wakeup?) */
1929 [ 0x0d ] = KEY_MUTE, 2073 { 0x0d, KEY_MUTE },
1930 2074
1931 [ 0x1e ] = KEY_TV, 2075 { 0x1e, KEY_TV },
1932 [ 0x00 ] = KEY_VIDEO, 2076 { 0x00, KEY_VIDEO },
1933 [ 0x01 ] = KEY_AUDIO, /* music */ 2077 { 0x01, KEY_AUDIO }, /* music */
1934 [ 0x02 ] = KEY_MHP, /* picture */ 2078 { 0x02, KEY_MHP }, /* picture */
1935 2079
1936 [ 0x1f ] = KEY_1, 2080 { 0x1f, KEY_1 },
1937 [ 0x03 ] = KEY_2, 2081 { 0x03, KEY_2 },
1938 [ 0x04 ] = KEY_3, 2082 { 0x04, KEY_3 },
1939 [ 0x05 ] = KEY_4, 2083 { 0x05, KEY_4 },
1940 [ 0x1c ] = KEY_5, 2084 { 0x1c, KEY_5 },
1941 [ 0x06 ] = KEY_6, 2085 { 0x06, KEY_6 },
1942 [ 0x07 ] = KEY_7, 2086 { 0x07, KEY_7 },
1943 [ 0x08 ] = KEY_8, 2087 { 0x08, KEY_8 },
1944 [ 0x1d ] = KEY_9, 2088 { 0x1d, KEY_9 },
1945 [ 0x0a ] = KEY_0, 2089 { 0x0a, KEY_0 },
1946 2090
1947 [ 0x09 ] = KEY_LIST, /* -/-- */ 2091 { 0x09, KEY_LIST }, /* -/-- */
1948 [ 0x0b ] = KEY_LAST, /* recall */ 2092 { 0x0b, KEY_LAST }, /* recall */
1949 2093
1950 [ 0x14 ] = KEY_HOME, /* win start menu */ 2094 { 0x14, KEY_HOME }, /* win start menu */
1951 [ 0x15 ] = KEY_EXIT, /* exit */ 2095 { 0x15, KEY_EXIT }, /* exit */
1952 [ 0x16 ] = KEY_UP, 2096 { 0x16, KEY_CHANNELUP }, /* UP */
1953 [ 0x12 ] = KEY_DOWN, 2097 { 0x12, KEY_CHANNELDOWN }, /* DOWN */
1954 [ 0x0c ] = KEY_RIGHT, 2098 { 0x0c, KEY_VOLUMEUP }, /* RIGHT */
1955 [ 0x17 ] = KEY_LEFT, 2099 { 0x17, KEY_VOLUMEDOWN }, /* LEFT */
1956 2100
1957 [ 0x18 ] = KEY_ENTER, /* OK */ 2101 { 0x18, KEY_ENTER }, /* OK */
1958 2102
1959 [ 0x0e ] = KEY_ESC, 2103 { 0x0e, KEY_ESC },
1960 [ 0x13 ] = KEY_D, /* desktop */ 2104 { 0x13, KEY_CYCLEWINDOWS }, /* desktop */
1961 [ 0x11 ] = KEY_TAB, 2105 { 0x11, KEY_TAB },
1962 [ 0x19 ] = KEY_SWITCHVIDEOMODE, /* switch */ 2106 { 0x19, KEY_SWITCHVIDEOMODE }, /* switch */
1963 2107
1964 [ 0x1a ] = KEY_MENU, 2108 { 0x1a, KEY_MENU },
1965 [ 0x1b ] = KEY_ZOOM, /* fullscreen */ 2109 { 0x1b, KEY_ZOOM }, /* fullscreen */
1966 [ 0x44 ] = KEY_TIME, /* time shift */ 2110 { 0x44, KEY_TIME }, /* time shift */
1967 [ 0x40 ] = KEY_MODE, /* source */ 2111 { 0x40, KEY_MODE }, /* source */
1968 2112
1969 [ 0x5a ] = KEY_RECORD, 2113 { 0x5a, KEY_RECORD },
1970 [ 0x42 ] = KEY_PLAY, /* play/pause */ 2114 { 0x42, KEY_PLAY }, /* play/pause */
1971 [ 0x45 ] = KEY_STOP, 2115 { 0x45, KEY_STOP },
1972 [ 0x43 ] = KEY_CAMERA, /* camera icon */ 2116 { 0x43, KEY_CAMERA }, /* camera icon */
1973 2117
1974 [ 0x48 ] = KEY_REWIND, 2118 { 0x48, KEY_REWIND },
1975 [ 0x4a ] = KEY_FASTFORWARD, 2119 { 0x4a, KEY_FASTFORWARD },
1976 [ 0x49 ] = KEY_PREVIOUS, 2120 { 0x49, KEY_PREVIOUS },
1977 [ 0x4b ] = KEY_NEXT, 2121 { 0x4b, KEY_NEXT },
1978 2122
1979 [ 0x4c ] = KEY_FAVORITES, /* tv wall */ 2123 { 0x4c, KEY_FAVORITES }, /* tv wall */
1980 [ 0x4d ] = KEY_SOUND, /* DVD sound */ 2124 { 0x4d, KEY_SOUND }, /* DVD sound */
1981 [ 0x4e ] = KEY_LANGUAGE, /* DVD lang */ 2125 { 0x4e, KEY_LANGUAGE }, /* DVD lang */
1982 [ 0x4f ] = KEY_TEXT, /* DVD text */ 2126 { 0x4f, KEY_TEXT }, /* DVD text */
1983 2127
1984 [ 0x50 ] = KEY_SLEEP, /* shutdown */ 2128 { 0x50, KEY_SLEEP }, /* shutdown */
1985 [ 0x51 ] = KEY_MODE, /* stereo > main */ 2129 { 0x51, KEY_MODE }, /* stereo > main */
1986 [ 0x52 ] = KEY_SELECT, /* stereo > sap */ 2130 { 0x52, KEY_SELECT }, /* stereo > sap */
1987 [ 0x53 ] = KEY_PROG1, /* teletext */ 2131 { 0x53, KEY_PROG1 }, /* teletext */
1988 2132
1989 2133
1990 [ 0x59 ] = KEY_RED, /* AP1 */ 2134 { 0x59, KEY_RED }, /* AP1 */
1991 [ 0x41 ] = KEY_GREEN, /* AP2 */ 2135 { 0x41, KEY_GREEN }, /* AP2 */
1992 [ 0x47 ] = KEY_YELLOW, /* AP3 */ 2136 { 0x47, KEY_YELLOW }, /* AP3 */
1993 [ 0x57 ] = KEY_BLUE, /* AP4 */ 2137 { 0x57, KEY_BLUE }, /* AP4 */
1994}; 2138};
1995EXPORT_SYMBOL_GPL(ir_codes_encore_enltv); 2139
2140struct ir_scancode_table ir_codes_encore_enltv_table = {
2141 .scan = ir_codes_encore_enltv,
2142 .size = ARRAY_SIZE(ir_codes_encore_enltv),
2143};
2144EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_table);
1996 2145
1997/* Encore ENLTV2-FM - silver plastic - "Wand Media" written at the botton 2146/* Encore ENLTV2-FM - silver plastic - "Wand Media" written at the botton
1998 Mauro Carvalho Chehab <mchehab@infradead.org> */ 2147 Mauro Carvalho Chehab <mchehab@infradead.org> */
1999IR_KEYTAB_TYPE ir_codes_encore_enltv2[IR_KEYTAB_SIZE] = { 2148static struct ir_scancode ir_codes_encore_enltv2[] = {
2000 [0x4c] = KEY_POWER2, 2149 { 0x4c, KEY_POWER2 },
2001 [0x4a] = KEY_TUNER, 2150 { 0x4a, KEY_TUNER },
2002 [0x40] = KEY_1, 2151 { 0x40, KEY_1 },
2003 [0x60] = KEY_2, 2152 { 0x60, KEY_2 },
2004 [0x50] = KEY_3, 2153 { 0x50, KEY_3 },
2005 [0x70] = KEY_4, 2154 { 0x70, KEY_4 },
2006 [0x48] = KEY_5, 2155 { 0x48, KEY_5 },
2007 [0x68] = KEY_6, 2156 { 0x68, KEY_6 },
2008 [0x58] = KEY_7, 2157 { 0x58, KEY_7 },
2009 [0x78] = KEY_8, 2158 { 0x78, KEY_8 },
2010 [0x44] = KEY_9, 2159 { 0x44, KEY_9 },
2011 [0x54] = KEY_0, 2160 { 0x54, KEY_0 },
2012 2161
2013 [0x64] = KEY_LAST, /* +100 */ 2162 { 0x64, KEY_LAST }, /* +100 */
2014 [0x4e] = KEY_AGAIN, /* Recall */ 2163 { 0x4e, KEY_AGAIN }, /* Recall */
2015 2164
2016 [0x6c] = KEY_SWITCHVIDEOMODE, /* Video Source */ 2165 { 0x6c, KEY_SWITCHVIDEOMODE }, /* Video Source */
2017 [0x5e] = KEY_MENU, 2166 { 0x5e, KEY_MENU },
2018 [0x56] = KEY_SCREEN, 2167 { 0x56, KEY_SCREEN },
2019 [0x7a] = KEY_SETUP, 2168 { 0x7a, KEY_SETUP },
2020 2169
2021 [0x46] = KEY_MUTE, 2170 { 0x46, KEY_MUTE },
2022 [0x5c] = KEY_MODE, /* Stereo */ 2171 { 0x5c, KEY_MODE }, /* Stereo */
2023 [0x74] = KEY_INFO, 2172 { 0x74, KEY_INFO },
2024 [0x7c] = KEY_CLEAR, 2173 { 0x7c, KEY_CLEAR },
2025 2174
2026 [0x55] = KEY_UP, 2175 { 0x55, KEY_UP },
2027 [0x49] = KEY_DOWN, 2176 { 0x49, KEY_DOWN },
2028 [0x7e] = KEY_LEFT, 2177 { 0x7e, KEY_LEFT },
2029 [0x59] = KEY_RIGHT, 2178 { 0x59, KEY_RIGHT },
2030 [0x6a] = KEY_ENTER, 2179 { 0x6a, KEY_ENTER },
2031 2180
2032 [0x42] = KEY_VOLUMEUP, 2181 { 0x42, KEY_VOLUMEUP },
2033 [0x62] = KEY_VOLUMEDOWN, 2182 { 0x62, KEY_VOLUMEDOWN },
2034 [0x52] = KEY_CHANNELUP, 2183 { 0x52, KEY_CHANNELUP },
2035 [0x72] = KEY_CHANNELDOWN, 2184 { 0x72, KEY_CHANNELDOWN },
2036 2185
2037 [0x41] = KEY_RECORD, 2186 { 0x41, KEY_RECORD },
2038 [0x51] = KEY_SHUFFLE, /* Snapshot */ 2187 { 0x51, KEY_CAMERA }, /* Snapshot */
2039 [0x75] = KEY_TIME, /* Timeshift */ 2188 { 0x75, KEY_TIME }, /* Timeshift */
2040 [0x71] = KEY_TV2, /* PIP */ 2189 { 0x71, KEY_TV2 }, /* PIP */
2041 2190
2042 [0x45] = KEY_REWIND, 2191 { 0x45, KEY_REWIND },
2043 [0x6f] = KEY_PAUSE, 2192 { 0x6f, KEY_PAUSE },
2044 [0x7d] = KEY_FORWARD, 2193 { 0x7d, KEY_FORWARD },
2045 [0x79] = KEY_STOP, 2194 { 0x79, KEY_STOP },
2046}; 2195};
2047EXPORT_SYMBOL_GPL(ir_codes_encore_enltv2); 2196
2197struct ir_scancode_table ir_codes_encore_enltv2_table = {
2198 .scan = ir_codes_encore_enltv2,
2199 .size = ARRAY_SIZE(ir_codes_encore_enltv2),
2200};
2201EXPORT_SYMBOL_GPL(ir_codes_encore_enltv2_table);
2048 2202
2049/* for the Technotrend 1500 bundled remotes (grey and black): */ 2203/* for the Technotrend 1500 bundled remotes (grey and black): */
2050IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE] = { 2204static struct ir_scancode ir_codes_tt_1500[] = {
2051 [ 0x01 ] = KEY_POWER, 2205 { 0x01, KEY_POWER },
2052 [ 0x02 ] = KEY_SHUFFLE, /* ? double-arrow key */ 2206 { 0x02, KEY_SHUFFLE }, /* ? double-arrow key */
2053 [ 0x03 ] = KEY_1, 2207 { 0x03, KEY_1 },
2054 [ 0x04 ] = KEY_2, 2208 { 0x04, KEY_2 },
2055 [ 0x05 ] = KEY_3, 2209 { 0x05, KEY_3 },
2056 [ 0x06 ] = KEY_4, 2210 { 0x06, KEY_4 },
2057 [ 0x07 ] = KEY_5, 2211 { 0x07, KEY_5 },
2058 [ 0x08 ] = KEY_6, 2212 { 0x08, KEY_6 },
2059 [ 0x09 ] = KEY_7, 2213 { 0x09, KEY_7 },
2060 [ 0x0a ] = KEY_8, 2214 { 0x0a, KEY_8 },
2061 [ 0x0b ] = KEY_9, 2215 { 0x0b, KEY_9 },
2062 [ 0x0c ] = KEY_0, 2216 { 0x0c, KEY_0 },
2063 [ 0x0d ] = KEY_UP, 2217 { 0x0d, KEY_UP },
2064 [ 0x0e ] = KEY_LEFT, 2218 { 0x0e, KEY_LEFT },
2065 [ 0x0f ] = KEY_OK, 2219 { 0x0f, KEY_OK },
2066 [ 0x10 ] = KEY_RIGHT, 2220 { 0x10, KEY_RIGHT },
2067 [ 0x11 ] = KEY_DOWN, 2221 { 0x11, KEY_DOWN },
2068 [ 0x12 ] = KEY_INFO, 2222 { 0x12, KEY_INFO },
2069 [ 0x13 ] = KEY_EXIT, 2223 { 0x13, KEY_EXIT },
2070 [ 0x14 ] = KEY_RED, 2224 { 0x14, KEY_RED },
2071 [ 0x15 ] = KEY_GREEN, 2225 { 0x15, KEY_GREEN },
2072 [ 0x16 ] = KEY_YELLOW, 2226 { 0x16, KEY_YELLOW },
2073 [ 0x17 ] = KEY_BLUE, 2227 { 0x17, KEY_BLUE },
2074 [ 0x18 ] = KEY_MUTE, 2228 { 0x18, KEY_MUTE },
2075 [ 0x19 ] = KEY_TEXT, 2229 { 0x19, KEY_TEXT },
2076 [ 0x1a ] = KEY_MODE, /* ? TV/Radio */ 2230 { 0x1a, KEY_MODE }, /* ? TV/Radio */
2077 [ 0x21 ] = KEY_OPTION, 2231 { 0x21, KEY_OPTION },
2078 [ 0x22 ] = KEY_EPG, 2232 { 0x22, KEY_EPG },
2079 [ 0x23 ] = KEY_CHANNELUP, 2233 { 0x23, KEY_CHANNELUP },
2080 [ 0x24 ] = KEY_CHANNELDOWN, 2234 { 0x24, KEY_CHANNELDOWN },
2081 [ 0x25 ] = KEY_VOLUMEUP, 2235 { 0x25, KEY_VOLUMEUP },
2082 [ 0x26 ] = KEY_VOLUMEDOWN, 2236 { 0x26, KEY_VOLUMEDOWN },
2083 [ 0x27 ] = KEY_SETUP, 2237 { 0x27, KEY_SETUP },
2084 [ 0x3a ] = KEY_RECORD, /* these keys are only in the black remote */ 2238 { 0x3a, KEY_RECORD }, /* these keys are only in the black remote */
2085 [ 0x3b ] = KEY_PLAY, 2239 { 0x3b, KEY_PLAY },
2086 [ 0x3c ] = KEY_STOP, 2240 { 0x3c, KEY_STOP },
2087 [ 0x3d ] = KEY_REWIND, 2241 { 0x3d, KEY_REWIND },
2088 [ 0x3e ] = KEY_PAUSE, 2242 { 0x3e, KEY_PAUSE },
2089 [ 0x3f ] = KEY_FORWARD, 2243 { 0x3f, KEY_FORWARD },
2090}; 2244};
2091 2245
2092EXPORT_SYMBOL_GPL(ir_codes_tt_1500); 2246struct ir_scancode_table ir_codes_tt_1500_table = {
2247 .scan = ir_codes_tt_1500,
2248 .size = ARRAY_SIZE(ir_codes_tt_1500),
2249};
2250EXPORT_SYMBOL_GPL(ir_codes_tt_1500_table);
2093 2251
2094/* DViCO FUSION HDTV MCE remote */ 2252/* DViCO FUSION HDTV MCE remote */
2095IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE] = { 2253static struct ir_scancode ir_codes_fusionhdtv_mce[] = {
2096 2254
2097 [ 0x0b ] = KEY_1, 2255 { 0x0b, KEY_1 },
2098 [ 0x17 ] = KEY_2, 2256 { 0x17, KEY_2 },
2099 [ 0x1b ] = KEY_3, 2257 { 0x1b, KEY_3 },
2100 [ 0x07 ] = KEY_4, 2258 { 0x07, KEY_4 },
2101 [ 0x50 ] = KEY_5, 2259 { 0x50, KEY_5 },
2102 [ 0x54 ] = KEY_6, 2260 { 0x54, KEY_6 },
2103 [ 0x48 ] = KEY_7, 2261 { 0x48, KEY_7 },
2104 [ 0x4c ] = KEY_8, 2262 { 0x4c, KEY_8 },
2105 [ 0x58 ] = KEY_9, 2263 { 0x58, KEY_9 },
2106 [ 0x03 ] = KEY_0, 2264 { 0x03, KEY_0 },
2107 2265
2108 [ 0x5e ] = KEY_OK, 2266 { 0x5e, KEY_OK },
2109 [ 0x51 ] = KEY_UP, 2267 { 0x51, KEY_UP },
2110 [ 0x53 ] = KEY_DOWN, 2268 { 0x53, KEY_DOWN },
2111 [ 0x5b ] = KEY_LEFT, 2269 { 0x5b, KEY_LEFT },
2112 [ 0x5f ] = KEY_RIGHT, 2270 { 0x5f, KEY_RIGHT },
2113 2271
2114 [ 0x02 ] = KEY_TV, /* Labeled DTV on remote */ 2272 { 0x02, KEY_TV }, /* Labeled DTV on remote */
2115 [ 0x0e ] = KEY_MP3, 2273 { 0x0e, KEY_MP3 },
2116 [ 0x1a ] = KEY_DVD, 2274 { 0x1a, KEY_DVD },
2117 [ 0x1e ] = KEY_FAVORITES, /* Labeled CPF on remote */ 2275 { 0x1e, KEY_FAVORITES }, /* Labeled CPF on remote */
2118 [ 0x16 ] = KEY_SETUP, 2276 { 0x16, KEY_SETUP },
2119 [ 0x46 ] = KEY_POWER2, /* TV On/Off button on remote */ 2277 { 0x46, KEY_POWER2 }, /* TV On/Off button on remote */
2120 [ 0x0a ] = KEY_EPG, /* Labeled Guide on remote */ 2278 { 0x0a, KEY_EPG }, /* Labeled Guide on remote */
2121 2279
2122 [ 0x49 ] = KEY_BACK, 2280 { 0x49, KEY_BACK },
2123 [ 0x59 ] = KEY_INFO, /* Labeled MORE on remote */ 2281 { 0x59, KEY_INFO }, /* Labeled MORE on remote */
2124 [ 0x4d ] = KEY_MENU, /* Labeled DVDMENU on remote */ 2282 { 0x4d, KEY_MENU }, /* Labeled DVDMENU on remote */
2125 [ 0x55 ] = KEY_CYCLEWINDOWS, /* Labeled ALT-TAB on remote */ 2283 { 0x55, KEY_CYCLEWINDOWS }, /* Labeled ALT-TAB on remote */
2126 2284
2127 [ 0x0f ] = KEY_PREVIOUSSONG, /* Labeled |<< REPLAY on remote */ 2285 { 0x0f, KEY_PREVIOUSSONG }, /* Labeled |<< REPLAY on remote */
2128 [ 0x12 ] = KEY_NEXTSONG, /* Labeled >>| SKIP on remote */ 2286 { 0x12, KEY_NEXTSONG }, /* Labeled >>| SKIP on remote */
2129 [ 0x42 ] = KEY_ENTER, /* Labeled START with a green 2287 { 0x42, KEY_ENTER }, /* Labeled START with a green
2130 * MS windows logo on remote */ 2288 MS windows logo on remote */
2131 2289
2132 [ 0x15 ] = KEY_VOLUMEUP, 2290 { 0x15, KEY_VOLUMEUP },
2133 [ 0x05 ] = KEY_VOLUMEDOWN, 2291 { 0x05, KEY_VOLUMEDOWN },
2134 [ 0x11 ] = KEY_CHANNELUP, 2292 { 0x11, KEY_CHANNELUP },
2135 [ 0x09 ] = KEY_CHANNELDOWN, 2293 { 0x09, KEY_CHANNELDOWN },
2136 2294
2137 [ 0x52 ] = KEY_CAMERA, 2295 { 0x52, KEY_CAMERA },
2138 [ 0x5a ] = KEY_TUNER, 2296 { 0x5a, KEY_TUNER },
2139 [ 0x19 ] = KEY_OPEN, 2297 { 0x19, KEY_OPEN },
2140 2298
2141 [ 0x13 ] = KEY_MODE, /* 4:3 16:9 select */ 2299 { 0x13, KEY_MODE }, /* 4:3 16:9 select */
2142 [ 0x1f ] = KEY_ZOOM, 2300 { 0x1f, KEY_ZOOM },
2143 2301
2144 [ 0x43 ] = KEY_REWIND, 2302 { 0x43, KEY_REWIND },
2145 [ 0x47 ] = KEY_PLAYPAUSE, 2303 { 0x47, KEY_PLAYPAUSE },
2146 [ 0x4f ] = KEY_FASTFORWARD, 2304 { 0x4f, KEY_FASTFORWARD },
2147 [ 0x57 ] = KEY_MUTE, 2305 { 0x57, KEY_MUTE },
2148 [ 0x0d ] = KEY_STOP, 2306 { 0x0d, KEY_STOP },
2149 [ 0x01 ] = KEY_RECORD, 2307 { 0x01, KEY_RECORD },
2150 [ 0x4e ] = KEY_POWER, 2308 { 0x4e, KEY_POWER },
2151}; 2309};
2152 2310
2153EXPORT_SYMBOL_GPL(ir_codes_fusionhdtv_mce); 2311struct ir_scancode_table ir_codes_fusionhdtv_mce_table = {
2312 .scan = ir_codes_fusionhdtv_mce,
2313 .size = ARRAY_SIZE(ir_codes_fusionhdtv_mce),
2314};
2315EXPORT_SYMBOL_GPL(ir_codes_fusionhdtv_mce_table);
2154 2316
2155/* Pinnacle PCTV HD 800i mini remote */ 2317/* Pinnacle PCTV HD 800i mini remote */
2156IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE] = { 2318static struct ir_scancode ir_codes_pinnacle_pctv_hd[] = {
2157 2319
2158 [0x0f] = KEY_1, 2320 { 0x0f, KEY_1 },
2159 [0x15] = KEY_2, 2321 { 0x15, KEY_2 },
2160 [0x10] = KEY_3, 2322 { 0x10, KEY_3 },
2161 [0x18] = KEY_4, 2323 { 0x18, KEY_4 },
2162 [0x1b] = KEY_5, 2324 { 0x1b, KEY_5 },
2163 [0x1e] = KEY_6, 2325 { 0x1e, KEY_6 },
2164 [0x11] = KEY_7, 2326 { 0x11, KEY_7 },
2165 [0x21] = KEY_8, 2327 { 0x21, KEY_8 },
2166 [0x12] = KEY_9, 2328 { 0x12, KEY_9 },
2167 [0x27] = KEY_0, 2329 { 0x27, KEY_0 },
2168 2330
2169 [0x24] = KEY_ZOOM, 2331 { 0x24, KEY_ZOOM },
2170 [0x2a] = KEY_SUBTITLE, 2332 { 0x2a, KEY_SUBTITLE },
2171 2333
2172 [0x00] = KEY_MUTE, 2334 { 0x00, KEY_MUTE },
2173 [0x01] = KEY_ENTER, /* Pinnacle Logo */ 2335 { 0x01, KEY_ENTER }, /* Pinnacle Logo */
2174 [0x39] = KEY_POWER, 2336 { 0x39, KEY_POWER },
2175 2337
2176 [0x03] = KEY_VOLUMEUP, 2338 { 0x03, KEY_VOLUMEUP },
2177 [0x09] = KEY_VOLUMEDOWN, 2339 { 0x09, KEY_VOLUMEDOWN },
2178 [0x06] = KEY_CHANNELUP, 2340 { 0x06, KEY_CHANNELUP },
2179 [0x0c] = KEY_CHANNELDOWN, 2341 { 0x0c, KEY_CHANNELDOWN },
2180 2342
2181 [0x2d] = KEY_REWIND, 2343 { 0x2d, KEY_REWIND },
2182 [0x30] = KEY_PLAYPAUSE, 2344 { 0x30, KEY_PLAYPAUSE },
2183 [0x33] = KEY_FASTFORWARD, 2345 { 0x33, KEY_FASTFORWARD },
2184 [0x3c] = KEY_STOP, 2346 { 0x3c, KEY_STOP },
2185 [0x36] = KEY_RECORD, 2347 { 0x36, KEY_RECORD },
2186 [0x3f] = KEY_EPG, /* Labeled "?" */ 2348 { 0x3f, KEY_EPG }, /* Labeled "?" */
2187}; 2349};
2188EXPORT_SYMBOL_GPL(ir_codes_pinnacle_pctv_hd); 2350
2351struct ir_scancode_table ir_codes_pinnacle_pctv_hd_table = {
2352 .scan = ir_codes_pinnacle_pctv_hd,
2353 .size = ARRAY_SIZE(ir_codes_pinnacle_pctv_hd),
2354};
2355EXPORT_SYMBOL_GPL(ir_codes_pinnacle_pctv_hd_table);
2189 2356
2190/* 2357/*
2191 * Igor Kuznetsov <igk72@ya.ru> 2358 * Igor Kuznetsov <igk72@ya.ru>
@@ -2198,13 +2365,13 @@ EXPORT_SYMBOL_GPL(ir_codes_pinnacle_pctv_hd);
2198 * the button labels (several variants when appropriate) 2365 * the button labels (several variants when appropriate)
2199 * helps to descide which keycodes to assign to the buttons. 2366 * helps to descide which keycodes to assign to the buttons.
2200 */ 2367 */
2201IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE] = { 2368static struct ir_scancode ir_codes_behold[] = {
2202 2369
2203 /* 0x1c 0x12 * 2370 /* 0x1c 0x12 *
2204 * TV/FM POWER * 2371 * TV/FM POWER *
2205 * */ 2372 * */
2206 [ 0x1c ] = KEY_TUNER, /*XXX KEY_TV KEY_RADIO */ 2373 { 0x1c, KEY_TUNER }, /* XXX KEY_TV / KEY_RADIO */
2207 [ 0x12 ] = KEY_POWER, 2374 { 0x12, KEY_POWER },
2208 2375
2209 /* 0x01 0x02 0x03 * 2376 /* 0x01 0x02 0x03 *
2210 * 1 2 3 * 2377 * 1 2 3 *
@@ -2215,28 +2382,28 @@ IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE] = {
2215 * 0x07 0x08 0x09 * 2382 * 0x07 0x08 0x09 *
2216 * 7 8 9 * 2383 * 7 8 9 *
2217 * */ 2384 * */
2218 [ 0x01 ] = KEY_1, 2385 { 0x01, KEY_1 },
2219 [ 0x02 ] = KEY_2, 2386 { 0x02, KEY_2 },
2220 [ 0x03 ] = KEY_3, 2387 { 0x03, KEY_3 },
2221 [ 0x04 ] = KEY_4, 2388 { 0x04, KEY_4 },
2222 [ 0x05 ] = KEY_5, 2389 { 0x05, KEY_5 },
2223 [ 0x06 ] = KEY_6, 2390 { 0x06, KEY_6 },
2224 [ 0x07 ] = KEY_7, 2391 { 0x07, KEY_7 },
2225 [ 0x08 ] = KEY_8, 2392 { 0x08, KEY_8 },
2226 [ 0x09 ] = KEY_9, 2393 { 0x09, KEY_9 },
2227 2394
2228 /* 0x0a 0x00 0x17 * 2395 /* 0x0a 0x00 0x17 *
2229 * RECALL 0 MODE * 2396 * RECALL 0 MODE *
2230 * */ 2397 * */
2231 [ 0x0a ] = KEY_AGAIN, 2398 { 0x0a, KEY_AGAIN },
2232 [ 0x00 ] = KEY_0, 2399 { 0x00, KEY_0 },
2233 [ 0x17 ] = KEY_MODE, 2400 { 0x17, KEY_MODE },
2234 2401
2235 /* 0x14 0x10 * 2402 /* 0x14 0x10 *
2236 * ASPECT FULLSCREEN * 2403 * ASPECT FULLSCREEN *
2237 * */ 2404 * */
2238 [ 0x14 ] = KEY_SCREEN, 2405 { 0x14, KEY_SCREEN },
2239 [ 0x10 ] = KEY_ZOOM, 2406 { 0x10, KEY_ZOOM },
2240 2407
2241 /* 0x0b * 2408 /* 0x0b *
2242 * Up * 2409 * Up *
@@ -2247,17 +2414,17 @@ IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE] = {
2247 * 0x015 * 2414 * 0x015 *
2248 * Down * 2415 * Down *
2249 * */ 2416 * */
2250 [ 0x0b ] = KEY_CHANNELUP, /*XXX KEY_UP */ 2417 { 0x0b, KEY_CHANNELUP },
2251 [ 0x18 ] = KEY_VOLUMEDOWN, /*XXX KEY_LEFT */ 2418 { 0x18, KEY_VOLUMEDOWN },
2252 [ 0x16 ] = KEY_OK, /*XXX KEY_ENTER */ 2419 { 0x16, KEY_OK }, /* XXX KEY_ENTER */
2253 [ 0x0c ] = KEY_VOLUMEUP, /*XXX KEY_RIGHT */ 2420 { 0x0c, KEY_VOLUMEUP },
2254 [ 0x15 ] = KEY_CHANNELDOWN, /*XXX KEY_DOWN */ 2421 { 0x15, KEY_CHANNELDOWN },
2255 2422
2256 /* 0x11 0x0d * 2423 /* 0x11 0x0d *
2257 * MUTE INFO * 2424 * MUTE INFO *
2258 * */ 2425 * */
2259 [ 0x11 ] = KEY_MUTE, 2426 { 0x11, KEY_MUTE },
2260 [ 0x0d ] = KEY_INFO, 2427 { 0x0d, KEY_INFO },
2261 2428
2262 /* 0x0f 0x1b 0x1a * 2429 /* 0x0f 0x1b 0x1a *
2263 * RECORD PLAY/PAUSE STOP * 2430 * RECORD PLAY/PAUSE STOP *
@@ -2266,30 +2433,34 @@ IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE] = {
2266 *TELETEXT AUDIO SOURCE * 2433 *TELETEXT AUDIO SOURCE *
2267 * RED YELLOW * 2434 * RED YELLOW *
2268 * */ 2435 * */
2269 [ 0x0f ] = KEY_RECORD, 2436 { 0x0f, KEY_RECORD },
2270 [ 0x1b ] = KEY_PLAYPAUSE, 2437 { 0x1b, KEY_PLAYPAUSE },
2271 [ 0x1a ] = KEY_STOP, 2438 { 0x1a, KEY_STOP },
2272 [ 0x0e ] = KEY_TEXT, 2439 { 0x0e, KEY_TEXT },
2273 [ 0x1f ] = KEY_RED, /*XXX KEY_AUDIO */ 2440 { 0x1f, KEY_RED }, /*XXX KEY_AUDIO */
2274 [ 0x1e ] = KEY_YELLOW, /*XXX KEY_SOURCE */ 2441 { 0x1e, KEY_YELLOW }, /*XXX KEY_SOURCE */
2275 2442
2276 /* 0x1d 0x13 0x19 * 2443 /* 0x1d 0x13 0x19 *
2277 * SLEEP PREVIEW DVB * 2444 * SLEEP PREVIEW DVB *
2278 * GREEN BLUE * 2445 * GREEN BLUE *
2279 * */ 2446 * */
2280 [ 0x1d ] = KEY_SLEEP, 2447 { 0x1d, KEY_SLEEP },
2281 [ 0x13 ] = KEY_GREEN, 2448 { 0x13, KEY_GREEN },
2282 [ 0x19 ] = KEY_BLUE, /*XXX KEY_SAT */ 2449 { 0x19, KEY_BLUE }, /* XXX KEY_SAT */
2283 2450
2284 /* 0x58 0x5c * 2451 /* 0x58 0x5c *
2285 * FREEZE SNAPSHOT * 2452 * FREEZE SNAPSHOT *
2286 * */ 2453 * */
2287 [ 0x58 ] = KEY_SLOW, 2454 { 0x58, KEY_SLOW },
2288 [ 0x5c ] = KEY_SAVE, 2455 { 0x5c, KEY_CAMERA },
2289 2456
2290}; 2457};
2291 2458
2292EXPORT_SYMBOL_GPL(ir_codes_behold); 2459struct ir_scancode_table ir_codes_behold_table = {
2460 .scan = ir_codes_behold,
2461 .size = ARRAY_SIZE(ir_codes_behold),
2462};
2463EXPORT_SYMBOL_GPL(ir_codes_behold_table);
2293 2464
2294/* Beholder Intl. Ltd. 2008 2465/* Beholder Intl. Ltd. 2008
2295 * Dmitry Belimov d.belimov@google.com 2466 * Dmitry Belimov d.belimov@google.com
@@ -2299,16 +2470,16 @@ EXPORT_SYMBOL_GPL(ir_codes_behold);
2299 * the button labels (several variants when appropriate) 2470 * the button labels (several variants when appropriate)
2300 * helps to descide which keycodes to assign to the buttons. 2471 * helps to descide which keycodes to assign to the buttons.
2301 */ 2472 */
2302IR_KEYTAB_TYPE ir_codes_behold_columbus[IR_KEYTAB_SIZE] = { 2473static struct ir_scancode ir_codes_behold_columbus[] = {
2303 2474
2304 /* 0x13 0x11 0x1C 0x12 * 2475 /* 0x13 0x11 0x1C 0x12 *
2305 * Mute Source TV/FM Power * 2476 * Mute Source TV/FM Power *
2306 * */ 2477 * */
2307 2478
2308 [0x13] = KEY_MUTE, 2479 { 0x13, KEY_MUTE },
2309 [0x11] = KEY_PROPS, 2480 { 0x11, KEY_PROPS },
2310 [0x1C] = KEY_TUNER, /* KEY_TV/KEY_RADIO */ 2481 { 0x1C, KEY_TUNER }, /* KEY_TV/KEY_RADIO */
2311 [0x12] = KEY_POWER, 2482 { 0x12, KEY_POWER },
2312 2483
2313 /* 0x01 0x02 0x03 0x0D * 2484 /* 0x01 0x02 0x03 0x0D *
2314 * 1 2 3 Stereo * 2485 * 1 2 3 Stereo *
@@ -2319,173 +2490,188 @@ IR_KEYTAB_TYPE ir_codes_behold_columbus[IR_KEYTAB_SIZE] = {
2319 * 0x07 0x08 0x09 0x10 * 2490 * 0x07 0x08 0x09 0x10 *
2320 * 7 8 9 Zoom * 2491 * 7 8 9 Zoom *
2321 * */ 2492 * */
2322 [0x01] = KEY_1, 2493 { 0x01, KEY_1 },
2323 [0x02] = KEY_2, 2494 { 0x02, KEY_2 },
2324 [0x03] = KEY_3, 2495 { 0x03, KEY_3 },
2325 [0x0D] = KEY_SETUP, /* Setup key */ 2496 { 0x0D, KEY_SETUP }, /* Setup key */
2326 [0x04] = KEY_4, 2497 { 0x04, KEY_4 },
2327 [0x05] = KEY_5, 2498 { 0x05, KEY_5 },
2328 [0x06] = KEY_6, 2499 { 0x06, KEY_6 },
2329 [0x19] = KEY_BOOKMARKS, /* Snapshot key */ 2500 { 0x19, KEY_CAMERA }, /* Snapshot key */
2330 [0x07] = KEY_7, 2501 { 0x07, KEY_7 },
2331 [0x08] = KEY_8, 2502 { 0x08, KEY_8 },
2332 [0x09] = KEY_9, 2503 { 0x09, KEY_9 },
2333 [0x10] = KEY_ZOOM, 2504 { 0x10, KEY_ZOOM },
2334 2505
2335 /* 0x0A 0x00 0x0B 0x0C * 2506 /* 0x0A 0x00 0x0B 0x0C *
2336 * RECALL 0 ChannelUp VolumeUp * 2507 * RECALL 0 ChannelUp VolumeUp *
2337 * */ 2508 * */
2338 [0x0A] = KEY_AGAIN, 2509 { 0x0A, KEY_AGAIN },
2339 [0x00] = KEY_0, 2510 { 0x00, KEY_0 },
2340 [0x0B] = KEY_CHANNELUP, 2511 { 0x0B, KEY_CHANNELUP },
2341 [0x0C] = KEY_VOLUMEUP, 2512 { 0x0C, KEY_VOLUMEUP },
2342 2513
2343 /* 0x1B 0x1D 0x15 0x18 * 2514 /* 0x1B 0x1D 0x15 0x18 *
2344 * Timeshift Record ChannelDown VolumeDown * 2515 * Timeshift Record ChannelDown VolumeDown *
2345 * */ 2516 * */
2346 2517
2347 [0x1B] = KEY_REWIND, 2518 { 0x1B, KEY_TIME },
2348 [0x1D] = KEY_RECORD, 2519 { 0x1D, KEY_RECORD },
2349 [0x15] = KEY_CHANNELDOWN, 2520 { 0x15, KEY_CHANNELDOWN },
2350 [0x18] = KEY_VOLUMEDOWN, 2521 { 0x18, KEY_VOLUMEDOWN },
2351 2522
2352 /* 0x0E 0x1E 0x0F 0x1A * 2523 /* 0x0E 0x1E 0x0F 0x1A *
2353 * Stop Pause Previouse Next * 2524 * Stop Pause Previouse Next *
2354 * */ 2525 * */
2355 2526
2356 [0x0E] = KEY_STOP, 2527 { 0x0E, KEY_STOP },
2357 [0x1E] = KEY_PAUSE, 2528 { 0x1E, KEY_PAUSE },
2358 [0x0F] = KEY_PREVIOUS, 2529 { 0x0F, KEY_PREVIOUS },
2359 [0x1A] = KEY_NEXT, 2530 { 0x1A, KEY_NEXT },
2531
2532};
2360 2533
2534struct ir_scancode_table ir_codes_behold_columbus_table = {
2535 .scan = ir_codes_behold_columbus,
2536 .size = ARRAY_SIZE(ir_codes_behold_columbus),
2361}; 2537};
2362EXPORT_SYMBOL_GPL(ir_codes_behold_columbus); 2538EXPORT_SYMBOL_GPL(ir_codes_behold_columbus_table);
2363 2539
2364/* 2540/*
2365 * Remote control for the Genius TVGO A11MCE 2541 * Remote control for the Genius TVGO A11MCE
2366 * Adrian Pardini <pardo.bsso@gmail.com> 2542 * Adrian Pardini <pardo.bsso@gmail.com>
2367 */ 2543 */
2368IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE] = { 2544static struct ir_scancode ir_codes_genius_tvgo_a11mce[] = {
2369 /* Keys 0 to 9 */ 2545 /* Keys 0 to 9 */
2370 [0x48] = KEY_0, 2546 { 0x48, KEY_0 },
2371 [0x09] = KEY_1, 2547 { 0x09, KEY_1 },
2372 [0x1d] = KEY_2, 2548 { 0x1d, KEY_2 },
2373 [0x1f] = KEY_3, 2549 { 0x1f, KEY_3 },
2374 [0x19] = KEY_4, 2550 { 0x19, KEY_4 },
2375 [0x1b] = KEY_5, 2551 { 0x1b, KEY_5 },
2376 [0x11] = KEY_6, 2552 { 0x11, KEY_6 },
2377 [0x17] = KEY_7, 2553 { 0x17, KEY_7 },
2378 [0x12] = KEY_8, 2554 { 0x12, KEY_8 },
2379 [0x16] = KEY_9, 2555 { 0x16, KEY_9 },
2380 2556
2381 [0x54] = KEY_RECORD, /* recording */ 2557 { 0x54, KEY_RECORD }, /* recording */
2382 [0x06] = KEY_MUTE, /* mute */ 2558 { 0x06, KEY_MUTE }, /* mute */
2383 [0x10] = KEY_POWER, 2559 { 0x10, KEY_POWER },
2384 [0x40] = KEY_LAST, /* recall */ 2560 { 0x40, KEY_LAST }, /* recall */
2385 [0x4c] = KEY_CHANNELUP, /* channel / program + */ 2561 { 0x4c, KEY_CHANNELUP }, /* channel / program + */
2386 [0x00] = KEY_CHANNELDOWN, /* channel / program - */ 2562 { 0x00, KEY_CHANNELDOWN }, /* channel / program - */
2387 [0x0d] = KEY_VOLUMEUP, 2563 { 0x0d, KEY_VOLUMEUP },
2388 [0x15] = KEY_VOLUMEDOWN, 2564 { 0x15, KEY_VOLUMEDOWN },
2389 [0x4d] = KEY_OK, /* also labeled as Pause */ 2565 { 0x4d, KEY_OK }, /* also labeled as Pause */
2390 [0x1c] = KEY_ZOOM, /* full screen and Stop*/ 2566 { 0x1c, KEY_ZOOM }, /* full screen and Stop*/
2391 [0x02] = KEY_MODE, /* AV Source or Rewind*/ 2567 { 0x02, KEY_MODE }, /* AV Source or Rewind*/
2392 [0x04] = KEY_LIST, /* -/-- */ 2568 { 0x04, KEY_LIST }, /* -/-- */
2393 /* small arrows above numbers */ 2569 /* small arrows above numbers */
2394 [0x1a] = KEY_NEXT, /* also Fast Forward */ 2570 { 0x1a, KEY_NEXT }, /* also Fast Forward */
2395 [0x0e] = KEY_PREVIOUS, /* also Rewind */ 2571 { 0x0e, KEY_PREVIOUS }, /* also Rewind */
2396 /* these are in a rather non standard layout and have 2572 /* these are in a rather non standard layout and have
2397 an alternate name written */ 2573 an alternate name written */
2398 [0x1e] = KEY_UP, /* Video Setting */ 2574 { 0x1e, KEY_UP }, /* Video Setting */
2399 [0x0a] = KEY_DOWN, /* Video Default */ 2575 { 0x0a, KEY_DOWN }, /* Video Default */
2400 [0x05] = KEY_LEFT, /* Snapshot */ 2576 { 0x05, KEY_CAMERA }, /* Snapshot */
2401 [0x0c] = KEY_RIGHT, /* Hide Panel */ 2577 { 0x0c, KEY_RIGHT }, /* Hide Panel */
2402 /* Four buttons without label */ 2578 /* Four buttons without label */
2403 [0x49] = KEY_RED, 2579 { 0x49, KEY_RED },
2404 [0x0b] = KEY_GREEN, 2580 { 0x0b, KEY_GREEN },
2405 [0x13] = KEY_YELLOW, 2581 { 0x13, KEY_YELLOW },
2406 [0x50] = KEY_BLUE, 2582 { 0x50, KEY_BLUE },
2583};
2584
2585struct ir_scancode_table ir_codes_genius_tvgo_a11mce_table = {
2586 .scan = ir_codes_genius_tvgo_a11mce,
2587 .size = ARRAY_SIZE(ir_codes_genius_tvgo_a11mce),
2407}; 2588};
2408EXPORT_SYMBOL_GPL(ir_codes_genius_tvgo_a11mce); 2589EXPORT_SYMBOL_GPL(ir_codes_genius_tvgo_a11mce_table);
2409 2590
2410/* 2591/*
2411 * Remote control for Powercolor Real Angel 330 2592 * Remote control for Powercolor Real Angel 330
2412 * Daniel Fraga <fragabr@gmail.com> 2593 * Daniel Fraga <fragabr@gmail.com>
2413 */ 2594 */
2414IR_KEYTAB_TYPE ir_codes_powercolor_real_angel[IR_KEYTAB_SIZE] = { 2595static struct ir_scancode ir_codes_powercolor_real_angel[] = {
2415 [0x38] = KEY_SWITCHVIDEOMODE, /* switch inputs */ 2596 { 0x38, KEY_SWITCHVIDEOMODE }, /* switch inputs */
2416 [0x0c] = KEY_MEDIA, /* Turn ON/OFF App */ 2597 { 0x0c, KEY_MEDIA }, /* Turn ON/OFF App */
2417 [0x00] = KEY_0, 2598 { 0x00, KEY_0 },
2418 [0x01] = KEY_1, 2599 { 0x01, KEY_1 },
2419 [0x02] = KEY_2, 2600 { 0x02, KEY_2 },
2420 [0x03] = KEY_3, 2601 { 0x03, KEY_3 },
2421 [0x04] = KEY_4, 2602 { 0x04, KEY_4 },
2422 [0x05] = KEY_5, 2603 { 0x05, KEY_5 },
2423 [0x06] = KEY_6, 2604 { 0x06, KEY_6 },
2424 [0x07] = KEY_7, 2605 { 0x07, KEY_7 },
2425 [0x08] = KEY_8, 2606 { 0x08, KEY_8 },
2426 [0x09] = KEY_9, 2607 { 0x09, KEY_9 },
2427 [0x0a] = KEY_DIGITS, /* single, double, tripple digit */ 2608 { 0x0a, KEY_DIGITS }, /* single, double, tripple digit */
2428 [0x29] = KEY_PREVIOUS, /* previous channel */ 2609 { 0x29, KEY_PREVIOUS }, /* previous channel */
2429 [0x12] = KEY_BRIGHTNESSUP, 2610 { 0x12, KEY_BRIGHTNESSUP },
2430 [0x13] = KEY_BRIGHTNESSDOWN, 2611 { 0x13, KEY_BRIGHTNESSDOWN },
2431 [0x2b] = KEY_MODE, /* stereo/mono */ 2612 { 0x2b, KEY_MODE }, /* stereo/mono */
2432 [0x2c] = KEY_TEXT, /* teletext */ 2613 { 0x2c, KEY_TEXT }, /* teletext */
2433 [0x20] = KEY_UP, /* channel up */ 2614 { 0x20, KEY_CHANNELUP }, /* channel up */
2434 [0x21] = KEY_DOWN, /* channel down */ 2615 { 0x21, KEY_CHANNELDOWN }, /* channel down */
2435 [0x10] = KEY_RIGHT, /* volume up */ 2616 { 0x10, KEY_VOLUMEUP }, /* volume up */
2436 [0x11] = KEY_LEFT, /* volume down */ 2617 { 0x11, KEY_VOLUMEDOWN }, /* volume down */
2437 [0x0d] = KEY_MUTE, 2618 { 0x0d, KEY_MUTE },
2438 [0x1f] = KEY_RECORD, 2619 { 0x1f, KEY_RECORD },
2439 [0x17] = KEY_PLAY, 2620 { 0x17, KEY_PLAY },
2440 [0x16] = KEY_PAUSE, 2621 { 0x16, KEY_PAUSE },
2441 [0x0b] = KEY_STOP, 2622 { 0x0b, KEY_STOP },
2442 [0x27] = KEY_FASTFORWARD, 2623 { 0x27, KEY_FASTFORWARD },
2443 [0x26] = KEY_REWIND, 2624 { 0x26, KEY_REWIND },
2444 [0x1e] = KEY_SEARCH, /* autoscan */ 2625 { 0x1e, KEY_SEARCH }, /* autoscan */
2445 [0x0e] = KEY_SHUFFLE, /* snapshot */ 2626 { 0x0e, KEY_CAMERA }, /* snapshot */
2446 [0x2d] = KEY_SETUP, 2627 { 0x2d, KEY_SETUP },
2447 [0x0f] = KEY_SCREEN, /* full screen */ 2628 { 0x0f, KEY_SCREEN }, /* full screen */
2448 [0x14] = KEY_RADIO, /* FM radio */ 2629 { 0x14, KEY_RADIO }, /* FM radio */
2449 [0x25] = KEY_POWER, /* power */ 2630 { 0x25, KEY_POWER }, /* power */
2450}; 2631};
2451EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel); 2632
2633struct ir_scancode_table ir_codes_powercolor_real_angel_table = {
2634 .scan = ir_codes_powercolor_real_angel,
2635 .size = ARRAY_SIZE(ir_codes_powercolor_real_angel),
2636};
2637EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel_table);
2452 2638
2453/* Kworld Plus TV Analog Lite PCI IR 2639/* Kworld Plus TV Analog Lite PCI IR
2454 Mauro Carvalho Chehab <mchehab@infradead.org> 2640 Mauro Carvalho Chehab <mchehab@infradead.org>
2455 */ 2641 */
2456IR_KEYTAB_TYPE ir_codes_kworld_plus_tv_analog[IR_KEYTAB_SIZE] = { 2642static struct ir_scancode ir_codes_kworld_plus_tv_analog[] = {
2457 [0x0c] = KEY_PROG1, /* Kworld key */ 2643 { 0x0c, KEY_PROG1 }, /* Kworld key */
2458 [0x16] = KEY_CLOSECD, /* -> ) */ 2644 { 0x16, KEY_CLOSECD }, /* -> ) */
2459 [0x1d] = KEY_POWER2, 2645 { 0x1d, KEY_POWER2 },
2460 2646
2461 [0x00] = KEY_1, 2647 { 0x00, KEY_1 },
2462 [0x01] = KEY_2, 2648 { 0x01, KEY_2 },
2463 [0x02] = KEY_3, /* Two keys have the same code: 3 and left */ 2649 { 0x02, KEY_3 }, /* Two keys have the same code: 3 and left */
2464 [0x03] = KEY_4, /* Two keys have the same code: 3 and right */ 2650 { 0x03, KEY_4 }, /* Two keys have the same code: 3 and right */
2465 [0x04] = KEY_5, 2651 { 0x04, KEY_5 },
2466 [0x05] = KEY_6, 2652 { 0x05, KEY_6 },
2467 [0x06] = KEY_7, 2653 { 0x06, KEY_7 },
2468 [0x07] = KEY_8, 2654 { 0x07, KEY_8 },
2469 [0x08] = KEY_9, 2655 { 0x08, KEY_9 },
2470 [0x0a] = KEY_0, 2656 { 0x0a, KEY_0 },
2471 2657
2472 [0x09] = KEY_AGAIN, 2658 { 0x09, KEY_AGAIN },
2473 [0x14] = KEY_MUTE, 2659 { 0x14, KEY_MUTE },
2474 2660
2475 [0x20] = KEY_UP, 2661 { 0x20, KEY_UP },
2476 [0x21] = KEY_DOWN, 2662 { 0x21, KEY_DOWN },
2477 [0x0b] = KEY_ENTER, 2663 { 0x0b, KEY_ENTER },
2478 2664
2479 [0x10] = KEY_CHANNELUP, 2665 { 0x10, KEY_CHANNELUP },
2480 [0x11] = KEY_CHANNELDOWN, 2666 { 0x11, KEY_CHANNELDOWN },
2481 2667
2482 /* Couldn't map key left/key right since those 2668 /* Couldn't map key left/key right since those
2483 conflict with '3' and '4' scancodes 2669 conflict with '3' and '4' scancodes
2484 I dunno what the original driver does 2670 I dunno what the original driver does
2485 */ 2671 */
2486 2672
2487 [0x13] = KEY_VOLUMEUP, 2673 { 0x13, KEY_VOLUMEUP },
2488 [0x12] = KEY_VOLUMEDOWN, 2674 { 0x12, KEY_VOLUMEDOWN },
2489 2675
2490 /* The lower part of the IR 2676 /* The lower part of the IR
2491 There are several duplicated keycodes there. 2677 There are several duplicated keycodes there.
@@ -2496,280 +2682,468 @@ IR_KEYTAB_TYPE ir_codes_kworld_plus_tv_analog[IR_KEYTAB_SIZE] = {
2496 Also, it is not related to the time between keyup 2682 Also, it is not related to the time between keyup
2497 and keydown. 2683 and keydown.
2498 */ 2684 */
2499 [0x19] = KEY_PAUSE, /* Timeshift */ 2685 { 0x19, KEY_TIME}, /* Timeshift */
2500 [0x1a] = KEY_STOP, 2686 { 0x1a, KEY_STOP},
2501 [0x1b] = KEY_RECORD, 2687 { 0x1b, KEY_RECORD},
2502 2688
2503 [0x22] = KEY_TEXT, 2689 { 0x22, KEY_TEXT},
2504 2690
2505 [0x15] = KEY_AUDIO, /* ((*)) */ 2691 { 0x15, KEY_AUDIO}, /* ((*)) */
2506 [0x0f] = KEY_ZOOM, 2692 { 0x0f, KEY_ZOOM},
2507 [0x1c] = KEY_SHUFFLE, /* snapshot */ 2693 { 0x1c, KEY_CAMERA}, /* snapshot */
2508 2694
2509 [0x18] = KEY_RED, /* B */ 2695 { 0x18, KEY_RED}, /* B */
2510 [0x23] = KEY_GREEN, /* C */ 2696 { 0x23, KEY_GREEN}, /* C */
2511}; 2697};
2512EXPORT_SYMBOL_GPL(ir_codes_kworld_plus_tv_analog); 2698struct ir_scancode_table ir_codes_kworld_plus_tv_analog_table = {
2699 .scan = ir_codes_kworld_plus_tv_analog,
2700 .size = ARRAY_SIZE(ir_codes_kworld_plus_tv_analog),
2701};
2702EXPORT_SYMBOL_GPL(ir_codes_kworld_plus_tv_analog_table);
2513 2703
2514/* Kaiomy TVnPC U2 2704/* Kaiomy TVnPC U2
2515 Mauro Carvalho Chehab <mchehab@infradead.org> 2705 Mauro Carvalho Chehab <mchehab@infradead.org>
2516 */ 2706 */
2517IR_KEYTAB_TYPE ir_codes_kaiomy[IR_KEYTAB_SIZE] = { 2707static struct ir_scancode ir_codes_kaiomy[] = {
2518 [0x43] = KEY_POWER2, 2708 { 0x43, KEY_POWER2},
2519 [0x01] = KEY_LIST, 2709 { 0x01, KEY_LIST},
2520 [0x0b] = KEY_ZOOM, 2710 { 0x0b, KEY_ZOOM},
2521 [0x03] = KEY_POWER, 2711 { 0x03, KEY_POWER},
2522
2523 [0x04] = KEY_1,
2524 [0x08] = KEY_2,
2525 [0x02] = KEY_3,
2526
2527 [0x0f] = KEY_4,
2528 [0x05] = KEY_5,
2529 [0x06] = KEY_6,
2530
2531 [0x0c] = KEY_7,
2532 [0x0d] = KEY_8,
2533 [0x0a] = KEY_9,
2534
2535 [0x11] = KEY_0,
2536
2537 [0x09] = KEY_CHANNELUP,
2538 [0x07] = KEY_CHANNELDOWN,
2539
2540 [0x0e] = KEY_VOLUMEUP,
2541 [0x13] = KEY_VOLUMEDOWN,
2542
2543 [0x10] = KEY_HOME,
2544 [0x12] = KEY_ENTER,
2545
2546 [0x14] = KEY_RECORD,
2547 [0x15] = KEY_STOP,
2548 [0x16] = KEY_PLAY,
2549 [0x17] = KEY_MUTE,
2550
2551 [0x18] = KEY_UP,
2552 [0x19] = KEY_DOWN,
2553 [0x1a] = KEY_LEFT,
2554 [0x1b] = KEY_RIGHT,
2555
2556 [0x1c] = KEY_RED,
2557 [0x1d] = KEY_GREEN,
2558 [0x1e] = KEY_YELLOW,
2559 [0x1f] = KEY_BLUE,
2560};
2561EXPORT_SYMBOL_GPL(ir_codes_kaiomy);
2562
2563IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE] = {
2564 [0x20] = KEY_LIST,
2565 [0x00] = KEY_POWER,
2566 [0x28] = KEY_1,
2567 [0x18] = KEY_2,
2568 [0x38] = KEY_3,
2569 [0x24] = KEY_4,
2570 [0x14] = KEY_5,
2571 [0x34] = KEY_6,
2572 [0x2c] = KEY_7,
2573 [0x1c] = KEY_8,
2574 [0x3c] = KEY_9,
2575 [0x12] = KEY_SUBTITLE,
2576 [0x22] = KEY_0,
2577 [0x32] = KEY_REWIND,
2578 [0x3a] = KEY_SHUFFLE,
2579 [0x02] = KEY_PRINT,
2580 [0x11] = KEY_CHANNELDOWN,
2581 [0x31] = KEY_CHANNELUP,
2582 [0x0c] = KEY_ZOOM,
2583 [0x1e] = KEY_VOLUMEDOWN,
2584 [0x3e] = KEY_VOLUMEUP,
2585 [0x0a] = KEY_MUTE,
2586 [0x04] = KEY_AUDIO,
2587 [0x26] = KEY_RECORD,
2588 [0x06] = KEY_PLAY,
2589 [0x36] = KEY_STOP,
2590 [0x16] = KEY_PAUSE,
2591 [0x2e] = KEY_REWIND,
2592 [0x0e] = KEY_FASTFORWARD,
2593 [0x30] = KEY_TEXT,
2594 [0x21] = KEY_GREEN,
2595 [0x01] = KEY_BLUE,
2596 [0x08] = KEY_EPG,
2597 [0x2a] = KEY_MENU,
2598};
2599EXPORT_SYMBOL_GPL(ir_codes_avermedia_a16d);
2600 2712
2601/* Encore ENLTV-FM v5.3 2713 { 0x04, KEY_1},
2602 Mauro Carvalho Chehab <mchehab@infradead.org> 2714 { 0x08, KEY_2},
2603 */ 2715 { 0x02, KEY_3},
2604IR_KEYTAB_TYPE ir_codes_encore_enltv_fm53[IR_KEYTAB_SIZE] = {
2605 [0x10] = KEY_POWER2,
2606 [0x06] = KEY_MUTE,
2607
2608 [0x09] = KEY_1,
2609 [0x1d] = KEY_2,
2610 [0x1f] = KEY_3,
2611 [0x19] = KEY_4,
2612 [0x1b] = KEY_5,
2613 [0x11] = KEY_6,
2614 [0x17] = KEY_7,
2615 [0x12] = KEY_8,
2616 [0x16] = KEY_9,
2617 [0x48] = KEY_0,
2618
2619 [0x04] = KEY_LIST, /* -/-- */
2620 [0x40] = KEY_LAST, /* recall */
2621
2622 [0x02] = KEY_MODE, /* TV/AV */
2623 [0x05] = KEY_SHUFFLE, /* SNAPSHOT */
2624
2625 [0x4c] = KEY_CHANNELUP, /* UP */
2626 [0x00] = KEY_CHANNELDOWN, /* DOWN */
2627 [0x0d] = KEY_VOLUMEUP, /* RIGHT */
2628 [0x15] = KEY_VOLUMEDOWN, /* LEFT */
2629 [0x49] = KEY_ENTER, /* OK */
2630
2631 [0x54] = KEY_RECORD,
2632 [0x4d] = KEY_PLAY, /* pause */
2633
2634 [0x1e] = KEY_UP, /* video setting */
2635 [0x0e] = KEY_RIGHT, /* <- */
2636 [0x1a] = KEY_LEFT, /* -> */
2637
2638 [0x0a] = KEY_DOWN, /* video default */
2639 [0x0c] = KEY_ZOOM, /* hide pannel */
2640 [0x47] = KEY_SLEEP, /* shutdown */
2641};
2642EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_fm53);
2643 2716
2644/* Zogis Real Audio 220 - 32 keys IR */ 2717 { 0x0f, KEY_4},
2645IR_KEYTAB_TYPE ir_codes_real_audio_220_32_keys[IR_KEYTAB_SIZE] = { 2718 { 0x05, KEY_5},
2646 [0x1c] = KEY_RADIO, 2719 { 0x06, KEY_6},
2647 [0x12] = KEY_POWER2, 2720
2721 { 0x0c, KEY_7},
2722 { 0x0d, KEY_8},
2723 { 0x0a, KEY_9},
2648 2724
2649 [0x01] = KEY_1, 2725 { 0x11, KEY_0},
2650 [0x02] = KEY_2,
2651 [0x03] = KEY_3,
2652 [0x04] = KEY_4,
2653 [0x05] = KEY_5,
2654 [0x06] = KEY_6,
2655 [0x07] = KEY_7,
2656 [0x08] = KEY_8,
2657 [0x09] = KEY_9,
2658 [0x00] = KEY_0,
2659 2726
2660 [0x0c] = KEY_VOLUMEUP, 2727 { 0x09, KEY_CHANNELUP},
2661 [0x18] = KEY_VOLUMEDOWN, 2728 { 0x07, KEY_CHANNELDOWN},
2662 [0x0b] = KEY_CHANNELUP,
2663 [0x15] = KEY_CHANNELDOWN,
2664 [0x16] = KEY_ENTER,
2665 2729
2666 [0x11] = KEY_LIST, /* Source */ 2730 { 0x0e, KEY_VOLUMEUP},
2667 [0x0d] = KEY_AUDIO, /* stereo */ 2731 { 0x13, KEY_VOLUMEDOWN},
2668 2732
2669 [0x0f] = KEY_PREVIOUS, /* Prev */ 2733 { 0x10, KEY_HOME},
2670 [0x1b] = KEY_PAUSE, /* Timeshift */ 2734 { 0x12, KEY_ENTER},
2671 [0x1a] = KEY_NEXT, /* Next */
2672 2735
2673 [0x0e] = KEY_STOP, 2736 { 0x14, KEY_RECORD},
2674 [0x1f] = KEY_PLAY, 2737 { 0x15, KEY_STOP},
2675 [0x1e] = KEY_PLAYPAUSE, /* Pause */ 2738 { 0x16, KEY_PLAY},
2739 { 0x17, KEY_MUTE},
2676 2740
2677 [0x1d] = KEY_RECORD, 2741 { 0x18, KEY_UP},
2678 [0x13] = KEY_MUTE, 2742 { 0x19, KEY_DOWN},
2679 [0x19] = KEY_SHUFFLE, /* Snapshot */ 2743 { 0x1a, KEY_LEFT},
2744 { 0x1b, KEY_RIGHT},
2680 2745
2746 { 0x1c, KEY_RED},
2747 { 0x1d, KEY_GREEN},
2748 { 0x1e, KEY_YELLOW},
2749 { 0x1f, KEY_BLUE},
2750};
2751struct ir_scancode_table ir_codes_kaiomy_table = {
2752 .scan = ir_codes_kaiomy,
2753 .size = ARRAY_SIZE(ir_codes_kaiomy),
2754};
2755EXPORT_SYMBOL_GPL(ir_codes_kaiomy_table);
2756
2757static struct ir_scancode ir_codes_avermedia_a16d[] = {
2758 { 0x20, KEY_LIST},
2759 { 0x00, KEY_POWER},
2760 { 0x28, KEY_1},
2761 { 0x18, KEY_2},
2762 { 0x38, KEY_3},
2763 { 0x24, KEY_4},
2764 { 0x14, KEY_5},
2765 { 0x34, KEY_6},
2766 { 0x2c, KEY_7},
2767 { 0x1c, KEY_8},
2768 { 0x3c, KEY_9},
2769 { 0x12, KEY_SUBTITLE},
2770 { 0x22, KEY_0},
2771 { 0x32, KEY_REWIND},
2772 { 0x3a, KEY_SHUFFLE},
2773 { 0x02, KEY_PRINT},
2774 { 0x11, KEY_CHANNELDOWN},
2775 { 0x31, KEY_CHANNELUP},
2776 { 0x0c, KEY_ZOOM},
2777 { 0x1e, KEY_VOLUMEDOWN},
2778 { 0x3e, KEY_VOLUMEUP},
2779 { 0x0a, KEY_MUTE},
2780 { 0x04, KEY_AUDIO},
2781 { 0x26, KEY_RECORD},
2782 { 0x06, KEY_PLAY},
2783 { 0x36, KEY_STOP},
2784 { 0x16, KEY_PAUSE},
2785 { 0x2e, KEY_REWIND},
2786 { 0x0e, KEY_FASTFORWARD},
2787 { 0x30, KEY_TEXT},
2788 { 0x21, KEY_GREEN},
2789 { 0x01, KEY_BLUE},
2790 { 0x08, KEY_EPG},
2791 { 0x2a, KEY_MENU},
2792};
2793struct ir_scancode_table ir_codes_avermedia_a16d_table = {
2794 .scan = ir_codes_avermedia_a16d,
2795 .size = ARRAY_SIZE(ir_codes_avermedia_a16d),
2681}; 2796};
2682EXPORT_SYMBOL_GPL(ir_codes_real_audio_220_32_keys); 2797EXPORT_SYMBOL_GPL(ir_codes_avermedia_a16d_table);
2798
2799/* Encore ENLTV-FM v5.3
2800 Mauro Carvalho Chehab <mchehab@infradead.org>
2801 */
2802static struct ir_scancode ir_codes_encore_enltv_fm53[] = {
2803 { 0x10, KEY_POWER2},
2804 { 0x06, KEY_MUTE},
2805
2806 { 0x09, KEY_1},
2807 { 0x1d, KEY_2},
2808 { 0x1f, KEY_3},
2809 { 0x19, KEY_4},
2810 { 0x1b, KEY_5},
2811 { 0x11, KEY_6},
2812 { 0x17, KEY_7},
2813 { 0x12, KEY_8},
2814 { 0x16, KEY_9},
2815 { 0x48, KEY_0},
2816
2817 { 0x04, KEY_LIST}, /* -/-- */
2818 { 0x40, KEY_LAST}, /* recall */
2819
2820 { 0x02, KEY_MODE}, /* TV/AV */
2821 { 0x05, KEY_CAMERA}, /* SNAPSHOT */
2822
2823 { 0x4c, KEY_CHANNELUP}, /* UP */
2824 { 0x00, KEY_CHANNELDOWN}, /* DOWN */
2825 { 0x0d, KEY_VOLUMEUP}, /* RIGHT */
2826 { 0x15, KEY_VOLUMEDOWN}, /* LEFT */
2827 { 0x49, KEY_ENTER}, /* OK */
2828
2829 { 0x54, KEY_RECORD},
2830 { 0x4d, KEY_PLAY}, /* pause */
2831
2832 { 0x1e, KEY_MENU}, /* video setting */
2833 { 0x0e, KEY_RIGHT}, /* <- */
2834 { 0x1a, KEY_LEFT}, /* -> */
2835
2836 { 0x0a, KEY_CLEAR}, /* video default */
2837 { 0x0c, KEY_ZOOM}, /* hide pannel */
2838 { 0x47, KEY_SLEEP}, /* shutdown */
2839};
2840struct ir_scancode_table ir_codes_encore_enltv_fm53_table = {
2841 .scan = ir_codes_encore_enltv_fm53,
2842 .size = ARRAY_SIZE(ir_codes_encore_enltv_fm53),
2843};
2844EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_fm53_table);
2845
2846/* Zogis Real Audio 220 - 32 keys IR */
2847static struct ir_scancode ir_codes_real_audio_220_32_keys[] = {
2848 { 0x1c, KEY_RADIO},
2849 { 0x12, KEY_POWER2},
2850
2851 { 0x01, KEY_1},
2852 { 0x02, KEY_2},
2853 { 0x03, KEY_3},
2854 { 0x04, KEY_4},
2855 { 0x05, KEY_5},
2856 { 0x06, KEY_6},
2857 { 0x07, KEY_7},
2858 { 0x08, KEY_8},
2859 { 0x09, KEY_9},
2860 { 0x00, KEY_0},
2861
2862 { 0x0c, KEY_VOLUMEUP},
2863 { 0x18, KEY_VOLUMEDOWN},
2864 { 0x0b, KEY_CHANNELUP},
2865 { 0x15, KEY_CHANNELDOWN},
2866 { 0x16, KEY_ENTER},
2867
2868 { 0x11, KEY_LIST}, /* Source */
2869 { 0x0d, KEY_AUDIO}, /* stereo */
2870
2871 { 0x0f, KEY_PREVIOUS}, /* Prev */
2872 { 0x1b, KEY_TIME}, /* Timeshift */
2873 { 0x1a, KEY_NEXT}, /* Next */
2874
2875 { 0x0e, KEY_STOP},
2876 { 0x1f, KEY_PLAY},
2877 { 0x1e, KEY_PLAYPAUSE}, /* Pause */
2878
2879 { 0x1d, KEY_RECORD},
2880 { 0x13, KEY_MUTE},
2881 { 0x19, KEY_CAMERA}, /* Snapshot */
2882
2883};
2884struct ir_scancode_table ir_codes_real_audio_220_32_keys_table = {
2885 .scan = ir_codes_real_audio_220_32_keys,
2886 .size = ARRAY_SIZE(ir_codes_real_audio_220_32_keys),
2887};
2888EXPORT_SYMBOL_GPL(ir_codes_real_audio_220_32_keys_table);
2683 2889
2684/* ATI TV Wonder HD 600 USB 2890/* ATI TV Wonder HD 600 USB
2685 Devin Heitmueller <devin.heitmueller@gmail.com> 2891 Devin Heitmueller <devin.heitmueller@gmail.com>
2686 */ 2892 */
2687IR_KEYTAB_TYPE ir_codes_ati_tv_wonder_hd_600[IR_KEYTAB_SIZE] = { 2893static struct ir_scancode ir_codes_ati_tv_wonder_hd_600[] = {
2688 [0x00] = KEY_RECORD, /* Row 1 */ 2894 { 0x00, KEY_RECORD}, /* Row 1 */
2689 [0x01] = KEY_PLAYPAUSE, 2895 { 0x01, KEY_PLAYPAUSE},
2690 [0x02] = KEY_STOP, 2896 { 0x02, KEY_STOP},
2691 [0x03] = KEY_POWER, 2897 { 0x03, KEY_POWER},
2692 [0x04] = KEY_PREVIOUS, /* Row 2 */ 2898 { 0x04, KEY_PREVIOUS}, /* Row 2 */
2693 [0x05] = KEY_REWIND, 2899 { 0x05, KEY_REWIND},
2694 [0x06] = KEY_FORWARD, 2900 { 0x06, KEY_FORWARD},
2695 [0x07] = KEY_NEXT, 2901 { 0x07, KEY_NEXT},
2696 [0x08] = KEY_EPG, /* Row 3 */ 2902 { 0x08, KEY_EPG}, /* Row 3 */
2697 [0x09] = KEY_HOME, 2903 { 0x09, KEY_HOME},
2698 [0x0a] = KEY_MENU, 2904 { 0x0a, KEY_MENU},
2699 [0x0b] = KEY_CHANNELUP, 2905 { 0x0b, KEY_CHANNELUP},
2700 [0x0c] = KEY_BACK, /* Row 4 */ 2906 { 0x0c, KEY_BACK}, /* Row 4 */
2701 [0x0d] = KEY_UP, 2907 { 0x0d, KEY_UP},
2702 [0x0e] = KEY_INFO, 2908 { 0x0e, KEY_INFO},
2703 [0x0f] = KEY_CHANNELDOWN, 2909 { 0x0f, KEY_CHANNELDOWN},
2704 [0x10] = KEY_LEFT, /* Row 5 */ 2910 { 0x10, KEY_LEFT}, /* Row 5 */
2705 [0x11] = KEY_SELECT, 2911 { 0x11, KEY_SELECT},
2706 [0x12] = KEY_RIGHT, 2912 { 0x12, KEY_RIGHT},
2707 [0x13] = KEY_VOLUMEUP, 2913 { 0x13, KEY_VOLUMEUP},
2708 [0x14] = KEY_LAST, /* Row 6 */ 2914 { 0x14, KEY_LAST}, /* Row 6 */
2709 [0x15] = KEY_DOWN, 2915 { 0x15, KEY_DOWN},
2710 [0x16] = KEY_MUTE, 2916 { 0x16, KEY_MUTE},
2711 [0x17] = KEY_VOLUMEDOWN, 2917 { 0x17, KEY_VOLUMEDOWN},
2712}; 2918};
2713 2919struct ir_scancode_table ir_codes_ati_tv_wonder_hd_600_table = {
2714EXPORT_SYMBOL_GPL(ir_codes_ati_tv_wonder_hd_600); 2920 .scan = ir_codes_ati_tv_wonder_hd_600,
2921 .size = ARRAY_SIZE(ir_codes_ati_tv_wonder_hd_600),
2922};
2923EXPORT_SYMBOL_GPL(ir_codes_ati_tv_wonder_hd_600_table);
2715 2924
2716/* DVBWorld remotes 2925/* DVBWorld remotes
2717 Igor M. Liplianin <liplianin@me.by> 2926 Igor M. Liplianin <liplianin@me.by>
2718 */ 2927 */
2719IR_KEYTAB_TYPE ir_codes_dm1105_nec[IR_KEYTAB_SIZE] = { 2928static struct ir_scancode ir_codes_dm1105_nec[] = {
2720 [0x0a] = KEY_Q, /*power*/ 2929 { 0x0a, KEY_POWER2}, /* power */
2721 [0x0c] = KEY_M, /*mute*/ 2930 { 0x0c, KEY_MUTE}, /* mute */
2722 [0x11] = KEY_1, 2931 { 0x11, KEY_1},
2723 [0x12] = KEY_2, 2932 { 0x12, KEY_2},
2724 [0x13] = KEY_3, 2933 { 0x13, KEY_3},
2725 [0x14] = KEY_4, 2934 { 0x14, KEY_4},
2726 [0x15] = KEY_5, 2935 { 0x15, KEY_5},
2727 [0x16] = KEY_6, 2936 { 0x16, KEY_6},
2728 [0x17] = KEY_7, 2937 { 0x17, KEY_7},
2729 [0x18] = KEY_8, 2938 { 0x18, KEY_8},
2730 [0x19] = KEY_9, 2939 { 0x19, KEY_9},
2731 [0x10] = KEY_0, 2940 { 0x10, KEY_0},
2732 [0x1c] = KEY_PAGEUP, /*ch+*/ 2941 { 0x1c, KEY_CHANNELUP}, /* ch+ */
2733 [0x0f] = KEY_PAGEDOWN, /*ch-*/ 2942 { 0x0f, KEY_CHANNELDOWN}, /* ch- */
2734 [0x1a] = KEY_O, /*vol+*/ 2943 { 0x1a, KEY_VOLUMEUP}, /* vol+ */
2735 [0x0e] = KEY_Z, /*vol-*/ 2944 { 0x0e, KEY_VOLUMEDOWN}, /* vol- */
2736 [0x04] = KEY_R, /*rec*/ 2945 { 0x04, KEY_RECORD}, /* rec */
2737 [0x09] = KEY_D, /*fav*/ 2946 { 0x09, KEY_CHANNEL}, /* fav */
2738 [0x08] = KEY_BACKSPACE, /*rewind*/ 2947 { 0x08, KEY_BACKSPACE}, /* rewind */
2739 [0x07] = KEY_A, /*fast*/ 2948 { 0x07, KEY_FASTFORWARD}, /* fast */
2740 [0x0b] = KEY_P, /*pause*/ 2949 { 0x0b, KEY_PAUSE}, /* pause */
2741 [0x02] = KEY_ESC, /*cancel*/ 2950 { 0x02, KEY_ESC}, /* cancel */
2742 [0x03] = KEY_G, /*tab*/ 2951 { 0x03, KEY_TAB}, /* tab */
2743 [0x00] = KEY_UP, /*up*/ 2952 { 0x00, KEY_UP}, /* up */
2744 [0x1f] = KEY_ENTER, /*ok*/ 2953 { 0x1f, KEY_ENTER}, /* ok */
2745 [0x01] = KEY_DOWN, /*down*/ 2954 { 0x01, KEY_DOWN}, /* down */
2746 [0x05] = KEY_C, /*cap*/ 2955 { 0x05, KEY_RECORD}, /* cap */
2747 [0x06] = KEY_S, /*stop*/ 2956 { 0x06, KEY_STOP}, /* stop */
2748 [0x40] = KEY_F, /*full*/ 2957 { 0x40, KEY_ZOOM}, /* full */
2749 [0x1e] = KEY_W, /*tvmode*/ 2958 { 0x1e, KEY_TV}, /* tvmode */
2750 [0x1b] = KEY_B, /*recall*/ 2959 { 0x1b, KEY_B}, /* recall */
2751}; 2960};
2752EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec); 2961struct ir_scancode_table ir_codes_dm1105_nec_table = {
2962 .scan = ir_codes_dm1105_nec,
2963 .size = ARRAY_SIZE(ir_codes_dm1105_nec),
2964};
2965EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec_table);
2966
2967/* Terratec Cinergy Hybrid T USB XS
2968 Devin Heitmueller <dheitmueller@linuxtv.org>
2969 */
2970static struct ir_scancode ir_codes_terratec_cinergy_xs[] = {
2971 { 0x41, KEY_HOME},
2972 { 0x01, KEY_POWER},
2973 { 0x42, KEY_MENU},
2974 { 0x02, KEY_1},
2975 { 0x03, KEY_2},
2976 { 0x04, KEY_3},
2977 { 0x43, KEY_SUBTITLE},
2978 { 0x05, KEY_4},
2979 { 0x06, KEY_5},
2980 { 0x07, KEY_6},
2981 { 0x44, KEY_TEXT},
2982 { 0x08, KEY_7},
2983 { 0x09, KEY_8},
2984 { 0x0a, KEY_9},
2985 { 0x45, KEY_DELETE},
2986 { 0x0b, KEY_TUNER},
2987 { 0x0c, KEY_0},
2988 { 0x0d, KEY_MODE},
2989 { 0x46, KEY_TV},
2990 { 0x47, KEY_DVD},
2991 { 0x49, KEY_VIDEO},
2992 { 0x4b, KEY_AUX},
2993 { 0x10, KEY_UP},
2994 { 0x11, KEY_LEFT},
2995 { 0x12, KEY_OK},
2996 { 0x13, KEY_RIGHT},
2997 { 0x14, KEY_DOWN},
2998 { 0x0f, KEY_EPG},
2999 { 0x16, KEY_INFO},
3000 { 0x4d, KEY_BACKSPACE},
3001 { 0x1c, KEY_VOLUMEUP},
3002 { 0x4c, KEY_PLAY},
3003 { 0x1b, KEY_CHANNELUP},
3004 { 0x1e, KEY_VOLUMEDOWN},
3005 { 0x1d, KEY_MUTE},
3006 { 0x1f, KEY_CHANNELDOWN},
3007 { 0x17, KEY_RED},
3008 { 0x18, KEY_GREEN},
3009 { 0x19, KEY_YELLOW},
3010 { 0x1a, KEY_BLUE},
3011 { 0x58, KEY_RECORD},
3012 { 0x48, KEY_STOP},
3013 { 0x40, KEY_PAUSE},
3014 { 0x54, KEY_LAST},
3015 { 0x4e, KEY_REWIND},
3016 { 0x4f, KEY_FASTFORWARD},
3017 { 0x5c, KEY_NEXT},
3018};
3019struct ir_scancode_table ir_codes_terratec_cinergy_xs_table = {
3020 .scan = ir_codes_terratec_cinergy_xs,
3021 .size = ARRAY_SIZE(ir_codes_terratec_cinergy_xs),
3022};
3023EXPORT_SYMBOL_GPL(ir_codes_terratec_cinergy_xs_table);
2753 3024
2754/* EVGA inDtube 3025/* EVGA inDtube
2755 Devin Heitmueller <devin.heitmueller@gmail.com> 3026 Devin Heitmueller <devin.heitmueller@gmail.com>
2756 */ 3027 */
2757IR_KEYTAB_TYPE ir_codes_evga_indtube[IR_KEYTAB_SIZE] = { 3028static struct ir_scancode ir_codes_evga_indtube[] = {
2758 [0x12] = KEY_POWER, 3029 { 0x12, KEY_POWER},
2759 [0x02] = KEY_MODE, /* TV */ 3030 { 0x02, KEY_MODE}, /* TV */
2760 [0x14] = KEY_MUTE, 3031 { 0x14, KEY_MUTE},
2761 [0x1a] = KEY_CHANNELUP, 3032 { 0x1a, KEY_CHANNELUP},
2762 [0x16] = KEY_TV2, /* PIP */ 3033 { 0x16, KEY_TV2}, /* PIP */
2763 [0x1d] = KEY_VOLUMEUP, 3034 { 0x1d, KEY_VOLUMEUP},
2764 [0x05] = KEY_CHANNELDOWN, 3035 { 0x05, KEY_CHANNELDOWN},
2765 [0x0f] = KEY_PLAYPAUSE, 3036 { 0x0f, KEY_PLAYPAUSE},
2766 [0x19] = KEY_VOLUMEDOWN, 3037 { 0x19, KEY_VOLUMEDOWN},
2767 [0x1c] = KEY_REWIND, 3038 { 0x1c, KEY_REWIND},
2768 [0x0d] = KEY_RECORD, 3039 { 0x0d, KEY_RECORD},
2769 [0x18] = KEY_FORWARD, 3040 { 0x18, KEY_FORWARD},
2770 [0x1e] = KEY_PREVIOUS, 3041 { 0x1e, KEY_PREVIOUS},
2771 [0x1b] = KEY_STOP, 3042 { 0x1b, KEY_STOP},
2772 [0x1f] = KEY_NEXT, 3043 { 0x1f, KEY_NEXT},
2773 [0x13] = KEY_CAMERA, 3044 { 0x13, KEY_CAMERA},
2774}; 3045};
2775EXPORT_SYMBOL_GPL(ir_codes_evga_indtube); 3046struct ir_scancode_table ir_codes_evga_indtube_table = {
3047 .scan = ir_codes_evga_indtube,
3048 .size = ARRAY_SIZE(ir_codes_evga_indtube),
3049};
3050EXPORT_SYMBOL_GPL(ir_codes_evga_indtube_table);
3051
3052static struct ir_scancode ir_codes_videomate_s350[] = {
3053 { 0x00, KEY_TV},
3054 { 0x01, KEY_DVD},
3055 { 0x04, KEY_RECORD},
3056 { 0x05, KEY_VIDEO}, /* TV/Video */
3057 { 0x07, KEY_STOP},
3058 { 0x08, KEY_PLAYPAUSE},
3059 { 0x0a, KEY_REWIND},
3060 { 0x0f, KEY_FASTFORWARD},
3061 { 0x10, KEY_CHANNELUP},
3062 { 0x12, KEY_VOLUMEUP},
3063 { 0x13, KEY_CHANNELDOWN},
3064 { 0x14, KEY_MUTE},
3065 { 0x15, KEY_VOLUMEDOWN},
3066 { 0x16, KEY_1},
3067 { 0x17, KEY_2},
3068 { 0x18, KEY_3},
3069 { 0x19, KEY_4},
3070 { 0x1a, KEY_5},
3071 { 0x1b, KEY_6},
3072 { 0x1c, KEY_7},
3073 { 0x1d, KEY_8},
3074 { 0x1e, KEY_9},
3075 { 0x1f, KEY_0},
3076 { 0x21, KEY_SLEEP},
3077 { 0x24, KEY_ZOOM},
3078 { 0x25, KEY_LAST}, /* Recall */
3079 { 0x26, KEY_SUBTITLE}, /* CC */
3080 { 0x27, KEY_LANGUAGE}, /* MTS */
3081 { 0x29, KEY_CHANNEL}, /* SURF */
3082 { 0x2b, KEY_A},
3083 { 0x2c, KEY_B},
3084 { 0x2f, KEY_CAMERA}, /* Snapshot */
3085 { 0x23, KEY_RADIO},
3086 { 0x02, KEY_PREVIOUSSONG},
3087 { 0x06, KEY_NEXTSONG},
3088 { 0x03, KEY_EPG},
3089 { 0x09, KEY_SETUP},
3090 { 0x22, KEY_BACKSPACE},
3091 { 0x0c, KEY_UP},
3092 { 0x0e, KEY_DOWN},
3093 { 0x0b, KEY_LEFT},
3094 { 0x0d, KEY_RIGHT},
3095 { 0x11, KEY_ENTER},
3096 { 0x20, KEY_TEXT},
3097};
3098struct ir_scancode_table ir_codes_videomate_s350_table = {
3099 .scan = ir_codes_videomate_s350,
3100 .size = ARRAY_SIZE(ir_codes_videomate_s350),
3101};
3102EXPORT_SYMBOL_GPL(ir_codes_videomate_s350_table);
3103
3104/* GADMEI UTV330+ RM008Z remote
3105 Shine Liu <shinel@foxmail.com>
3106 */
3107static struct ir_scancode ir_codes_gadmei_rm008z[] = {
3108 { 0x14, KEY_POWER2}, /* POWER OFF */
3109 { 0x0c, KEY_MUTE}, /* MUTE */
3110
3111 { 0x18, KEY_TV}, /* TV */
3112 { 0x0e, KEY_VIDEO}, /* AV */
3113 { 0x0b, KEY_AUDIO}, /* SV */
3114 { 0x0f, KEY_RADIO}, /* FM */
3115
3116 { 0x00, KEY_1},
3117 { 0x01, KEY_2},
3118 { 0x02, KEY_3},
3119 { 0x03, KEY_4},
3120 { 0x04, KEY_5},
3121 { 0x05, KEY_6},
3122 { 0x06, KEY_7},
3123 { 0x07, KEY_8},
3124 { 0x08, KEY_9},
3125 { 0x09, KEY_0},
3126 { 0x0a, KEY_INFO}, /* OSD */
3127 { 0x1c, KEY_BACKSPACE}, /* LAST */
3128
3129 { 0x0d, KEY_PLAY}, /* PLAY */
3130 { 0x1e, KEY_CAMERA}, /* SNAPSHOT */
3131 { 0x1a, KEY_RECORD}, /* RECORD */
3132 { 0x17, KEY_STOP}, /* STOP */
3133
3134 { 0x1f, KEY_UP}, /* UP */
3135 { 0x44, KEY_DOWN}, /* DOWN */
3136 { 0x46, KEY_TAB}, /* BACK */
3137 { 0x4a, KEY_ZOOM}, /* FULLSECREEN */
3138
3139 { 0x10, KEY_VOLUMEUP}, /* VOLUMEUP */
3140 { 0x11, KEY_VOLUMEDOWN}, /* VOLUMEDOWN */
3141 { 0x12, KEY_CHANNELUP}, /* CHANNELUP */
3142 { 0x13, KEY_CHANNELDOWN}, /* CHANNELDOWN */
3143 { 0x15, KEY_ENTER}, /* OK */
3144};
3145struct ir_scancode_table ir_codes_gadmei_rm008z_table = {
3146 .scan = ir_codes_gadmei_rm008z,
3147 .size = ARRAY_SIZE(ir_codes_gadmei_rm008z),
3148};
3149EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table);
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
index b10935630154..bc4b004ba7db 100644
--- a/drivers/media/common/tuners/tda18271-fe.c
+++ b/drivers/media/common/tuners/tda18271-fe.c
@@ -27,7 +27,7 @@ module_param_named(debug, tda18271_debug, int, 0644);
27MODULE_PARM_DESC(debug, "set debug level " 27MODULE_PARM_DESC(debug, "set debug level "
28 "(info=1, map=2, reg=4, adv=8, cal=16 (or-able))"); 28 "(info=1, map=2, reg=4, adv=8, cal=16 (or-able))");
29 29
30static int tda18271_cal_on_startup; 30static int tda18271_cal_on_startup = -1;
31module_param_named(cal, tda18271_cal_on_startup, int, 0644); 31module_param_named(cal, tda18271_cal_on_startup, int, 0644);
32MODULE_PARM_DESC(cal, "perform RF tracking filter calibration on startup"); 32MODULE_PARM_DESC(cal, "perform RF tracking filter calibration on startup");
33 33
@@ -1192,10 +1192,25 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
1192 case 0: 1192 case 0:
1193 goto fail; 1193 goto fail;
1194 case 1: 1194 case 1:
1195 {
1195 /* new tuner instance */ 1196 /* new tuner instance */
1197 int rf_cal_on_startup;
1198
1196 priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; 1199 priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
1197 priv->role = (cfg) ? cfg->role : TDA18271_MASTER; 1200 priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
1198 priv->config = (cfg) ? cfg->config : 0; 1201 priv->config = (cfg) ? cfg->config : 0;
1202
1203 /* tda18271_cal_on_startup == -1 when cal
1204 * module option is unset */
1205 if (tda18271_cal_on_startup == -1) {
1206 /* honor attach-time configuration */
1207 rf_cal_on_startup =
1208 ((cfg) && (cfg->rf_cal_on_startup)) ? 1 : 0;
1209 } else {
1210 /* module option overrides attach configuration */
1211 rf_cal_on_startup = tda18271_cal_on_startup;
1212 }
1213
1199 priv->cal_initialized = false; 1214 priv->cal_initialized = false;
1200 mutex_init(&priv->lock); 1215 mutex_init(&priv->lock);
1201 1216
@@ -1213,11 +1228,12 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
1213 mutex_lock(&priv->lock); 1228 mutex_lock(&priv->lock);
1214 tda18271_init_regs(fe); 1229 tda18271_init_regs(fe);
1215 1230
1216 if ((tda18271_cal_on_startup) && (priv->id == TDA18271HDC2)) 1231 if ((rf_cal_on_startup) && (priv->id == TDA18271HDC2))
1217 tda18271c2_rf_cal_init(fe); 1232 tda18271c2_rf_cal_init(fe);
1218 1233
1219 mutex_unlock(&priv->lock); 1234 mutex_unlock(&priv->lock);
1220 break; 1235 break;
1236 }
1221 default: 1237 default:
1222 /* existing tuner instance */ 1238 /* existing tuner instance */
1223 fe->tuner_priv = priv; 1239 fe->tuner_priv = priv;
diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h
index 74beb28806f8..e6a80ad09356 100644
--- a/drivers/media/common/tuners/tda18271-priv.h
+++ b/drivers/media/common/tuners/tda18271-priv.h
@@ -137,17 +137,17 @@ extern int tda18271_debug;
137#define tda_printk(kern, fmt, arg...) \ 137#define tda_printk(kern, fmt, arg...) \
138 printk(kern "%s: " fmt, __func__, ##arg) 138 printk(kern "%s: " fmt, __func__, ##arg)
139 139
140#define dprintk(kern, lvl, fmt, arg...) do {\ 140#define tda_dprintk(lvl, fmt, arg...) do {\
141 if (tda18271_debug & lvl) \ 141 if (tda18271_debug & lvl) \
142 tda_printk(kern, fmt, ##arg); } while (0) 142 tda_printk(KERN_DEBUG, fmt, ##arg); } while (0)
143 143
144#define tda_info(fmt, arg...) printk(KERN_INFO fmt, ##arg) 144#define tda_info(fmt, arg...) printk(KERN_INFO fmt, ##arg)
145#define tda_warn(fmt, arg...) tda_printk(KERN_WARNING, fmt, ##arg) 145#define tda_warn(fmt, arg...) tda_printk(KERN_WARNING, fmt, ##arg)
146#define tda_err(fmt, arg...) tda_printk(KERN_ERR, fmt, ##arg) 146#define tda_err(fmt, arg...) tda_printk(KERN_ERR, fmt, ##arg)
147#define tda_dbg(fmt, arg...) dprintk(KERN_DEBUG, DBG_INFO, fmt, ##arg) 147#define tda_dbg(fmt, arg...) tda_dprintk(DBG_INFO, fmt, ##arg)
148#define tda_map(fmt, arg...) dprintk(KERN_DEBUG, DBG_MAP, fmt, ##arg) 148#define tda_map(fmt, arg...) tda_dprintk(DBG_MAP, fmt, ##arg)
149#define tda_reg(fmt, arg...) dprintk(KERN_DEBUG, DBG_REG, fmt, ##arg) 149#define tda_reg(fmt, arg...) tda_dprintk(DBG_REG, fmt, ##arg)
150#define tda_cal(fmt, arg...) dprintk(KERN_DEBUG, DBG_CAL, fmt, ##arg) 150#define tda_cal(fmt, arg...) tda_dprintk(DBG_CAL, fmt, ##arg)
151 151
152#define tda_fail(ret) \ 152#define tda_fail(ret) \
153({ \ 153({ \
diff --git a/drivers/media/common/tuners/tda18271.h b/drivers/media/common/tuners/tda18271.h
index 53a9892a18d0..71bac9593f1e 100644
--- a/drivers/media/common/tuners/tda18271.h
+++ b/drivers/media/common/tuners/tda18271.h
@@ -77,6 +77,9 @@ struct tda18271_config {
77 /* use i2c gate provided by analog or digital demod */ 77 /* use i2c gate provided by analog or digital demod */
78 enum tda18271_i2c_gate gate; 78 enum tda18271_i2c_gate gate;
79 79
80 /* force rf tracking filter calibration on startup */
81 unsigned int rf_cal_on_startup:1;
82
80 /* some i2c providers cant write all 39 registers at once */ 83 /* some i2c providers cant write all 39 registers at once */
81 unsigned int small_i2c:1; 84 unsigned int small_i2c:1;
82 85
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c
index 149d54cdf7b9..8abbcc5fcf95 100644
--- a/drivers/media/common/tuners/tuner-simple.c
+++ b/drivers/media/common/tuners/tuner-simple.c
@@ -144,6 +144,8 @@ static inline int tuner_stereo(const int type, const int status)
144 case TUNER_LG_NTSC_TAPE: 144 case TUNER_LG_NTSC_TAPE:
145 case TUNER_TCL_MF02GIP_5N: 145 case TUNER_TCL_MF02GIP_5N:
146 return ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); 146 return ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
147 case TUNER_PHILIPS_FM1216MK5:
148 return status | TUNER_STEREO;
147 default: 149 default:
148 return status & TUNER_STEREO; 150 return status & TUNER_STEREO;
149 } 151 }
@@ -508,6 +510,10 @@ static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer)
508 case TUNER_TCL_MF02GIP_5N: 510 case TUNER_TCL_MF02GIP_5N:
509 buffer[3] = 0x19; 511 buffer[3] = 0x19;
510 break; 512 break;
513 case TUNER_PHILIPS_FM1216MK5:
514 buffer[2] = 0x88;
515 buffer[3] = 0x09;
516 break;
511 case TUNER_TNF_5335MF: 517 case TUNER_TNF_5335MF:
512 buffer[3] = 0x11; 518 buffer[3] = 0x11;
513 break; 519 break;
diff --git a/drivers/media/common/tuners/tuner-types.c b/drivers/media/common/tuners/tuner-types.c
index 6a7f1a417c27..5c6ef1e23c94 100644
--- a/drivers/media/common/tuners/tuner-types.c
+++ b/drivers/media/common/tuners/tuner-types.c
@@ -1301,6 +1301,25 @@ static struct tuner_params tuner_fq1216lme_mk3_params[] = {
1301 }, 1301 },
1302}; 1302};
1303 1303
1304/* ----- TUNER_PARTSNIC_PTI_5NF05 - Partsnic (Daewoo) PTI-5NF05 NTSC ----- */
1305
1306static struct tuner_range tuner_partsnic_pti_5nf05_ranges[] = {
1307 /* The datasheet specified channel ranges and the bandswitch byte */
1308 /* The control byte value of 0x8e is just a guess */
1309 { 16 * 133.25 /*MHz*/, 0x8e, 0x01, }, /* Channels 2 - B */
1310 { 16 * 367.25 /*MHz*/, 0x8e, 0x02, }, /* Channels C - W+11 */
1311 { 16 * 999.99 , 0x8e, 0x08, }, /* Channels W+12 - 69 */
1312};
1313
1314static struct tuner_params tuner_partsnic_pti_5nf05_params[] = {
1315 {
1316 .type = TUNER_PARAM_TYPE_NTSC,
1317 .ranges = tuner_partsnic_pti_5nf05_ranges,
1318 .count = ARRAY_SIZE(tuner_partsnic_pti_5nf05_ranges),
1319 .cb_first_if_lower_freq = 1, /* not specified but safe to do */
1320 },
1321};
1322
1304/* --------------------------------------------------------------------- */ 1323/* --------------------------------------------------------------------- */
1305 1324
1306struct tunertype tuners[] = { 1325struct tunertype tuners[] = {
@@ -1753,6 +1772,12 @@ struct tunertype tuners[] = {
1753 .params = tuner_fq1216lme_mk3_params, 1772 .params = tuner_fq1216lme_mk3_params,
1754 .count = ARRAY_SIZE(tuner_fq1216lme_mk3_params), 1773 .count = ARRAY_SIZE(tuner_fq1216lme_mk3_params),
1755 }, 1774 },
1775
1776 [TUNER_PARTSNIC_PTI_5NF05] = {
1777 .name = "Partsnic (Daewoo) PTI-5NF05",
1778 .params = tuner_partsnic_pti_5nf05_params,
1779 .count = ARRAY_SIZE(tuner_partsnic_pti_5nf05_params),
1780 },
1756}; 1781};
1757EXPORT_SYMBOL(tuners); 1782EXPORT_SYMBOL(tuners);
1758 1783
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index b0198691892a..1d0e4b1ef10c 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -2,6 +2,19 @@
2# DVB device configuration 2# DVB device configuration
3# 3#
4 4
5config DVB_MAX_ADAPTERS
6 int "maximum number of DVB/ATSC adapters"
7 depends on DVB_CORE
8 default 8
9 range 1 255
10 help
11 Maximum number of DVB/ATSC adapters. Increasing this number
12 increases the memory consumption of the DVB subsystem even
13 if a much lower number of DVB/ATSC adapters is present.
14 Only values in the range 4-32 are tested.
15
16 If you are unsure about this, use the default value 8
17
5config DVB_DYNAMIC_MINORS 18config DVB_DYNAMIC_MINORS
6 bool "Dynamic DVB minor allocation" 19 bool "Dynamic DVB minor allocation"
7 depends on DVB_CORE 20 depends on DVB_CORE
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 9a6307a347b2..850a6c606750 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -66,7 +66,7 @@ static int flexcop_sleep(struct dvb_frontend* fe)
66#endif 66#endif
67 67
68/* SkyStar2 DVB-S rev 2.3 */ 68/* SkyStar2 DVB-S rev 2.3 */
69#if FE_SUPPORTED(MT312) 69#if FE_SUPPORTED(MT312) && FE_SUPPORTED(PLL)
70static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) 70static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
71{ 71{
72/* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */ 72/* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */
@@ -155,55 +155,34 @@ static struct mt312_config skystar23_samsung_tbdu18132_config = {
155 .demod_address = 0x0e, 155 .demod_address = 0x0e,
156}; 156};
157 157
158static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend *fe,
159 struct dvb_frontend_parameters *params)
160{
161 u8 buf[4];
162 u32 div;
163 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf,
164 .len = sizeof(buf) };
165 struct flexcop_device *fc = fe->dvb->priv;
166 div = (params->frequency + (125/2)) / 125;
167
168 buf[0] = (div >> 8) & 0x7f;
169 buf[1] = (div >> 0) & 0xff;
170 buf[2] = 0x84 | ((div >> 10) & 0x60);
171 buf[3] = 0x80;
172
173 if (params->frequency < 1550000)
174 buf[3] |= 0x02;
175
176 if (fe->ops.i2c_gate_ctrl)
177 fe->ops.i2c_gate_ctrl(fe, 1);
178 if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1)
179 return -EIO;
180 return 0;
181}
182
183static int skystar2_rev23_attach(struct flexcop_device *fc, 158static int skystar2_rev23_attach(struct flexcop_device *fc,
184 struct i2c_adapter *i2c) 159 struct i2c_adapter *i2c)
185{ 160{
161 struct dvb_frontend_ops *ops;
162
186 fc->fe = dvb_attach(mt312_attach, &skystar23_samsung_tbdu18132_config, i2c); 163 fc->fe = dvb_attach(mt312_attach, &skystar23_samsung_tbdu18132_config, i2c);
187 if (fc->fe != NULL) { 164 if (!fc->fe)
188 struct dvb_frontend_ops *ops = &fc->fe->ops; 165 return 0;
189 ops->tuner_ops.set_params = 166
190 skystar23_samsung_tbdu18132_tuner_set_params; 167 if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61, i2c,
191 ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; 168 DVB_PLL_SAMSUNG_TBDU18132))
192 ops->diseqc_send_burst = flexcop_diseqc_send_burst; 169 return 0;
193 ops->set_tone = flexcop_set_tone; 170
194 ops->set_voltage = flexcop_set_voltage; 171 ops = &fc->fe->ops;
195 fc->fe_sleep = ops->sleep; 172 ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
196 ops->sleep = flexcop_sleep; 173 ops->diseqc_send_burst = flexcop_diseqc_send_burst;
197 return 1; 174 ops->set_tone = flexcop_set_tone;
198 } 175 ops->set_voltage = flexcop_set_voltage;
199 return 0; 176 fc->fe_sleep = ops->sleep;
177 ops->sleep = flexcop_sleep;
178 return 1;
200} 179}
201#else 180#else
202#define skystar2_rev23_attach NULL 181#define skystar2_rev23_attach NULL
203#endif 182#endif
204 183
205/* SkyStar2 DVB-S rev 2.6 */ 184/* SkyStar2 DVB-S rev 2.6 */
206#if FE_SUPPORTED(STV0299) 185#if FE_SUPPORTED(STV0299) && FE_SUPPORTED(PLL)
207static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe, 186static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe,
208 u32 srate, u32 ratio) 187 u32 srate, u32 ratio)
209{ 188{
@@ -232,31 +211,6 @@ static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe,
232 return 0; 211 return 0;
233} 212}
234 213
235static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend *fe,
236 struct dvb_frontend_parameters *params)
237{
238 u8 buf[4];
239 u32 div;
240 struct i2c_msg msg = {
241 .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
242 struct flexcop_device *fc = fe->dvb->priv;
243 div = params->frequency / 125;
244
245 buf[0] = (div >> 8) & 0x7f;
246 buf[1] = div & 0xff;
247 buf[2] = 0x84; /* 0xC4 */
248 buf[3] = 0x08;
249
250 if (params->frequency < 1500000)
251 buf[3] |= 0x10;
252
253 if (fe->ops.i2c_gate_ctrl)
254 fe->ops.i2c_gate_ctrl(fe, 1);
255 if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1)
256 return -EIO;
257 return 0;
258}
259
260static u8 samsung_tbmu24112_inittab[] = { 214static u8 samsung_tbmu24112_inittab[] = {
261 0x01, 0x15, 215 0x01, 0x15,
262 0x02, 0x30, 216 0x02, 0x30,
@@ -318,15 +272,18 @@ static int skystar2_rev26_attach(struct flexcop_device *fc,
318 struct i2c_adapter *i2c) 272 struct i2c_adapter *i2c)
319{ 273{
320 fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c); 274 fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c);
321 if (fc->fe != NULL) { 275 if (!fc->fe)
322 struct dvb_frontend_ops *ops = &fc->fe->ops; 276 return 0;
323 ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params; 277
324 ops->set_voltage = flexcop_set_voltage; 278 if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61, i2c,
325 fc->fe_sleep = ops->sleep; 279 DVB_PLL_SAMSUNG_TBMU24112))
326 ops->sleep = flexcop_sleep; 280 return 0;
327 return 1; 281
328 } 282 fc->fe->ops.set_voltage = flexcop_set_voltage;
329 return 0; 283 fc->fe_sleep = fc->fe->ops.sleep;
284 fc->fe->ops.sleep = flexcop_sleep;
285 return 1;
286
330} 287}
331#else 288#else
332#define skystar2_rev26_attach NULL 289#define skystar2_rev26_attach NULL
@@ -421,7 +378,7 @@ static int skystar2_rev28_attach(struct flexcop_device *fc,
421 if (!fc->fe) 378 if (!fc->fe)
422 return 0; 379 return 0;
423 380
424 i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);; 381 i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);
425 if (!i2c_tuner) 382 if (!i2c_tuner)
426 return 0; 383 return 0;
427 384
@@ -449,7 +406,7 @@ static int skystar2_rev28_attach(struct flexcop_device *fc,
449#endif 406#endif
450 407
451/* AirStar DVB-T */ 408/* AirStar DVB-T */
452#if FE_SUPPORTED(MT352) 409#if FE_SUPPORTED(MT352) && FE_SUPPORTED(PLL)
453static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe) 410static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe)
454{ 411{
455 static u8 mt352_clock_config[] = { 0x89, 0x18, 0x2d }; 412 static u8 mt352_clock_config[] = { 0x89, 0x18, 0x2d };
@@ -467,32 +424,6 @@ static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe)
467 return 0; 424 return 0;
468} 425}
469 426
470static int samsung_tdtc9251dh0_calc_regs(struct dvb_frontend *fe,
471 struct dvb_frontend_parameters *params, u8* pllbuf, int buf_len)
472{
473 u32 div;
474 unsigned char bs = 0;
475
476 if (buf_len < 5)
477 return -EINVAL;
478
479#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
480 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
481 if (params->frequency >= 48000000 && params->frequency <= 154000000) \
482 bs = 0x09;
483 if (params->frequency >= 161000000 && params->frequency <= 439000000) \
484 bs = 0x0a;
485 if (params->frequency >= 447000000 && params->frequency <= 863000000) \
486 bs = 0x08;
487
488 pllbuf[0] = 0x61;
489 pllbuf[1] = div >> 8;
490 pllbuf[2] = div & 0xff;
491 pllbuf[3] = 0xcc;
492 pllbuf[4] = bs;
493 return 5;
494}
495
496static struct mt352_config samsung_tdtc9251dh0_config = { 427static struct mt352_config samsung_tdtc9251dh0_config = {
497 .demod_address = 0x0f, 428 .demod_address = 0x0f,
498 .demod_init = samsung_tdtc9251dh0_demod_init, 429 .demod_init = samsung_tdtc9251dh0_demod_init,
@@ -502,11 +433,11 @@ static int airstar_dvbt_attach(struct flexcop_device *fc,
502 struct i2c_adapter *i2c) 433 struct i2c_adapter *i2c)
503{ 434{
504 fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c); 435 fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
505 if (fc->fe != NULL) { 436 if (!fc->fe)
506 fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs; 437 return 0;
507 return 1; 438
508 } 439 return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL,
509 return 0; 440 DVB_PLL_SAMSUNG_TDTC9251DH0);
510} 441}
511#else 442#else
512#define airstar_dvbt_attach NULL 443#define airstar_dvbt_attach NULL
@@ -580,54 +511,7 @@ static int airstar_atsc3_attach(struct flexcop_device *fc,
580#endif 511#endif
581 512
582/* CableStar2 DVB-C */ 513/* CableStar2 DVB-C */
583#if FE_SUPPORTED(STV0297) 514#if FE_SUPPORTED(STV0297) && FE_SUPPORTED(PLL)
584static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe,
585 struct dvb_frontend_parameters *fep)
586{
587 struct flexcop_device *fc = fe->dvb->priv;
588 u8 buf[4];
589 u16 div;
590 int ret;
591
592/* 62.5 kHz * 10 */
593#define REF_FREQ 625
594#define FREQ_OFFSET 36125
595
596 div = ((fep->frequency/1000 + FREQ_OFFSET) * 10) / REF_FREQ;
597/* 4 MHz = 4000 KHz */
598
599 buf[0] = (u8)( div >> 8) & 0x7f;
600 buf[1] = (u8) div & 0xff;
601
602/* F(osc) = N * Reference Freq. (62.5 kHz)
603 * byte 2 : 0 N14 N13 N12 N11 N10 N9 N8
604 * byte 3 : N7 N6 N5 N4 N3 N2 N1 N0
605 * byte 4 : 1 * * AGD R3 R2 R1 R0
606 * byte 5 : C1 * RE RTS BS4 BS3 BS2 BS1
607 * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95 */
608 buf[2] = 0x95;
609
610/* Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5
611 * 47 - 153 0 * 0 0 0 0 0 1 0x01
612 * 153 - 430 0 * 0 0 0 0 1 0 0x02
613 * 430 - 822 0 * 0 0 1 0 0 0 0x08
614 * 822 - 862 1 * 0 0 1 0 0 0 0x88 */
615
616 if (fep->frequency <= 153000000) buf[3] = 0x01;
617 else if (fep->frequency <= 430000000) buf[3] = 0x02;
618 else if (fep->frequency <= 822000000) buf[3] = 0x08;
619 else buf[3] = 0x88;
620
621 if (fe->ops.i2c_gate_ctrl)
622 fe->ops.i2c_gate_ctrl(fe, 0);
623 deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n", fep->frequency,
624 buf[0], buf[1], buf[2], buf[3]);
625 ret = fc->i2c_request(&fc->fc_i2c_adap[2],
626 FC_WRITE, 0x61, buf[0], &buf[1], 3);
627 deb_tuner("tuner write returned: %d\n",ret);
628 return ret;
629}
630
631static u8 alps_tdee4_stv0297_inittab[] = { 515static u8 alps_tdee4_stv0297_inittab[] = {
632 0x80, 0x01, 516 0x80, 0x01,
633 0x80, 0x00, 517 0x80, 0x00,
@@ -711,13 +595,25 @@ static int cablestar2_attach(struct flexcop_device *fc,
711{ 595{
712 fc->fc_i2c_adap[0].no_base_addr = 1; 596 fc->fc_i2c_adap[0].no_base_addr = 1;
713 fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c); 597 fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c);
714 if (!fc->fe) { 598 if (!fc->fe)
715 /* Reset for next frontend to try */ 599 goto fail;
716 fc->fc_i2c_adap[0].no_base_addr = 0; 600
717 return 0; 601 /* This tuner doesn't use the stv0297's I2C gate, but instead the
718 } 602 * tuner is connected to a different flexcop I2C adapter. */
719 fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params; 603 if (fc->fe->ops.i2c_gate_ctrl)
604 fc->fe->ops.i2c_gate_ctrl(fc->fe, 0);
605 fc->fe->ops.i2c_gate_ctrl = NULL;
606
607 if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61,
608 &fc->fc_i2c_adap[2].i2c_adap, DVB_PLL_TDEE4))
609 goto fail;
610
720 return 1; 611 return 1;
612
613fail:
614 /* Reset for next frontend to try */
615 fc->fc_i2c_adap[0].no_base_addr = 0;
616 return 0;
721} 617}
722#else 618#else
723#define cablestar2_attach NULL 619#define cablestar2_attach NULL
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index fec1d77fa855..91353a6faf1d 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -1059,7 +1059,7 @@ static int dst_get_tuner_info(struct dst_state *state)
1059 dprintk(verbose, DST_ERROR, 1, "DST type has TS=188"); 1059 dprintk(verbose, DST_ERROR, 1, "DST type has TS=188");
1060 } 1060 }
1061 if (state->board_info[0] == 0xbc) { 1061 if (state->board_info[0] == 0xbc) {
1062 if (state->type_flags != DST_TYPE_IS_ATSC) 1062 if (state->dst_type != DST_TYPE_IS_ATSC)
1063 state->type_flags |= DST_TYPE_HAS_TS188; 1063 state->type_flags |= DST_TYPE_HAS_TS188;
1064 else 1064 else
1065 state->type_flags |= DST_TYPE_HAS_NEWTUNE_2; 1065 state->type_flags |= DST_TYPE_HAS_NEWTUNE_2;
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
index 4dbd7d4185af..2d099e271751 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -44,6 +44,14 @@
44#include "cx24116.h" 44#include "cx24116.h"
45#include "z0194a.h" 45#include "z0194a.h"
46 46
47#define UNSET (-1U)
48
49#define DM1105_BOARD_NOAUTO UNSET
50#define DM1105_BOARD_UNKNOWN 0
51#define DM1105_BOARD_DVBWORLD_2002 1
52#define DM1105_BOARD_DVBWORLD_2004 2
53#define DM1105_BOARD_AXESS_DM05 3
54
47/* ----------------------------------------------- */ 55/* ----------------------------------------------- */
48/* 56/*
49 * PCI ID's 57 * PCI ID's
@@ -153,20 +161,105 @@
153 161
154/* GPIO's for LNB power control */ 162/* GPIO's for LNB power control */
155#define DM1105_LNB_MASK 0x00000000 163#define DM1105_LNB_MASK 0x00000000
164#define DM1105_LNB_OFF 0x00020000
156#define DM1105_LNB_13V 0x00010100 165#define DM1105_LNB_13V 0x00010100
157#define DM1105_LNB_18V 0x00000100 166#define DM1105_LNB_18V 0x00000100
158 167
159/* GPIO's for LNB power control for Axess DM05 */ 168/* GPIO's for LNB power control for Axess DM05 */
160#define DM05_LNB_MASK 0x00000000 169#define DM05_LNB_MASK 0x00000000
170#define DM05_LNB_OFF 0x00020000/* actually 13v */
161#define DM05_LNB_13V 0x00020000 171#define DM05_LNB_13V 0x00020000
162#define DM05_LNB_18V 0x00030000 172#define DM05_LNB_18V 0x00030000
163 173
174static unsigned int card[] = {[0 ... 3] = UNSET };
175module_param_array(card, int, NULL, 0444);
176MODULE_PARM_DESC(card, "card type");
177
164static int ir_debug; 178static int ir_debug;
165module_param(ir_debug, int, 0644); 179module_param(ir_debug, int, 0644);
166MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); 180MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
167 181
182static unsigned int dm1105_devcount;
183
168DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 184DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
169 185
186struct dm1105_board {
187 char *name;
188};
189
190struct dm1105_subid {
191 u16 subvendor;
192 u16 subdevice;
193 u32 card;
194};
195
196static const struct dm1105_board dm1105_boards[] = {
197 [DM1105_BOARD_UNKNOWN] = {
198 .name = "UNKNOWN/GENERIC",
199 },
200 [DM1105_BOARD_DVBWORLD_2002] = {
201 .name = "DVBWorld PCI 2002",
202 },
203 [DM1105_BOARD_DVBWORLD_2004] = {
204 .name = "DVBWorld PCI 2004",
205 },
206 [DM1105_BOARD_AXESS_DM05] = {
207 .name = "Axess/EasyTv DM05",
208 },
209};
210
211static const struct dm1105_subid dm1105_subids[] = {
212 {
213 .subvendor = 0x0000,
214 .subdevice = 0x2002,
215 .card = DM1105_BOARD_DVBWORLD_2002,
216 }, {
217 .subvendor = 0x0001,
218 .subdevice = 0x2002,
219 .card = DM1105_BOARD_DVBWORLD_2002,
220 }, {
221 .subvendor = 0x0000,
222 .subdevice = 0x2004,
223 .card = DM1105_BOARD_DVBWORLD_2004,
224 }, {
225 .subvendor = 0x0001,
226 .subdevice = 0x2004,
227 .card = DM1105_BOARD_DVBWORLD_2004,
228 }, {
229 .subvendor = 0x195d,
230 .subdevice = 0x1105,
231 .card = DM1105_BOARD_AXESS_DM05,
232 },
233};
234
235static void dm1105_card_list(struct pci_dev *pci)
236{
237 int i;
238
239 if (0 == pci->subsystem_vendor &&
240 0 == pci->subsystem_device) {
241 printk(KERN_ERR
242 "dm1105: Your board has no valid PCI Subsystem ID\n"
243 "dm1105: and thus can't be autodetected\n"
244 "dm1105: Please pass card=<n> insmod option to\n"
245 "dm1105: workaround that. Redirect complaints to\n"
246 "dm1105: the vendor of the TV card. Best regards,\n"
247 "dm1105: -- tux\n");
248 } else {
249 printk(KERN_ERR
250 "dm1105: Your board isn't known (yet) to the driver.\n"
251 "dm1105: You can try to pick one of the existing\n"
252 "dm1105: card configs via card=<n> insmod option.\n"
253 "dm1105: Updating to the latest version might help\n"
254 "dm1105: as well.\n");
255 }
256 printk(KERN_ERR "Here is a list of valid choices for the card=<n> "
257 "insmod option:\n");
258 for (i = 0; i < ARRAY_SIZE(dm1105_boards); i++)
259 printk(KERN_ERR "dm1105: card=%d -> %s\n",
260 i, dm1105_boards[i].name);
261}
262
170/* infrared remote control */ 263/* infrared remote control */
171struct infrared { 264struct infrared {
172 struct input_dev *input_dev; 265 struct input_dev *input_dev;
@@ -193,6 +286,8 @@ struct dm1105dvb {
193 struct dvb_frontend *fe; 286 struct dvb_frontend *fe;
194 struct dvb_net dvbnet; 287 struct dvb_net dvbnet;
195 unsigned int full_ts_users; 288 unsigned int full_ts_users;
289 unsigned int boardnr;
290 int nr;
196 291
197 /* i2c */ 292 /* i2c */
198 struct i2c_adapter i2c_adap; 293 struct i2c_adapter i2c_adap;
@@ -211,7 +306,6 @@ struct dm1105dvb {
211 unsigned int PacketErrorCount; 306 unsigned int PacketErrorCount;
212 unsigned int dmarst; 307 unsigned int dmarst;
213 spinlock_t lock; 308 spinlock_t lock;
214
215}; 309};
216 310
217#define dm_io_mem(reg) ((unsigned long)(&dm1105dvb->io_mem[reg])) 311#define dm_io_mem(reg) ((unsigned long)(&dm1105dvb->io_mem[reg]))
@@ -326,16 +420,20 @@ static inline struct dm1105dvb *frontend_to_dm1105dvb(struct dvb_frontend *fe)
326static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) 420static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
327{ 421{
328 struct dm1105dvb *dm1105dvb = frontend_to_dm1105dvb(fe); 422 struct dm1105dvb *dm1105dvb = frontend_to_dm1105dvb(fe);
329 u32 lnb_mask, lnb_13v, lnb_18v; 423 u32 lnb_mask, lnb_13v, lnb_18v, lnb_off;
330 424
331 switch (dm1105dvb->pdev->subsystem_device) { 425 switch (dm1105dvb->boardnr) {
332 case PCI_DEVICE_ID_DM05: 426 case DM1105_BOARD_AXESS_DM05:
333 lnb_mask = DM05_LNB_MASK; 427 lnb_mask = DM05_LNB_MASK;
428 lnb_off = DM05_LNB_OFF;
334 lnb_13v = DM05_LNB_13V; 429 lnb_13v = DM05_LNB_13V;
335 lnb_18v = DM05_LNB_18V; 430 lnb_18v = DM05_LNB_18V;
336 break; 431 break;
432 case DM1105_BOARD_DVBWORLD_2002:
433 case DM1105_BOARD_DVBWORLD_2004:
337 default: 434 default:
338 lnb_mask = DM1105_LNB_MASK; 435 lnb_mask = DM1105_LNB_MASK;
436 lnb_off = DM1105_LNB_OFF;
339 lnb_13v = DM1105_LNB_13V; 437 lnb_13v = DM1105_LNB_13V;
340 lnb_18v = DM1105_LNB_18V; 438 lnb_18v = DM1105_LNB_18V;
341 } 439 }
@@ -343,8 +441,10 @@ static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volta
343 outl(lnb_mask, dm_io_mem(DM1105_GPIOCTR)); 441 outl(lnb_mask, dm_io_mem(DM1105_GPIOCTR));
344 if (voltage == SEC_VOLTAGE_18) 442 if (voltage == SEC_VOLTAGE_18)
345 outl(lnb_18v , dm_io_mem(DM1105_GPIOVAL)); 443 outl(lnb_18v , dm_io_mem(DM1105_GPIOVAL));
346 else 444 else if (voltage == SEC_VOLTAGE_13)
347 outl(lnb_13v, dm_io_mem(DM1105_GPIOVAL)); 445 outl(lnb_13v, dm_io_mem(DM1105_GPIOVAL));
446 else
447 outl(lnb_off, dm_io_mem(DM1105_GPIOVAL));
348 448
349 return 0; 449 return 0;
350} 450}
@@ -477,7 +577,7 @@ static irqreturn_t dm1105dvb_irq(int irq, void *dev_id)
477int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) 577int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
478{ 578{
479 struct input_dev *input_dev; 579 struct input_dev *input_dev;
480 IR_KEYTAB_TYPE *ir_codes = ir_codes_dm1105_nec; 580 struct ir_scancode_table *ir_codes = &ir_codes_dm1105_nec_table;
481 int ir_type = IR_TYPE_OTHER; 581 int ir_type = IR_TYPE_OTHER;
482 int err = -ENOMEM; 582 int err = -ENOMEM;
483 583
@@ -589,8 +689,8 @@ static int __devinit frontend_init(struct dm1105dvb *dm1105dvb)
589{ 689{
590 int ret; 690 int ret;
591 691
592 switch (dm1105dvb->pdev->subsystem_device) { 692 switch (dm1105dvb->boardnr) {
593 case PCI_DEVICE_ID_DW2004: 693 case DM1105_BOARD_DVBWORLD_2004:
594 dm1105dvb->fe = dvb_attach( 694 dm1105dvb->fe = dvb_attach(
595 cx24116_attach, &serit_sp2633_config, 695 cx24116_attach, &serit_sp2633_config,
596 &dm1105dvb->i2c_adap); 696 &dm1105dvb->i2c_adap);
@@ -598,6 +698,8 @@ static int __devinit frontend_init(struct dm1105dvb *dm1105dvb)
598 dm1105dvb->fe->ops.set_voltage = dm1105dvb_set_voltage; 698 dm1105dvb->fe->ops.set_voltage = dm1105dvb_set_voltage;
599 699
600 break; 700 break;
701 case DM1105_BOARD_DVBWORLD_2002:
702 case DM1105_BOARD_AXESS_DM05:
601 default: 703 default:
602 dm1105dvb->fe = dvb_attach( 704 dm1105dvb->fe = dvb_attach(
603 stv0299_attach, &sharp_z0194a_config, 705 stv0299_attach, &sharp_z0194a_config,
@@ -676,11 +778,31 @@ static int __devinit dm1105_probe(struct pci_dev *pdev,
676 struct dvb_demux *dvbdemux; 778 struct dvb_demux *dvbdemux;
677 struct dmx_demux *dmx; 779 struct dmx_demux *dmx;
678 int ret = -ENOMEM; 780 int ret = -ENOMEM;
781 int i;
679 782
680 dm1105dvb = kzalloc(sizeof(struct dm1105dvb), GFP_KERNEL); 783 dm1105dvb = kzalloc(sizeof(struct dm1105dvb), GFP_KERNEL);
681 if (!dm1105dvb) 784 if (!dm1105dvb)
682 return -ENOMEM; 785 return -ENOMEM;
683 786
787 /* board config */
788 dm1105dvb->nr = dm1105_devcount;
789 dm1105dvb->boardnr = UNSET;
790 if (card[dm1105dvb->nr] < ARRAY_SIZE(dm1105_boards))
791 dm1105dvb->boardnr = card[dm1105dvb->nr];
792 for (i = 0; UNSET == dm1105dvb->boardnr &&
793 i < ARRAY_SIZE(dm1105_subids); i++)
794 if (pdev->subsystem_vendor ==
795 dm1105_subids[i].subvendor &&
796 pdev->subsystem_device ==
797 dm1105_subids[i].subdevice)
798 dm1105dvb->boardnr = dm1105_subids[i].card;
799
800 if (UNSET == dm1105dvb->boardnr) {
801 dm1105dvb->boardnr = DM1105_BOARD_UNKNOWN;
802 dm1105_card_list(pdev);
803 }
804
805 dm1105_devcount++;
684 dm1105dvb->pdev = pdev; 806 dm1105dvb->pdev = pdev;
685 dm1105dvb->buffer_size = 5 * DM1105_DMA_BYTES; 807 dm1105dvb->buffer_size = 5 * DM1105_DMA_BYTES;
686 dm1105dvb->PacketErrorCount = 0; 808 dm1105dvb->PacketErrorCount = 0;
@@ -853,6 +975,7 @@ static void __devexit dm1105_remove(struct pci_dev *pdev)
853 pci_release_regions(pdev); 975 pci_release_regions(pdev);
854 pci_disable_device(pdev); 976 pci_disable_device(pdev);
855 pci_set_drvdata(pdev, NULL); 977 pci_set_drvdata(pdev, NULL);
978 dm1105_devcount--;
856 kfree(dm1105dvb); 979 kfree(dm1105dvb);
857} 980}
858 981
@@ -861,17 +984,12 @@ static struct pci_device_id dm1105_id_table[] __devinitdata = {
861 .vendor = PCI_VENDOR_ID_TRIGEM, 984 .vendor = PCI_VENDOR_ID_TRIGEM,
862 .device = PCI_DEVICE_ID_DM1105, 985 .device = PCI_DEVICE_ID_DM1105,
863 .subvendor = PCI_ANY_ID, 986 .subvendor = PCI_ANY_ID,
864 .subdevice = PCI_DEVICE_ID_DW2002, 987 .subdevice = PCI_ANY_ID,
865 }, {
866 .vendor = PCI_VENDOR_ID_TRIGEM,
867 .device = PCI_DEVICE_ID_DM1105,
868 .subvendor = PCI_ANY_ID,
869 .subdevice = PCI_DEVICE_ID_DW2004,
870 }, { 988 }, {
871 .vendor = PCI_VENDOR_ID_AXESS, 989 .vendor = PCI_VENDOR_ID_AXESS,
872 .device = PCI_DEVICE_ID_DM05, 990 .device = PCI_DEVICE_ID_DM05,
873 .subvendor = PCI_VENDOR_ID_AXESS, 991 .subvendor = PCI_ANY_ID,
874 .subdevice = PCI_DEVICE_ID_DM05, 992 .subdevice = PCI_ANY_ID,
875 }, { 993 }, {
876 /* empty */ 994 /* empty */
877 }, 995 },
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 6d6121eb5d59..3750ff48cba1 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -430,6 +430,8 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
430/* stop feed but only mark the specified filter as stopped (state set) */ 430/* stop feed but only mark the specified filter as stopped (state set) */
431static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter) 431static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter)
432{ 432{
433 struct dmxdev_feed *feed;
434
433 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET); 435 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
434 436
435 switch (dmxdevfilter->type) { 437 switch (dmxdevfilter->type) {
@@ -438,7 +440,8 @@ static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter)
438 dmxdevfilter->feed.sec->stop_filtering(dmxdevfilter->feed.sec); 440 dmxdevfilter->feed.sec->stop_filtering(dmxdevfilter->feed.sec);
439 break; 441 break;
440 case DMXDEV_TYPE_PES: 442 case DMXDEV_TYPE_PES:
441 dmxdevfilter->feed.ts->stop_filtering(dmxdevfilter->feed.ts); 443 list_for_each_entry(feed, &dmxdevfilter->feed.ts, next)
444 feed->ts->stop_filtering(feed->ts);
442 break; 445 break;
443 default: 446 default:
444 return -EINVAL; 447 return -EINVAL;
@@ -449,13 +452,23 @@ static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter)
449/* start feed associated with the specified filter */ 452/* start feed associated with the specified filter */
450static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter) 453static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter)
451{ 454{
455 struct dmxdev_feed *feed;
456 int ret;
457
452 dvb_dmxdev_filter_state_set(filter, DMXDEV_STATE_GO); 458 dvb_dmxdev_filter_state_set(filter, DMXDEV_STATE_GO);
453 459
454 switch (filter->type) { 460 switch (filter->type) {
455 case DMXDEV_TYPE_SEC: 461 case DMXDEV_TYPE_SEC:
456 return filter->feed.sec->start_filtering(filter->feed.sec); 462 return filter->feed.sec->start_filtering(filter->feed.sec);
457 case DMXDEV_TYPE_PES: 463 case DMXDEV_TYPE_PES:
458 return filter->feed.ts->start_filtering(filter->feed.ts); 464 list_for_each_entry(feed, &filter->feed.ts, next) {
465 ret = feed->ts->start_filtering(feed->ts);
466 if (ret < 0) {
467 dvb_dmxdev_feed_stop(filter);
468 return ret;
469 }
470 }
471 break;
459 default: 472 default:
460 return -EINVAL; 473 return -EINVAL;
461 } 474 }
@@ -487,6 +500,9 @@ static int dvb_dmxdev_feed_restart(struct dmxdev_filter *filter)
487 500
488static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter) 501static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter)
489{ 502{
503 struct dmxdev_feed *feed;
504 struct dmx_demux *demux;
505
490 if (dmxdevfilter->state < DMXDEV_STATE_GO) 506 if (dmxdevfilter->state < DMXDEV_STATE_GO)
491 return 0; 507 return 0;
492 508
@@ -503,13 +519,12 @@ static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter)
503 dmxdevfilter->feed.sec = NULL; 519 dmxdevfilter->feed.sec = NULL;
504 break; 520 break;
505 case DMXDEV_TYPE_PES: 521 case DMXDEV_TYPE_PES:
506 if (!dmxdevfilter->feed.ts)
507 break;
508 dvb_dmxdev_feed_stop(dmxdevfilter); 522 dvb_dmxdev_feed_stop(dmxdevfilter);
509 dmxdevfilter->dev->demux-> 523 demux = dmxdevfilter->dev->demux;
510 release_ts_feed(dmxdevfilter->dev->demux, 524 list_for_each_entry(feed, &dmxdevfilter->feed.ts, next) {
511 dmxdevfilter->feed.ts); 525 demux->release_ts_feed(demux, feed->ts);
512 dmxdevfilter->feed.ts = NULL; 526 feed->ts = NULL;
527 }
513 break; 528 break;
514 default: 529 default:
515 if (dmxdevfilter->state == DMXDEV_STATE_ALLOCATED) 530 if (dmxdevfilter->state == DMXDEV_STATE_ALLOCATED)
@@ -521,19 +536,88 @@ static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter)
521 return 0; 536 return 0;
522} 537}
523 538
539static void dvb_dmxdev_delete_pids(struct dmxdev_filter *dmxdevfilter)
540{
541 struct dmxdev_feed *feed, *tmp;
542
543 /* delete all PIDs */
544 list_for_each_entry_safe(feed, tmp, &dmxdevfilter->feed.ts, next) {
545 list_del(&feed->next);
546 kfree(feed);
547 }
548
549 BUG_ON(!list_empty(&dmxdevfilter->feed.ts));
550}
551
524static inline int dvb_dmxdev_filter_reset(struct dmxdev_filter *dmxdevfilter) 552static inline int dvb_dmxdev_filter_reset(struct dmxdev_filter *dmxdevfilter)
525{ 553{
526 if (dmxdevfilter->state < DMXDEV_STATE_SET) 554 if (dmxdevfilter->state < DMXDEV_STATE_SET)
527 return 0; 555 return 0;
528 556
557 if (dmxdevfilter->type == DMXDEV_TYPE_PES)
558 dvb_dmxdev_delete_pids(dmxdevfilter);
559
529 dmxdevfilter->type = DMXDEV_TYPE_NONE; 560 dmxdevfilter->type = DMXDEV_TYPE_NONE;
530 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED); 561 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
531 return 0; 562 return 0;
532} 563}
533 564
565static int dvb_dmxdev_start_feed(struct dmxdev *dmxdev,
566 struct dmxdev_filter *filter,
567 struct dmxdev_feed *feed)
568{
569 struct timespec timeout = { 0 };
570 struct dmx_pes_filter_params *para = &filter->params.pes;
571 dmx_output_t otype;
572 int ret;
573 int ts_type;
574 enum dmx_ts_pes ts_pes;
575 struct dmx_ts_feed *tsfeed;
576
577 feed->ts = NULL;
578 otype = para->output;
579
580 ts_pes = (enum dmx_ts_pes)para->pes_type;
581
582 if (ts_pes < DMX_PES_OTHER)
583 ts_type = TS_DECODER;
584 else
585 ts_type = 0;
586
587 if (otype == DMX_OUT_TS_TAP)
588 ts_type |= TS_PACKET;
589 else if (otype == DMX_OUT_TSDEMUX_TAP)
590 ts_type |= TS_PACKET | TS_DEMUX;
591 else if (otype == DMX_OUT_TAP)
592 ts_type |= TS_PACKET | TS_DEMUX | TS_PAYLOAD_ONLY;
593
594 ret = dmxdev->demux->allocate_ts_feed(dmxdev->demux, &feed->ts,
595 dvb_dmxdev_ts_callback);
596 if (ret < 0)
597 return ret;
598
599 tsfeed = feed->ts;
600 tsfeed->priv = filter;
601
602 ret = tsfeed->set(tsfeed, feed->pid, ts_type, ts_pes, 32768, timeout);
603 if (ret < 0) {
604 dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);
605 return ret;
606 }
607
608 ret = tsfeed->start_filtering(tsfeed);
609 if (ret < 0) {
610 dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);
611 return ret;
612 }
613
614 return 0;
615}
616
534static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) 617static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
535{ 618{
536 struct dmxdev *dmxdev = filter->dev; 619 struct dmxdev *dmxdev = filter->dev;
620 struct dmxdev_feed *feed;
537 void *mem; 621 void *mem;
538 int ret, i; 622 int ret, i;
539 623
@@ -631,56 +715,14 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
631 break; 715 break;
632 } 716 }
633 case DMXDEV_TYPE_PES: 717 case DMXDEV_TYPE_PES:
634 { 718 list_for_each_entry(feed, &filter->feed.ts, next) {
635 struct timespec timeout = { 0 }; 719 ret = dvb_dmxdev_start_feed(dmxdev, filter, feed);
636 struct dmx_pes_filter_params *para = &filter->params.pes; 720 if (ret < 0) {
637 dmx_output_t otype; 721 dvb_dmxdev_filter_stop(filter);
638 int ts_type; 722 return ret;
639 enum dmx_ts_pes ts_pes; 723 }
640 struct dmx_ts_feed **tsfeed = &filter->feed.ts;
641
642 filter->feed.ts = NULL;
643 otype = para->output;
644
645 ts_pes = (enum dmx_ts_pes)para->pes_type;
646
647 if (ts_pes < DMX_PES_OTHER)
648 ts_type = TS_DECODER;
649 else
650 ts_type = 0;
651
652 if (otype == DMX_OUT_TS_TAP)
653 ts_type |= TS_PACKET;
654 else if (otype == DMX_OUT_TSDEMUX_TAP)
655 ts_type |= TS_PACKET | TS_DEMUX;
656 else if (otype == DMX_OUT_TAP)
657 ts_type |= TS_PACKET | TS_DEMUX | TS_PAYLOAD_ONLY;
658
659 ret = dmxdev->demux->allocate_ts_feed(dmxdev->demux,
660 tsfeed,
661 dvb_dmxdev_ts_callback);
662 if (ret < 0)
663 return ret;
664
665 (*tsfeed)->priv = filter;
666
667 ret = (*tsfeed)->set(*tsfeed, para->pid, ts_type, ts_pes,
668 32768, timeout);
669 if (ret < 0) {
670 dmxdev->demux->release_ts_feed(dmxdev->demux,
671 *tsfeed);
672 return ret;
673 }
674
675 ret = filter->feed.ts->start_filtering(filter->feed.ts);
676 if (ret < 0) {
677 dmxdev->demux->release_ts_feed(dmxdev->demux,
678 *tsfeed);
679 return ret;
680 } 724 }
681
682 break; 725 break;
683 }
684 default: 726 default:
685 return -EINVAL; 727 return -EINVAL;
686 } 728 }
@@ -718,7 +760,7 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
718 dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192); 760 dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);
719 dmxdevfilter->type = DMXDEV_TYPE_NONE; 761 dmxdevfilter->type = DMXDEV_TYPE_NONE;
720 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED); 762 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
721 dmxdevfilter->feed.ts = NULL; 763 INIT_LIST_HEAD(&dmxdevfilter->feed.ts);
722 init_timer(&dmxdevfilter->timer); 764 init_timer(&dmxdevfilter->timer);
723 765
724 dvbdev->users++; 766 dvbdev->users++;
@@ -760,6 +802,55 @@ static inline void invert_mode(dmx_filter_t *filter)
760 filter->mode[i] ^= 0xff; 802 filter->mode[i] ^= 0xff;
761} 803}
762 804
805static int dvb_dmxdev_add_pid(struct dmxdev *dmxdev,
806 struct dmxdev_filter *filter, u16 pid)
807{
808 struct dmxdev_feed *feed;
809
810 if ((filter->type != DMXDEV_TYPE_PES) ||
811 (filter->state < DMXDEV_STATE_SET))
812 return -EINVAL;
813
814 /* only TS packet filters may have multiple PIDs */
815 if ((filter->params.pes.output != DMX_OUT_TSDEMUX_TAP) &&
816 (!list_empty(&filter->feed.ts)))
817 return -EINVAL;
818
819 feed = kzalloc(sizeof(struct dmxdev_feed), GFP_KERNEL);
820 if (feed == NULL)
821 return -ENOMEM;
822
823 feed->pid = pid;
824 list_add(&feed->next, &filter->feed.ts);
825
826 if (filter->state >= DMXDEV_STATE_GO)
827 return dvb_dmxdev_start_feed(dmxdev, filter, feed);
828
829 return 0;
830}
831
832static int dvb_dmxdev_remove_pid(struct dmxdev *dmxdev,
833 struct dmxdev_filter *filter, u16 pid)
834{
835 struct dmxdev_feed *feed, *tmp;
836
837 if ((filter->type != DMXDEV_TYPE_PES) ||
838 (filter->state < DMXDEV_STATE_SET))
839 return -EINVAL;
840
841 list_for_each_entry_safe(feed, tmp, &filter->feed.ts, next) {
842 if ((feed->pid == pid) && (feed->ts != NULL)) {
843 feed->ts->stop_filtering(feed->ts);
844 filter->dev->demux->release_ts_feed(filter->dev->demux,
845 feed->ts);
846 list_del(&feed->next);
847 kfree(feed);
848 }
849 }
850
851 return 0;
852}
853
763static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev, 854static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev,
764 struct dmxdev_filter *dmxdevfilter, 855 struct dmxdev_filter *dmxdevfilter,
765 struct dmx_sct_filter_params *params) 856 struct dmx_sct_filter_params *params)
@@ -784,7 +875,10 @@ static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev,
784 struct dmxdev_filter *dmxdevfilter, 875 struct dmxdev_filter *dmxdevfilter,
785 struct dmx_pes_filter_params *params) 876 struct dmx_pes_filter_params *params)
786{ 877{
878 int ret;
879
787 dvb_dmxdev_filter_stop(dmxdevfilter); 880 dvb_dmxdev_filter_stop(dmxdevfilter);
881 dvb_dmxdev_filter_reset(dmxdevfilter);
788 882
789 if (params->pes_type > DMX_PES_OTHER || params->pes_type < 0) 883 if (params->pes_type > DMX_PES_OTHER || params->pes_type < 0)
790 return -EINVAL; 884 return -EINVAL;
@@ -795,6 +889,11 @@ static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev,
795 889
796 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET); 890 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
797 891
892 ret = dvb_dmxdev_add_pid(dmxdev, dmxdevfilter,
893 dmxdevfilter->params.pes.pid);
894 if (ret < 0)
895 return ret;
896
798 if (params->flags & DMX_IMMEDIATE_START) 897 if (params->flags & DMX_IMMEDIATE_START)
799 return dvb_dmxdev_filter_start(dmxdevfilter); 898 return dvb_dmxdev_filter_start(dmxdevfilter);
800 899
@@ -958,6 +1057,24 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
958 &((struct dmx_stc *)parg)->base); 1057 &((struct dmx_stc *)parg)->base);
959 break; 1058 break;
960 1059
1060 case DMX_ADD_PID:
1061 if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
1062 ret = -ERESTARTSYS;
1063 break;
1064 }
1065 ret = dvb_dmxdev_add_pid(dmxdev, dmxdevfilter, *(u16 *)parg);
1066 mutex_unlock(&dmxdevfilter->mutex);
1067 break;
1068
1069 case DMX_REMOVE_PID:
1070 if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
1071 ret = -ERESTARTSYS;
1072 break;
1073 }
1074 ret = dvb_dmxdev_remove_pid(dmxdev, dmxdevfilter, *(u16 *)parg);
1075 mutex_unlock(&dmxdevfilter->mutex);
1076 break;
1077
961 default: 1078 default:
962 ret = -EINVAL; 1079 ret = -EINVAL;
963 break; 1080 break;
diff --git a/drivers/media/dvb/dvb-core/dmxdev.h b/drivers/media/dvb/dvb-core/dmxdev.h
index 29746e70d325..c1379b56dfb4 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.h
+++ b/drivers/media/dvb/dvb-core/dmxdev.h
@@ -53,13 +53,20 @@ enum dmxdev_state {
53 DMXDEV_STATE_TIMEDOUT 53 DMXDEV_STATE_TIMEDOUT
54}; 54};
55 55
56struct dmxdev_feed {
57 u16 pid;
58 struct dmx_ts_feed *ts;
59 struct list_head next;
60};
61
56struct dmxdev_filter { 62struct dmxdev_filter {
57 union { 63 union {
58 struct dmx_section_filter *sec; 64 struct dmx_section_filter *sec;
59 } filter; 65 } filter;
60 66
61 union { 67 union {
62 struct dmx_ts_feed *ts; 68 /* list of TS and PES feeds (struct dmxdev_feed) */
69 struct list_head ts;
63 struct dmx_section_feed *sec; 70 struct dmx_section_feed *sec;
64 } feed; 71 } feed;
65 72
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index cfe2768d24af..eef6d3616626 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -425,13 +425,9 @@ no_dvb_demux_tscheck:
425 if ((DVR_FEED(feed)) && (dvr_done++)) 425 if ((DVR_FEED(feed)) && (dvr_done++))
426 continue; 426 continue;
427 427
428 if (feed->pid == pid) { 428 if (feed->pid == pid)
429 dvb_dmx_swfilter_packet_type(feed, buf); 429 dvb_dmx_swfilter_packet_type(feed, buf);
430 if (DVR_FEED(feed)) 430 else if (feed->pid == 0x2000)
431 continue;
432 }
433
434 if (feed->pid == 0x2000)
435 feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts, DMX_OK); 431 feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts, DMX_OK);
436 } 432 }
437} 433}
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index f50ca7292a7d..d13ebcb0c6b6 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -72,6 +72,7 @@ MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open(
72#define FESTATE_ZIGZAG_FAST 32 72#define FESTATE_ZIGZAG_FAST 32
73#define FESTATE_ZIGZAG_SLOW 64 73#define FESTATE_ZIGZAG_SLOW 64
74#define FESTATE_DISEQC 128 74#define FESTATE_DISEQC 128
75#define FESTATE_ERROR 256
75#define FESTATE_WAITFORLOCK (FESTATE_TUNING_FAST | FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW | FESTATE_DISEQC) 76#define FESTATE_WAITFORLOCK (FESTATE_TUNING_FAST | FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW | FESTATE_DISEQC)
76#define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST) 77#define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST)
77#define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW) 78#define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW)
@@ -269,6 +270,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
269{ 270{
270 int autoinversion; 271 int autoinversion;
271 int ready = 0; 272 int ready = 0;
273 int fe_set_err = 0;
272 struct dvb_frontend_private *fepriv = fe->frontend_priv; 274 struct dvb_frontend_private *fepriv = fe->frontend_priv;
273 int original_inversion = fepriv->parameters.inversion; 275 int original_inversion = fepriv->parameters.inversion;
274 u32 original_frequency = fepriv->parameters.frequency; 276 u32 original_frequency = fepriv->parameters.frequency;
@@ -345,7 +347,11 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
345 if (autoinversion) 347 if (autoinversion)
346 fepriv->parameters.inversion = fepriv->inversion; 348 fepriv->parameters.inversion = fepriv->inversion;
347 if (fe->ops.set_frontend) 349 if (fe->ops.set_frontend)
348 fe->ops.set_frontend(fe, &fepriv->parameters); 350 fe_set_err = fe->ops.set_frontend(fe, &fepriv->parameters);
351 if (fe_set_err < 0) {
352 fepriv->state = FESTATE_ERROR;
353 return fe_set_err;
354 }
349 355
350 fepriv->parameters.frequency = original_frequency; 356 fepriv->parameters.frequency = original_frequency;
351 fepriv->parameters.inversion = original_inversion; 357 fepriv->parameters.inversion = original_inversion;
@@ -357,6 +363,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
357static void dvb_frontend_swzigzag(struct dvb_frontend *fe) 363static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
358{ 364{
359 fe_status_t s = 0; 365 fe_status_t s = 0;
366 int retval = 0;
360 struct dvb_frontend_private *fepriv = fe->frontend_priv; 367 struct dvb_frontend_private *fepriv = fe->frontend_priv;
361 368
362 /* if we've got no parameters, just keep idling */ 369 /* if we've got no parameters, just keep idling */
@@ -370,8 +377,12 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
370 if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) { 377 if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) {
371 if (fepriv->state & FESTATE_RETUNE) { 378 if (fepriv->state & FESTATE_RETUNE) {
372 if (fe->ops.set_frontend) 379 if (fe->ops.set_frontend)
373 fe->ops.set_frontend(fe, &fepriv->parameters); 380 retval = fe->ops.set_frontend(fe,
374 fepriv->state = FESTATE_TUNED; 381 &fepriv->parameters);
382 if (retval < 0)
383 fepriv->state = FESTATE_ERROR;
384 else
385 fepriv->state = FESTATE_TUNED;
375 } 386 }
376 fepriv->delay = 3*HZ; 387 fepriv->delay = 3*HZ;
377 fepriv->quality = 0; 388 fepriv->quality = 0;
@@ -449,7 +460,11 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
449 fepriv->delay = fepriv->min_delay; 460 fepriv->delay = fepriv->min_delay;
450 461
451 /* peform a tune */ 462 /* peform a tune */
452 if (dvb_frontend_swzigzag_autotune(fe, fepriv->check_wrapped)) { 463 retval = dvb_frontend_swzigzag_autotune(fe,
464 fepriv->check_wrapped);
465 if (retval < 0) {
466 return;
467 } else if (retval) {
453 /* OK, if we've run out of trials at the fast speed. 468 /* OK, if we've run out of trials at the fast speed.
454 * Drop back to slow for the _next_ attempt */ 469 * Drop back to slow for the _next_ attempt */
455 fepriv->state = FESTATE_SEARCHING_SLOW; 470 fepriv->state = FESTATE_SEARCHING_SLOW;
@@ -823,6 +838,15 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
823 } 838 }
824 } 839 }
825 840
841 /* check for supported modulation */
842 if (fe->ops.info.type == FE_QAM &&
843 (parms->u.qam.modulation > QAM_AUTO ||
844 !((1 << (parms->u.qam.modulation + 10)) & fe->ops.info.caps))) {
845 printk(KERN_WARNING "DVB: adapter %i frontend %i modulation %u not supported\n",
846 fe->dvb->num, fe->id, parms->u.qam.modulation);
847 return -EINVAL;
848 }
849
826 return 0; 850 return 0;
827} 851}
828 852
@@ -1499,7 +1523,8 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file,
1499 1523
1500 /* if retune was requested but hasn't occured yet, prevent 1524 /* if retune was requested but hasn't occured yet, prevent
1501 * that user get signal state from previous tuning */ 1525 * that user get signal state from previous tuning */
1502 if(fepriv->state == FESTATE_RETUNE) { 1526 if (fepriv->state == FESTATE_RETUNE ||
1527 fepriv->state == FESTATE_ERROR) {
1503 err=0; 1528 err=0;
1504 *status = 0; 1529 *status = 0;
1505 break; 1530 break;
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index 487919bea7ae..895e2efca8a9 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -30,7 +30,12 @@
30 30
31#define DVB_MAJOR 212 31#define DVB_MAJOR 212
32 32
33#if defined(CONFIG_DVB_MAX_ADAPTERS) && CONFIG_DVB_MAX_ADAPTERS > 0
34#define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS
35#else
36#warning invalid CONFIG_DVB_MAX_ADAPTERS value
33#define DVB_MAX_ADAPTERS 8 37#define DVB_MAX_ADAPTERS 8
38#endif
34 39
35#define DVB_UNSET (-1) 40#define DVB_UNSET (-1)
36 41
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 496c1a37034c..8b8bc04ee980 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -253,7 +253,7 @@ config DVB_USB_AF9005_REMOTE
253 Afatech AF9005 based receiver. 253 Afatech AF9005 based receiver.
254 254
255config DVB_USB_DW2102 255config DVB_USB_DW2102
256 tristate "DvbWorld DVB-S/S2 USB2.0 support" 256 tristate "DvbWorld & TeVii DVB-S/S2 USB2.0 support"
257 depends on DVB_USB 257 depends on DVB_USB
258 select DVB_PLL if !DVB_FE_CUSTOMISE 258 select DVB_PLL if !DVB_FE_CUSTOMISE
259 select DVB_STV0299 if !DVB_FE_CUSTOMISE 259 select DVB_STV0299 if !DVB_FE_CUSTOMISE
@@ -262,9 +262,11 @@ config DVB_USB_DW2102
262 select DVB_CX24116 if !DVB_FE_CUSTOMISE 262 select DVB_CX24116 if !DVB_FE_CUSTOMISE
263 select DVB_SI21XX if !DVB_FE_CUSTOMISE 263 select DVB_SI21XX if !DVB_FE_CUSTOMISE
264 select DVB_TDA10021 if !DVB_FE_CUSTOMISE 264 select DVB_TDA10021 if !DVB_FE_CUSTOMISE
265 select DVB_MT312 if !DVB_FE_CUSTOMISE
266 select DVB_ZL10039 if !DVB_FE_CUSTOMISE
265 help 267 help
266 Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers 268 Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers
267 and the TeVii S650. 269 and the TeVii S650, S630.
268 270
269config DVB_USB_CINERGY_T2 271config DVB_USB_CINERGY_T2
270 tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver" 272 tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver"
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
index dc8c8784caa8..6247239982e9 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -38,41 +38,41 @@ static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_pr
38} 38}
39 39
40static struct dvb_usb_rc_key a800_rc_keys[] = { 40static struct dvb_usb_rc_key a800_rc_keys[] = {
41 { 0x02, 0x01, KEY_PROG1 }, /* SOURCE */ 41 { 0x0201, KEY_PROG1 }, /* SOURCE */
42 { 0x02, 0x00, KEY_POWER }, /* POWER */ 42 { 0x0200, KEY_POWER }, /* POWER */
43 { 0x02, 0x05, KEY_1 }, /* 1 */ 43 { 0x0205, KEY_1 }, /* 1 */
44 { 0x02, 0x06, KEY_2 }, /* 2 */ 44 { 0x0206, KEY_2 }, /* 2 */
45 { 0x02, 0x07, KEY_3 }, /* 3 */ 45 { 0x0207, KEY_3 }, /* 3 */
46 { 0x02, 0x09, KEY_4 }, /* 4 */ 46 { 0x0209, KEY_4 }, /* 4 */
47 { 0x02, 0x0a, KEY_5 }, /* 5 */ 47 { 0x020a, KEY_5 }, /* 5 */
48 { 0x02, 0x0b, KEY_6 }, /* 6 */ 48 { 0x020b, KEY_6 }, /* 6 */
49 { 0x02, 0x0d, KEY_7 }, /* 7 */ 49 { 0x020d, KEY_7 }, /* 7 */
50 { 0x02, 0x0e, KEY_8 }, /* 8 */ 50 { 0x020e, KEY_8 }, /* 8 */
51 { 0x02, 0x0f, KEY_9 }, /* 9 */ 51 { 0x020f, KEY_9 }, /* 9 */
52 { 0x02, 0x12, KEY_LEFT }, /* L / DISPLAY */ 52 { 0x0212, KEY_LEFT }, /* L / DISPLAY */
53 { 0x02, 0x11, KEY_0 }, /* 0 */ 53 { 0x0211, KEY_0 }, /* 0 */
54 { 0x02, 0x13, KEY_RIGHT }, /* R / CH RTN */ 54 { 0x0213, KEY_RIGHT }, /* R / CH RTN */
55 { 0x02, 0x17, KEY_PROG2 }, /* SNAP SHOT */ 55 { 0x0217, KEY_PROG2 }, /* SNAP SHOT */
56 { 0x02, 0x10, KEY_PROG3 }, /* 16-CH PREV */ 56 { 0x0210, KEY_PROG3 }, /* 16-CH PREV */
57 { 0x02, 0x1e, KEY_VOLUMEDOWN }, /* VOL DOWN */ 57 { 0x021e, KEY_VOLUMEDOWN }, /* VOL DOWN */
58 { 0x02, 0x0c, KEY_ZOOM }, /* FULL SCREEN */ 58 { 0x020c, KEY_ZOOM }, /* FULL SCREEN */
59 { 0x02, 0x1f, KEY_VOLUMEUP }, /* VOL UP */ 59 { 0x021f, KEY_VOLUMEUP }, /* VOL UP */
60 { 0x02, 0x14, KEY_MUTE }, /* MUTE */ 60 { 0x0214, KEY_MUTE }, /* MUTE */
61 { 0x02, 0x08, KEY_AUDIO }, /* AUDIO */ 61 { 0x0208, KEY_AUDIO }, /* AUDIO */
62 { 0x02, 0x19, KEY_RECORD }, /* RECORD */ 62 { 0x0219, KEY_RECORD }, /* RECORD */
63 { 0x02, 0x18, KEY_PLAY }, /* PLAY */ 63 { 0x0218, KEY_PLAY }, /* PLAY */
64 { 0x02, 0x1b, KEY_STOP }, /* STOP */ 64 { 0x021b, KEY_STOP }, /* STOP */
65 { 0x02, 0x1a, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */ 65 { 0x021a, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */
66 { 0x02, 0x1d, KEY_BACK }, /* << / RED */ 66 { 0x021d, KEY_BACK }, /* << / RED */
67 { 0x02, 0x1c, KEY_FORWARD }, /* >> / YELLOW */ 67 { 0x021c, KEY_FORWARD }, /* >> / YELLOW */
68 { 0x02, 0x03, KEY_TEXT }, /* TELETEXT */ 68 { 0x0203, KEY_TEXT }, /* TELETEXT */
69 { 0x02, 0x04, KEY_EPG }, /* EPG */ 69 { 0x0204, KEY_EPG }, /* EPG */
70 { 0x02, 0x15, KEY_MENU }, /* MENU */ 70 { 0x0215, KEY_MENU }, /* MENU */
71 71
72 { 0x03, 0x03, KEY_CHANNELUP }, /* CH UP */ 72 { 0x0303, KEY_CHANNELUP }, /* CH UP */
73 { 0x03, 0x02, KEY_CHANNELDOWN }, /* CH DOWN */ 73 { 0x0302, KEY_CHANNELDOWN }, /* CH DOWN */
74 { 0x03, 0x01, KEY_FIRST }, /* |<< / GREEN */ 74 { 0x0301, KEY_FIRST }, /* |<< / GREEN */
75 { 0x03, 0x00, KEY_LAST }, /* >>| / BLUE */ 75 { 0x0300, KEY_LAST }, /* >>| / BLUE */
76 76
77}; 77};
78 78
diff --git a/drivers/media/dvb/dvb-usb/af9005-remote.c b/drivers/media/dvb/dvb-usb/af9005-remote.c
index 7c596f926764..f4379c650a19 100644
--- a/drivers/media/dvb/dvb-usb/af9005-remote.c
+++ b/drivers/media/dvb/dvb-usb/af9005-remote.c
@@ -35,43 +35,43 @@ MODULE_PARM_DESC(debug,
35 35
36struct dvb_usb_rc_key af9005_rc_keys[] = { 36struct dvb_usb_rc_key af9005_rc_keys[] = {
37 37
38 {0x01, 0xb7, KEY_POWER}, 38 {0x01b7, KEY_POWER},
39 {0x01, 0xa7, KEY_VOLUMEUP}, 39 {0x01a7, KEY_VOLUMEUP},
40 {0x01, 0x87, KEY_CHANNELUP}, 40 {0x0187, KEY_CHANNELUP},
41 {0x01, 0x7f, KEY_MUTE}, 41 {0x017f, KEY_MUTE},
42 {0x01, 0xbf, KEY_VOLUMEDOWN}, 42 {0x01bf, KEY_VOLUMEDOWN},
43 {0x01, 0x3f, KEY_CHANNELDOWN}, 43 {0x013f, KEY_CHANNELDOWN},
44 {0x01, 0xdf, KEY_1}, 44 {0x01df, KEY_1},
45 {0x01, 0x5f, KEY_2}, 45 {0x015f, KEY_2},
46 {0x01, 0x9f, KEY_3}, 46 {0x019f, KEY_3},
47 {0x01, 0x1f, KEY_4}, 47 {0x011f, KEY_4},
48 {0x01, 0xef, KEY_5}, 48 {0x01ef, KEY_5},
49 {0x01, 0x6f, KEY_6}, 49 {0x016f, KEY_6},
50 {0x01, 0xaf, KEY_7}, 50 {0x01af, KEY_7},
51 {0x01, 0x27, KEY_8}, 51 {0x0127, KEY_8},
52 {0x01, 0x07, KEY_9}, 52 {0x0107, KEY_9},
53 {0x01, 0xcf, KEY_ZOOM}, 53 {0x01cf, KEY_ZOOM},
54 {0x01, 0x4f, KEY_0}, 54 {0x014f, KEY_0},
55 {0x01, 0x8f, KEY_GOTO}, /* marked jump on the remote */ 55 {0x018f, KEY_GOTO}, /* marked jump on the remote */
56 56
57 {0x00, 0xbd, KEY_POWER}, 57 {0x00bd, KEY_POWER},
58 {0x00, 0x7d, KEY_VOLUMEUP}, 58 {0x007d, KEY_VOLUMEUP},
59 {0x00, 0xfd, KEY_CHANNELUP}, 59 {0x00fd, KEY_CHANNELUP},
60 {0x00, 0x9d, KEY_MUTE}, 60 {0x009d, KEY_MUTE},
61 {0x00, 0x5d, KEY_VOLUMEDOWN}, 61 {0x005d, KEY_VOLUMEDOWN},
62 {0x00, 0xdd, KEY_CHANNELDOWN}, 62 {0x00dd, KEY_CHANNELDOWN},
63 {0x00, 0xad, KEY_1}, 63 {0x00ad, KEY_1},
64 {0x00, 0x6d, KEY_2}, 64 {0x006d, KEY_2},
65 {0x00, 0xed, KEY_3}, 65 {0x00ed, KEY_3},
66 {0x00, 0x8d, KEY_4}, 66 {0x008d, KEY_4},
67 {0x00, 0x4d, KEY_5}, 67 {0x004d, KEY_5},
68 {0x00, 0xcd, KEY_6}, 68 {0x00cd, KEY_6},
69 {0x00, 0xb5, KEY_7}, 69 {0x00b5, KEY_7},
70 {0x00, 0x75, KEY_8}, 70 {0x0075, KEY_8},
71 {0x00, 0xf5, KEY_9}, 71 {0x00f5, KEY_9},
72 {0x00, 0x95, KEY_ZOOM}, 72 {0x0095, KEY_ZOOM},
73 {0x00, 0x55, KEY_0}, 73 {0x0055, KEY_0},
74 {0x00, 0xd5, KEY_GOTO}, /* marked jump on the remote */ 74 {0x00d5, KEY_GOTO}, /* marked jump on the remote */
75}; 75};
76 76
77int af9005_rc_keys_size = ARRAY_SIZE(af9005_rc_keys); 77int af9005_rc_keys_size = ARRAY_SIZE(af9005_rc_keys);
@@ -131,8 +131,8 @@ int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, u32 * event,
131 return 0; 131 return 0;
132 } 132 }
133 for (i = 0; i < af9005_rc_keys_size; i++) { 133 for (i = 0; i < af9005_rc_keys_size; i++) {
134 if (af9005_rc_keys[i].custom == cust 134 if (rc5_custom(&af9005_rc_keys[i]) == cust
135 && af9005_rc_keys[i].data == dat) { 135 && rc5_data(&af9005_rc_keys[i]) == dat) {
136 *event = af9005_rc_keys[i].event; 136 *event = af9005_rc_keys[i].event;
137 *state = REMOTE_KEY_PRESSED; 137 *state = REMOTE_KEY_PRESSED;
138 deb_decode 138 deb_decode
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index 26690dfb3260..99cdd0d101ca 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -538,24 +538,22 @@ exit:
538/* dump eeprom */ 538/* dump eeprom */
539static int af9015_eeprom_dump(struct dvb_usb_device *d) 539static int af9015_eeprom_dump(struct dvb_usb_device *d)
540{ 540{
541 char buf[4+3*16+1], buf2[4];
542 u8 reg, val; 541 u8 reg, val;
543 542
544 for (reg = 0; ; reg++) { 543 for (reg = 0; ; reg++) {
545 if (reg % 16 == 0) { 544 if (reg % 16 == 0) {
546 if (reg) 545 if (reg)
547 deb_info("%s\n", buf); 546 deb_info(KERN_CONT "\n");
548 sprintf(buf, "%02x: ", reg); 547 deb_info(KERN_DEBUG "%02x:", reg);
549 } 548 }
550 if (af9015_read_reg_i2c(d, AF9015_I2C_EEPROM, reg, &val) == 0) 549 if (af9015_read_reg_i2c(d, AF9015_I2C_EEPROM, reg, &val) == 0)
551 sprintf(buf2, "%02x ", val); 550 deb_info(KERN_CONT " %02x", val);
552 else 551 else
553 strcpy(buf2, "-- "); 552 deb_info(KERN_CONT " --");
554 strcat(buf, buf2);
555 if (reg == 0xff) 553 if (reg == 0xff)
556 break; 554 break;
557 } 555 }
558 deb_info("%s\n", buf); 556 deb_info(KERN_CONT "\n");
559 return 0; 557 return 0;
560} 558}
561 559
@@ -1045,8 +1043,8 @@ static int af9015_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
1045 *state = REMOTE_NO_KEY_PRESSED; 1043 *state = REMOTE_NO_KEY_PRESSED;
1046 1044
1047 for (i = 0; i < d->props.rc_key_map_size; i++) { 1045 for (i = 0; i < d->props.rc_key_map_size; i++) {
1048 if (!buf[1] && keymap[i].custom == buf[0] && 1046 if (!buf[1] && rc5_custom(&keymap[i]) == buf[0] &&
1049 keymap[i].data == buf[2]) { 1047 rc5_data(&keymap[i]) == buf[2]) {
1050 *event = keymap[i].event; 1048 *event = keymap[i].event;
1051 *state = REMOTE_KEY_PRESSED; 1049 *state = REMOTE_KEY_PRESSED;
1052 break; 1050 break;
@@ -1266,6 +1264,7 @@ static struct usb_device_id af9015_usb_table[] = {
1266 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)}, 1264 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)},
1267 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)}, 1265 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)},
1268 {USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)}, 1266 {USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)},
1267/* 25 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)},
1269 {0}, 1268 {0},
1270}; 1269};
1271MODULE_DEVICE_TABLE(usb, af9015_usb_table); 1270MODULE_DEVICE_TABLE(usb, af9015_usb_table);
@@ -1346,7 +1345,8 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1346 { 1345 {
1347 .name = "KWorld PlusTV Dual DVB-T Stick " \ 1346 .name = "KWorld PlusTV Dual DVB-T Stick " \
1348 "(DVB-T 399U)", 1347 "(DVB-T 399U)",
1349 .cold_ids = {&af9015_usb_table[4], NULL}, 1348 .cold_ids = {&af9015_usb_table[4],
1349 &af9015_usb_table[25], NULL},
1350 .warm_ids = {NULL}, 1350 .warm_ids = {NULL},
1351 }, 1351 },
1352 { 1352 {
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
index 8d81a17c116d..c41f30e4a1b8 100644
--- a/drivers/media/dvb/dvb-usb/af9015.h
+++ b/drivers/media/dvb/dvb-usb/af9015.h
@@ -121,21 +121,21 @@ enum af9015_remote {
121 121
122/* Leadtek WinFast DTV Dongle Gold */ 122/* Leadtek WinFast DTV Dongle Gold */
123static struct dvb_usb_rc_key af9015_rc_keys_leadtek[] = { 123static struct dvb_usb_rc_key af9015_rc_keys_leadtek[] = {
124 { 0x00, 0x1e, KEY_1 }, 124 { 0x001e, KEY_1 },
125 { 0x00, 0x1f, KEY_2 }, 125 { 0x001f, KEY_2 },
126 { 0x00, 0x20, KEY_3 }, 126 { 0x0020, KEY_3 },
127 { 0x00, 0x21, KEY_4 }, 127 { 0x0021, KEY_4 },
128 { 0x00, 0x22, KEY_5 }, 128 { 0x0022, KEY_5 },
129 { 0x00, 0x23, KEY_6 }, 129 { 0x0023, KEY_6 },
130 { 0x00, 0x24, KEY_7 }, 130 { 0x0024, KEY_7 },
131 { 0x00, 0x25, KEY_8 }, 131 { 0x0025, KEY_8 },
132 { 0x00, 0x26, KEY_9 }, 132 { 0x0026, KEY_9 },
133 { 0x00, 0x27, KEY_0 }, 133 { 0x0027, KEY_0 },
134 { 0x00, 0x28, KEY_ENTER }, 134 { 0x0028, KEY_ENTER },
135 { 0x00, 0x4f, KEY_VOLUMEUP }, 135 { 0x004f, KEY_VOLUMEUP },
136 { 0x00, 0x50, KEY_VOLUMEDOWN }, 136 { 0x0050, KEY_VOLUMEDOWN },
137 { 0x00, 0x51, KEY_CHANNELDOWN }, 137 { 0x0051, KEY_CHANNELDOWN },
138 { 0x00, 0x52, KEY_CHANNELUP }, 138 { 0x0052, KEY_CHANNELUP },
139}; 139};
140 140
141static u8 af9015_ir_table_leadtek[] = { 141static u8 af9015_ir_table_leadtek[] = {
@@ -193,60 +193,60 @@ static u8 af9015_ir_table_leadtek[] = {
193 193
194/* TwinHan AzureWave AD-TU700(704J) */ 194/* TwinHan AzureWave AD-TU700(704J) */
195static struct dvb_usb_rc_key af9015_rc_keys_twinhan[] = { 195static struct dvb_usb_rc_key af9015_rc_keys_twinhan[] = {
196 { 0x05, 0x3f, KEY_POWER }, 196 { 0x053f, KEY_POWER },
197 { 0x00, 0x19, KEY_FAVORITES }, /* Favorite List */ 197 { 0x0019, KEY_FAVORITES }, /* Favorite List */
198 { 0x00, 0x04, KEY_TEXT }, /* Teletext */ 198 { 0x0004, KEY_TEXT }, /* Teletext */
199 { 0x00, 0x0e, KEY_POWER }, 199 { 0x000e, KEY_POWER },
200 { 0x00, 0x0e, KEY_INFO }, /* Preview */ 200 { 0x000e, KEY_INFO }, /* Preview */
201 { 0x00, 0x08, KEY_EPG }, /* Info/EPG */ 201 { 0x0008, KEY_EPG }, /* Info/EPG */
202 { 0x00, 0x0f, KEY_LIST }, /* Record List */ 202 { 0x000f, KEY_LIST }, /* Record List */
203 { 0x00, 0x1e, KEY_1 }, 203 { 0x001e, KEY_1 },
204 { 0x00, 0x1f, KEY_2 }, 204 { 0x001f, KEY_2 },
205 { 0x00, 0x20, KEY_3 }, 205 { 0x0020, KEY_3 },
206 { 0x00, 0x21, KEY_4 }, 206 { 0x0021, KEY_4 },
207 { 0x00, 0x22, KEY_5 }, 207 { 0x0022, KEY_5 },
208 { 0x00, 0x23, KEY_6 }, 208 { 0x0023, KEY_6 },
209 { 0x00, 0x24, KEY_7 }, 209 { 0x0024, KEY_7 },
210 { 0x00, 0x25, KEY_8 }, 210 { 0x0025, KEY_8 },
211 { 0x00, 0x26, KEY_9 }, 211 { 0x0026, KEY_9 },
212 { 0x00, 0x27, KEY_0 }, 212 { 0x0027, KEY_0 },
213 { 0x00, 0x29, KEY_CANCEL }, /* Cancel */ 213 { 0x0029, KEY_CANCEL }, /* Cancel */
214 { 0x00, 0x4c, KEY_CLEAR }, /* Clear */ 214 { 0x004c, KEY_CLEAR }, /* Clear */
215 { 0x00, 0x2a, KEY_BACK }, /* Back */ 215 { 0x002a, KEY_BACK }, /* Back */
216 { 0x00, 0x2b, KEY_TAB }, /* Tab */ 216 { 0x002b, KEY_TAB }, /* Tab */
217 { 0x00, 0x52, KEY_UP }, /* up arrow */ 217 { 0x0052, KEY_UP }, /* up arrow */
218 { 0x00, 0x51, KEY_DOWN }, /* down arrow */ 218 { 0x0051, KEY_DOWN }, /* down arrow */
219 { 0x00, 0x4f, KEY_RIGHT }, /* right arrow */ 219 { 0x004f, KEY_RIGHT }, /* right arrow */
220 { 0x00, 0x50, KEY_LEFT }, /* left arrow */ 220 { 0x0050, KEY_LEFT }, /* left arrow */
221 { 0x00, 0x28, KEY_ENTER }, /* Enter / ok */ 221 { 0x0028, KEY_ENTER }, /* Enter / ok */
222 { 0x02, 0x52, KEY_VOLUMEUP }, 222 { 0x0252, KEY_VOLUMEUP },
223 { 0x02, 0x51, KEY_VOLUMEDOWN }, 223 { 0x0251, KEY_VOLUMEDOWN },
224 { 0x00, 0x4e, KEY_CHANNELDOWN }, 224 { 0x004e, KEY_CHANNELDOWN },
225 { 0x00, 0x4b, KEY_CHANNELUP }, 225 { 0x004b, KEY_CHANNELUP },
226 { 0x00, 0x4a, KEY_RECORD }, 226 { 0x004a, KEY_RECORD },
227 { 0x01, 0x11, KEY_PLAY }, 227 { 0x0111, KEY_PLAY },
228 { 0x00, 0x17, KEY_PAUSE }, 228 { 0x0017, KEY_PAUSE },
229 { 0x00, 0x0c, KEY_REWIND }, /* FR << */ 229 { 0x000c, KEY_REWIND }, /* FR << */
230 { 0x00, 0x11, KEY_FASTFORWARD }, /* FF >> */ 230 { 0x0011, KEY_FASTFORWARD }, /* FF >> */
231 { 0x01, 0x15, KEY_PREVIOUS }, /* Replay */ 231 { 0x0115, KEY_PREVIOUS }, /* Replay */
232 { 0x01, 0x0e, KEY_NEXT }, /* Skip */ 232 { 0x010e, KEY_NEXT }, /* Skip */
233 { 0x00, 0x13, KEY_CAMERA }, /* Capture */ 233 { 0x0013, KEY_CAMERA }, /* Capture */
234 { 0x01, 0x0f, KEY_LANGUAGE }, /* SAP */ 234 { 0x010f, KEY_LANGUAGE }, /* SAP */
235 { 0x01, 0x13, KEY_TV2 }, /* PIP */ 235 { 0x0113, KEY_TV2 }, /* PIP */
236 { 0x00, 0x1d, KEY_ZOOM }, /* Full Screen */ 236 { 0x001d, KEY_ZOOM }, /* Full Screen */
237 { 0x01, 0x17, KEY_SUBTITLE }, /* Subtitle / CC */ 237 { 0x0117, KEY_SUBTITLE }, /* Subtitle / CC */
238 { 0x00, 0x10, KEY_MUTE }, 238 { 0x0010, KEY_MUTE },
239 { 0x01, 0x19, KEY_AUDIO }, /* L/R */ /* TODO better event */ 239 { 0x0119, KEY_AUDIO }, /* L/R */ /* TODO better event */
240 { 0x01, 0x16, KEY_SLEEP }, /* Hibernate */ 240 { 0x0116, KEY_SLEEP }, /* Hibernate */
241 { 0x01, 0x16, KEY_SWITCHVIDEOMODE }, 241 { 0x0116, KEY_SWITCHVIDEOMODE },
242 /* A/V */ /* TODO does not work */ 242 /* A/V */ /* TODO does not work */
243 { 0x00, 0x06, KEY_AGAIN }, /* Recall */ 243 { 0x0006, KEY_AGAIN }, /* Recall */
244 { 0x01, 0x16, KEY_KPPLUS }, /* Zoom+ */ /* TODO does not work */ 244 { 0x0116, KEY_KPPLUS }, /* Zoom+ */ /* TODO does not work */
245 { 0x01, 0x16, KEY_KPMINUS }, /* Zoom- */ /* TODO does not work */ 245 { 0x0116, KEY_KPMINUS }, /* Zoom- */ /* TODO does not work */
246 { 0x02, 0x15, KEY_RED }, 246 { 0x0215, KEY_RED },
247 { 0x02, 0x0a, KEY_GREEN }, 247 { 0x020a, KEY_GREEN },
248 { 0x02, 0x1c, KEY_YELLOW }, 248 { 0x021c, KEY_YELLOW },
249 { 0x02, 0x05, KEY_BLUE }, 249 { 0x0205, KEY_BLUE },
250}; 250};
251 251
252static u8 af9015_ir_table_twinhan[] = { 252static u8 af9015_ir_table_twinhan[] = {
@@ -304,24 +304,24 @@ static u8 af9015_ir_table_twinhan[] = {
304 304
305/* A-Link DTU(m) */ 305/* A-Link DTU(m) */
306static struct dvb_usb_rc_key af9015_rc_keys_a_link[] = { 306static struct dvb_usb_rc_key af9015_rc_keys_a_link[] = {
307 { 0x00, 0x1e, KEY_1 }, 307 { 0x001e, KEY_1 },
308 { 0x00, 0x1f, KEY_2 }, 308 { 0x001f, KEY_2 },
309 { 0x00, 0x20, KEY_3 }, 309 { 0x0020, KEY_3 },
310 { 0x00, 0x21, KEY_4 }, 310 { 0x0021, KEY_4 },
311 { 0x00, 0x22, KEY_5 }, 311 { 0x0022, KEY_5 },
312 { 0x00, 0x23, KEY_6 }, 312 { 0x0023, KEY_6 },
313 { 0x00, 0x24, KEY_7 }, 313 { 0x0024, KEY_7 },
314 { 0x00, 0x25, KEY_8 }, 314 { 0x0025, KEY_8 },
315 { 0x00, 0x26, KEY_9 }, 315 { 0x0026, KEY_9 },
316 { 0x00, 0x27, KEY_0 }, 316 { 0x0027, KEY_0 },
317 { 0x00, 0x2e, KEY_CHANNELUP }, 317 { 0x002e, KEY_CHANNELUP },
318 { 0x00, 0x2d, KEY_CHANNELDOWN }, 318 { 0x002d, KEY_CHANNELDOWN },
319 { 0x04, 0x28, KEY_ZOOM }, 319 { 0x0428, KEY_ZOOM },
320 { 0x00, 0x41, KEY_MUTE }, 320 { 0x0041, KEY_MUTE },
321 { 0x00, 0x42, KEY_VOLUMEDOWN }, 321 { 0x0042, KEY_VOLUMEDOWN },
322 { 0x00, 0x43, KEY_VOLUMEUP }, 322 { 0x0043, KEY_VOLUMEUP },
323 { 0x00, 0x44, KEY_GOTO }, /* jump */ 323 { 0x0044, KEY_GOTO }, /* jump */
324 { 0x05, 0x45, KEY_POWER }, 324 { 0x0545, KEY_POWER },
325}; 325};
326 326
327static u8 af9015_ir_table_a_link[] = { 327static u8 af9015_ir_table_a_link[] = {
@@ -347,24 +347,24 @@ static u8 af9015_ir_table_a_link[] = {
347 347
348/* MSI DIGIVOX mini II V3.0 */ 348/* MSI DIGIVOX mini II V3.0 */
349static struct dvb_usb_rc_key af9015_rc_keys_msi[] = { 349static struct dvb_usb_rc_key af9015_rc_keys_msi[] = {
350 { 0x00, 0x1e, KEY_1 }, 350 { 0x001e, KEY_1 },
351 { 0x00, 0x1f, KEY_2 }, 351 { 0x001f, KEY_2 },
352 { 0x00, 0x20, KEY_3 }, 352 { 0x0020, KEY_3 },
353 { 0x00, 0x21, KEY_4 }, 353 { 0x0021, KEY_4 },
354 { 0x00, 0x22, KEY_5 }, 354 { 0x0022, KEY_5 },
355 { 0x00, 0x23, KEY_6 }, 355 { 0x0023, KEY_6 },
356 { 0x00, 0x24, KEY_7 }, 356 { 0x0024, KEY_7 },
357 { 0x00, 0x25, KEY_8 }, 357 { 0x0025, KEY_8 },
358 { 0x00, 0x26, KEY_9 }, 358 { 0x0026, KEY_9 },
359 { 0x00, 0x27, KEY_0 }, 359 { 0x0027, KEY_0 },
360 { 0x03, 0x0f, KEY_CHANNELUP }, 360 { 0x030f, KEY_CHANNELUP },
361 { 0x03, 0x0e, KEY_CHANNELDOWN }, 361 { 0x030e, KEY_CHANNELDOWN },
362 { 0x00, 0x42, KEY_VOLUMEDOWN }, 362 { 0x0042, KEY_VOLUMEDOWN },
363 { 0x00, 0x43, KEY_VOLUMEUP }, 363 { 0x0043, KEY_VOLUMEUP },
364 { 0x05, 0x45, KEY_POWER }, 364 { 0x0545, KEY_POWER },
365 { 0x00, 0x52, KEY_UP }, /* up */ 365 { 0x0052, KEY_UP }, /* up */
366 { 0x00, 0x51, KEY_DOWN }, /* down */ 366 { 0x0051, KEY_DOWN }, /* down */
367 { 0x00, 0x28, KEY_ENTER }, 367 { 0x0028, KEY_ENTER },
368}; 368};
369 369
370static u8 af9015_ir_table_msi[] = { 370static u8 af9015_ir_table_msi[] = {
@@ -390,42 +390,42 @@ static u8 af9015_ir_table_msi[] = {
390 390
391/* MYGICTV U718 */ 391/* MYGICTV U718 */
392static struct dvb_usb_rc_key af9015_rc_keys_mygictv[] = { 392static struct dvb_usb_rc_key af9015_rc_keys_mygictv[] = {
393 { 0x00, 0x3d, KEY_SWITCHVIDEOMODE }, 393 { 0x003d, KEY_SWITCHVIDEOMODE },
394 /* TV / AV */ 394 /* TV / AV */
395 { 0x05, 0x45, KEY_POWER }, 395 { 0x0545, KEY_POWER },
396 { 0x00, 0x1e, KEY_1 }, 396 { 0x001e, KEY_1 },
397 { 0x00, 0x1f, KEY_2 }, 397 { 0x001f, KEY_2 },
398 { 0x00, 0x20, KEY_3 }, 398 { 0x0020, KEY_3 },
399 { 0x00, 0x21, KEY_4 }, 399 { 0x0021, KEY_4 },
400 { 0x00, 0x22, KEY_5 }, 400 { 0x0022, KEY_5 },
401 { 0x00, 0x23, KEY_6 }, 401 { 0x0023, KEY_6 },
402 { 0x00, 0x24, KEY_7 }, 402 { 0x0024, KEY_7 },
403 { 0x00, 0x25, KEY_8 }, 403 { 0x0025, KEY_8 },
404 { 0x00, 0x26, KEY_9 }, 404 { 0x0026, KEY_9 },
405 { 0x00, 0x27, KEY_0 }, 405 { 0x0027, KEY_0 },
406 { 0x00, 0x41, KEY_MUTE }, 406 { 0x0041, KEY_MUTE },
407 { 0x00, 0x2a, KEY_ESC }, /* Esc */ 407 { 0x002a, KEY_ESC }, /* Esc */
408 { 0x00, 0x2e, KEY_CHANNELUP }, 408 { 0x002e, KEY_CHANNELUP },
409 { 0x00, 0x2d, KEY_CHANNELDOWN }, 409 { 0x002d, KEY_CHANNELDOWN },
410 { 0x00, 0x42, KEY_VOLUMEDOWN }, 410 { 0x0042, KEY_VOLUMEDOWN },
411 { 0x00, 0x43, KEY_VOLUMEUP }, 411 { 0x0043, KEY_VOLUMEUP },
412 { 0x00, 0x52, KEY_UP }, /* up arrow */ 412 { 0x0052, KEY_UP }, /* up arrow */
413 { 0x00, 0x51, KEY_DOWN }, /* down arrow */ 413 { 0x0051, KEY_DOWN }, /* down arrow */
414 { 0x00, 0x4f, KEY_RIGHT }, /* right arrow */ 414 { 0x004f, KEY_RIGHT }, /* right arrow */
415 { 0x00, 0x50, KEY_LEFT }, /* left arrow */ 415 { 0x0050, KEY_LEFT }, /* left arrow */
416 { 0x00, 0x28, KEY_ENTER }, /* ok */ 416 { 0x0028, KEY_ENTER }, /* ok */
417 { 0x01, 0x15, KEY_RECORD }, 417 { 0x0115, KEY_RECORD },
418 { 0x03, 0x13, KEY_PLAY }, 418 { 0x0313, KEY_PLAY },
419 { 0x01, 0x13, KEY_PAUSE }, 419 { 0x0113, KEY_PAUSE },
420 { 0x01, 0x16, KEY_STOP }, 420 { 0x0116, KEY_STOP },
421 { 0x03, 0x07, KEY_REWIND }, /* FR << */ 421 { 0x0307, KEY_REWIND }, /* FR << */
422 { 0x03, 0x09, KEY_FASTFORWARD }, /* FF >> */ 422 { 0x0309, KEY_FASTFORWARD }, /* FF >> */
423 { 0x00, 0x3b, KEY_TIME }, /* TimeShift */ 423 { 0x003b, KEY_TIME }, /* TimeShift */
424 { 0x00, 0x3e, KEY_CAMERA }, /* Snapshot */ 424 { 0x003e, KEY_CAMERA }, /* Snapshot */
425 { 0x03, 0x16, KEY_CYCLEWINDOWS }, /* yellow, min / max */ 425 { 0x0316, KEY_CYCLEWINDOWS }, /* yellow, min / max */
426 { 0x00, 0x00, KEY_ZOOM }, /* 'select' (?) */ 426 { 0x0000, KEY_ZOOM }, /* 'select' (?) */
427 { 0x03, 0x16, KEY_SHUFFLE }, /* Shuffle */ 427 { 0x0316, KEY_SHUFFLE }, /* Shuffle */
428 { 0x03, 0x45, KEY_POWER }, 428 { 0x0345, KEY_POWER },
429}; 429};
430 430
431static u8 af9015_ir_table_mygictv[] = { 431static u8 af9015_ir_table_mygictv[] = {
@@ -516,41 +516,41 @@ static u8 af9015_ir_table_kworld[] = {
516 516
517/* AverMedia Volar X */ 517/* AverMedia Volar X */
518static struct dvb_usb_rc_key af9015_rc_keys_avermedia[] = { 518static struct dvb_usb_rc_key af9015_rc_keys_avermedia[] = {
519 { 0x05, 0x3d, KEY_PROG1 }, /* SOURCE */ 519 { 0x053d, KEY_PROG1 }, /* SOURCE */
520 { 0x05, 0x12, KEY_POWER }, /* POWER */ 520 { 0x0512, KEY_POWER }, /* POWER */
521 { 0x05, 0x1e, KEY_1 }, /* 1 */ 521 { 0x051e, KEY_1 }, /* 1 */
522 { 0x05, 0x1f, KEY_2 }, /* 2 */ 522 { 0x051f, KEY_2 }, /* 2 */
523 { 0x05, 0x20, KEY_3 }, /* 3 */ 523 { 0x0520, KEY_3 }, /* 3 */
524 { 0x05, 0x21, KEY_4 }, /* 4 */ 524 { 0x0521, KEY_4 }, /* 4 */
525 { 0x05, 0x22, KEY_5 }, /* 5 */ 525 { 0x0522, KEY_5 }, /* 5 */
526 { 0x05, 0x23, KEY_6 }, /* 6 */ 526 { 0x0523, KEY_6 }, /* 6 */
527 { 0x05, 0x24, KEY_7 }, /* 7 */ 527 { 0x0524, KEY_7 }, /* 7 */
528 { 0x05, 0x25, KEY_8 }, /* 8 */ 528 { 0x0525, KEY_8 }, /* 8 */
529 { 0x05, 0x26, KEY_9 }, /* 9 */ 529 { 0x0526, KEY_9 }, /* 9 */
530 { 0x05, 0x3f, KEY_LEFT }, /* L / DISPLAY */ 530 { 0x053f, KEY_LEFT }, /* L / DISPLAY */
531 { 0x05, 0x27, KEY_0 }, /* 0 */ 531 { 0x0527, KEY_0 }, /* 0 */
532 { 0x05, 0x0f, KEY_RIGHT }, /* R / CH RTN */ 532 { 0x050f, KEY_RIGHT }, /* R / CH RTN */
533 { 0x05, 0x18, KEY_PROG2 }, /* SNAP SHOT */ 533 { 0x0518, KEY_PROG2 }, /* SNAP SHOT */
534 { 0x05, 0x1c, KEY_PROG3 }, /* 16-CH PREV */ 534 { 0x051c, KEY_PROG3 }, /* 16-CH PREV */
535 { 0x05, 0x2d, KEY_VOLUMEDOWN }, /* VOL DOWN */ 535 { 0x052d, KEY_VOLUMEDOWN }, /* VOL DOWN */
536 { 0x05, 0x3e, KEY_ZOOM }, /* FULL SCREEN */ 536 { 0x053e, KEY_ZOOM }, /* FULL SCREEN */
537 { 0x05, 0x2e, KEY_VOLUMEUP }, /* VOL UP */ 537 { 0x052e, KEY_VOLUMEUP }, /* VOL UP */
538 { 0x05, 0x10, KEY_MUTE }, /* MUTE */ 538 { 0x0510, KEY_MUTE }, /* MUTE */
539 { 0x05, 0x04, KEY_AUDIO }, /* AUDIO */ 539 { 0x0504, KEY_AUDIO }, /* AUDIO */
540 { 0x05, 0x15, KEY_RECORD }, /* RECORD */ 540 { 0x0515, KEY_RECORD }, /* RECORD */
541 { 0x05, 0x11, KEY_PLAY }, /* PLAY */ 541 { 0x0511, KEY_PLAY }, /* PLAY */
542 { 0x05, 0x16, KEY_STOP }, /* STOP */ 542 { 0x0516, KEY_STOP }, /* STOP */
543 { 0x05, 0x0c, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */ 543 { 0x050c, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */
544 { 0x05, 0x05, KEY_BACK }, /* << / RED */ 544 { 0x0505, KEY_BACK }, /* << / RED */
545 { 0x05, 0x09, KEY_FORWARD }, /* >> / YELLOW */ 545 { 0x0509, KEY_FORWARD }, /* >> / YELLOW */
546 { 0x05, 0x17, KEY_TEXT }, /* TELETEXT */ 546 { 0x0517, KEY_TEXT }, /* TELETEXT */
547 { 0x05, 0x0a, KEY_EPG }, /* EPG */ 547 { 0x050a, KEY_EPG }, /* EPG */
548 { 0x05, 0x13, KEY_MENU }, /* MENU */ 548 { 0x0513, KEY_MENU }, /* MENU */
549 549
550 { 0x05, 0x0e, KEY_CHANNELUP }, /* CH UP */ 550 { 0x050e, KEY_CHANNELUP }, /* CH UP */
551 { 0x05, 0x0d, KEY_CHANNELDOWN }, /* CH DOWN */ 551 { 0x050d, KEY_CHANNELDOWN }, /* CH DOWN */
552 { 0x05, 0x19, KEY_FIRST }, /* |<< / GREEN */ 552 { 0x0519, KEY_FIRST }, /* |<< / GREEN */
553 { 0x05, 0x08, KEY_LAST }, /* >>| / BLUE */ 553 { 0x0508, KEY_LAST }, /* >>| / BLUE */
554}; 554};
555 555
556static u8 af9015_ir_table_avermedia[] = { 556static u8 af9015_ir_table_avermedia[] = {
@@ -622,34 +622,34 @@ static u8 af9015_ir_table_avermedia_ks[] = {
622 622
623/* Digittrade DVB-T USB Stick */ 623/* Digittrade DVB-T USB Stick */
624static struct dvb_usb_rc_key af9015_rc_keys_digittrade[] = { 624static struct dvb_usb_rc_key af9015_rc_keys_digittrade[] = {
625 { 0x01, 0x0f, KEY_LAST }, /* RETURN */ 625 { 0x010f, KEY_LAST }, /* RETURN */
626 { 0x05, 0x17, KEY_TEXT }, /* TELETEXT */ 626 { 0x0517, KEY_TEXT }, /* TELETEXT */
627 { 0x01, 0x08, KEY_EPG }, /* EPG */ 627 { 0x0108, KEY_EPG }, /* EPG */
628 { 0x05, 0x13, KEY_POWER }, /* POWER */ 628 { 0x0513, KEY_POWER }, /* POWER */
629 { 0x01, 0x09, KEY_ZOOM }, /* FULLSCREEN */ 629 { 0x0109, KEY_ZOOM }, /* FULLSCREEN */
630 { 0x00, 0x40, KEY_AUDIO }, /* DUAL SOUND */ 630 { 0x0040, KEY_AUDIO }, /* DUAL SOUND */
631 { 0x00, 0x2c, KEY_PRINT }, /* SNAPSHOT */ 631 { 0x002c, KEY_PRINT }, /* SNAPSHOT */
632 { 0x05, 0x16, KEY_SUBTITLE }, /* SUBTITLE */ 632 { 0x0516, KEY_SUBTITLE }, /* SUBTITLE */
633 { 0x00, 0x52, KEY_CHANNELUP }, /* CH Up */ 633 { 0x0052, KEY_CHANNELUP }, /* CH Up */
634 { 0x00, 0x51, KEY_CHANNELDOWN },/* Ch Dn */ 634 { 0x0051, KEY_CHANNELDOWN },/* Ch Dn */
635 { 0x00, 0x57, KEY_VOLUMEUP }, /* Vol Up */ 635 { 0x0057, KEY_VOLUMEUP }, /* Vol Up */
636 { 0x00, 0x56, KEY_VOLUMEDOWN }, /* Vol Dn */ 636 { 0x0056, KEY_VOLUMEDOWN }, /* Vol Dn */
637 { 0x01, 0x10, KEY_MUTE }, /* MUTE */ 637 { 0x0110, KEY_MUTE }, /* MUTE */
638 { 0x00, 0x27, KEY_0 }, 638 { 0x0027, KEY_0 },
639 { 0x00, 0x1e, KEY_1 }, 639 { 0x001e, KEY_1 },
640 { 0x00, 0x1f, KEY_2 }, 640 { 0x001f, KEY_2 },
641 { 0x00, 0x20, KEY_3 }, 641 { 0x0020, KEY_3 },
642 { 0x00, 0x21, KEY_4 }, 642 { 0x0021, KEY_4 },
643 { 0x00, 0x22, KEY_5 }, 643 { 0x0022, KEY_5 },
644 { 0x00, 0x23, KEY_6 }, 644 { 0x0023, KEY_6 },
645 { 0x00, 0x24, KEY_7 }, 645 { 0x0024, KEY_7 },
646 { 0x00, 0x25, KEY_8 }, 646 { 0x0025, KEY_8 },
647 { 0x00, 0x26, KEY_9 }, 647 { 0x0026, KEY_9 },
648 { 0x01, 0x17, KEY_PLAYPAUSE }, /* TIMESHIFT */ 648 { 0x0117, KEY_PLAYPAUSE }, /* TIMESHIFT */
649 { 0x01, 0x15, KEY_RECORD }, /* RECORD */ 649 { 0x0115, KEY_RECORD }, /* RECORD */
650 { 0x03, 0x13, KEY_PLAY }, /* PLAY */ 650 { 0x0313, KEY_PLAY }, /* PLAY */
651 { 0x01, 0x16, KEY_STOP }, /* STOP */ 651 { 0x0116, KEY_STOP }, /* STOP */
652 { 0x01, 0x13, KEY_PAUSE }, /* PAUSE */ 652 { 0x0113, KEY_PAUSE }, /* PAUSE */
653}; 653};
654 654
655static u8 af9015_ir_table_digittrade[] = { 655static u8 af9015_ir_table_digittrade[] = {
@@ -685,34 +685,34 @@ static u8 af9015_ir_table_digittrade[] = {
685 685
686/* TREKSTOR DVB-T USB Stick */ 686/* TREKSTOR DVB-T USB Stick */
687static struct dvb_usb_rc_key af9015_rc_keys_trekstor[] = { 687static struct dvb_usb_rc_key af9015_rc_keys_trekstor[] = {
688 { 0x07, 0x04, KEY_AGAIN }, /* Home */ 688 { 0x0704, KEY_AGAIN }, /* Home */
689 { 0x07, 0x05, KEY_MUTE }, /* Mute */ 689 { 0x0705, KEY_MUTE }, /* Mute */
690 { 0x07, 0x06, KEY_UP }, /* Up */ 690 { 0x0706, KEY_UP }, /* Up */
691 { 0x07, 0x07, KEY_DOWN }, /* Down */ 691 { 0x0707, KEY_DOWN }, /* Down */
692 { 0x07, 0x09, KEY_RIGHT }, /* Right */ 692 { 0x0709, KEY_RIGHT }, /* Right */
693 { 0x07, 0x0a, KEY_ENTER }, /* OK */ 693 { 0x070a, KEY_ENTER }, /* OK */
694 { 0x07, 0x0b, KEY_FASTFORWARD }, /* Fast forward */ 694 { 0x070b, KEY_FASTFORWARD }, /* Fast forward */
695 { 0x07, 0x0c, KEY_REWIND }, /* Rewind */ 695 { 0x070c, KEY_REWIND }, /* Rewind */
696 { 0x07, 0x0d, KEY_PLAY }, /* Play/Pause */ 696 { 0x070d, KEY_PLAY }, /* Play/Pause */
697 { 0x07, 0x0e, KEY_VOLUMEUP }, /* Volume + */ 697 { 0x070e, KEY_VOLUMEUP }, /* Volume + */
698 { 0x07, 0x0f, KEY_VOLUMEDOWN }, /* Volume - */ 698 { 0x070f, KEY_VOLUMEDOWN }, /* Volume - */
699 { 0x07, 0x10, KEY_RECORD }, /* Record */ 699 { 0x0710, KEY_RECORD }, /* Record */
700 { 0x07, 0x11, KEY_STOP }, /* Stop */ 700 { 0x0711, KEY_STOP }, /* Stop */
701 { 0x07, 0x12, KEY_ZOOM }, /* TV */ 701 { 0x0712, KEY_ZOOM }, /* TV */
702 { 0x07, 0x13, KEY_EPG }, /* Info/EPG */ 702 { 0x0713, KEY_EPG }, /* Info/EPG */
703 { 0x07, 0x14, KEY_CHANNELDOWN }, /* Channel - */ 703 { 0x0714, KEY_CHANNELDOWN }, /* Channel - */
704 { 0x07, 0x15, KEY_CHANNELUP }, /* Channel + */ 704 { 0x0715, KEY_CHANNELUP }, /* Channel + */
705 { 0x07, 0x1e, KEY_1 }, 705 { 0x071e, KEY_1 },
706 { 0x07, 0x1f, KEY_2 }, 706 { 0x071f, KEY_2 },
707 { 0x07, 0x20, KEY_3 }, 707 { 0x0720, KEY_3 },
708 { 0x07, 0x21, KEY_4 }, 708 { 0x0721, KEY_4 },
709 { 0x07, 0x22, KEY_5 }, 709 { 0x0722, KEY_5 },
710 { 0x07, 0x23, KEY_6 }, 710 { 0x0723, KEY_6 },
711 { 0x07, 0x24, KEY_7 }, 711 { 0x0724, KEY_7 },
712 { 0x07, 0x25, KEY_8 }, 712 { 0x0725, KEY_8 },
713 { 0x07, 0x26, KEY_9 }, 713 { 0x0726, KEY_9 },
714 { 0x07, 0x08, KEY_LEFT }, /* LEFT */ 714 { 0x0708, KEY_LEFT }, /* LEFT */
715 { 0x07, 0x27, KEY_0 }, 715 { 0x0727, KEY_0 },
716}; 716};
717 717
718static u8 af9015_ir_table_trekstor[] = { 718static u8 af9015_ir_table_trekstor[] = {
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
index c6e7b4215d6b..7381aff4dcf6 100644
--- a/drivers/media/dvb/dvb-usb/anysee.c
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -389,8 +389,8 @@ static int anysee_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
389 *state = REMOTE_NO_KEY_PRESSED; 389 *state = REMOTE_NO_KEY_PRESSED;
390 390
391 for (i = 0; i < d->props.rc_key_map_size; i++) { 391 for (i = 0; i < d->props.rc_key_map_size; i++) {
392 if (keymap[i].custom == ircode[0] && 392 if (rc5_custom(&keymap[i]) == ircode[0] &&
393 keymap[i].data == ircode[1]) { 393 rc5_data(&keymap[i]) == ircode[1]) {
394 *event = keymap[i].event; 394 *event = keymap[i].event;
395 *state = REMOTE_KEY_PRESSED; 395 *state = REMOTE_KEY_PRESSED;
396 return 0; 396 return 0;
@@ -400,50 +400,50 @@ static int anysee_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
400} 400}
401 401
402static struct dvb_usb_rc_key anysee_rc_keys[] = { 402static struct dvb_usb_rc_key anysee_rc_keys[] = {
403 { 0x01, 0x00, KEY_0 }, 403 { 0x0100, KEY_0 },
404 { 0x01, 0x01, KEY_1 }, 404 { 0x0101, KEY_1 },
405 { 0x01, 0x02, KEY_2 }, 405 { 0x0102, KEY_2 },
406 { 0x01, 0x03, KEY_3 }, 406 { 0x0103, KEY_3 },
407 { 0x01, 0x04, KEY_4 }, 407 { 0x0104, KEY_4 },
408 { 0x01, 0x05, KEY_5 }, 408 { 0x0105, KEY_5 },
409 { 0x01, 0x06, KEY_6 }, 409 { 0x0106, KEY_6 },
410 { 0x01, 0x07, KEY_7 }, 410 { 0x0107, KEY_7 },
411 { 0x01, 0x08, KEY_8 }, 411 { 0x0108, KEY_8 },
412 { 0x01, 0x09, KEY_9 }, 412 { 0x0109, KEY_9 },
413 { 0x01, 0x0a, KEY_POWER }, 413 { 0x010a, KEY_POWER },
414 { 0x01, 0x0b, KEY_DOCUMENTS }, /* * */ 414 { 0x010b, KEY_DOCUMENTS }, /* * */
415 { 0x01, 0x19, KEY_FAVORITES }, 415 { 0x0119, KEY_FAVORITES },
416 { 0x01, 0x20, KEY_SLEEP }, 416 { 0x0120, KEY_SLEEP },
417 { 0x01, 0x21, KEY_MODE }, /* 4:3 / 16:9 select */ 417 { 0x0121, KEY_MODE }, /* 4:3 / 16:9 select */
418 { 0x01, 0x22, KEY_ZOOM }, 418 { 0x0122, KEY_ZOOM },
419 { 0x01, 0x47, KEY_TEXT }, 419 { 0x0147, KEY_TEXT },
420 { 0x01, 0x16, KEY_TV }, /* TV / radio select */ 420 { 0x0116, KEY_TV }, /* TV / radio select */
421 { 0x01, 0x1e, KEY_LANGUAGE }, /* Second Audio Program */ 421 { 0x011e, KEY_LANGUAGE }, /* Second Audio Program */
422 { 0x01, 0x1a, KEY_SUBTITLE }, 422 { 0x011a, KEY_SUBTITLE },
423 { 0x01, 0x1b, KEY_CAMERA }, /* screenshot */ 423 { 0x011b, KEY_CAMERA }, /* screenshot */
424 { 0x01, 0x42, KEY_MUTE }, 424 { 0x0142, KEY_MUTE },
425 { 0x01, 0x0e, KEY_MENU }, 425 { 0x010e, KEY_MENU },
426 { 0x01, 0x0f, KEY_EPG }, 426 { 0x010f, KEY_EPG },
427 { 0x01, 0x17, KEY_INFO }, 427 { 0x0117, KEY_INFO },
428 { 0x01, 0x10, KEY_EXIT }, 428 { 0x0110, KEY_EXIT },
429 { 0x01, 0x13, KEY_VOLUMEUP }, 429 { 0x0113, KEY_VOLUMEUP },
430 { 0x01, 0x12, KEY_VOLUMEDOWN }, 430 { 0x0112, KEY_VOLUMEDOWN },
431 { 0x01, 0x11, KEY_CHANNELUP }, 431 { 0x0111, KEY_CHANNELUP },
432 { 0x01, 0x14, KEY_CHANNELDOWN }, 432 { 0x0114, KEY_CHANNELDOWN },
433 { 0x01, 0x15, KEY_OK }, 433 { 0x0115, KEY_OK },
434 { 0x01, 0x1d, KEY_RED }, 434 { 0x011d, KEY_RED },
435 { 0x01, 0x1f, KEY_GREEN }, 435 { 0x011f, KEY_GREEN },
436 { 0x01, 0x1c, KEY_YELLOW }, 436 { 0x011c, KEY_YELLOW },
437 { 0x01, 0x44, KEY_BLUE }, 437 { 0x0144, KEY_BLUE },
438 { 0x01, 0x0c, KEY_SHUFFLE }, /* snapshot */ 438 { 0x010c, KEY_SHUFFLE }, /* snapshot */
439 { 0x01, 0x48, KEY_STOP }, 439 { 0x0148, KEY_STOP },
440 { 0x01, 0x50, KEY_PLAY }, 440 { 0x0150, KEY_PLAY },
441 { 0x01, 0x51, KEY_PAUSE }, 441 { 0x0151, KEY_PAUSE },
442 { 0x01, 0x49, KEY_RECORD }, 442 { 0x0149, KEY_RECORD },
443 { 0x01, 0x18, KEY_PREVIOUS }, /* |<< */ 443 { 0x0118, KEY_PREVIOUS }, /* |<< */
444 { 0x01, 0x0d, KEY_NEXT }, /* >>| */ 444 { 0x010d, KEY_NEXT }, /* >>| */
445 { 0x01, 0x24, KEY_PROG1 }, /* F1 */ 445 { 0x0124, KEY_PROG1 }, /* F1 */
446 { 0x01, 0x25, KEY_PROG2 }, /* F2 */ 446 { 0x0125, KEY_PROG2 }, /* F2 */
447}; 447};
448 448
449/* DVB USB Driver stuff */ 449/* DVB USB Driver stuff */
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-core.c b/drivers/media/dvb/dvb-usb/cinergyT2-core.c
index 80e37a0d0892..e37ac4d48602 100644
--- a/drivers/media/dvb/dvb-usb/cinergyT2-core.c
+++ b/drivers/media/dvb/dvb-usb/cinergyT2-core.c
@@ -85,43 +85,43 @@ static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap)
85} 85}
86 86
87static struct dvb_usb_rc_key cinergyt2_rc_keys[] = { 87static struct dvb_usb_rc_key cinergyt2_rc_keys[] = {
88 { 0x04, 0x01, KEY_POWER }, 88 { 0x0401, KEY_POWER },
89 { 0x04, 0x02, KEY_1 }, 89 { 0x0402, KEY_1 },
90 { 0x04, 0x03, KEY_2 }, 90 { 0x0403, KEY_2 },
91 { 0x04, 0x04, KEY_3 }, 91 { 0x0404, KEY_3 },
92 { 0x04, 0x05, KEY_4 }, 92 { 0x0405, KEY_4 },
93 { 0x04, 0x06, KEY_5 }, 93 { 0x0406, KEY_5 },
94 { 0x04, 0x07, KEY_6 }, 94 { 0x0407, KEY_6 },
95 { 0x04, 0x08, KEY_7 }, 95 { 0x0408, KEY_7 },
96 { 0x04, 0x09, KEY_8 }, 96 { 0x0409, KEY_8 },
97 { 0x04, 0x0a, KEY_9 }, 97 { 0x040a, KEY_9 },
98 { 0x04, 0x0c, KEY_0 }, 98 { 0x040c, KEY_0 },
99 { 0x04, 0x0b, KEY_VIDEO }, 99 { 0x040b, KEY_VIDEO },
100 { 0x04, 0x0d, KEY_REFRESH }, 100 { 0x040d, KEY_REFRESH },
101 { 0x04, 0x0e, KEY_SELECT }, 101 { 0x040e, KEY_SELECT },
102 { 0x04, 0x0f, KEY_EPG }, 102 { 0x040f, KEY_EPG },
103 { 0x04, 0x10, KEY_UP }, 103 { 0x0410, KEY_UP },
104 { 0x04, 0x14, KEY_DOWN }, 104 { 0x0414, KEY_DOWN },
105 { 0x04, 0x11, KEY_LEFT }, 105 { 0x0411, KEY_LEFT },
106 { 0x04, 0x13, KEY_RIGHT }, 106 { 0x0413, KEY_RIGHT },
107 { 0x04, 0x12, KEY_OK }, 107 { 0x0412, KEY_OK },
108 { 0x04, 0x15, KEY_TEXT }, 108 { 0x0415, KEY_TEXT },
109 { 0x04, 0x16, KEY_INFO }, 109 { 0x0416, KEY_INFO },
110 { 0x04, 0x17, KEY_RED }, 110 { 0x0417, KEY_RED },
111 { 0x04, 0x18, KEY_GREEN }, 111 { 0x0418, KEY_GREEN },
112 { 0x04, 0x19, KEY_YELLOW }, 112 { 0x0419, KEY_YELLOW },
113 { 0x04, 0x1a, KEY_BLUE }, 113 { 0x041a, KEY_BLUE },
114 { 0x04, 0x1c, KEY_VOLUMEUP }, 114 { 0x041c, KEY_VOLUMEUP },
115 { 0x04, 0x1e, KEY_VOLUMEDOWN }, 115 { 0x041e, KEY_VOLUMEDOWN },
116 { 0x04, 0x1d, KEY_MUTE }, 116 { 0x041d, KEY_MUTE },
117 { 0x04, 0x1b, KEY_CHANNELUP }, 117 { 0x041b, KEY_CHANNELUP },
118 { 0x04, 0x1f, KEY_CHANNELDOWN }, 118 { 0x041f, KEY_CHANNELDOWN },
119 { 0x04, 0x40, KEY_PAUSE }, 119 { 0x0440, KEY_PAUSE },
120 { 0x04, 0x4c, KEY_PLAY }, 120 { 0x044c, KEY_PLAY },
121 { 0x04, 0x58, KEY_RECORD }, 121 { 0x0458, KEY_RECORD },
122 { 0x04, 0x54, KEY_PREVIOUS }, 122 { 0x0454, KEY_PREVIOUS },
123 { 0x04, 0x48, KEY_STOP }, 123 { 0x0448, KEY_STOP },
124 { 0x04, 0x5c, KEY_NEXT } 124 { 0x045c, KEY_NEXT }
125}; 125};
126 126
127/* Number of keypresses to ignore before detect repeating */ 127/* Number of keypresses to ignore before detect repeating */
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-fe.c b/drivers/media/dvb/dvb-usb/cinergyT2-fe.c
index 649f25cca49e..9cd51ac12076 100644
--- a/drivers/media/dvb/dvb-usb/cinergyT2-fe.c
+++ b/drivers/media/dvb/dvb-usb/cinergyT2-fe.c
@@ -275,6 +275,7 @@ static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe,
275 param.tps = cpu_to_le16(compute_tps(fep)); 275 param.tps = cpu_to_le16(compute_tps(fep));
276 param.freq = cpu_to_le32(fep->frequency / 1000); 276 param.freq = cpu_to_le32(fep->frequency / 1000);
277 param.bandwidth = 8 - fep->u.ofdm.bandwidth - BANDWIDTH_8_MHZ; 277 param.bandwidth = 8 - fep->u.ofdm.bandwidth - BANDWIDTH_8_MHZ;
278 param.flags = 0;
278 279
279 err = dvb_usb_generic_rw(state->d, 280 err = dvb_usb_generic_rw(state->d,
280 (char *)&param, sizeof(param), 281 (char *)&param, sizeof(param),
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 406d7fba369d..f65591fb7cec 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -38,7 +38,7 @@
38#include "mxl5005s.h" 38#include "mxl5005s.h"
39#include "dib7000p.h" 39#include "dib7000p.h"
40#include "dib0070.h" 40#include "dib0070.h"
41#include "lgs8gl5.h" 41#include "lgs8gxx.h"
42 42
43/* debug */ 43/* debug */
44static int dvb_usb_cxusb_debug; 44static int dvb_usb_cxusb_debug;
@@ -392,8 +392,8 @@ static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
392 *state = REMOTE_NO_KEY_PRESSED; 392 *state = REMOTE_NO_KEY_PRESSED;
393 393
394 for (i = 0; i < d->props.rc_key_map_size; i++) { 394 for (i = 0; i < d->props.rc_key_map_size; i++) {
395 if (keymap[i].custom == ircode[2] && 395 if (rc5_custom(&keymap[i]) == ircode[2] &&
396 keymap[i].data == ircode[3]) { 396 rc5_data(&keymap[i]) == ircode[3]) {
397 *event = keymap[i].event; 397 *event = keymap[i].event;
398 *state = REMOTE_KEY_PRESSED; 398 *state = REMOTE_KEY_PRESSED;
399 399
@@ -420,8 +420,8 @@ static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
420 return 0; 420 return 0;
421 421
422 for (i = 0; i < d->props.rc_key_map_size; i++) { 422 for (i = 0; i < d->props.rc_key_map_size; i++) {
423 if (keymap[i].custom == ircode[1] && 423 if (rc5_custom(&keymap[i]) == ircode[1] &&
424 keymap[i].data == ircode[2]) { 424 rc5_data(&keymap[i]) == ircode[2]) {
425 *event = keymap[i].event; 425 *event = keymap[i].event;
426 *state = REMOTE_KEY_PRESSED; 426 *state = REMOTE_KEY_PRESSED;
427 427
@@ -446,8 +446,8 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
446 return 0; 446 return 0;
447 447
448 for (i = 0; i < d->props.rc_key_map_size; i++) { 448 for (i = 0; i < d->props.rc_key_map_size; i++) {
449 if (keymap[i].custom == ircode[0] && 449 if (rc5_custom(&keymap[i]) == ircode[0] &&
450 keymap[i].data == ircode[1]) { 450 rc5_data(&keymap[i]) == ircode[1]) {
451 *event = keymap[i].event; 451 *event = keymap[i].event;
452 *state = REMOTE_KEY_PRESSED; 452 *state = REMOTE_KEY_PRESSED;
453 453
@@ -459,128 +459,128 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
459} 459}
460 460
461static struct dvb_usb_rc_key dvico_mce_rc_keys[] = { 461static struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
462 { 0xfe, 0x02, KEY_TV }, 462 { 0xfe02, KEY_TV },
463 { 0xfe, 0x0e, KEY_MP3 }, 463 { 0xfe0e, KEY_MP3 },
464 { 0xfe, 0x1a, KEY_DVD }, 464 { 0xfe1a, KEY_DVD },
465 { 0xfe, 0x1e, KEY_FAVORITES }, 465 { 0xfe1e, KEY_FAVORITES },
466 { 0xfe, 0x16, KEY_SETUP }, 466 { 0xfe16, KEY_SETUP },
467 { 0xfe, 0x46, KEY_POWER2 }, 467 { 0xfe46, KEY_POWER2 },
468 { 0xfe, 0x0a, KEY_EPG }, 468 { 0xfe0a, KEY_EPG },
469 { 0xfe, 0x49, KEY_BACK }, 469 { 0xfe49, KEY_BACK },
470 { 0xfe, 0x4d, KEY_MENU }, 470 { 0xfe4d, KEY_MENU },
471 { 0xfe, 0x51, KEY_UP }, 471 { 0xfe51, KEY_UP },
472 { 0xfe, 0x5b, KEY_LEFT }, 472 { 0xfe5b, KEY_LEFT },
473 { 0xfe, 0x5f, KEY_RIGHT }, 473 { 0xfe5f, KEY_RIGHT },
474 { 0xfe, 0x53, KEY_DOWN }, 474 { 0xfe53, KEY_DOWN },
475 { 0xfe, 0x5e, KEY_OK }, 475 { 0xfe5e, KEY_OK },
476 { 0xfe, 0x59, KEY_INFO }, 476 { 0xfe59, KEY_INFO },
477 { 0xfe, 0x55, KEY_TAB }, 477 { 0xfe55, KEY_TAB },
478 { 0xfe, 0x0f, KEY_PREVIOUSSONG },/* Replay */ 478 { 0xfe0f, KEY_PREVIOUSSONG },/* Replay */
479 { 0xfe, 0x12, KEY_NEXTSONG }, /* Skip */ 479 { 0xfe12, KEY_NEXTSONG }, /* Skip */
480 { 0xfe, 0x42, KEY_ENTER }, /* Windows/Start */ 480 { 0xfe42, KEY_ENTER }, /* Windows/Start */
481 { 0xfe, 0x15, KEY_VOLUMEUP }, 481 { 0xfe15, KEY_VOLUMEUP },
482 { 0xfe, 0x05, KEY_VOLUMEDOWN }, 482 { 0xfe05, KEY_VOLUMEDOWN },
483 { 0xfe, 0x11, KEY_CHANNELUP }, 483 { 0xfe11, KEY_CHANNELUP },
484 { 0xfe, 0x09, KEY_CHANNELDOWN }, 484 { 0xfe09, KEY_CHANNELDOWN },
485 { 0xfe, 0x52, KEY_CAMERA }, 485 { 0xfe52, KEY_CAMERA },
486 { 0xfe, 0x5a, KEY_TUNER }, /* Live */ 486 { 0xfe5a, KEY_TUNER }, /* Live */
487 { 0xfe, 0x19, KEY_OPEN }, 487 { 0xfe19, KEY_OPEN },
488 { 0xfe, 0x0b, KEY_1 }, 488 { 0xfe0b, KEY_1 },
489 { 0xfe, 0x17, KEY_2 }, 489 { 0xfe17, KEY_2 },
490 { 0xfe, 0x1b, KEY_3 }, 490 { 0xfe1b, KEY_3 },
491 { 0xfe, 0x07, KEY_4 }, 491 { 0xfe07, KEY_4 },
492 { 0xfe, 0x50, KEY_5 }, 492 { 0xfe50, KEY_5 },
493 { 0xfe, 0x54, KEY_6 }, 493 { 0xfe54, KEY_6 },
494 { 0xfe, 0x48, KEY_7 }, 494 { 0xfe48, KEY_7 },
495 { 0xfe, 0x4c, KEY_8 }, 495 { 0xfe4c, KEY_8 },
496 { 0xfe, 0x58, KEY_9 }, 496 { 0xfe58, KEY_9 },
497 { 0xfe, 0x13, KEY_ANGLE }, /* Aspect */ 497 { 0xfe13, KEY_ANGLE }, /* Aspect */
498 { 0xfe, 0x03, KEY_0 }, 498 { 0xfe03, KEY_0 },
499 { 0xfe, 0x1f, KEY_ZOOM }, 499 { 0xfe1f, KEY_ZOOM },
500 { 0xfe, 0x43, KEY_REWIND }, 500 { 0xfe43, KEY_REWIND },
501 { 0xfe, 0x47, KEY_PLAYPAUSE }, 501 { 0xfe47, KEY_PLAYPAUSE },
502 { 0xfe, 0x4f, KEY_FASTFORWARD }, 502 { 0xfe4f, KEY_FASTFORWARD },
503 { 0xfe, 0x57, KEY_MUTE }, 503 { 0xfe57, KEY_MUTE },
504 { 0xfe, 0x0d, KEY_STOP }, 504 { 0xfe0d, KEY_STOP },
505 { 0xfe, 0x01, KEY_RECORD }, 505 { 0xfe01, KEY_RECORD },
506 { 0xfe, 0x4e, KEY_POWER }, 506 { 0xfe4e, KEY_POWER },
507}; 507};
508 508
509static struct dvb_usb_rc_key dvico_portable_rc_keys[] = { 509static struct dvb_usb_rc_key dvico_portable_rc_keys[] = {
510 { 0xfc, 0x02, KEY_SETUP }, /* Profile */ 510 { 0xfc02, KEY_SETUP }, /* Profile */
511 { 0xfc, 0x43, KEY_POWER2 }, 511 { 0xfc43, KEY_POWER2 },
512 { 0xfc, 0x06, KEY_EPG }, 512 { 0xfc06, KEY_EPG },
513 { 0xfc, 0x5a, KEY_BACK }, 513 { 0xfc5a, KEY_BACK },
514 { 0xfc, 0x05, KEY_MENU }, 514 { 0xfc05, KEY_MENU },
515 { 0xfc, 0x47, KEY_INFO }, 515 { 0xfc47, KEY_INFO },
516 { 0xfc, 0x01, KEY_TAB }, 516 { 0xfc01, KEY_TAB },
517 { 0xfc, 0x42, KEY_PREVIOUSSONG },/* Replay */ 517 { 0xfc42, KEY_PREVIOUSSONG },/* Replay */
518 { 0xfc, 0x49, KEY_VOLUMEUP }, 518 { 0xfc49, KEY_VOLUMEUP },
519 { 0xfc, 0x09, KEY_VOLUMEDOWN }, 519 { 0xfc09, KEY_VOLUMEDOWN },
520 { 0xfc, 0x54, KEY_CHANNELUP }, 520 { 0xfc54, KEY_CHANNELUP },
521 { 0xfc, 0x0b, KEY_CHANNELDOWN }, 521 { 0xfc0b, KEY_CHANNELDOWN },
522 { 0xfc, 0x16, KEY_CAMERA }, 522 { 0xfc16, KEY_CAMERA },
523 { 0xfc, 0x40, KEY_TUNER }, /* ATV/DTV */ 523 { 0xfc40, KEY_TUNER }, /* ATV/DTV */
524 { 0xfc, 0x45, KEY_OPEN }, 524 { 0xfc45, KEY_OPEN },
525 { 0xfc, 0x19, KEY_1 }, 525 { 0xfc19, KEY_1 },
526 { 0xfc, 0x18, KEY_2 }, 526 { 0xfc18, KEY_2 },
527 { 0xfc, 0x1b, KEY_3 }, 527 { 0xfc1b, KEY_3 },
528 { 0xfc, 0x1a, KEY_4 }, 528 { 0xfc1a, KEY_4 },
529 { 0xfc, 0x58, KEY_5 }, 529 { 0xfc58, KEY_5 },
530 { 0xfc, 0x59, KEY_6 }, 530 { 0xfc59, KEY_6 },
531 { 0xfc, 0x15, KEY_7 }, 531 { 0xfc15, KEY_7 },
532 { 0xfc, 0x14, KEY_8 }, 532 { 0xfc14, KEY_8 },
533 { 0xfc, 0x17, KEY_9 }, 533 { 0xfc17, KEY_9 },
534 { 0xfc, 0x44, KEY_ANGLE }, /* Aspect */ 534 { 0xfc44, KEY_ANGLE }, /* Aspect */
535 { 0xfc, 0x55, KEY_0 }, 535 { 0xfc55, KEY_0 },
536 { 0xfc, 0x07, KEY_ZOOM }, 536 { 0xfc07, KEY_ZOOM },
537 { 0xfc, 0x0a, KEY_REWIND }, 537 { 0xfc0a, KEY_REWIND },
538 { 0xfc, 0x08, KEY_PLAYPAUSE }, 538 { 0xfc08, KEY_PLAYPAUSE },
539 { 0xfc, 0x4b, KEY_FASTFORWARD }, 539 { 0xfc4b, KEY_FASTFORWARD },
540 { 0xfc, 0x5b, KEY_MUTE }, 540 { 0xfc5b, KEY_MUTE },
541 { 0xfc, 0x04, KEY_STOP }, 541 { 0xfc04, KEY_STOP },
542 { 0xfc, 0x56, KEY_RECORD }, 542 { 0xfc56, KEY_RECORD },
543 { 0xfc, 0x57, KEY_POWER }, 543 { 0xfc57, KEY_POWER },
544 { 0xfc, 0x41, KEY_UNKNOWN }, /* INPUT */ 544 { 0xfc41, KEY_UNKNOWN }, /* INPUT */
545 { 0xfc, 0x00, KEY_UNKNOWN }, /* HD */ 545 { 0xfc00, KEY_UNKNOWN }, /* HD */
546}; 546};
547 547
548static struct dvb_usb_rc_key d680_dmb_rc_keys[] = { 548static struct dvb_usb_rc_key d680_dmb_rc_keys[] = {
549 { 0x00, 0x38, KEY_UNKNOWN }, /* TV/AV */ 549 { 0x0038, KEY_UNKNOWN }, /* TV/AV */
550 { 0x08, 0x0c, KEY_ZOOM }, 550 { 0x080c, KEY_ZOOM },
551 { 0x08, 0x00, KEY_0 }, 551 { 0x0800, KEY_0 },
552 { 0x00, 0x01, KEY_1 }, 552 { 0x0001, KEY_1 },
553 { 0x08, 0x02, KEY_2 }, 553 { 0x0802, KEY_2 },
554 { 0x00, 0x03, KEY_3 }, 554 { 0x0003, KEY_3 },
555 { 0x08, 0x04, KEY_4 }, 555 { 0x0804, KEY_4 },
556 { 0x00, 0x05, KEY_5 }, 556 { 0x0005, KEY_5 },
557 { 0x08, 0x06, KEY_6 }, 557 { 0x0806, KEY_6 },
558 { 0x00, 0x07, KEY_7 }, 558 { 0x0007, KEY_7 },
559 { 0x08, 0x08, KEY_8 }, 559 { 0x0808, KEY_8 },
560 { 0x00, 0x09, KEY_9 }, 560 { 0x0009, KEY_9 },
561 { 0x00, 0x0a, KEY_MUTE }, 561 { 0x000a, KEY_MUTE },
562 { 0x08, 0x29, KEY_BACK }, 562 { 0x0829, KEY_BACK },
563 { 0x00, 0x12, KEY_CHANNELUP }, 563 { 0x0012, KEY_CHANNELUP },
564 { 0x08, 0x13, KEY_CHANNELDOWN }, 564 { 0x0813, KEY_CHANNELDOWN },
565 { 0x00, 0x2b, KEY_VOLUMEUP }, 565 { 0x002b, KEY_VOLUMEUP },
566 { 0x08, 0x2c, KEY_VOLUMEDOWN }, 566 { 0x082c, KEY_VOLUMEDOWN },
567 { 0x00, 0x20, KEY_UP }, 567 { 0x0020, KEY_UP },
568 { 0x08, 0x21, KEY_DOWN }, 568 { 0x0821, KEY_DOWN },
569 { 0x00, 0x11, KEY_LEFT }, 569 { 0x0011, KEY_LEFT },
570 { 0x08, 0x10, KEY_RIGHT }, 570 { 0x0810, KEY_RIGHT },
571 { 0x00, 0x0d, KEY_OK }, 571 { 0x000d, KEY_OK },
572 { 0x08, 0x1f, KEY_RECORD }, 572 { 0x081f, KEY_RECORD },
573 { 0x00, 0x17, KEY_PLAYPAUSE }, 573 { 0x0017, KEY_PLAYPAUSE },
574 { 0x08, 0x16, KEY_PLAYPAUSE }, 574 { 0x0816, KEY_PLAYPAUSE },
575 { 0x00, 0x0b, KEY_STOP }, 575 { 0x000b, KEY_STOP },
576 { 0x08, 0x27, KEY_FASTFORWARD }, 576 { 0x0827, KEY_FASTFORWARD },
577 { 0x00, 0x26, KEY_REWIND }, 577 { 0x0026, KEY_REWIND },
578 { 0x08, 0x1e, KEY_UNKNOWN }, /* Time Shift */ 578 { 0x081e, KEY_UNKNOWN }, /* Time Shift */
579 { 0x00, 0x0e, KEY_UNKNOWN }, /* Snapshot */ 579 { 0x000e, KEY_UNKNOWN }, /* Snapshot */
580 { 0x08, 0x2d, KEY_UNKNOWN }, /* Mouse Cursor */ 580 { 0x082d, KEY_UNKNOWN }, /* Mouse Cursor */
581 { 0x00, 0x0f, KEY_UNKNOWN }, /* Minimize/Maximize */ 581 { 0x000f, KEY_UNKNOWN }, /* Minimize/Maximize */
582 { 0x08, 0x14, KEY_UNKNOWN }, /* Shuffle */ 582 { 0x0814, KEY_UNKNOWN }, /* Shuffle */
583 { 0x00, 0x25, KEY_POWER }, 583 { 0x0025, KEY_POWER },
584}; 584};
585 585
586static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) 586static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
@@ -1094,8 +1094,18 @@ static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
1094 return -EIO; 1094 return -EIO;
1095} 1095}
1096 1096
1097static struct lgs8gl5_config lgs8gl5_cfg = { 1097static struct lgs8gxx_config d680_lgs8gl5_cfg = {
1098 .prod = LGS8GXX_PROD_LGS8GL5,
1098 .demod_address = 0x19, 1099 .demod_address = 0x19,
1100 .serial_ts = 0,
1101 .ts_clk_pol = 0,
1102 .ts_clk_gated = 1,
1103 .if_clk_freq = 30400, /* 30.4 MHz */
1104 .if_freq = 5725, /* 5.725 MHz */
1105 .if_neg_center = 0,
1106 .ext_adc = 0,
1107 .adc_signed = 0,
1108 .if_neg_edge = 0,
1099}; 1109};
1100 1110
1101static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap) 1111static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap)
@@ -1135,7 +1145,7 @@ static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap)
1135 msleep(100); 1145 msleep(100);
1136 1146
1137 /* Attach frontend */ 1147 /* Attach frontend */
1138 adap->fe = dvb_attach(lgs8gl5_attach, &lgs8gl5_cfg, &d->i2c_adap); 1148 adap->fe = dvb_attach(lgs8gxx_attach, &d680_lgs8gl5_cfg, &d->i2c_adap);
1139 if (adap->fe == NULL) 1149 if (adap->fe == NULL)
1140 return -EIO; 1150 return -EIO;
1141 1151
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 818b2ab584bf..d1d6f4491403 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -310,7 +310,7 @@ static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap)
310 struct i2c_adapter *tun_i2c; 310 struct i2c_adapter *tun_i2c;
311 tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); 311 tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
312 return dvb_attach(mt2266_attach, adap->fe, tun_i2c, 312 return dvb_attach(mt2266_attach, adap->fe, tun_i2c,
313 &stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0;; 313 &stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0;
314} 314}
315 315
316/* STK7700-PH: Digital/Analog Hybrid Tuner, e.h. Cinergy HT USB HE */ 316/* STK7700-PH: Digital/Analog Hybrid Tuner, e.h. Cinergy HT USB HE */
@@ -509,7 +509,8 @@ static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event,
509 return 0; 509 return 0;
510 } 510 }
511 for (i=0;i<d->props.rc_key_map_size; i++) { 511 for (i=0;i<d->props.rc_key_map_size; i++) {
512 if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) { 512 if (rc5_custom(&keymap[i]) == key[3-2] &&
513 rc5_data(&keymap[i]) == key[3-3]) {
513 st->rc_counter = 0; 514 st->rc_counter = 0;
514 *event = keymap[i].event; 515 *event = keymap[i].event;
515 *state = REMOTE_KEY_PRESSED; 516 *state = REMOTE_KEY_PRESSED;
@@ -522,7 +523,8 @@ static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event,
522 default: { 523 default: {
523 /* RC-5 protocol changes toggle bit on new keypress */ 524 /* RC-5 protocol changes toggle bit on new keypress */
524 for (i = 0; i < d->props.rc_key_map_size; i++) { 525 for (i = 0; i < d->props.rc_key_map_size; i++) {
525 if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) { 526 if (rc5_custom(&keymap[i]) == key[3-2] &&
527 rc5_data(&keymap[i]) == key[3-3]) {
526 if (d->last_event == keymap[i].event && 528 if (d->last_event == keymap[i].event &&
527 key[3-1] == st->rc_toggle) { 529 key[3-1] == st->rc_toggle) {
528 st->rc_counter++; 530 st->rc_counter++;
@@ -616,8 +618,8 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
616 618
617 /* Find the key in the map */ 619 /* Find the key in the map */
618 for (i = 0; i < d->props.rc_key_map_size; i++) { 620 for (i = 0; i < d->props.rc_key_map_size; i++) {
619 if (keymap[i].custom == poll_reply.system_lsb && 621 if (rc5_custom(&keymap[i]) == poll_reply.system_lsb &&
620 keymap[i].data == poll_reply.data) { 622 rc5_data(&keymap[i]) == poll_reply.data) {
621 *event = keymap[i].event; 623 *event = keymap[i].event;
622 found = 1; 624 found = 1;
623 break; 625 break;
@@ -684,193 +686,193 @@ static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
684 686
685static struct dvb_usb_rc_key dib0700_rc_keys[] = { 687static struct dvb_usb_rc_key dib0700_rc_keys[] = {
686 /* Key codes for the tiny Pinnacle remote*/ 688 /* Key codes for the tiny Pinnacle remote*/
687 { 0x07, 0x00, KEY_MUTE }, 689 { 0x0700, KEY_MUTE },
688 { 0x07, 0x01, KEY_MENU }, // Pinnacle logo 690 { 0x0701, KEY_MENU }, /* Pinnacle logo */
689 { 0x07, 0x39, KEY_POWER }, 691 { 0x0739, KEY_POWER },
690 { 0x07, 0x03, KEY_VOLUMEUP }, 692 { 0x0703, KEY_VOLUMEUP },
691 { 0x07, 0x09, KEY_VOLUMEDOWN }, 693 { 0x0709, KEY_VOLUMEDOWN },
692 { 0x07, 0x06, KEY_CHANNELUP }, 694 { 0x0706, KEY_CHANNELUP },
693 { 0x07, 0x0c, KEY_CHANNELDOWN }, 695 { 0x070c, KEY_CHANNELDOWN },
694 { 0x07, 0x0f, KEY_1 }, 696 { 0x070f, KEY_1 },
695 { 0x07, 0x15, KEY_2 }, 697 { 0x0715, KEY_2 },
696 { 0x07, 0x10, KEY_3 }, 698 { 0x0710, KEY_3 },
697 { 0x07, 0x18, KEY_4 }, 699 { 0x0718, KEY_4 },
698 { 0x07, 0x1b, KEY_5 }, 700 { 0x071b, KEY_5 },
699 { 0x07, 0x1e, KEY_6 }, 701 { 0x071e, KEY_6 },
700 { 0x07, 0x11, KEY_7 }, 702 { 0x0711, KEY_7 },
701 { 0x07, 0x21, KEY_8 }, 703 { 0x0721, KEY_8 },
702 { 0x07, 0x12, KEY_9 }, 704 { 0x0712, KEY_9 },
703 { 0x07, 0x27, KEY_0 }, 705 { 0x0727, KEY_0 },
704 { 0x07, 0x24, KEY_SCREEN }, // 'Square' key 706 { 0x0724, KEY_SCREEN }, /* 'Square' key */
705 { 0x07, 0x2a, KEY_TEXT }, // 'T' key 707 { 0x072a, KEY_TEXT }, /* 'T' key */
706 { 0x07, 0x2d, KEY_REWIND }, 708 { 0x072d, KEY_REWIND },
707 { 0x07, 0x30, KEY_PLAY }, 709 { 0x0730, KEY_PLAY },
708 { 0x07, 0x33, KEY_FASTFORWARD }, 710 { 0x0733, KEY_FASTFORWARD },
709 { 0x07, 0x36, KEY_RECORD }, 711 { 0x0736, KEY_RECORD },
710 { 0x07, 0x3c, KEY_STOP }, 712 { 0x073c, KEY_STOP },
711 { 0x07, 0x3f, KEY_CANCEL }, // '?' key 713 { 0x073f, KEY_CANCEL }, /* '?' key */
712 /* Key codes for the Terratec Cinergy DT XS Diversity, similar to cinergyT2.c */ 714 /* Key codes for the Terratec Cinergy DT XS Diversity, similar to cinergyT2.c */
713 { 0xeb, 0x01, KEY_POWER }, 715 { 0xeb01, KEY_POWER },
714 { 0xeb, 0x02, KEY_1 }, 716 { 0xeb02, KEY_1 },
715 { 0xeb, 0x03, KEY_2 }, 717 { 0xeb03, KEY_2 },
716 { 0xeb, 0x04, KEY_3 }, 718 { 0xeb04, KEY_3 },
717 { 0xeb, 0x05, KEY_4 }, 719 { 0xeb05, KEY_4 },
718 { 0xeb, 0x06, KEY_5 }, 720 { 0xeb06, KEY_5 },
719 { 0xeb, 0x07, KEY_6 }, 721 { 0xeb07, KEY_6 },
720 { 0xeb, 0x08, KEY_7 }, 722 { 0xeb08, KEY_7 },
721 { 0xeb, 0x09, KEY_8 }, 723 { 0xeb09, KEY_8 },
722 { 0xeb, 0x0a, KEY_9 }, 724 { 0xeb0a, KEY_9 },
723 { 0xeb, 0x0b, KEY_VIDEO }, 725 { 0xeb0b, KEY_VIDEO },
724 { 0xeb, 0x0c, KEY_0 }, 726 { 0xeb0c, KEY_0 },
725 { 0xeb, 0x0d, KEY_REFRESH }, 727 { 0xeb0d, KEY_REFRESH },
726 { 0xeb, 0x0f, KEY_EPG }, 728 { 0xeb0f, KEY_EPG },
727 { 0xeb, 0x10, KEY_UP }, 729 { 0xeb10, KEY_UP },
728 { 0xeb, 0x11, KEY_LEFT }, 730 { 0xeb11, KEY_LEFT },
729 { 0xeb, 0x12, KEY_OK }, 731 { 0xeb12, KEY_OK },
730 { 0xeb, 0x13, KEY_RIGHT }, 732 { 0xeb13, KEY_RIGHT },
731 { 0xeb, 0x14, KEY_DOWN }, 733 { 0xeb14, KEY_DOWN },
732 { 0xeb, 0x16, KEY_INFO }, 734 { 0xeb16, KEY_INFO },
733 { 0xeb, 0x17, KEY_RED }, 735 { 0xeb17, KEY_RED },
734 { 0xeb, 0x18, KEY_GREEN }, 736 { 0xeb18, KEY_GREEN },
735 { 0xeb, 0x19, KEY_YELLOW }, 737 { 0xeb19, KEY_YELLOW },
736 { 0xeb, 0x1a, KEY_BLUE }, 738 { 0xeb1a, KEY_BLUE },
737 { 0xeb, 0x1b, KEY_CHANNELUP }, 739 { 0xeb1b, KEY_CHANNELUP },
738 { 0xeb, 0x1c, KEY_VOLUMEUP }, 740 { 0xeb1c, KEY_VOLUMEUP },
739 { 0xeb, 0x1d, KEY_MUTE }, 741 { 0xeb1d, KEY_MUTE },
740 { 0xeb, 0x1e, KEY_VOLUMEDOWN }, 742 { 0xeb1e, KEY_VOLUMEDOWN },
741 { 0xeb, 0x1f, KEY_CHANNELDOWN }, 743 { 0xeb1f, KEY_CHANNELDOWN },
742 { 0xeb, 0x40, KEY_PAUSE }, 744 { 0xeb40, KEY_PAUSE },
743 { 0xeb, 0x41, KEY_HOME }, 745 { 0xeb41, KEY_HOME },
744 { 0xeb, 0x42, KEY_MENU }, /* DVD Menu */ 746 { 0xeb42, KEY_MENU }, /* DVD Menu */
745 { 0xeb, 0x43, KEY_SUBTITLE }, 747 { 0xeb43, KEY_SUBTITLE },
746 { 0xeb, 0x44, KEY_TEXT }, /* Teletext */ 748 { 0xeb44, KEY_TEXT }, /* Teletext */
747 { 0xeb, 0x45, KEY_DELETE }, 749 { 0xeb45, KEY_DELETE },
748 { 0xeb, 0x46, KEY_TV }, 750 { 0xeb46, KEY_TV },
749 { 0xeb, 0x47, KEY_DVD }, 751 { 0xeb47, KEY_DVD },
750 { 0xeb, 0x48, KEY_STOP }, 752 { 0xeb48, KEY_STOP },
751 { 0xeb, 0x49, KEY_VIDEO }, 753 { 0xeb49, KEY_VIDEO },
752 { 0xeb, 0x4a, KEY_AUDIO }, /* Music */ 754 { 0xeb4a, KEY_AUDIO }, /* Music */
753 { 0xeb, 0x4b, KEY_SCREEN }, /* Pic */ 755 { 0xeb4b, KEY_SCREEN }, /* Pic */
754 { 0xeb, 0x4c, KEY_PLAY }, 756 { 0xeb4c, KEY_PLAY },
755 { 0xeb, 0x4d, KEY_BACK }, 757 { 0xeb4d, KEY_BACK },
756 { 0xeb, 0x4e, KEY_REWIND }, 758 { 0xeb4e, KEY_REWIND },
757 { 0xeb, 0x4f, KEY_FASTFORWARD }, 759 { 0xeb4f, KEY_FASTFORWARD },
758 { 0xeb, 0x54, KEY_PREVIOUS }, 760 { 0xeb54, KEY_PREVIOUS },
759 { 0xeb, 0x58, KEY_RECORD }, 761 { 0xeb58, KEY_RECORD },
760 { 0xeb, 0x5c, KEY_NEXT }, 762 { 0xeb5c, KEY_NEXT },
761 763
762 /* Key codes for the Haupauge WinTV Nova-TD, copied from nova-t-usb2.c (Nova-T USB2) */ 764 /* Key codes for the Haupauge WinTV Nova-TD, copied from nova-t-usb2.c (Nova-T USB2) */
763 { 0x1e, 0x00, KEY_0 }, 765 { 0x1e00, KEY_0 },
764 { 0x1e, 0x01, KEY_1 }, 766 { 0x1e01, KEY_1 },
765 { 0x1e, 0x02, KEY_2 }, 767 { 0x1e02, KEY_2 },
766 { 0x1e, 0x03, KEY_3 }, 768 { 0x1e03, KEY_3 },
767 { 0x1e, 0x04, KEY_4 }, 769 { 0x1e04, KEY_4 },
768 { 0x1e, 0x05, KEY_5 }, 770 { 0x1e05, KEY_5 },
769 { 0x1e, 0x06, KEY_6 }, 771 { 0x1e06, KEY_6 },
770 { 0x1e, 0x07, KEY_7 }, 772 { 0x1e07, KEY_7 },
771 { 0x1e, 0x08, KEY_8 }, 773 { 0x1e08, KEY_8 },
772 { 0x1e, 0x09, KEY_9 }, 774 { 0x1e09, KEY_9 },
773 { 0x1e, 0x0a, KEY_KPASTERISK }, 775 { 0x1e0a, KEY_KPASTERISK },
774 { 0x1e, 0x0b, KEY_RED }, 776 { 0x1e0b, KEY_RED },
775 { 0x1e, 0x0c, KEY_RADIO }, 777 { 0x1e0c, KEY_RADIO },
776 { 0x1e, 0x0d, KEY_MENU }, 778 { 0x1e0d, KEY_MENU },
777 { 0x1e, 0x0e, KEY_GRAVE }, /* # */ 779 { 0x1e0e, KEY_GRAVE }, /* # */
778 { 0x1e, 0x0f, KEY_MUTE }, 780 { 0x1e0f, KEY_MUTE },
779 { 0x1e, 0x10, KEY_VOLUMEUP }, 781 { 0x1e10, KEY_VOLUMEUP },
780 { 0x1e, 0x11, KEY_VOLUMEDOWN }, 782 { 0x1e11, KEY_VOLUMEDOWN },
781 { 0x1e, 0x12, KEY_CHANNEL }, 783 { 0x1e12, KEY_CHANNEL },
782 { 0x1e, 0x14, KEY_UP }, 784 { 0x1e14, KEY_UP },
783 { 0x1e, 0x15, KEY_DOWN }, 785 { 0x1e15, KEY_DOWN },
784 { 0x1e, 0x16, KEY_LEFT }, 786 { 0x1e16, KEY_LEFT },
785 { 0x1e, 0x17, KEY_RIGHT }, 787 { 0x1e17, KEY_RIGHT },
786 { 0x1e, 0x18, KEY_VIDEO }, 788 { 0x1e18, KEY_VIDEO },
787 { 0x1e, 0x19, KEY_AUDIO }, 789 { 0x1e19, KEY_AUDIO },
788 { 0x1e, 0x1a, KEY_MEDIA }, 790 { 0x1e1a, KEY_MEDIA },
789 { 0x1e, 0x1b, KEY_EPG }, 791 { 0x1e1b, KEY_EPG },
790 { 0x1e, 0x1c, KEY_TV }, 792 { 0x1e1c, KEY_TV },
791 { 0x1e, 0x1e, KEY_NEXT }, 793 { 0x1e1e, KEY_NEXT },
792 { 0x1e, 0x1f, KEY_BACK }, 794 { 0x1e1f, KEY_BACK },
793 { 0x1e, 0x20, KEY_CHANNELUP }, 795 { 0x1e20, KEY_CHANNELUP },
794 { 0x1e, 0x21, KEY_CHANNELDOWN }, 796 { 0x1e21, KEY_CHANNELDOWN },
795 { 0x1e, 0x24, KEY_LAST }, /* Skip backwards */ 797 { 0x1e24, KEY_LAST }, /* Skip backwards */
796 { 0x1e, 0x25, KEY_OK }, 798 { 0x1e25, KEY_OK },
797 { 0x1e, 0x29, KEY_BLUE}, 799 { 0x1e29, KEY_BLUE},
798 { 0x1e, 0x2e, KEY_GREEN }, 800 { 0x1e2e, KEY_GREEN },
799 { 0x1e, 0x30, KEY_PAUSE }, 801 { 0x1e30, KEY_PAUSE },
800 { 0x1e, 0x32, KEY_REWIND }, 802 { 0x1e32, KEY_REWIND },
801 { 0x1e, 0x34, KEY_FASTFORWARD }, 803 { 0x1e34, KEY_FASTFORWARD },
802 { 0x1e, 0x35, KEY_PLAY }, 804 { 0x1e35, KEY_PLAY },
803 { 0x1e, 0x36, KEY_STOP }, 805 { 0x1e36, KEY_STOP },
804 { 0x1e, 0x37, KEY_RECORD }, 806 { 0x1e37, KEY_RECORD },
805 { 0x1e, 0x38, KEY_YELLOW }, 807 { 0x1e38, KEY_YELLOW },
806 { 0x1e, 0x3b, KEY_GOTO }, 808 { 0x1e3b, KEY_GOTO },
807 { 0x1e, 0x3d, KEY_POWER }, 809 { 0x1e3d, KEY_POWER },
808 810
809 /* Key codes for the Leadtek Winfast DTV Dongle */ 811 /* Key codes for the Leadtek Winfast DTV Dongle */
810 { 0x00, 0x42, KEY_POWER }, 812 { 0x0042, KEY_POWER },
811 { 0x07, 0x7c, KEY_TUNER }, 813 { 0x077c, KEY_TUNER },
812 { 0x0f, 0x4e, KEY_PRINT }, /* PREVIEW */ 814 { 0x0f4e, KEY_PRINT }, /* PREVIEW */
813 { 0x08, 0x40, KEY_SCREEN }, /* full screen toggle*/ 815 { 0x0840, KEY_SCREEN }, /* full screen toggle*/
814 { 0x0f, 0x71, KEY_DOT }, /* frequency */ 816 { 0x0f71, KEY_DOT }, /* frequency */
815 { 0x07, 0x43, KEY_0 }, 817 { 0x0743, KEY_0 },
816 { 0x0c, 0x41, KEY_1 }, 818 { 0x0c41, KEY_1 },
817 { 0x04, 0x43, KEY_2 }, 819 { 0x0443, KEY_2 },
818 { 0x0b, 0x7f, KEY_3 }, 820 { 0x0b7f, KEY_3 },
819 { 0x0e, 0x41, KEY_4 }, 821 { 0x0e41, KEY_4 },
820 { 0x06, 0x43, KEY_5 }, 822 { 0x0643, KEY_5 },
821 { 0x09, 0x7f, KEY_6 }, 823 { 0x097f, KEY_6 },
822 { 0x0d, 0x7e, KEY_7 }, 824 { 0x0d7e, KEY_7 },
823 { 0x05, 0x7c, KEY_8 }, 825 { 0x057c, KEY_8 },
824 { 0x0a, 0x40, KEY_9 }, 826 { 0x0a40, KEY_9 },
825 { 0x0e, 0x4e, KEY_CLEAR }, 827 { 0x0e4e, KEY_CLEAR },
826 { 0x04, 0x7c, KEY_CHANNEL }, /* show channel number */ 828 { 0x047c, KEY_CHANNEL }, /* show channel number */
827 { 0x0f, 0x41, KEY_LAST }, /* recall */ 829 { 0x0f41, KEY_LAST }, /* recall */
828 { 0x03, 0x42, KEY_MUTE }, 830 { 0x0342, KEY_MUTE },
829 { 0x06, 0x4c, KEY_RESERVED }, /* PIP button*/ 831 { 0x064c, KEY_RESERVED }, /* PIP button*/
830 { 0x01, 0x72, KEY_SHUFFLE }, /* SNAPSHOT */ 832 { 0x0172, KEY_SHUFFLE }, /* SNAPSHOT */
831 { 0x0c, 0x4e, KEY_PLAYPAUSE }, /* TIMESHIFT */ 833 { 0x0c4e, KEY_PLAYPAUSE }, /* TIMESHIFT */
832 { 0x0b, 0x70, KEY_RECORD }, 834 { 0x0b70, KEY_RECORD },
833 { 0x03, 0x7d, KEY_VOLUMEUP }, 835 { 0x037d, KEY_VOLUMEUP },
834 { 0x01, 0x7d, KEY_VOLUMEDOWN }, 836 { 0x017d, KEY_VOLUMEDOWN },
835 { 0x02, 0x42, KEY_CHANNELUP }, 837 { 0x0242, KEY_CHANNELUP },
836 { 0x00, 0x7d, KEY_CHANNELDOWN }, 838 { 0x007d, KEY_CHANNELDOWN },
837 839
838 /* Key codes for Nova-TD "credit card" remote control. */ 840 /* Key codes for Nova-TD "credit card" remote control. */
839 { 0x1d, 0x00, KEY_0 }, 841 { 0x1d00, KEY_0 },
840 { 0x1d, 0x01, KEY_1 }, 842 { 0x1d01, KEY_1 },
841 { 0x1d, 0x02, KEY_2 }, 843 { 0x1d02, KEY_2 },
842 { 0x1d, 0x03, KEY_3 }, 844 { 0x1d03, KEY_3 },
843 { 0x1d, 0x04, KEY_4 }, 845 { 0x1d04, KEY_4 },
844 { 0x1d, 0x05, KEY_5 }, 846 { 0x1d05, KEY_5 },
845 { 0x1d, 0x06, KEY_6 }, 847 { 0x1d06, KEY_6 },
846 { 0x1d, 0x07, KEY_7 }, 848 { 0x1d07, KEY_7 },
847 { 0x1d, 0x08, KEY_8 }, 849 { 0x1d08, KEY_8 },
848 { 0x1d, 0x09, KEY_9 }, 850 { 0x1d09, KEY_9 },
849 { 0x1d, 0x0a, KEY_TEXT }, 851 { 0x1d0a, KEY_TEXT },
850 { 0x1d, 0x0d, KEY_MENU }, 852 { 0x1d0d, KEY_MENU },
851 { 0x1d, 0x0f, KEY_MUTE }, 853 { 0x1d0f, KEY_MUTE },
852 { 0x1d, 0x10, KEY_VOLUMEUP }, 854 { 0x1d10, KEY_VOLUMEUP },
853 { 0x1d, 0x11, KEY_VOLUMEDOWN }, 855 { 0x1d11, KEY_VOLUMEDOWN },
854 { 0x1d, 0x12, KEY_CHANNEL }, 856 { 0x1d12, KEY_CHANNEL },
855 { 0x1d, 0x14, KEY_UP }, 857 { 0x1d14, KEY_UP },
856 { 0x1d, 0x15, KEY_DOWN }, 858 { 0x1d15, KEY_DOWN },
857 { 0x1d, 0x16, KEY_LEFT }, 859 { 0x1d16, KEY_LEFT },
858 { 0x1d, 0x17, KEY_RIGHT }, 860 { 0x1d17, KEY_RIGHT },
859 { 0x1d, 0x1c, KEY_TV }, 861 { 0x1d1c, KEY_TV },
860 { 0x1d, 0x1e, KEY_NEXT }, 862 { 0x1d1e, KEY_NEXT },
861 { 0x1d, 0x1f, KEY_BACK }, 863 { 0x1d1f, KEY_BACK },
862 { 0x1d, 0x20, KEY_CHANNELUP }, 864 { 0x1d20, KEY_CHANNELUP },
863 { 0x1d, 0x21, KEY_CHANNELDOWN }, 865 { 0x1d21, KEY_CHANNELDOWN },
864 { 0x1d, 0x24, KEY_LAST }, 866 { 0x1d24, KEY_LAST },
865 { 0x1d, 0x25, KEY_OK }, 867 { 0x1d25, KEY_OK },
866 { 0x1d, 0x30, KEY_PAUSE }, 868 { 0x1d30, KEY_PAUSE },
867 { 0x1d, 0x32, KEY_REWIND }, 869 { 0x1d32, KEY_REWIND },
868 { 0x1d, 0x34, KEY_FASTFORWARD }, 870 { 0x1d34, KEY_FASTFORWARD },
869 { 0x1d, 0x35, KEY_PLAY }, 871 { 0x1d35, KEY_PLAY },
870 { 0x1d, 0x36, KEY_STOP }, 872 { 0x1d36, KEY_STOP },
871 { 0x1d, 0x37, KEY_RECORD }, 873 { 0x1d37, KEY_RECORD },
872 { 0x1d, 0x3b, KEY_GOTO }, 874 { 0x1d3b, KEY_GOTO },
873 { 0x1d, 0x3d, KEY_POWER }, 875 { 0x1d3d, KEY_POWER },
874}; 876};
875 877
876/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */ 878/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
@@ -1497,6 +1499,8 @@ struct usb_device_id dib0700_usb_id_table[] = {
1497 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_H) }, 1499 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_H) },
1498 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T3) }, 1500 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T3) },
1499 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T5) }, 1501 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T5) },
1502 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D) },
1503 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D_2) },
1500 { 0 } /* Terminating entry */ 1504 { 0 } /* Terminating entry */
1501}; 1505};
1502MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); 1506MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1624,7 +1628,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1624 } 1628 }
1625 }, 1629 },
1626 1630
1627 .num_device_descs = 4, 1631 .num_device_descs = 5,
1628 .devices = { 1632 .devices = {
1629 { "Pinnacle PCTV 2000e", 1633 { "Pinnacle PCTV 2000e",
1630 { &dib0700_usb_id_table[11], NULL }, 1634 { &dib0700_usb_id_table[11], NULL },
@@ -1642,6 +1646,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1642 { &dib0700_usb_id_table[14], NULL }, 1646 { &dib0700_usb_id_table[14], NULL },
1643 { NULL }, 1647 { NULL },
1644 }, 1648 },
1649 { "YUAN High-Tech DiBcom STK7700D",
1650 { &dib0700_usb_id_table[55], NULL },
1651 { NULL },
1652 },
1645 1653
1646 }, 1654 },
1647 1655
@@ -1822,7 +1830,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1822 }, 1830 },
1823 }, 1831 },
1824 1832
1825 .num_device_descs = 8, 1833 .num_device_descs = 9,
1826 .devices = { 1834 .devices = {
1827 { "Terratec Cinergy HT USB XE", 1835 { "Terratec Cinergy HT USB XE",
1828 { &dib0700_usb_id_table[27], NULL }, 1836 { &dib0700_usb_id_table[27], NULL },
@@ -1856,7 +1864,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1856 { &dib0700_usb_id_table[51], NULL }, 1864 { &dib0700_usb_id_table[51], NULL },
1857 { NULL }, 1865 { NULL },
1858 }, 1866 },
1859 1867 { "YUAN High-Tech STK7700D",
1868 { &dib0700_usb_id_table[54], NULL },
1869 { NULL },
1870 },
1860 }, 1871 },
1861 .rc_interval = DEFAULT_RC_INTERVAL, 1872 .rc_interval = DEFAULT_RC_INTERVAL,
1862 .rc_key_map = dib0700_rc_keys, 1873 .rc_key_map = dib0700_rc_keys,
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c
index 8dbad1ec53c4..da34979b5337 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-common.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-common.c
@@ -318,132 +318,132 @@ EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);
318 */ 318 */
319struct dvb_usb_rc_key dibusb_rc_keys[] = { 319struct dvb_usb_rc_key dibusb_rc_keys[] = {
320 /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */ 320 /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
321 { 0x00, 0x16, KEY_POWER }, 321 { 0x0016, KEY_POWER },
322 { 0x00, 0x10, KEY_MUTE }, 322 { 0x0010, KEY_MUTE },
323 { 0x00, 0x03, KEY_1 }, 323 { 0x0003, KEY_1 },
324 { 0x00, 0x01, KEY_2 }, 324 { 0x0001, KEY_2 },
325 { 0x00, 0x06, KEY_3 }, 325 { 0x0006, KEY_3 },
326 { 0x00, 0x09, KEY_4 }, 326 { 0x0009, KEY_4 },
327 { 0x00, 0x1d, KEY_5 }, 327 { 0x001d, KEY_5 },
328 { 0x00, 0x1f, KEY_6 }, 328 { 0x001f, KEY_6 },
329 { 0x00, 0x0d, KEY_7 }, 329 { 0x000d, KEY_7 },
330 { 0x00, 0x19, KEY_8 }, 330 { 0x0019, KEY_8 },
331 { 0x00, 0x1b, KEY_9 }, 331 { 0x001b, KEY_9 },
332 { 0x00, 0x15, KEY_0 }, 332 { 0x0015, KEY_0 },
333 { 0x00, 0x05, KEY_CHANNELUP }, 333 { 0x0005, KEY_CHANNELUP },
334 { 0x00, 0x02, KEY_CHANNELDOWN }, 334 { 0x0002, KEY_CHANNELDOWN },
335 { 0x00, 0x1e, KEY_VOLUMEUP }, 335 { 0x001e, KEY_VOLUMEUP },
336 { 0x00, 0x0a, KEY_VOLUMEDOWN }, 336 { 0x000a, KEY_VOLUMEDOWN },
337 { 0x00, 0x11, KEY_RECORD }, 337 { 0x0011, KEY_RECORD },
338 { 0x00, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */ 338 { 0x0017, KEY_FAVORITES }, /* Heart symbol - Channel list. */
339 { 0x00, 0x14, KEY_PLAY }, 339 { 0x0014, KEY_PLAY },
340 { 0x00, 0x1a, KEY_STOP }, 340 { 0x001a, KEY_STOP },
341 { 0x00, 0x40, KEY_REWIND }, 341 { 0x0040, KEY_REWIND },
342 { 0x00, 0x12, KEY_FASTFORWARD }, 342 { 0x0012, KEY_FASTFORWARD },
343 { 0x00, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */ 343 { 0x000e, KEY_PREVIOUS }, /* Recall - Previous channel. */
344 { 0x00, 0x4c, KEY_PAUSE }, 344 { 0x004c, KEY_PAUSE },
345 { 0x00, 0x4d, KEY_SCREEN }, /* Full screen mode. */ 345 { 0x004d, KEY_SCREEN }, /* Full screen mode. */
346 { 0x00, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */ 346 { 0x0054, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
347 /* additional keys TwinHan VisionPlus, the Artec seemingly not have */ 347 /* additional keys TwinHan VisionPlus, the Artec seemingly not have */
348 { 0x00, 0x0c, KEY_CANCEL }, /* Cancel */ 348 { 0x000c, KEY_CANCEL }, /* Cancel */
349 { 0x00, 0x1c, KEY_EPG }, /* EPG */ 349 { 0x001c, KEY_EPG }, /* EPG */
350 { 0x00, 0x00, KEY_TAB }, /* Tab */ 350 { 0x0000, KEY_TAB }, /* Tab */
351 { 0x00, 0x48, KEY_INFO }, /* Preview */ 351 { 0x0048, KEY_INFO }, /* Preview */
352 { 0x00, 0x04, KEY_LIST }, /* RecordList */ 352 { 0x0004, KEY_LIST }, /* RecordList */
353 { 0x00, 0x0f, KEY_TEXT }, /* Teletext */ 353 { 0x000f, KEY_TEXT }, /* Teletext */
354 /* Key codes for the KWorld/ADSTech/JetWay remote. */ 354 /* Key codes for the KWorld/ADSTech/JetWay remote. */
355 { 0x86, 0x12, KEY_POWER }, 355 { 0x8612, KEY_POWER },
356 { 0x86, 0x0f, KEY_SELECT }, /* source */ 356 { 0x860f, KEY_SELECT }, /* source */
357 { 0x86, 0x0c, KEY_UNKNOWN }, /* scan */ 357 { 0x860c, KEY_UNKNOWN }, /* scan */
358 { 0x86, 0x0b, KEY_EPG }, 358 { 0x860b, KEY_EPG },
359 { 0x86, 0x10, KEY_MUTE }, 359 { 0x8610, KEY_MUTE },
360 { 0x86, 0x01, KEY_1 }, 360 { 0x8601, KEY_1 },
361 { 0x86, 0x02, KEY_2 }, 361 { 0x8602, KEY_2 },
362 { 0x86, 0x03, KEY_3 }, 362 { 0x8603, KEY_3 },
363 { 0x86, 0x04, KEY_4 }, 363 { 0x8604, KEY_4 },
364 { 0x86, 0x05, KEY_5 }, 364 { 0x8605, KEY_5 },
365 { 0x86, 0x06, KEY_6 }, 365 { 0x8606, KEY_6 },
366 { 0x86, 0x07, KEY_7 }, 366 { 0x8607, KEY_7 },
367 { 0x86, 0x08, KEY_8 }, 367 { 0x8608, KEY_8 },
368 { 0x86, 0x09, KEY_9 }, 368 { 0x8609, KEY_9 },
369 { 0x86, 0x0a, KEY_0 }, 369 { 0x860a, KEY_0 },
370 { 0x86, 0x18, KEY_ZOOM }, 370 { 0x8618, KEY_ZOOM },
371 { 0x86, 0x1c, KEY_UNKNOWN }, /* preview */ 371 { 0x861c, KEY_UNKNOWN }, /* preview */
372 { 0x86, 0x13, KEY_UNKNOWN }, /* snap */ 372 { 0x8613, KEY_UNKNOWN }, /* snap */
373 { 0x86, 0x00, KEY_UNDO }, 373 { 0x8600, KEY_UNDO },
374 { 0x86, 0x1d, KEY_RECORD }, 374 { 0x861d, KEY_RECORD },
375 { 0x86, 0x0d, KEY_STOP }, 375 { 0x860d, KEY_STOP },
376 { 0x86, 0x0e, KEY_PAUSE }, 376 { 0x860e, KEY_PAUSE },
377 { 0x86, 0x16, KEY_PLAY }, 377 { 0x8616, KEY_PLAY },
378 { 0x86, 0x11, KEY_BACK }, 378 { 0x8611, KEY_BACK },
379 { 0x86, 0x19, KEY_FORWARD }, 379 { 0x8619, KEY_FORWARD },
380 { 0x86, 0x14, KEY_UNKNOWN }, /* pip */ 380 { 0x8614, KEY_UNKNOWN }, /* pip */
381 { 0x86, 0x15, KEY_ESC }, 381 { 0x8615, KEY_ESC },
382 { 0x86, 0x1a, KEY_UP }, 382 { 0x861a, KEY_UP },
383 { 0x86, 0x1e, KEY_DOWN }, 383 { 0x861e, KEY_DOWN },
384 { 0x86, 0x1f, KEY_LEFT }, 384 { 0x861f, KEY_LEFT },
385 { 0x86, 0x1b, KEY_RIGHT }, 385 { 0x861b, KEY_RIGHT },
386 386
387 /* Key codes for the DiBcom MOD3000 remote. */ 387 /* Key codes for the DiBcom MOD3000 remote. */
388 { 0x80, 0x00, KEY_MUTE }, 388 { 0x8000, KEY_MUTE },
389 { 0x80, 0x01, KEY_TEXT }, 389 { 0x8001, KEY_TEXT },
390 { 0x80, 0x02, KEY_HOME }, 390 { 0x8002, KEY_HOME },
391 { 0x80, 0x03, KEY_POWER }, 391 { 0x8003, KEY_POWER },
392 392
393 { 0x80, 0x04, KEY_RED }, 393 { 0x8004, KEY_RED },
394 { 0x80, 0x05, KEY_GREEN }, 394 { 0x8005, KEY_GREEN },
395 { 0x80, 0x06, KEY_YELLOW }, 395 { 0x8006, KEY_YELLOW },
396 { 0x80, 0x07, KEY_BLUE }, 396 { 0x8007, KEY_BLUE },
397 397
398 { 0x80, 0x08, KEY_DVD }, 398 { 0x8008, KEY_DVD },
399 { 0x80, 0x09, KEY_AUDIO }, 399 { 0x8009, KEY_AUDIO },
400 { 0x80, 0x0a, KEY_MEDIA }, /* Pictures */ 400 { 0x800a, KEY_MEDIA }, /* Pictures */
401 { 0x80, 0x0b, KEY_VIDEO }, 401 { 0x800b, KEY_VIDEO },
402 402
403 { 0x80, 0x0c, KEY_BACK }, 403 { 0x800c, KEY_BACK },
404 { 0x80, 0x0d, KEY_UP }, 404 { 0x800d, KEY_UP },
405 { 0x80, 0x0e, KEY_RADIO }, 405 { 0x800e, KEY_RADIO },
406 { 0x80, 0x0f, KEY_EPG }, 406 { 0x800f, KEY_EPG },
407 407
408 { 0x80, 0x10, KEY_LEFT }, 408 { 0x8010, KEY_LEFT },
409 { 0x80, 0x11, KEY_OK }, 409 { 0x8011, KEY_OK },
410 { 0x80, 0x12, KEY_RIGHT }, 410 { 0x8012, KEY_RIGHT },
411 { 0x80, 0x13, KEY_UNKNOWN }, /* SAP */ 411 { 0x8013, KEY_UNKNOWN }, /* SAP */
412 412
413 { 0x80, 0x14, KEY_TV }, 413 { 0x8014, KEY_TV },
414 { 0x80, 0x15, KEY_DOWN }, 414 { 0x8015, KEY_DOWN },
415 { 0x80, 0x16, KEY_MENU }, /* DVD Menu */ 415 { 0x8016, KEY_MENU }, /* DVD Menu */
416 { 0x80, 0x17, KEY_LAST }, 416 { 0x8017, KEY_LAST },
417 417
418 { 0x80, 0x18, KEY_RECORD }, 418 { 0x8018, KEY_RECORD },
419 { 0x80, 0x19, KEY_STOP }, 419 { 0x8019, KEY_STOP },
420 { 0x80, 0x1a, KEY_PAUSE }, 420 { 0x801a, KEY_PAUSE },
421 { 0x80, 0x1b, KEY_PLAY }, 421 { 0x801b, KEY_PLAY },
422 422
423 { 0x80, 0x1c, KEY_PREVIOUS }, 423 { 0x801c, KEY_PREVIOUS },
424 { 0x80, 0x1d, KEY_REWIND }, 424 { 0x801d, KEY_REWIND },
425 { 0x80, 0x1e, KEY_FASTFORWARD }, 425 { 0x801e, KEY_FASTFORWARD },
426 { 0x80, 0x1f, KEY_NEXT}, 426 { 0x801f, KEY_NEXT},
427 427
428 { 0x80, 0x40, KEY_1 }, 428 { 0x8040, KEY_1 },
429 { 0x80, 0x41, KEY_2 }, 429 { 0x8041, KEY_2 },
430 { 0x80, 0x42, KEY_3 }, 430 { 0x8042, KEY_3 },
431 { 0x80, 0x43, KEY_CHANNELUP }, 431 { 0x8043, KEY_CHANNELUP },
432 432
433 { 0x80, 0x44, KEY_4 }, 433 { 0x8044, KEY_4 },
434 { 0x80, 0x45, KEY_5 }, 434 { 0x8045, KEY_5 },
435 { 0x80, 0x46, KEY_6 }, 435 { 0x8046, KEY_6 },
436 { 0x80, 0x47, KEY_CHANNELDOWN }, 436 { 0x8047, KEY_CHANNELDOWN },
437 437
438 { 0x80, 0x48, KEY_7 }, 438 { 0x8048, KEY_7 },
439 { 0x80, 0x49, KEY_8 }, 439 { 0x8049, KEY_8 },
440 { 0x80, 0x4a, KEY_9 }, 440 { 0x804a, KEY_9 },
441 { 0x80, 0x4b, KEY_VOLUMEUP }, 441 { 0x804b, KEY_VOLUMEUP },
442 442
443 { 0x80, 0x4c, KEY_CLEAR }, 443 { 0x804c, KEY_CLEAR },
444 { 0x80, 0x4d, KEY_0 }, 444 { 0x804d, KEY_0 },
445 { 0x80, 0x4e, KEY_ENTER }, 445 { 0x804e, KEY_ENTER },
446 { 0x80, 0x4f, KEY_VOLUMEDOWN }, 446 { 0x804f, KEY_VOLUMEDOWN },
447}; 447};
448EXPORT_SYMBOL(dibusb_rc_keys); 448EXPORT_SYMBOL(dibusb_rc_keys);
449 449
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c
index 059cec955318..a05b9f875663 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mc.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c
@@ -42,6 +42,8 @@ static struct usb_device_id dibusb_dib3000mc_table [] = {
42/* 11 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14_WARM) }, 42/* 11 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14_WARM) },
43/* 12 */ { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_COLD) }, 43/* 12 */ { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_COLD) },
44/* 13 */ { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_WARM) }, 44/* 13 */ { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_WARM) },
45/* 14 */ { USB_DEVICE(USB_VID_HUMAX_COEX, USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD) },
46/* 15 */ { USB_DEVICE(USB_VID_HUMAX_COEX, USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM) },
45 { } /* Terminating entry */ 47 { } /* Terminating entry */
46}; 48};
47MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table); 49MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table);
@@ -66,7 +68,7 @@ static struct dvb_usb_device_properties dibusb_mc_properties = {
66 /* parameter for the MPEG2-data transfer */ 68 /* parameter for the MPEG2-data transfer */
67 .stream = { 69 .stream = {
68 .type = USB_BULK, 70 .type = USB_BULK,
69 .count = 7, 71 .count = 8,
70 .endpoint = 0x06, 72 .endpoint = 0x06,
71 .u = { 73 .u = {
72 .bulk = { 74 .bulk = {
@@ -88,7 +90,7 @@ static struct dvb_usb_device_properties dibusb_mc_properties = {
88 90
89 .generic_bulk_ctrl_endpoint = 0x01, 91 .generic_bulk_ctrl_endpoint = 0x01,
90 92
91 .num_device_descs = 7, 93 .num_device_descs = 8,
92 .devices = { 94 .devices = {
93 { "DiBcom USB2.0 DVB-T reference design (MOD3000P)", 95 { "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
94 { &dibusb_dib3000mc_table[0], NULL }, 96 { &dibusb_dib3000mc_table[0], NULL },
@@ -119,6 +121,10 @@ static struct dvb_usb_device_properties dibusb_mc_properties = {
119 { &dibusb_dib3000mc_table[12], NULL }, 121 { &dibusb_dib3000mc_table[12], NULL },
120 { &dibusb_dib3000mc_table[13], NULL }, 122 { &dibusb_dib3000mc_table[13], NULL },
121 }, 123 },
124 { "Humax/Coex DVB-T USB Stick 2.0 High Speed",
125 { &dibusb_dib3000mc_table[14], NULL },
126 { &dibusb_dib3000mc_table[15], NULL },
127 },
122 { NULL }, 128 { NULL },
123 } 129 }
124}; 130};
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
index b545cf3eab2e..955147d00756 100644
--- a/drivers/media/dvb/dvb-usb/digitv.c
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -162,61 +162,61 @@ static int digitv_tuner_attach(struct dvb_usb_adapter *adap)
162} 162}
163 163
164static struct dvb_usb_rc_key digitv_rc_keys[] = { 164static struct dvb_usb_rc_key digitv_rc_keys[] = {
165 { 0x5f, 0x55, KEY_0 }, 165 { 0x5f55, KEY_0 },
166 { 0x6f, 0x55, KEY_1 }, 166 { 0x6f55, KEY_1 },
167 { 0x9f, 0x55, KEY_2 }, 167 { 0x9f55, KEY_2 },
168 { 0xaf, 0x55, KEY_3 }, 168 { 0xaf55, KEY_3 },
169 { 0x5f, 0x56, KEY_4 }, 169 { 0x5f56, KEY_4 },
170 { 0x6f, 0x56, KEY_5 }, 170 { 0x6f56, KEY_5 },
171 { 0x9f, 0x56, KEY_6 }, 171 { 0x9f56, KEY_6 },
172 { 0xaf, 0x56, KEY_7 }, 172 { 0xaf56, KEY_7 },
173 { 0x5f, 0x59, KEY_8 }, 173 { 0x5f59, KEY_8 },
174 { 0x6f, 0x59, KEY_9 }, 174 { 0x6f59, KEY_9 },
175 { 0x9f, 0x59, KEY_TV }, 175 { 0x9f59, KEY_TV },
176 { 0xaf, 0x59, KEY_AUX }, 176 { 0xaf59, KEY_AUX },
177 { 0x5f, 0x5a, KEY_DVD }, 177 { 0x5f5a, KEY_DVD },
178 { 0x6f, 0x5a, KEY_POWER }, 178 { 0x6f5a, KEY_POWER },
179 { 0x9f, 0x5a, KEY_MHP }, /* labelled 'Picture' */ 179 { 0x9f5a, KEY_MHP }, /* labelled 'Picture' */
180 { 0xaf, 0x5a, KEY_AUDIO }, 180 { 0xaf5a, KEY_AUDIO },
181 { 0x5f, 0x65, KEY_INFO }, 181 { 0x5f65, KEY_INFO },
182 { 0x6f, 0x65, KEY_F13 }, /* 16:9 */ 182 { 0x6f65, KEY_F13 }, /* 16:9 */
183 { 0x9f, 0x65, KEY_F14 }, /* 14:9 */ 183 { 0x9f65, KEY_F14 }, /* 14:9 */
184 { 0xaf, 0x65, KEY_EPG }, 184 { 0xaf65, KEY_EPG },
185 { 0x5f, 0x66, KEY_EXIT }, 185 { 0x5f66, KEY_EXIT },
186 { 0x6f, 0x66, KEY_MENU }, 186 { 0x6f66, KEY_MENU },
187 { 0x9f, 0x66, KEY_UP }, 187 { 0x9f66, KEY_UP },
188 { 0xaf, 0x66, KEY_DOWN }, 188 { 0xaf66, KEY_DOWN },
189 { 0x5f, 0x69, KEY_LEFT }, 189 { 0x5f69, KEY_LEFT },
190 { 0x6f, 0x69, KEY_RIGHT }, 190 { 0x6f69, KEY_RIGHT },
191 { 0x9f, 0x69, KEY_ENTER }, 191 { 0x9f69, KEY_ENTER },
192 { 0xaf, 0x69, KEY_CHANNELUP }, 192 { 0xaf69, KEY_CHANNELUP },
193 { 0x5f, 0x6a, KEY_CHANNELDOWN }, 193 { 0x5f6a, KEY_CHANNELDOWN },
194 { 0x6f, 0x6a, KEY_VOLUMEUP }, 194 { 0x6f6a, KEY_VOLUMEUP },
195 { 0x9f, 0x6a, KEY_VOLUMEDOWN }, 195 { 0x9f6a, KEY_VOLUMEDOWN },
196 { 0xaf, 0x6a, KEY_RED }, 196 { 0xaf6a, KEY_RED },
197 { 0x5f, 0x95, KEY_GREEN }, 197 { 0x5f95, KEY_GREEN },
198 { 0x6f, 0x95, KEY_YELLOW }, 198 { 0x6f95, KEY_YELLOW },
199 { 0x9f, 0x95, KEY_BLUE }, 199 { 0x9f95, KEY_BLUE },
200 { 0xaf, 0x95, KEY_SUBTITLE }, 200 { 0xaf95, KEY_SUBTITLE },
201 { 0x5f, 0x96, KEY_F15 }, /* AD */ 201 { 0x5f96, KEY_F15 }, /* AD */
202 { 0x6f, 0x96, KEY_TEXT }, 202 { 0x6f96, KEY_TEXT },
203 { 0x9f, 0x96, KEY_MUTE }, 203 { 0x9f96, KEY_MUTE },
204 { 0xaf, 0x96, KEY_REWIND }, 204 { 0xaf96, KEY_REWIND },
205 { 0x5f, 0x99, KEY_STOP }, 205 { 0x5f99, KEY_STOP },
206 { 0x6f, 0x99, KEY_PLAY }, 206 { 0x6f99, KEY_PLAY },
207 { 0x9f, 0x99, KEY_FASTFORWARD }, 207 { 0x9f99, KEY_FASTFORWARD },
208 { 0xaf, 0x99, KEY_F16 }, /* chapter */ 208 { 0xaf99, KEY_F16 }, /* chapter */
209 { 0x5f, 0x9a, KEY_PAUSE }, 209 { 0x5f9a, KEY_PAUSE },
210 { 0x6f, 0x9a, KEY_PLAY }, 210 { 0x6f9a, KEY_PLAY },
211 { 0x9f, 0x9a, KEY_RECORD }, 211 { 0x9f9a, KEY_RECORD },
212 { 0xaf, 0x9a, KEY_F17 }, /* picture in picture */ 212 { 0xaf9a, KEY_F17 }, /* picture in picture */
213 { 0x5f, 0xa5, KEY_KPPLUS }, /* zoom in */ 213 { 0x5fa5, KEY_KPPLUS }, /* zoom in */
214 { 0x6f, 0xa5, KEY_KPMINUS }, /* zoom out */ 214 { 0x6fa5, KEY_KPMINUS }, /* zoom out */
215 { 0x9f, 0xa5, KEY_F18 }, /* capture */ 215 { 0x9fa5, KEY_F18 }, /* capture */
216 { 0xaf, 0xa5, KEY_F19 }, /* web */ 216 { 0xafa5, KEY_F19 }, /* web */
217 { 0x5f, 0xa6, KEY_EMAIL }, 217 { 0x5fa6, KEY_EMAIL },
218 { 0x6f, 0xa6, KEY_PHONE }, 218 { 0x6fa6, KEY_PHONE },
219 { 0x9f, 0xa6, KEY_PC }, 219 { 0x9fa6, KEY_PC },
220}; 220};
221 221
222static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 222static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
@@ -238,8 +238,8 @@ static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
238 if (key[1] != 0) 238 if (key[1] != 0)
239 { 239 {
240 for (i = 0; i < d->props.rc_key_map_size; i++) { 240 for (i = 0; i < d->props.rc_key_map_size; i++) {
241 if (d->props.rc_key_map[i].custom == key[1] && 241 if (rc5_custom(&d->props.rc_key_map[i]) == key[1] &&
242 d->props.rc_key_map[i].data == key[2]) { 242 rc5_data(&d->props.rc_key_map[i]) == key[2]) {
243 *event = d->props.rc_key_map[i].event; 243 *event = d->props.rc_key_map[i].event;
244 *state = REMOTE_KEY_PRESSED; 244 *state = REMOTE_KEY_PRESSED;
245 return 0; 245 return 0;
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
index 81a6cbf60160..a1b12b01cbe4 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -58,24 +58,24 @@ static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
58/* remote control */ 58/* remote control */
59/* key list for the tiny remote control (Yakumo, don't know about the others) */ 59/* key list for the tiny remote control (Yakumo, don't know about the others) */
60static struct dvb_usb_rc_key dtt200u_rc_keys[] = { 60static struct dvb_usb_rc_key dtt200u_rc_keys[] = {
61 { 0x80, 0x01, KEY_MUTE }, 61 { 0x8001, KEY_MUTE },
62 { 0x80, 0x02, KEY_CHANNELDOWN }, 62 { 0x8002, KEY_CHANNELDOWN },
63 { 0x80, 0x03, KEY_VOLUMEDOWN }, 63 { 0x8003, KEY_VOLUMEDOWN },
64 { 0x80, 0x04, KEY_1 }, 64 { 0x8004, KEY_1 },
65 { 0x80, 0x05, KEY_2 }, 65 { 0x8005, KEY_2 },
66 { 0x80, 0x06, KEY_3 }, 66 { 0x8006, KEY_3 },
67 { 0x80, 0x07, KEY_4 }, 67 { 0x8007, KEY_4 },
68 { 0x80, 0x08, KEY_5 }, 68 { 0x8008, KEY_5 },
69 { 0x80, 0x09, KEY_6 }, 69 { 0x8009, KEY_6 },
70 { 0x80, 0x0a, KEY_7 }, 70 { 0x800a, KEY_7 },
71 { 0x80, 0x0c, KEY_ZOOM }, 71 { 0x800c, KEY_ZOOM },
72 { 0x80, 0x0d, KEY_0 }, 72 { 0x800d, KEY_0 },
73 { 0x80, 0x0e, KEY_SELECT }, 73 { 0x800e, KEY_SELECT },
74 { 0x80, 0x12, KEY_POWER }, 74 { 0x8012, KEY_POWER },
75 { 0x80, 0x1a, KEY_CHANNELUP }, 75 { 0x801a, KEY_CHANNELUP },
76 { 0x80, 0x1b, KEY_8 }, 76 { 0x801b, KEY_8 },
77 { 0x80, 0x1e, KEY_VOLUMEUP }, 77 { 0x801e, KEY_VOLUMEUP },
78 { 0x80, 0x1f, KEY_9 }, 78 { 0x801f, KEY_9 },
79}; 79};
80 80
81static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 81static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
index 326f7608954b..cead089bbb4f 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
@@ -19,7 +19,7 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d)
19 return -EINVAL; 19 return -EINVAL;
20 } 20 }
21 21
22 strncpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name)); 22 strlcpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name));
23 d->i2c_adap.class = I2C_CLASS_TV_DIGITAL, 23 d->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
24 d->i2c_adap.algo = d->props.i2c_algo; 24 d->i2c_adap.algo = d->props.i2c_algo;
25 d->i2c_adap.algo_data = NULL; 25 d->i2c_adap.algo_data = NULL;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 9593b7289994..185a5069b10b 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -58,6 +58,7 @@
58#define USB_VID_GIGABYTE 0x1044 58#define USB_VID_GIGABYTE 0x1044
59#define USB_VID_YUAN 0x1164 59#define USB_VID_YUAN 0x1164
60#define USB_VID_XTENSIONS 0x1ae7 60#define USB_VID_XTENSIONS 0x1ae7
61#define USB_VID_HUMAX_COEX 0x10b9
61 62
62/* Product IDs */ 63/* Product IDs */
63#define USB_PID_ADSTECH_USB2_COLD 0xa333 64#define USB_PID_ADSTECH_USB2_COLD 0xa333
@@ -103,6 +104,7 @@
103#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 104#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
104#define USB_PID_INTEL_CE9500 0x9500 105#define USB_PID_INTEL_CE9500 0x9500
105#define USB_PID_KWORLD_399U 0xe399 106#define USB_PID_KWORLD_399U 0xe399
107#define USB_PID_KWORLD_399U_2 0xe400
106#define USB_PID_KWORLD_395U 0xe396 108#define USB_PID_KWORLD_395U 0xe396
107#define USB_PID_KWORLD_395U_2 0xe39b 109#define USB_PID_KWORLD_395U_2 0xe39b
108#define USB_PID_KWORLD_395U_3 0xe395 110#define USB_PID_KWORLD_395U_3 0xe395
@@ -252,6 +254,8 @@
252#define USB_PID_YUAN_STK7700PH 0x1f08 254#define USB_PID_YUAN_STK7700PH 0x1f08
253#define USB_PID_YUAN_PD378S 0x2edc 255#define USB_PID_YUAN_PD378S 0x2edc
254#define USB_PID_YUAN_MC770 0x0871 256#define USB_PID_YUAN_MC770 0x0871
257#define USB_PID_YUAN_STK7700D 0x1efc
258#define USB_PID_YUAN_STK7700D_2 0x1e8c
255#define USB_PID_DW2102 0x2102 259#define USB_PID_DW2102 0x2102
256#define USB_PID_XTENSIONS_XD_380 0x0381 260#define USB_PID_XTENSIONS_XD_380 0x0381
257#define USB_PID_TELESTAR_STARSTICK_2 0x8000 261#define USB_PID_TELESTAR_STARSTICK_2 0x8000
@@ -259,5 +263,7 @@
259#define USB_PID_SONY_PLAYTV 0x0003 263#define USB_PID_SONY_PLAYTV 0x0003
260#define USB_PID_ELGATO_EYETV_DTT 0x0021 264#define USB_PID_ELGATO_EYETV_DTT 0x0021
261#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020 265#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020
266#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000
267#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM 0x5001
262 268
263#endif 269#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index c0c2c22ddd83..edde87c6aa3a 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -8,6 +8,71 @@
8#include "dvb-usb-common.h" 8#include "dvb-usb-common.h"
9#include <linux/usb/input.h> 9#include <linux/usb/input.h>
10 10
11static int dvb_usb_getkeycode(struct input_dev *dev,
12 int scancode, int *keycode)
13{
14 struct dvb_usb_device *d = input_get_drvdata(dev);
15
16 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
17 int i;
18
19 /* See if we can match the raw key code. */
20 for (i = 0; i < d->props.rc_key_map_size; i++)
21 if (keymap[i].scan == scancode) {
22 *keycode = keymap[i].event;
23 return 0;
24 }
25
26 /*
27 * If is there extra space, returns KEY_RESERVED,
28 * otherwise, input core won't let dvb_usb_setkeycode
29 * to work
30 */
31 for (i = 0; i < d->props.rc_key_map_size; i++)
32 if (keymap[i].event == KEY_RESERVED ||
33 keymap[i].event == KEY_UNKNOWN) {
34 *keycode = KEY_RESERVED;
35 return 0;
36 }
37
38 return -EINVAL;
39}
40
41static int dvb_usb_setkeycode(struct input_dev *dev,
42 int scancode, int keycode)
43{
44 struct dvb_usb_device *d = input_get_drvdata(dev);
45
46 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
47 int i;
48
49 /* Search if it is replacing an existing keycode */
50 for (i = 0; i < d->props.rc_key_map_size; i++)
51 if (keymap[i].scan == scancode) {
52 keymap[i].event = keycode;
53 return 0;
54 }
55
56 /* Search if is there a clean entry. If so, use it */
57 for (i = 0; i < d->props.rc_key_map_size; i++)
58 if (keymap[i].event == KEY_RESERVED ||
59 keymap[i].event == KEY_UNKNOWN) {
60 keymap[i].scan = scancode;
61 keymap[i].event = keycode;
62 return 0;
63 }
64
65 /*
66 * FIXME: Currently, it is not possible to increase the size of
67 * scancode table. For it to happen, one possibility
68 * would be to allocate a table with key_map_size + 1,
69 * copying data, appending the new key on it, and freeing
70 * the old one - or maybe just allocating some spare space
71 */
72
73 return -EINVAL;
74}
75
11/* Remote-control poll function - called every dib->rc_query_interval ms to see 76/* Remote-control poll function - called every dib->rc_query_interval ms to see
12 * whether the remote control has received anything. 77 * whether the remote control has received anything.
13 * 78 *
@@ -111,6 +176,8 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
111 input_dev->phys = d->rc_phys; 176 input_dev->phys = d->rc_phys;
112 usb_to_input_id(d->udev, &input_dev->id); 177 usb_to_input_id(d->udev, &input_dev->id);
113 input_dev->dev.parent = &d->udev->dev; 178 input_dev->dev.parent = &d->udev->dev;
179 input_dev->getkeycode = dvb_usb_getkeycode;
180 input_dev->setkeycode = dvb_usb_setkeycode;
114 181
115 /* set the bits for the keys */ 182 /* set the bits for the keys */
116 deb_rc("key map size: %d\n", d->props.rc_key_map_size); 183 deb_rc("key map size: %d\n", d->props.rc_key_map_size);
@@ -128,6 +195,8 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
128 input_dev->rep[REP_PERIOD] = d->props.rc_interval; 195 input_dev->rep[REP_PERIOD] = d->props.rc_interval;
129 input_dev->rep[REP_DELAY] = d->props.rc_interval + 150; 196 input_dev->rep[REP_DELAY] = d->props.rc_interval + 150;
130 197
198 input_set_drvdata(input_dev, d);
199
131 err = input_register_device(input_dev); 200 err = input_register_device(input_dev);
132 if (err) { 201 if (err) {
133 input_free_device(input_dev); 202 input_free_device(input_dev);
@@ -178,8 +247,8 @@ int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
178 } 247 }
179 /* See if we can match the raw key code. */ 248 /* See if we can match the raw key code. */
180 for (i = 0; i < d->props.rc_key_map_size; i++) 249 for (i = 0; i < d->props.rc_key_map_size; i++)
181 if (keymap[i].custom == keybuf[1] && 250 if (rc5_custom(&keymap[i]) == keybuf[1] &&
182 keymap[i].data == keybuf[3]) { 251 rc5_data(&keymap[i]) == keybuf[3]) {
183 *event = keymap[i].event; 252 *event = keymap[i].event;
184 *state = REMOTE_KEY_PRESSED; 253 *state = REMOTE_KEY_PRESSED;
185 return 0; 254 return 0;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index e441d274e6c1..fe2b87efb3f1 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -81,10 +81,25 @@ struct dvb_usb_device_description {
81 * @event: the input event assigned to key identified by custom and data 81 * @event: the input event assigned to key identified by custom and data
82 */ 82 */
83struct dvb_usb_rc_key { 83struct dvb_usb_rc_key {
84 u8 custom,data; 84 u16 scan;
85 u32 event; 85 u32 event;
86}; 86};
87 87
88static inline u8 rc5_custom(struct dvb_usb_rc_key *key)
89{
90 return (key->scan >> 8) & 0xff;
91}
92
93static inline u8 rc5_data(struct dvb_usb_rc_key *key)
94{
95 return key->scan & 0xff;
96}
97
98static inline u8 rc5_scan(struct dvb_usb_rc_key *key)
99{
100 return key->scan & 0xffff;
101}
102
88struct dvb_usb_device; 103struct dvb_usb_device;
89struct dvb_usb_adapter; 104struct dvb_usb_adapter;
90struct usb_data_stream; 105struct usb_data_stream;
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
index 75de49c0d943..5bb9479d154e 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -1,6 +1,6 @@
1/* DVB USB framework compliant Linux driver for the 1/* DVB USB framework compliant Linux driver for the
2* DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, 2* DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101,
3* TeVii S600, S650 Cards 3* TeVii S600, S630, S650 Cards
4* Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by) 4* Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by)
5* 5*
6* This program is free software; you can redistribute it and/or modify it 6* This program is free software; you can redistribute it and/or modify it
@@ -18,6 +18,8 @@
18#include "eds1547.h" 18#include "eds1547.h"
19#include "cx24116.h" 19#include "cx24116.h"
20#include "tda1002x.h" 20#include "tda1002x.h"
21#include "mt312.h"
22#include "zl10039.h"
21 23
22#ifndef USB_PID_DW2102 24#ifndef USB_PID_DW2102
23#define USB_PID_DW2102 0x2102 25#define USB_PID_DW2102 0x2102
@@ -39,6 +41,10 @@
39#define USB_PID_TEVII_S650 0xd650 41#define USB_PID_TEVII_S650 0xd650
40#endif 42#endif
41 43
44#ifndef USB_PID_TEVII_S630
45#define USB_PID_TEVII_S630 0xd630
46#endif
47
42#define DW210X_READ_MSG 0 48#define DW210X_READ_MSG 0
43#define DW210X_WRITE_MSG 1 49#define DW210X_WRITE_MSG 1
44 50
@@ -436,6 +442,69 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
436 return num; 442 return num;
437} 443}
438 444
445static int s630_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
446 int num)
447{
448 struct dvb_usb_device *d = i2c_get_adapdata(adap);
449 int ret = 0;
450
451 if (!d)
452 return -ENODEV;
453 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
454 return -EAGAIN;
455
456 switch (num) {
457 case 2: { /* read */
458 u8 ibuf[msg[1].len], obuf[3];
459 obuf[0] = msg[1].len;
460 obuf[1] = (msg[0].addr << 1);
461 obuf[2] = msg[0].buf[0];
462
463 ret = dw210x_op_rw(d->udev, 0x90, 0, 0,
464 obuf, 3, DW210X_WRITE_MSG);
465 msleep(5);
466 ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
467 ibuf, msg[1].len, DW210X_READ_MSG);
468 memcpy(msg[1].buf, ibuf, msg[1].len);
469 break;
470 }
471 case 1:
472 switch (msg[0].addr) {
473 case 0x60:
474 case 0x0e: {
475 /* write to zl10313, zl10039 register, */
476 u8 obuf[msg[0].len + 2];
477 obuf[0] = msg[0].len + 1;
478 obuf[1] = (msg[0].addr << 1);
479 memcpy(obuf + 2, msg[0].buf, msg[0].len);
480 ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
481 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
482 break;
483 }
484 case (DW2102_RC_QUERY): {
485 u8 ibuf[4];
486 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
487 ibuf, 4, DW210X_READ_MSG);
488 msg[0].buf[0] = ibuf[3];
489 break;
490 }
491 case (DW2102_VOLTAGE_CTRL): {
492 u8 obuf[2];
493 obuf[0] = 0x03;
494 obuf[1] = msg[0].buf[0];
495 ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
496 obuf, 2, DW210X_WRITE_MSG);
497 break;
498 }
499 }
500
501 break;
502 }
503
504 mutex_unlock(&d->i2c_mutex);
505 return num;
506}
507
439static u32 dw210x_i2c_func(struct i2c_adapter *adapter) 508static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
440{ 509{
441 return I2C_FUNC_I2C; 510 return I2C_FUNC_I2C;
@@ -466,6 +535,11 @@ static struct i2c_algorithm dw3101_i2c_algo = {
466 .functionality = dw210x_i2c_func, 535 .functionality = dw210x_i2c_func,
467}; 536};
468 537
538static struct i2c_algorithm s630_i2c_algo = {
539 .master_xfer = s630_i2c_transfer,
540 .functionality = dw210x_i2c_func,
541};
542
469static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) 543static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
470{ 544{
471 int i; 545 int i;
@@ -490,6 +564,37 @@ static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
490 return 0; 564 return 0;
491}; 565};
492 566
567static int s630_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
568{
569 int i, ret;
570 u8 buf[3], eeprom[256], eepromline[16];
571
572 for (i = 0; i < 256; i++) {
573 buf[0] = 1;
574 buf[1] = 0xa0;
575 buf[2] = i;
576 ret = dw210x_op_rw(d->udev, 0x90, 0, 0,
577 buf, 3, DW210X_WRITE_MSG);
578 ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
579 buf, 1, DW210X_READ_MSG);
580 if (ret < 0) {
581 err("read eeprom failed.");
582 return -1;
583 } else {
584 eepromline[i % 16] = buf[0];
585 eeprom[i] = buf[0];
586 }
587
588 if ((i % 16) == 15) {
589 deb_xfer("%02x: ", i - 15);
590 debug_dump(eepromline, 16, deb_xfer);
591 }
592 }
593
594 memcpy(mac, eeprom + 16, 6);
595 return 0;
596};
597
493static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) 598static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
494{ 599{
495 static u8 command_13v[1] = {0x00}; 600 static u8 command_13v[1] = {0x00};
@@ -535,6 +640,10 @@ static struct tda10023_config dw3101_tda10023_config = {
535 .invert = 1, 640 .invert = 1,
536}; 641};
537 642
643static struct mt312_config zl313_config = {
644 .demod_address = 0x0e,
645};
646
538static int dw2104_frontend_attach(struct dvb_usb_adapter *d) 647static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
539{ 648{
540 if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config, 649 if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config,
@@ -596,6 +705,18 @@ static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
596 return -EIO; 705 return -EIO;
597} 706}
598 707
708static int s630_frontend_attach(struct dvb_usb_adapter *d)
709{
710 d->fe = dvb_attach(mt312_attach, &zl313_config,
711 &d->dev->i2c_adap);
712 if (d->fe != NULL) {
713 d->fe->ops.set_voltage = dw210x_set_voltage;
714 info("Attached zl10313!\n");
715 return 0;
716 }
717 return -EIO;
718}
719
599static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) 720static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
600{ 721{
601 dvb_attach(dvb_pll_attach, adap->fe, 0x60, 722 dvb_attach(dvb_pll_attach, adap->fe, 0x60,
@@ -619,123 +740,131 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
619 return 0; 740 return 0;
620} 741}
621 742
743static int s630_zl10039_tuner_attach(struct dvb_usb_adapter *adap)
744{
745 dvb_attach(zl10039_attach, adap->fe, 0x60,
746 &adap->dev->i2c_adap);
747
748 return 0;
749}
750
622static struct dvb_usb_rc_key dw210x_rc_keys[] = { 751static struct dvb_usb_rc_key dw210x_rc_keys[] = {
623 { 0xf8, 0x0a, KEY_Q }, /*power*/ 752 { 0xf80a, KEY_Q }, /*power*/
624 { 0xf8, 0x0c, KEY_M }, /*mute*/ 753 { 0xf80c, KEY_M }, /*mute*/
625 { 0xf8, 0x11, KEY_1 }, 754 { 0xf811, KEY_1 },
626 { 0xf8, 0x12, KEY_2 }, 755 { 0xf812, KEY_2 },
627 { 0xf8, 0x13, KEY_3 }, 756 { 0xf813, KEY_3 },
628 { 0xf8, 0x14, KEY_4 }, 757 { 0xf814, KEY_4 },
629 { 0xf8, 0x15, KEY_5 }, 758 { 0xf815, KEY_5 },
630 { 0xf8, 0x16, KEY_6 }, 759 { 0xf816, KEY_6 },
631 { 0xf8, 0x17, KEY_7 }, 760 { 0xf817, KEY_7 },
632 { 0xf8, 0x18, KEY_8 }, 761 { 0xf818, KEY_8 },
633 { 0xf8, 0x19, KEY_9 }, 762 { 0xf819, KEY_9 },
634 { 0xf8, 0x10, KEY_0 }, 763 { 0xf810, KEY_0 },
635 { 0xf8, 0x1c, KEY_PAGEUP }, /*ch+*/ 764 { 0xf81c, KEY_PAGEUP }, /*ch+*/
636 { 0xf8, 0x0f, KEY_PAGEDOWN }, /*ch-*/ 765 { 0xf80f, KEY_PAGEDOWN }, /*ch-*/
637 { 0xf8, 0x1a, KEY_O }, /*vol+*/ 766 { 0xf81a, KEY_O }, /*vol+*/
638 { 0xf8, 0x0e, KEY_Z }, /*vol-*/ 767 { 0xf80e, KEY_Z }, /*vol-*/
639 { 0xf8, 0x04, KEY_R }, /*rec*/ 768 { 0xf804, KEY_R }, /*rec*/
640 { 0xf8, 0x09, KEY_D }, /*fav*/ 769 { 0xf809, KEY_D }, /*fav*/
641 { 0xf8, 0x08, KEY_BACKSPACE }, /*rewind*/ 770 { 0xf808, KEY_BACKSPACE }, /*rewind*/
642 { 0xf8, 0x07, KEY_A }, /*fast*/ 771 { 0xf807, KEY_A }, /*fast*/
643 { 0xf8, 0x0b, KEY_P }, /*pause*/ 772 { 0xf80b, KEY_P }, /*pause*/
644 { 0xf8, 0x02, KEY_ESC }, /*cancel*/ 773 { 0xf802, KEY_ESC }, /*cancel*/
645 { 0xf8, 0x03, KEY_G }, /*tab*/ 774 { 0xf803, KEY_G }, /*tab*/
646 { 0xf8, 0x00, KEY_UP }, /*up*/ 775 { 0xf800, KEY_UP }, /*up*/
647 { 0xf8, 0x1f, KEY_ENTER }, /*ok*/ 776 { 0xf81f, KEY_ENTER }, /*ok*/
648 { 0xf8, 0x01, KEY_DOWN }, /*down*/ 777 { 0xf801, KEY_DOWN }, /*down*/
649 { 0xf8, 0x05, KEY_C }, /*cap*/ 778 { 0xf805, KEY_C }, /*cap*/
650 { 0xf8, 0x06, KEY_S }, /*stop*/ 779 { 0xf806, KEY_S }, /*stop*/
651 { 0xf8, 0x40, KEY_F }, /*full*/ 780 { 0xf840, KEY_F }, /*full*/
652 { 0xf8, 0x1e, KEY_W }, /*tvmode*/ 781 { 0xf81e, KEY_W }, /*tvmode*/
653 { 0xf8, 0x1b, KEY_B }, /*recall*/ 782 { 0xf81b, KEY_B }, /*recall*/
654}; 783};
655 784
656static struct dvb_usb_rc_key tevii_rc_keys[] = { 785static struct dvb_usb_rc_key tevii_rc_keys[] = {
657 { 0xf8, 0x0a, KEY_POWER }, 786 { 0xf80a, KEY_POWER },
658 { 0xf8, 0x0c, KEY_MUTE }, 787 { 0xf80c, KEY_MUTE },
659 { 0xf8, 0x11, KEY_1 }, 788 { 0xf811, KEY_1 },
660 { 0xf8, 0x12, KEY_2 }, 789 { 0xf812, KEY_2 },
661 { 0xf8, 0x13, KEY_3 }, 790 { 0xf813, KEY_3 },
662 { 0xf8, 0x14, KEY_4 }, 791 { 0xf814, KEY_4 },
663 { 0xf8, 0x15, KEY_5 }, 792 { 0xf815, KEY_5 },
664 { 0xf8, 0x16, KEY_6 }, 793 { 0xf816, KEY_6 },
665 { 0xf8, 0x17, KEY_7 }, 794 { 0xf817, KEY_7 },
666 { 0xf8, 0x18, KEY_8 }, 795 { 0xf818, KEY_8 },
667 { 0xf8, 0x19, KEY_9 }, 796 { 0xf819, KEY_9 },
668 { 0xf8, 0x10, KEY_0 }, 797 { 0xf810, KEY_0 },
669 { 0xf8, 0x1c, KEY_MENU }, 798 { 0xf81c, KEY_MENU },
670 { 0xf8, 0x0f, KEY_VOLUMEDOWN }, 799 { 0xf80f, KEY_VOLUMEDOWN },
671 { 0xf8, 0x1a, KEY_LAST }, 800 { 0xf81a, KEY_LAST },
672 { 0xf8, 0x0e, KEY_OPEN }, 801 { 0xf80e, KEY_OPEN },
673 { 0xf8, 0x04, KEY_RECORD }, 802 { 0xf804, KEY_RECORD },
674 { 0xf8, 0x09, KEY_VOLUMEUP }, 803 { 0xf809, KEY_VOLUMEUP },
675 { 0xf8, 0x08, KEY_CHANNELUP }, 804 { 0xf808, KEY_CHANNELUP },
676 { 0xf8, 0x07, KEY_PVR }, 805 { 0xf807, KEY_PVR },
677 { 0xf8, 0x0b, KEY_TIME }, 806 { 0xf80b, KEY_TIME },
678 { 0xf8, 0x02, KEY_RIGHT }, 807 { 0xf802, KEY_RIGHT },
679 { 0xf8, 0x03, KEY_LEFT }, 808 { 0xf803, KEY_LEFT },
680 { 0xf8, 0x00, KEY_UP }, 809 { 0xf800, KEY_UP },
681 { 0xf8, 0x1f, KEY_OK }, 810 { 0xf81f, KEY_OK },
682 { 0xf8, 0x01, KEY_DOWN }, 811 { 0xf801, KEY_DOWN },
683 { 0xf8, 0x05, KEY_TUNER }, 812 { 0xf805, KEY_TUNER },
684 { 0xf8, 0x06, KEY_CHANNELDOWN }, 813 { 0xf806, KEY_CHANNELDOWN },
685 { 0xf8, 0x40, KEY_PLAYPAUSE }, 814 { 0xf840, KEY_PLAYPAUSE },
686 { 0xf8, 0x1e, KEY_REWIND }, 815 { 0xf81e, KEY_REWIND },
687 { 0xf8, 0x1b, KEY_FAVORITES }, 816 { 0xf81b, KEY_FAVORITES },
688 { 0xf8, 0x1d, KEY_BACK }, 817 { 0xf81d, KEY_BACK },
689 { 0xf8, 0x4d, KEY_FASTFORWARD }, 818 { 0xf84d, KEY_FASTFORWARD },
690 { 0xf8, 0x44, KEY_EPG }, 819 { 0xf844, KEY_EPG },
691 { 0xf8, 0x4c, KEY_INFO }, 820 { 0xf84c, KEY_INFO },
692 { 0xf8, 0x41, KEY_AB }, 821 { 0xf841, KEY_AB },
693 { 0xf8, 0x43, KEY_AUDIO }, 822 { 0xf843, KEY_AUDIO },
694 { 0xf8, 0x45, KEY_SUBTITLE }, 823 { 0xf845, KEY_SUBTITLE },
695 { 0xf8, 0x4a, KEY_LIST }, 824 { 0xf84a, KEY_LIST },
696 { 0xf8, 0x46, KEY_F1 }, 825 { 0xf846, KEY_F1 },
697 { 0xf8, 0x47, KEY_F2 }, 826 { 0xf847, KEY_F2 },
698 { 0xf8, 0x5e, KEY_F3 }, 827 { 0xf85e, KEY_F3 },
699 { 0xf8, 0x5c, KEY_F4 }, 828 { 0xf85c, KEY_F4 },
700 { 0xf8, 0x52, KEY_F5 }, 829 { 0xf852, KEY_F5 },
701 { 0xf8, 0x5a, KEY_F6 }, 830 { 0xf85a, KEY_F6 },
702 { 0xf8, 0x56, KEY_MODE }, 831 { 0xf856, KEY_MODE },
703 { 0xf8, 0x58, KEY_SWITCHVIDEOMODE }, 832 { 0xf858, KEY_SWITCHVIDEOMODE },
704}; 833};
705 834
706static struct dvb_usb_rc_key tbs_rc_keys[] = { 835static struct dvb_usb_rc_key tbs_rc_keys[] = {
707 { 0xf8, 0x84, KEY_POWER }, 836 { 0xf884, KEY_POWER },
708 { 0xf8, 0x94, KEY_MUTE }, 837 { 0xf894, KEY_MUTE },
709 { 0xf8, 0x87, KEY_1 }, 838 { 0xf887, KEY_1 },
710 { 0xf8, 0x86, KEY_2 }, 839 { 0xf886, KEY_2 },
711 { 0xf8, 0x85, KEY_3 }, 840 { 0xf885, KEY_3 },
712 { 0xf8, 0x8b, KEY_4 }, 841 { 0xf88b, KEY_4 },
713 { 0xf8, 0x8a, KEY_5 }, 842 { 0xf88a, KEY_5 },
714 { 0xf8, 0x89, KEY_6 }, 843 { 0xf889, KEY_6 },
715 { 0xf8, 0x8f, KEY_7 }, 844 { 0xf88f, KEY_7 },
716 { 0xf8, 0x8e, KEY_8 }, 845 { 0xf88e, KEY_8 },
717 { 0xf8, 0x8d, KEY_9 }, 846 { 0xf88d, KEY_9 },
718 { 0xf8, 0x92, KEY_0 }, 847 { 0xf892, KEY_0 },
719 { 0xf8, 0x96, KEY_CHANNELUP }, 848 { 0xf896, KEY_CHANNELUP },
720 { 0xf8, 0x91, KEY_CHANNELDOWN }, 849 { 0xf891, KEY_CHANNELDOWN },
721 { 0xf8, 0x93, KEY_VOLUMEUP }, 850 { 0xf893, KEY_VOLUMEUP },
722 { 0xf8, 0x8c, KEY_VOLUMEDOWN }, 851 { 0xf88c, KEY_VOLUMEDOWN },
723 { 0xf8, 0x83, KEY_RECORD }, 852 { 0xf883, KEY_RECORD },
724 { 0xf8, 0x98, KEY_PAUSE }, 853 { 0xf898, KEY_PAUSE },
725 { 0xf8, 0x99, KEY_OK }, 854 { 0xf899, KEY_OK },
726 { 0xf8, 0x9a, KEY_SHUFFLE }, 855 { 0xf89a, KEY_SHUFFLE },
727 { 0xf8, 0x81, KEY_UP }, 856 { 0xf881, KEY_UP },
728 { 0xf8, 0x90, KEY_LEFT }, 857 { 0xf890, KEY_LEFT },
729 { 0xf8, 0x82, KEY_RIGHT }, 858 { 0xf882, KEY_RIGHT },
730 { 0xf8, 0x88, KEY_DOWN }, 859 { 0xf888, KEY_DOWN },
731 { 0xf8, 0x95, KEY_FAVORITES }, 860 { 0xf895, KEY_FAVORITES },
732 { 0xf8, 0x97, KEY_SUBTITLE }, 861 { 0xf897, KEY_SUBTITLE },
733 { 0xf8, 0x9d, KEY_ZOOM }, 862 { 0xf89d, KEY_ZOOM },
734 { 0xf8, 0x9f, KEY_EXIT }, 863 { 0xf89f, KEY_EXIT },
735 { 0xf8, 0x9e, KEY_MENU }, 864 { 0xf89e, KEY_MENU },
736 { 0xf8, 0x9c, KEY_EPG }, 865 { 0xf89c, KEY_EPG },
737 { 0xf8, 0x80, KEY_PREVIOUS }, 866 { 0xf880, KEY_PREVIOUS },
738 { 0xf8, 0x9b, KEY_MODE } 867 { 0xf89b, KEY_MODE }
739}; 868};
740 869
741static struct dvb_usb_rc_keys_table keys_tables[] = { 870static struct dvb_usb_rc_keys_table keys_tables[] = {
@@ -763,9 +892,9 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
763 } 892 }
764 893
765 *state = REMOTE_NO_KEY_PRESSED; 894 *state = REMOTE_NO_KEY_PRESSED;
766 if (dw2102_i2c_transfer(&d->i2c_adap, &msg, 1) == 1) { 895 if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
767 for (i = 0; i < keymap_size ; i++) { 896 for (i = 0; i < keymap_size ; i++) {
768 if (keymap[i].data == msg.buf[0]) { 897 if (rc5_data(&keymap[i]) == msg.buf[0]) {
769 *state = REMOTE_KEY_PRESSED; 898 *state = REMOTE_KEY_PRESSED;
770 *event = keymap[i].event; 899 *event = keymap[i].event;
771 break; 900 break;
@@ -792,6 +921,7 @@ static struct usb_device_id dw2102_table[] = {
792 {USB_DEVICE(0x9022, USB_PID_TEVII_S650)}, 921 {USB_DEVICE(0x9022, USB_PID_TEVII_S650)},
793 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)}, 922 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
794 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)}, 923 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)},
924 {USB_DEVICE(0x9022, USB_PID_TEVII_S630)},
795 { } 925 { }
796}; 926};
797 927
@@ -806,6 +936,7 @@ static int dw2102_load_firmware(struct usb_device *dev,
806 u8 reset16[] = {0, 0, 0, 0, 0, 0, 0}; 936 u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
807 const struct firmware *fw; 937 const struct firmware *fw;
808 const char *filename = "dvb-usb-dw2101.fw"; 938 const char *filename = "dvb-usb-dw2101.fw";
939
809 switch (dev->descriptor.idProduct) { 940 switch (dev->descriptor.idProduct) {
810 case 0x2101: 941 case 0x2101:
811 ret = request_firmware(&fw, filename, &dev->dev); 942 ret = request_firmware(&fw, filename, &dev->dev);
@@ -1053,6 +1184,48 @@ static struct dvb_usb_device_properties dw3101_properties = {
1053 } 1184 }
1054}; 1185};
1055 1186
1187static struct dvb_usb_device_properties s630_properties = {
1188 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1189 .usb_ctrl = DEVICE_SPECIFIC,
1190 .firmware = "dvb-usb-s630.fw",
1191 .no_reconnect = 1,
1192
1193 .i2c_algo = &s630_i2c_algo,
1194 .rc_key_map = tevii_rc_keys,
1195 .rc_key_map_size = ARRAY_SIZE(tevii_rc_keys),
1196 .rc_interval = 150,
1197 .rc_query = dw2102_rc_query,
1198
1199 .generic_bulk_ctrl_endpoint = 0x81,
1200 .num_adapters = 1,
1201 .download_firmware = dw2102_load_firmware,
1202 .read_mac_address = s630_read_mac_address,
1203 .adapter = {
1204 {
1205 .frontend_attach = s630_frontend_attach,
1206 .streaming_ctrl = NULL,
1207 .tuner_attach = s630_zl10039_tuner_attach,
1208 .stream = {
1209 .type = USB_BULK,
1210 .count = 8,
1211 .endpoint = 0x82,
1212 .u = {
1213 .bulk = {
1214 .buffersize = 4096,
1215 }
1216 }
1217 },
1218 }
1219 },
1220 .num_device_descs = 1,
1221 .devices = {
1222 {"TeVii S630 USB",
1223 {&dw2102_table[6], NULL},
1224 {NULL},
1225 },
1226 }
1227};
1228
1056static int dw2102_probe(struct usb_interface *intf, 1229static int dw2102_probe(struct usb_interface *intf,
1057 const struct usb_device_id *id) 1230 const struct usb_device_id *id)
1058{ 1231{
@@ -1061,6 +1234,8 @@ static int dw2102_probe(struct usb_interface *intf,
1061 0 == dvb_usb_device_init(intf, &dw2104_properties, 1234 0 == dvb_usb_device_init(intf, &dw2104_properties,
1062 THIS_MODULE, NULL, adapter_nr) || 1235 THIS_MODULE, NULL, adapter_nr) ||
1063 0 == dvb_usb_device_init(intf, &dw3101_properties, 1236 0 == dvb_usb_device_init(intf, &dw3101_properties,
1237 THIS_MODULE, NULL, adapter_nr) ||
1238 0 == dvb_usb_device_init(intf, &s630_properties,
1064 THIS_MODULE, NULL, adapter_nr)) { 1239 THIS_MODULE, NULL, adapter_nr)) {
1065 return 0; 1240 return 0;
1066 } 1241 }
@@ -1094,6 +1269,6 @@ module_exit(dw2102_module_exit);
1094MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); 1269MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
1095MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," 1270MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
1096 " DVB-C 3101 USB2.0," 1271 " DVB-C 3101 USB2.0,"
1097 " TeVii S600, S650 USB2.0 devices"); 1272 " TeVii S600, S630, S650 USB2.0 devices");
1098MODULE_VERSION("0.1"); 1273MODULE_VERSION("0.1");
1099MODULE_LICENSE("GPL"); 1274MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c
index 54626a0dbf68..aec7a1943b66 100644
--- a/drivers/media/dvb/dvb-usb/m920x.c
+++ b/drivers/media/dvb/dvb-usb/m920x.c
@@ -140,7 +140,7 @@ static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
140 goto unlock; 140 goto unlock;
141 141
142 for (i = 0; i < d->props.rc_key_map_size; i++) 142 for (i = 0; i < d->props.rc_key_map_size; i++)
143 if (d->props.rc_key_map[i].data == rc_state[1]) { 143 if (rc5_data(&d->props.rc_key_map[i]) == rc_state[1]) {
144 *event = d->props.rc_key_map[i].event; 144 *event = d->props.rc_key_map[i].event;
145 145
146 switch(rc_state[0]) { 146 switch(rc_state[0]) {
@@ -562,42 +562,42 @@ static struct m920x_inits tvwalkertwin_rc_init [] = {
562 562
563/* ir keymaps */ 563/* ir keymaps */
564static struct dvb_usb_rc_key megasky_rc_keys [] = { 564static struct dvb_usb_rc_key megasky_rc_keys [] = {
565 { 0x0, 0x12, KEY_POWER }, 565 { 0x0012, KEY_POWER },
566 { 0x0, 0x1e, KEY_CYCLEWINDOWS }, /* min/max */ 566 { 0x001e, KEY_CYCLEWINDOWS }, /* min/max */
567 { 0x0, 0x02, KEY_CHANNELUP }, 567 { 0x0002, KEY_CHANNELUP },
568 { 0x0, 0x05, KEY_CHANNELDOWN }, 568 { 0x0005, KEY_CHANNELDOWN },
569 { 0x0, 0x03, KEY_VOLUMEUP }, 569 { 0x0003, KEY_VOLUMEUP },
570 { 0x0, 0x06, KEY_VOLUMEDOWN }, 570 { 0x0006, KEY_VOLUMEDOWN },
571 { 0x0, 0x04, KEY_MUTE }, 571 { 0x0004, KEY_MUTE },
572 { 0x0, 0x07, KEY_OK }, /* TS */ 572 { 0x0007, KEY_OK }, /* TS */
573 { 0x0, 0x08, KEY_STOP }, 573 { 0x0008, KEY_STOP },
574 { 0x0, 0x09, KEY_MENU }, /* swap */ 574 { 0x0009, KEY_MENU }, /* swap */
575 { 0x0, 0x0a, KEY_REWIND }, 575 { 0x000a, KEY_REWIND },
576 { 0x0, 0x1b, KEY_PAUSE }, 576 { 0x001b, KEY_PAUSE },
577 { 0x0, 0x1f, KEY_FASTFORWARD }, 577 { 0x001f, KEY_FASTFORWARD },
578 { 0x0, 0x0c, KEY_RECORD }, 578 { 0x000c, KEY_RECORD },
579 { 0x0, 0x0d, KEY_CAMERA }, /* screenshot */ 579 { 0x000d, KEY_CAMERA }, /* screenshot */
580 { 0x0, 0x0e, KEY_COFFEE }, /* "MTS" */ 580 { 0x000e, KEY_COFFEE }, /* "MTS" */
581}; 581};
582 582
583static struct dvb_usb_rc_key tvwalkertwin_rc_keys [] = { 583static struct dvb_usb_rc_key tvwalkertwin_rc_keys [] = {
584 { 0x0, 0x01, KEY_ZOOM }, /* Full Screen */ 584 { 0x0001, KEY_ZOOM }, /* Full Screen */
585 { 0x0, 0x02, KEY_CAMERA }, /* snapshot */ 585 { 0x0002, KEY_CAMERA }, /* snapshot */
586 { 0x0, 0x03, KEY_MUTE }, 586 { 0x0003, KEY_MUTE },
587 { 0x0, 0x04, KEY_REWIND }, 587 { 0x0004, KEY_REWIND },
588 { 0x0, 0x05, KEY_PLAYPAUSE }, /* Play/Pause */ 588 { 0x0005, KEY_PLAYPAUSE }, /* Play/Pause */
589 { 0x0, 0x06, KEY_FASTFORWARD }, 589 { 0x0006, KEY_FASTFORWARD },
590 { 0x0, 0x07, KEY_RECORD }, 590 { 0x0007, KEY_RECORD },
591 { 0x0, 0x08, KEY_STOP }, 591 { 0x0008, KEY_STOP },
592 { 0x0, 0x09, KEY_TIME }, /* Timeshift */ 592 { 0x0009, KEY_TIME }, /* Timeshift */
593 { 0x0, 0x0c, KEY_COFFEE }, /* Recall */ 593 { 0x000c, KEY_COFFEE }, /* Recall */
594 { 0x0, 0x0e, KEY_CHANNELUP }, 594 { 0x000e, KEY_CHANNELUP },
595 { 0x0, 0x12, KEY_POWER }, 595 { 0x0012, KEY_POWER },
596 { 0x0, 0x15, KEY_MENU }, /* source */ 596 { 0x0015, KEY_MENU }, /* source */
597 { 0x0, 0x18, KEY_CYCLEWINDOWS }, /* TWIN PIP */ 597 { 0x0018, KEY_CYCLEWINDOWS }, /* TWIN PIP */
598 { 0x0, 0x1a, KEY_CHANNELDOWN }, 598 { 0x001a, KEY_CHANNELDOWN },
599 { 0x0, 0x1b, KEY_VOLUMEDOWN }, 599 { 0x001b, KEY_VOLUMEDOWN },
600 { 0x0, 0x1e, KEY_VOLUMEUP }, 600 { 0x001e, KEY_VOLUMEUP },
601}; 601};
602 602
603/* DVB USB Driver stuff */ 603/* DVB USB Driver stuff */
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
index 07fb843c7c2b..b41d66ef8325 100644
--- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -22,51 +22,51 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
22 22
23/* Hauppauge NOVA-T USB2 keys */ 23/* Hauppauge NOVA-T USB2 keys */
24static struct dvb_usb_rc_key haupp_rc_keys [] = { 24static struct dvb_usb_rc_key haupp_rc_keys [] = {
25 { 0x1e, 0x00, KEY_0 }, 25 { 0x1e00, KEY_0 },
26 { 0x1e, 0x01, KEY_1 }, 26 { 0x1e01, KEY_1 },
27 { 0x1e, 0x02, KEY_2 }, 27 { 0x1e02, KEY_2 },
28 { 0x1e, 0x03, KEY_3 }, 28 { 0x1e03, KEY_3 },
29 { 0x1e, 0x04, KEY_4 }, 29 { 0x1e04, KEY_4 },
30 { 0x1e, 0x05, KEY_5 }, 30 { 0x1e05, KEY_5 },
31 { 0x1e, 0x06, KEY_6 }, 31 { 0x1e06, KEY_6 },
32 { 0x1e, 0x07, KEY_7 }, 32 { 0x1e07, KEY_7 },
33 { 0x1e, 0x08, KEY_8 }, 33 { 0x1e08, KEY_8 },
34 { 0x1e, 0x09, KEY_9 }, 34 { 0x1e09, KEY_9 },
35 { 0x1e, 0x0a, KEY_KPASTERISK }, 35 { 0x1e0a, KEY_KPASTERISK },
36 { 0x1e, 0x0b, KEY_RED }, 36 { 0x1e0b, KEY_RED },
37 { 0x1e, 0x0c, KEY_RADIO }, 37 { 0x1e0c, KEY_RADIO },
38 { 0x1e, 0x0d, KEY_MENU }, 38 { 0x1e0d, KEY_MENU },
39 { 0x1e, 0x0e, KEY_GRAVE }, /* # */ 39 { 0x1e0e, KEY_GRAVE }, /* # */
40 { 0x1e, 0x0f, KEY_MUTE }, 40 { 0x1e0f, KEY_MUTE },
41 { 0x1e, 0x10, KEY_VOLUMEUP }, 41 { 0x1e10, KEY_VOLUMEUP },
42 { 0x1e, 0x11, KEY_VOLUMEDOWN }, 42 { 0x1e11, KEY_VOLUMEDOWN },
43 { 0x1e, 0x12, KEY_CHANNEL }, 43 { 0x1e12, KEY_CHANNEL },
44 { 0x1e, 0x14, KEY_UP }, 44 { 0x1e14, KEY_UP },
45 { 0x1e, 0x15, KEY_DOWN }, 45 { 0x1e15, KEY_DOWN },
46 { 0x1e, 0x16, KEY_LEFT }, 46 { 0x1e16, KEY_LEFT },
47 { 0x1e, 0x17, KEY_RIGHT }, 47 { 0x1e17, KEY_RIGHT },
48 { 0x1e, 0x18, KEY_VIDEO }, 48 { 0x1e18, KEY_VIDEO },
49 { 0x1e, 0x19, KEY_AUDIO }, 49 { 0x1e19, KEY_AUDIO },
50 { 0x1e, 0x1a, KEY_MEDIA }, 50 { 0x1e1a, KEY_MEDIA },
51 { 0x1e, 0x1b, KEY_EPG }, 51 { 0x1e1b, KEY_EPG },
52 { 0x1e, 0x1c, KEY_TV }, 52 { 0x1e1c, KEY_TV },
53 { 0x1e, 0x1e, KEY_NEXT }, 53 { 0x1e1e, KEY_NEXT },
54 { 0x1e, 0x1f, KEY_BACK }, 54 { 0x1e1f, KEY_BACK },
55 { 0x1e, 0x20, KEY_CHANNELUP }, 55 { 0x1e20, KEY_CHANNELUP },
56 { 0x1e, 0x21, KEY_CHANNELDOWN }, 56 { 0x1e21, KEY_CHANNELDOWN },
57 { 0x1e, 0x24, KEY_LAST }, /* Skip backwards */ 57 { 0x1e24, KEY_LAST }, /* Skip backwards */
58 { 0x1e, 0x25, KEY_OK }, 58 { 0x1e25, KEY_OK },
59 { 0x1e, 0x29, KEY_BLUE}, 59 { 0x1e29, KEY_BLUE},
60 { 0x1e, 0x2e, KEY_GREEN }, 60 { 0x1e2e, KEY_GREEN },
61 { 0x1e, 0x30, KEY_PAUSE }, 61 { 0x1e30, KEY_PAUSE },
62 { 0x1e, 0x32, KEY_REWIND }, 62 { 0x1e32, KEY_REWIND },
63 { 0x1e, 0x34, KEY_FASTFORWARD }, 63 { 0x1e34, KEY_FASTFORWARD },
64 { 0x1e, 0x35, KEY_PLAY }, 64 { 0x1e35, KEY_PLAY },
65 { 0x1e, 0x36, KEY_STOP }, 65 { 0x1e36, KEY_STOP },
66 { 0x1e, 0x37, KEY_RECORD }, 66 { 0x1e37, KEY_RECORD },
67 { 0x1e, 0x38, KEY_YELLOW }, 67 { 0x1e38, KEY_YELLOW },
68 { 0x1e, 0x3b, KEY_GOTO }, 68 { 0x1e3b, KEY_GOTO },
69 { 0x1e, 0x3d, KEY_POWER }, 69 { 0x1e3d, KEY_POWER },
70}; 70};
71 71
72/* Firmware bug? sometimes, when a new key is pressed, the previous pressed key 72/* Firmware bug? sometimes, when a new key is pressed, the previous pressed key
@@ -92,10 +92,11 @@ static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
92 deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to c: %02x d: %02x toggle: %d\n",key[1],key[2],key[3],custom,data,toggle); 92 deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to c: %02x d: %02x toggle: %d\n",key[1],key[2],key[3],custom,data,toggle);
93 93
94 for (i = 0; i < ARRAY_SIZE(haupp_rc_keys); i++) { 94 for (i = 0; i < ARRAY_SIZE(haupp_rc_keys); i++) {
95 if (haupp_rc_keys[i].data == data && 95 if (rc5_data(&haupp_rc_keys[i]) == data &&
96 haupp_rc_keys[i].custom == custom) { 96 rc5_custom(&haupp_rc_keys[i]) == custom) {
97 97
98 deb_rc("c: %x, d: %x\n",haupp_rc_keys[i].data,haupp_rc_keys[i].custom); 98 deb_rc("c: %x, d: %x\n", rc5_data(&haupp_rc_keys[i]),
99 rc5_custom(&haupp_rc_keys[i]));
99 100
100 *event = haupp_rc_keys[i].event; 101 *event = haupp_rc_keys[i].event;
101 *state = REMOTE_KEY_PRESSED; 102 *state = REMOTE_KEY_PRESSED;
diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c
index 7e32d11f32b0..d4e230941679 100644
--- a/drivers/media/dvb/dvb-usb/opera1.c
+++ b/drivers/media/dvb/dvb-usb/opera1.c
@@ -332,32 +332,32 @@ static int opera1_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
332} 332}
333 333
334static struct dvb_usb_rc_key opera1_rc_keys[] = { 334static struct dvb_usb_rc_key opera1_rc_keys[] = {
335 {0x5f, 0xa0, KEY_1}, 335 {0x5fa0, KEY_1},
336 {0x51, 0xaf, KEY_2}, 336 {0x51af, KEY_2},
337 {0x5d, 0xa2, KEY_3}, 337 {0x5da2, KEY_3},
338 {0x41, 0xbe, KEY_4}, 338 {0x41be, KEY_4},
339 {0x0b, 0xf5, KEY_5}, 339 {0x0bf5, KEY_5},
340 {0x43, 0xbd, KEY_6}, 340 {0x43bd, KEY_6},
341 {0x47, 0xb8, KEY_7}, 341 {0x47b8, KEY_7},
342 {0x49, 0xb6, KEY_8}, 342 {0x49b6, KEY_8},
343 {0x05, 0xfa, KEY_9}, 343 {0x05fa, KEY_9},
344 {0x45, 0xba, KEY_0}, 344 {0x45ba, KEY_0},
345 {0x09, 0xf6, KEY_UP}, /*chanup */ 345 {0x09f6, KEY_UP}, /*chanup */
346 {0x1b, 0xe5, KEY_DOWN}, /*chandown */ 346 {0x1be5, KEY_DOWN}, /*chandown */
347 {0x5d, 0xa3, KEY_LEFT}, /*voldown */ 347 {0x5da3, KEY_LEFT}, /*voldown */
348 {0x5f, 0xa1, KEY_RIGHT}, /*volup */ 348 {0x5fa1, KEY_RIGHT}, /*volup */
349 {0x07, 0xf8, KEY_SPACE}, /*tab */ 349 {0x07f8, KEY_SPACE}, /*tab */
350 {0x1f, 0xe1, KEY_ENTER}, /*play ok */ 350 {0x1fe1, KEY_ENTER}, /*play ok */
351 {0x1b, 0xe4, KEY_Z}, /*zoom */ 351 {0x1be4, KEY_Z}, /*zoom */
352 {0x59, 0xa6, KEY_M}, /*mute */ 352 {0x59a6, KEY_M}, /*mute */
353 {0x5b, 0xa5, KEY_F}, /*tv/f */ 353 {0x5ba5, KEY_F}, /*tv/f */
354 {0x19, 0xe7, KEY_R}, /*rec */ 354 {0x19e7, KEY_R}, /*rec */
355 {0x01, 0xfe, KEY_S}, /*Stop */ 355 {0x01fe, KEY_S}, /*Stop */
356 {0x03, 0xfd, KEY_P}, /*pause */ 356 {0x03fd, KEY_P}, /*pause */
357 {0x03, 0xfc, KEY_W}, /*<- -> */ 357 {0x03fc, KEY_W}, /*<- -> */
358 {0x07, 0xf9, KEY_C}, /*capture */ 358 {0x07f9, KEY_C}, /*capture */
359 {0x47, 0xb9, KEY_Q}, /*exit */ 359 {0x47b9, KEY_Q}, /*exit */
360 {0x43, 0xbc, KEY_O}, /*power */ 360 {0x43bc, KEY_O}, /*power */
361 361
362}; 362};
363 363
@@ -405,8 +405,7 @@ static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)
405 send_key = (send_key & 0xffff) | 0x0100; 405 send_key = (send_key & 0xffff) | 0x0100;
406 406
407 for (i = 0; i < ARRAY_SIZE(opera1_rc_keys); i++) { 407 for (i = 0; i < ARRAY_SIZE(opera1_rc_keys); i++) {
408 if ((opera1_rc_keys[i].custom * 256 + 408 if (rc5_scan(&opera1_rc_keys[i]) == (send_key & 0xffff)) {
409 opera1_rc_keys[i].data) == (send_key & 0xffff)) {
410 *state = REMOTE_KEY_PRESSED; 409 *state = REMOTE_KEY_PRESSED;
411 *event = opera1_rc_keys[i].event; 410 *event = opera1_rc_keys[i].event;
412 opst->last_key_pressed = 411 opst->last_key_pressed =
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c
index 986fff9a5ba8..ef4e37d9c5ff 100644
--- a/drivers/media/dvb/dvb-usb/vp702x.c
+++ b/drivers/media/dvb/dvb-usb/vp702x.c
@@ -175,8 +175,8 @@ static int vp702x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
175 175
176/* keys for the enclosed remote control */ 176/* keys for the enclosed remote control */
177static struct dvb_usb_rc_key vp702x_rc_keys[] = { 177static struct dvb_usb_rc_key vp702x_rc_keys[] = {
178 { 0x00, 0x01, KEY_1 }, 178 { 0x0001, KEY_1 },
179 { 0x00, 0x02, KEY_2 }, 179 { 0x0002, KEY_2 },
180}; 180};
181 181
182/* remote control stuff (does not work with my box) */ 182/* remote control stuff (does not work with my box) */
@@ -198,7 +198,7 @@ static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
198 } 198 }
199 199
200 for (i = 0; i < ARRAY_SIZE(vp702x_rc_keys); i++) 200 for (i = 0; i < ARRAY_SIZE(vp702x_rc_keys); i++)
201 if (vp702x_rc_keys[i].custom == key[1]) { 201 if (rc5_custom(&vp702x_rc_keys[i]) == key[1]) {
202 *state = REMOTE_KEY_PRESSED; 202 *state = REMOTE_KEY_PRESSED;
203 *event = vp702x_rc_keys[i].event; 203 *event = vp702x_rc_keys[i].event;
204 break; 204 break;
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
index acb345504e0d..a59faa27912a 100644
--- a/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -100,56 +100,56 @@ static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff)
100/* The keymapping struct. Somehow this should be loaded to the driver, but 100/* The keymapping struct. Somehow this should be loaded to the driver, but
101 * currently it is hardcoded. */ 101 * currently it is hardcoded. */
102static struct dvb_usb_rc_key vp7045_rc_keys[] = { 102static struct dvb_usb_rc_key vp7045_rc_keys[] = {
103 { 0x00, 0x16, KEY_POWER }, 103 { 0x0016, KEY_POWER },
104 { 0x00, 0x10, KEY_MUTE }, 104 { 0x0010, KEY_MUTE },
105 { 0x00, 0x03, KEY_1 }, 105 { 0x0003, KEY_1 },
106 { 0x00, 0x01, KEY_2 }, 106 { 0x0001, KEY_2 },
107 { 0x00, 0x06, KEY_3 }, 107 { 0x0006, KEY_3 },
108 { 0x00, 0x09, KEY_4 }, 108 { 0x0009, KEY_4 },
109 { 0x00, 0x1d, KEY_5 }, 109 { 0x001d, KEY_5 },
110 { 0x00, 0x1f, KEY_6 }, 110 { 0x001f, KEY_6 },
111 { 0x00, 0x0d, KEY_7 }, 111 { 0x000d, KEY_7 },
112 { 0x00, 0x19, KEY_8 }, 112 { 0x0019, KEY_8 },
113 { 0x00, 0x1b, KEY_9 }, 113 { 0x001b, KEY_9 },
114 { 0x00, 0x15, KEY_0 }, 114 { 0x0015, KEY_0 },
115 { 0x00, 0x05, KEY_CHANNELUP }, 115 { 0x0005, KEY_CHANNELUP },
116 { 0x00, 0x02, KEY_CHANNELDOWN }, 116 { 0x0002, KEY_CHANNELDOWN },
117 { 0x00, 0x1e, KEY_VOLUMEUP }, 117 { 0x001e, KEY_VOLUMEUP },
118 { 0x00, 0x0a, KEY_VOLUMEDOWN }, 118 { 0x000a, KEY_VOLUMEDOWN },
119 { 0x00, 0x11, KEY_RECORD }, 119 { 0x0011, KEY_RECORD },
120 { 0x00, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */ 120 { 0x0017, KEY_FAVORITES }, /* Heart symbol - Channel list. */
121 { 0x00, 0x14, KEY_PLAY }, 121 { 0x0014, KEY_PLAY },
122 { 0x00, 0x1a, KEY_STOP }, 122 { 0x001a, KEY_STOP },
123 { 0x00, 0x40, KEY_REWIND }, 123 { 0x0040, KEY_REWIND },
124 { 0x00, 0x12, KEY_FASTFORWARD }, 124 { 0x0012, KEY_FASTFORWARD },
125 { 0x00, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */ 125 { 0x000e, KEY_PREVIOUS }, /* Recall - Previous channel. */
126 { 0x00, 0x4c, KEY_PAUSE }, 126 { 0x004c, KEY_PAUSE },
127 { 0x00, 0x4d, KEY_SCREEN }, /* Full screen mode. */ 127 { 0x004d, KEY_SCREEN }, /* Full screen mode. */
128 { 0x00, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */ 128 { 0x0054, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
129 { 0x00, 0x0c, KEY_CANCEL }, /* Cancel */ 129 { 0x000c, KEY_CANCEL }, /* Cancel */
130 { 0x00, 0x1c, KEY_EPG }, /* EPG */ 130 { 0x001c, KEY_EPG }, /* EPG */
131 { 0x00, 0x00, KEY_TAB }, /* Tab */ 131 { 0x0000, KEY_TAB }, /* Tab */
132 { 0x00, 0x48, KEY_INFO }, /* Preview */ 132 { 0x0048, KEY_INFO }, /* Preview */
133 { 0x00, 0x04, KEY_LIST }, /* RecordList */ 133 { 0x0004, KEY_LIST }, /* RecordList */
134 { 0x00, 0x0f, KEY_TEXT }, /* Teletext */ 134 { 0x000f, KEY_TEXT }, /* Teletext */
135 { 0x00, 0x41, KEY_PREVIOUSSONG }, 135 { 0x0041, KEY_PREVIOUSSONG },
136 { 0x00, 0x42, KEY_NEXTSONG }, 136 { 0x0042, KEY_NEXTSONG },
137 { 0x00, 0x4b, KEY_UP }, 137 { 0x004b, KEY_UP },
138 { 0x00, 0x51, KEY_DOWN }, 138 { 0x0051, KEY_DOWN },
139 { 0x00, 0x4e, KEY_LEFT }, 139 { 0x004e, KEY_LEFT },
140 { 0x00, 0x52, KEY_RIGHT }, 140 { 0x0052, KEY_RIGHT },
141 { 0x00, 0x4f, KEY_ENTER }, 141 { 0x004f, KEY_ENTER },
142 { 0x00, 0x13, KEY_CANCEL }, 142 { 0x0013, KEY_CANCEL },
143 { 0x00, 0x4a, KEY_CLEAR }, 143 { 0x004a, KEY_CLEAR },
144 { 0x00, 0x54, KEY_PRINT }, /* Capture */ 144 { 0x0054, KEY_PRINT }, /* Capture */
145 { 0x00, 0x43, KEY_SUBTITLE }, /* Subtitle/CC */ 145 { 0x0043, KEY_SUBTITLE }, /* Subtitle/CC */
146 { 0x00, 0x08, KEY_VIDEO }, /* A/V */ 146 { 0x0008, KEY_VIDEO }, /* A/V */
147 { 0x00, 0x07, KEY_SLEEP }, /* Hibernate */ 147 { 0x0007, KEY_SLEEP }, /* Hibernate */
148 { 0x00, 0x45, KEY_ZOOM }, /* Zoom+ */ 148 { 0x0045, KEY_ZOOM }, /* Zoom+ */
149 { 0x00, 0x18, KEY_RED}, 149 { 0x0018, KEY_RED},
150 { 0x00, 0x53, KEY_GREEN}, 150 { 0x0053, KEY_GREEN},
151 { 0x00, 0x5e, KEY_YELLOW}, 151 { 0x005e, KEY_YELLOW},
152 { 0x00, 0x5f, KEY_BLUE} 152 { 0x005f, KEY_BLUE}
153}; 153};
154 154
155static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 155static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
@@ -166,7 +166,7 @@ static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
166 } 166 }
167 167
168 for (i = 0; i < ARRAY_SIZE(vp7045_rc_keys); i++) 168 for (i = 0; i < ARRAY_SIZE(vp7045_rc_keys); i++)
169 if (vp7045_rc_keys[i].data == key) { 169 if (rc5_data(&vp7045_rc_keys[i]) == key) {
170 *state = REMOTE_KEY_PRESSED; 170 *state = REMOTE_KEY_PRESSED;
171 *event = vp7045_rc_keys[i].event; 171 *event = vp7045_rc_keys[i].event;
172 break; 172 break;
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c
index 32526f103b59..d1b67fe0f011 100644
--- a/drivers/media/dvb/firewire/firedtv-avc.c
+++ b/drivers/media/dvb/firewire/firedtv-avc.c
@@ -89,15 +89,33 @@ struct avc_response_frame {
89 u8 operand[509]; 89 u8 operand[509];
90}; 90};
91 91
92#define AVC_DEBUG_FCP_SUBACTIONS 1 92#define AVC_DEBUG_READ_DESCRIPTOR 0x0001
93#define AVC_DEBUG_FCP_PAYLOADS 2 93#define AVC_DEBUG_DSIT 0x0002
94#define AVC_DEBUG_DSD 0x0004
95#define AVC_DEBUG_REGISTER_REMOTE_CONTROL 0x0008
96#define AVC_DEBUG_LNB_CONTROL 0x0010
97#define AVC_DEBUG_TUNE_QPSK 0x0020
98#define AVC_DEBUG_TUNE_QPSK2 0x0040
99#define AVC_DEBUG_HOST2CA 0x0080
100#define AVC_DEBUG_CA2HOST 0x0100
101#define AVC_DEBUG_APPLICATION_PMT 0x4000
102#define AVC_DEBUG_FCP_PAYLOADS 0x8000
94 103
95static int avc_debug; 104static int avc_debug;
96module_param_named(debug, avc_debug, int, 0644); 105module_param_named(debug, avc_debug, int, 0644);
97MODULE_PARM_DESC(debug, "Verbose logging (default = 0" 106MODULE_PARM_DESC(debug, "Verbose logging (none = 0"
98 ", FCP subactions = " __stringify(AVC_DEBUG_FCP_SUBACTIONS) 107 ", FCP subactions"
99 ", FCP payloads = " __stringify(AVC_DEBUG_FCP_PAYLOADS) 108 ": READ DESCRIPTOR = " __stringify(AVC_DEBUG_READ_DESCRIPTOR)
100 ", or all = -1)"); 109 ", DSIT = " __stringify(AVC_DEBUG_DSIT)
110 ", REGISTER_REMOTE_CONTROL = " __stringify(AVC_DEBUG_REGISTER_REMOTE_CONTROL)
111 ", LNB CONTROL = " __stringify(AVC_DEBUG_LNB_CONTROL)
112 ", TUNE QPSK = " __stringify(AVC_DEBUG_TUNE_QPSK)
113 ", TUNE QPSK2 = " __stringify(AVC_DEBUG_TUNE_QPSK2)
114 ", HOST2CA = " __stringify(AVC_DEBUG_HOST2CA)
115 ", CA2HOST = " __stringify(AVC_DEBUG_CA2HOST)
116 "; Application sent PMT = " __stringify(AVC_DEBUG_APPLICATION_PMT)
117 ", FCP payloads = " __stringify(AVC_DEBUG_FCP_PAYLOADS)
118 ", or a combination, or all = -1)");
101 119
102static const char *debug_fcp_ctype(unsigned int ctype) 120static const char *debug_fcp_ctype(unsigned int ctype)
103{ 121{
@@ -118,48 +136,70 @@ static const char *debug_fcp_opcode(unsigned int opcode,
118 const u8 *data, int length) 136 const u8 *data, int length)
119{ 137{
120 switch (opcode) { 138 switch (opcode) {
121 case AVC_OPCODE_VENDOR: break; 139 case AVC_OPCODE_VENDOR:
122 case AVC_OPCODE_READ_DESCRIPTOR: return "ReadDescriptor"; 140 break;
123 case AVC_OPCODE_DSIT: return "DirectSelectInfo.Type"; 141 case AVC_OPCODE_READ_DESCRIPTOR:
124 case AVC_OPCODE_DSD: return "DirectSelectData"; 142 return avc_debug & AVC_DEBUG_READ_DESCRIPTOR ?
125 default: return "?"; 143 "ReadDescriptor" : NULL;
144 case AVC_OPCODE_DSIT:
145 return avc_debug & AVC_DEBUG_DSIT ?
146 "DirectSelectInfo.Type" : NULL;
147 case AVC_OPCODE_DSD:
148 return avc_debug & AVC_DEBUG_DSD ? "DirectSelectData" : NULL;
149 default:
150 return "Unknown";
126 } 151 }
127 152
128 if (length < 7 || 153 if (length < 7 ||
129 data[3] != SFE_VENDOR_DE_COMPANYID_0 || 154 data[3] != SFE_VENDOR_DE_COMPANYID_0 ||
130 data[4] != SFE_VENDOR_DE_COMPANYID_1 || 155 data[4] != SFE_VENDOR_DE_COMPANYID_1 ||
131 data[5] != SFE_VENDOR_DE_COMPANYID_2) 156 data[5] != SFE_VENDOR_DE_COMPANYID_2)
132 return "Vendor"; 157 return "Vendor/Unknown";
133 158
134 switch (data[6]) { 159 switch (data[6]) {
135 case SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL: return "RegisterRC"; 160 case SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL:
136 case SFE_VENDOR_OPCODE_LNB_CONTROL: return "LNBControl"; 161 return avc_debug & AVC_DEBUG_REGISTER_REMOTE_CONTROL ?
137 case SFE_VENDOR_OPCODE_TUNE_QPSK: return "TuneQPSK"; 162 "RegisterRC" : NULL;
138 case SFE_VENDOR_OPCODE_TUNE_QPSK2: return "TuneQPSK2"; 163 case SFE_VENDOR_OPCODE_LNB_CONTROL:
139 case SFE_VENDOR_OPCODE_HOST2CA: return "Host2CA"; 164 return avc_debug & AVC_DEBUG_LNB_CONTROL ? "LNBControl" : NULL;
140 case SFE_VENDOR_OPCODE_CA2HOST: return "CA2Host"; 165 case SFE_VENDOR_OPCODE_TUNE_QPSK:
166 return avc_debug & AVC_DEBUG_TUNE_QPSK ? "TuneQPSK" : NULL;
167 case SFE_VENDOR_OPCODE_TUNE_QPSK2:
168 return avc_debug & AVC_DEBUG_TUNE_QPSK2 ? "TuneQPSK2" : NULL;
169 case SFE_VENDOR_OPCODE_HOST2CA:
170 return avc_debug & AVC_DEBUG_HOST2CA ? "Host2CA" : NULL;
171 case SFE_VENDOR_OPCODE_CA2HOST:
172 return avc_debug & AVC_DEBUG_CA2HOST ? "CA2Host" : NULL;
141 } 173 }
142 return "Vendor"; 174 return "Vendor/Unknown";
143} 175}
144 176
145static void debug_fcp(const u8 *data, int length) 177static void debug_fcp(const u8 *data, int length)
146{ 178{
147 unsigned int subunit_type, subunit_id, op; 179 unsigned int subunit_type, subunit_id, opcode;
148 const char *prefix = data[0] > 7 ? "FCP <- " : "FCP -> "; 180 const char *op, *prefix;
181
182 prefix = data[0] > 7 ? "FCP <- " : "FCP -> ";
183 subunit_type = data[1] >> 3;
184 subunit_id = data[1] & 7;
185 opcode = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2];
186 op = debug_fcp_opcode(opcode, data, length);
149 187
150 if (avc_debug & AVC_DEBUG_FCP_SUBACTIONS) { 188 if (op) {
151 subunit_type = data[1] >> 3;
152 subunit_id = data[1] & 7;
153 op = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2];
154 printk(KERN_INFO "%ssu=%x.%x l=%d: %-8s - %s\n", 189 printk(KERN_INFO "%ssu=%x.%x l=%d: %-8s - %s\n",
155 prefix, subunit_type, subunit_id, length, 190 prefix, subunit_type, subunit_id, length,
156 debug_fcp_ctype(data[0]), 191 debug_fcp_ctype(data[0]), op);
157 debug_fcp_opcode(op, data, length)); 192 if (avc_debug & AVC_DEBUG_FCP_PAYLOADS)
193 print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_NONE,
194 16, 1, data, length, false);
158 } 195 }
196}
159 197
160 if (avc_debug & AVC_DEBUG_FCP_PAYLOADS) 198static void debug_pmt(char *msg, int length)
161 print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_NONE, 16, 1, 199{
162 data, length, false); 200 printk(KERN_INFO "APP PMT -> l=%d\n", length);
201 print_hex_dump(KERN_INFO, "APP PMT -> ", DUMP_PREFIX_NONE,
202 16, 1, msg, length, false);
163} 203}
164 204
165static int __avc_write(struct firedtv *fdtv, 205static int __avc_write(struct firedtv *fdtv,
@@ -254,6 +294,26 @@ int avc_recv(struct firedtv *fdtv, void *data, size_t length)
254 return 0; 294 return 0;
255} 295}
256 296
297static int add_pid_filter(struct firedtv *fdtv, u8 *operand)
298{
299 int i, n, pos = 1;
300
301 for (i = 0, n = 0; i < 16; i++) {
302 if (test_bit(i, &fdtv->channel_active)) {
303 operand[pos++] = 0x13; /* flowfunction relay */
304 operand[pos++] = 0x80; /* dsd_sel_spec_valid_flags -> PID */
305 operand[pos++] = (fdtv->channel_pid[i] >> 8) & 0x1f;
306 operand[pos++] = fdtv->channel_pid[i] & 0xff;
307 operand[pos++] = 0x00; /* tableID */
308 operand[pos++] = 0x00; /* filter_length */
309 n++;
310 }
311 }
312 operand[0] = n;
313
314 return pos;
315}
316
257/* 317/*
258 * tuning command for setting the relative LNB frequency 318 * tuning command for setting the relative LNB frequency
259 * (not supported by the AVC standard) 319 * (not supported by the AVC standard)
@@ -316,7 +376,8 @@ static void avc_tuner_tuneqpsk(struct firedtv *fdtv,
316 } 376 }
317} 377}
318 378
319static void avc_tuner_dsd_dvb_c(struct dvb_frontend_parameters *params, 379static void avc_tuner_dsd_dvb_c(struct firedtv *fdtv,
380 struct dvb_frontend_parameters *params,
320 struct avc_command_frame *c) 381 struct avc_command_frame *c)
321{ 382{
322 c->opcode = AVC_OPCODE_DSD; 383 c->opcode = AVC_OPCODE_DSD;
@@ -378,13 +439,13 @@ static void avc_tuner_dsd_dvb_c(struct dvb_frontend_parameters *params,
378 439
379 c->operand[20] = 0x00; 440 c->operand[20] = 0x00;
380 c->operand[21] = 0x00; 441 c->operand[21] = 0x00;
381 /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */
382 c->operand[22] = 0x00;
383 442
384 c->length = 28; 443 /* Add PIDs to filter */
444 c->length = ALIGN(22 + add_pid_filter(fdtv, &c->operand[22]) + 3, 4);
385} 445}
386 446
387static void avc_tuner_dsd_dvb_t(struct dvb_frontend_parameters *params, 447static void avc_tuner_dsd_dvb_t(struct firedtv *fdtv,
448 struct dvb_frontend_parameters *params,
388 struct avc_command_frame *c) 449 struct avc_command_frame *c)
389{ 450{
390 struct dvb_ofdm_parameters *ofdm = &params->u.ofdm; 451 struct dvb_ofdm_parameters *ofdm = &params->u.ofdm;
@@ -481,10 +542,9 @@ static void avc_tuner_dsd_dvb_t(struct dvb_frontend_parameters *params,
481 542
482 c->operand[15] = 0x00; /* network_ID[0] */ 543 c->operand[15] = 0x00; /* network_ID[0] */
483 c->operand[16] = 0x00; /* network_ID[1] */ 544 c->operand[16] = 0x00; /* network_ID[1] */
484 /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */
485 c->operand[17] = 0x00;
486 545
487 c->length = 24; 546 /* Add PIDs to filter */
547 c->length = ALIGN(17 + add_pid_filter(fdtv, &c->operand[17]) + 3, 4);
488} 548}
489 549
490int avc_tuner_dsd(struct firedtv *fdtv, 550int avc_tuner_dsd(struct firedtv *fdtv,
@@ -502,8 +562,8 @@ int avc_tuner_dsd(struct firedtv *fdtv,
502 switch (fdtv->type) { 562 switch (fdtv->type) {
503 case FIREDTV_DVB_S: 563 case FIREDTV_DVB_S:
504 case FIREDTV_DVB_S2: avc_tuner_tuneqpsk(fdtv, params, c); break; 564 case FIREDTV_DVB_S2: avc_tuner_tuneqpsk(fdtv, params, c); break;
505 case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(params, c); break; 565 case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(fdtv, params, c); break;
506 case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(params, c); break; 566 case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(fdtv, params, c); break;
507 default: 567 default:
508 BUG(); 568 BUG();
509 } 569 }
@@ -963,6 +1023,9 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
963 int es_info_length; 1023 int es_info_length;
964 int crc32_csum; 1024 int crc32_csum;
965 1025
1026 if (unlikely(avc_debug & AVC_DEBUG_APPLICATION_PMT))
1027 debug_pmt(msg, length);
1028
966 memset(c, 0, sizeof(*c)); 1029 memset(c, 0, sizeof(*c));
967 1030
968 c->ctype = AVC_CTYPE_CONTROL; 1031 c->ctype = AVC_CTYPE_CONTROL;
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index be967ac09a39..b794e860b4e2 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -81,6 +81,13 @@ config DVB_ZL10036
81 help 81 help
82 A DVB-S tuner module. Say Y when you want to support this frontend. 82 A DVB-S tuner module. Say Y when you want to support this frontend.
83 83
84config DVB_ZL10039
85 tristate "Zarlink ZL10039 silicon tuner"
86 depends on DVB_CORE && I2C
87 default m if DVB_FE_CUSTOMISE
88 help
89 A DVB-S tuner module. Say Y when you want to support this frontend.
90
84config DVB_S5H1420 91config DVB_S5H1420
85 tristate "Samsung S5H1420 based" 92 tristate "Samsung S5H1420 based"
86 depends on DVB_CORE && I2C 93 depends on DVB_CORE && I2C
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 832473c1e512..3b49d37ab5fa 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_DVB_SP887X) += sp887x.o
31obj-$(CONFIG_DVB_NXT6000) += nxt6000.o 31obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
32obj-$(CONFIG_DVB_MT352) += mt352.o 32obj-$(CONFIG_DVB_MT352) += mt352.o
33obj-$(CONFIG_DVB_ZL10036) += zl10036.o 33obj-$(CONFIG_DVB_ZL10036) += zl10036.o
34obj-$(CONFIG_DVB_ZL10039) += zl10039.o
34obj-$(CONFIG_DVB_ZL10353) += zl10353.o 35obj-$(CONFIG_DVB_ZL10353) += zl10353.o
35obj-$(CONFIG_DVB_CX22702) += cx22702.o 36obj-$(CONFIG_DVB_CX22702) += cx22702.o
36obj-$(CONFIG_DVB_DRX397XD) += drx397xD.o 37obj-$(CONFIG_DVB_DRX397XD) += drx397xD.o
diff --git a/drivers/media/dvb/frontends/cx22700.c b/drivers/media/dvb/frontends/cx22700.c
index fbd838eca268..5fbc0fc37ecd 100644
--- a/drivers/media/dvb/frontends/cx22700.c
+++ b/drivers/media/dvb/frontends/cx22700.c
@@ -155,7 +155,7 @@ static int cx22700_set_tps (struct cx22700_state *state, struct dvb_ofdm_paramet
155 p->hierarchy_information > HIERARCHY_4) 155 p->hierarchy_information > HIERARCHY_4)
156 return -EINVAL; 156 return -EINVAL;
157 157
158 if (p->bandwidth < BANDWIDTH_8_MHZ && p->bandwidth > BANDWIDTH_6_MHZ) 158 if (p->bandwidth < BANDWIDTH_8_MHZ || p->bandwidth > BANDWIDTH_6_MHZ)
159 return -EINVAL; 159 return -EINVAL;
160 160
161 if (p->bandwidth == BANDWIDTH_7_MHZ) 161 if (p->bandwidth == BANDWIDTH_7_MHZ)
diff --git a/drivers/media/dvb/frontends/cx24113.c b/drivers/media/dvb/frontends/cx24113.c
index e4fd533a427c..075b2b57cf09 100644
--- a/drivers/media/dvb/frontends/cx24113.c
+++ b/drivers/media/dvb/frontends/cx24113.c
@@ -303,6 +303,7 @@ static void cx24113_calc_pll_nf(struct cx24113_state *state, u16 *n, s32 *f)
303{ 303{
304 s32 N; 304 s32 N;
305 s64 F; 305 s64 F;
306 u64 dividend;
306 u8 R, r; 307 u8 R, r;
307 u8 vcodiv; 308 u8 vcodiv;
308 u8 factor; 309 u8 factor;
@@ -346,7 +347,10 @@ static void cx24113_calc_pll_nf(struct cx24113_state *state, u16 *n, s32 *f)
346 F = freq_hz; 347 F = freq_hz;
347 F *= (u64) (R * vcodiv * 262144); 348 F *= (u64) (R * vcodiv * 262144);
348 dprintk("1 N: %d, F: %lld, R: %d\n", N, (long long)F, R); 349 dprintk("1 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
349 do_div(F, state->config->xtal_khz*1000 * factor * 2); 350 /* do_div needs an u64 as first argument */
351 dividend = F;
352 do_div(dividend, state->config->xtal_khz * 1000 * factor * 2);
353 F = dividend;
350 dprintk("2 N: %d, F: %lld, R: %d\n", N, (long long)F, R); 354 dprintk("2 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
351 F -= (N + 32) * 262144; 355 F -= (N + 32) * 262144;
352 356
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c
index 0592f043ea64..d8f921b6fafd 100644
--- a/drivers/media/dvb/frontends/cx24123.c
+++ b/drivers/media/dvb/frontends/cx24123.c
@@ -458,7 +458,7 @@ static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate)
458 /* check if symbol rate is within limits */ 458 /* check if symbol rate is within limits */
459 if ((srate > state->frontend.ops.info.symbol_rate_max) || 459 if ((srate > state->frontend.ops.info.symbol_rate_max) ||
460 (srate < state->frontend.ops.info.symbol_rate_min)) 460 (srate < state->frontend.ops.info.symbol_rate_min))
461 return -EOPNOTSUPP;; 461 return -EOPNOTSUPP;
462 462
463 /* choose the sampling rate high enough for the required operation, 463 /* choose the sampling rate high enough for the required operation,
464 while optimizing the power consumed by the demodulator */ 464 while optimizing the power consumed by the demodulator */
diff --git a/drivers/media/dvb/frontends/dib0070.c b/drivers/media/dvb/frontends/dib0070.c
index fe895bf7b18f..da92cbe1b8ea 100644
--- a/drivers/media/dvb/frontends/dib0070.c
+++ b/drivers/media/dvb/frontends/dib0070.c
@@ -167,7 +167,7 @@ static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_par
167 break; 167 break;
168 case BAND_SBAND: 168 case BAND_SBAND:
169 LO4_SET_VCO_HFDIV(lo4, 0, 0); 169 LO4_SET_VCO_HFDIV(lo4, 0, 0);
170 LO4_SET_CTRIM(lo4, 1);; 170 LO4_SET_CTRIM(lo4, 1);
171 c = 1; 171 c = 1;
172 break; 172 break;
173 case BAND_UHF: 173 case BAND_UHF:
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
index 8217e5b38f47..fc96fbf03d6d 100644
--- a/drivers/media/dvb/frontends/dib7000p.c
+++ b/drivers/media/dvb/frontends/dib7000p.c
@@ -883,7 +883,7 @@ static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32
883 255, 255, 255, 255, 255, 255}; 883 255, 255, 255, 255, 255, 255};
884 884
885 u32 xtal = state->cfg.bw->xtal_hz / 1000; 885 u32 xtal = state->cfg.bw->xtal_hz / 1000;
886 int f_rel = ( (rf_khz + xtal/2) / xtal) * xtal - rf_khz; 886 int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz;
887 int k; 887 int k;
888 int coef_re[8],coef_im[8]; 888 int coef_re[8],coef_im[8];
889 int bw_khz = bw; 889 int bw_khz = bw;
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index 9f6349964cda..6d865d6161d7 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -389,6 +389,77 @@ static struct dvb_pll_desc dvb_pll_samsung_dtos403ih102a = {
389 } 389 }
390}; 390};
391 391
392/* Samsung TDTC9251DH0 DVB-T NIM, as used on AirStar 2 */
393static struct dvb_pll_desc dvb_pll_samsung_tdtc9251dh0 = {
394 .name = "Samsung TDTC9251DH0",
395 .min = 48000000,
396 .max = 863000000,
397 .iffreq = 36166667,
398 .count = 3,
399 .entries = {
400 { 157500000, 166667, 0xcc, 0x09 },
401 { 443000000, 166667, 0xcc, 0x0a },
402 { 863000000, 166667, 0xcc, 0x08 },
403 }
404};
405
406/* Samsung TBDU18132 DVB-S NIM with TSA5059 PLL, used in SkyStar2 DVB-S 2.3 */
407static struct dvb_pll_desc dvb_pll_samsung_tbdu18132 = {
408 .name = "Samsung TBDU18132",
409 .min = 950000,
410 .max = 2150000, /* guesses */
411 .iffreq = 0,
412 .count = 2,
413 .entries = {
414 { 1550000, 125, 0x84, 0x82 },
415 { 4095937, 125, 0x84, 0x80 },
416 }
417 /* TSA5059 PLL has a 17 bit divisor rather than the 15 bits supported
418 * by this driver. The two extra bits are 0x60 in the third byte. 15
419 * bits is enough for over 4 GHz, which is enough to cover the range
420 * of this tuner. We could use the additional divisor bits by adding
421 * more entries, e.g.
422 { 0x0ffff * 125 + 125/2, 125, 0x84 | 0x20, },
423 { 0x17fff * 125 + 125/2, 125, 0x84 | 0x40, },
424 { 0x1ffff * 125 + 125/2, 125, 0x84 | 0x60, }, */
425};
426
427/* Samsung TBMU24112 DVB-S NIM with SL1935 zero-IF tuner */
428static struct dvb_pll_desc dvb_pll_samsung_tbmu24112 = {
429 .name = "Samsung TBMU24112",
430 .min = 950000,
431 .max = 2150000, /* guesses */
432 .iffreq = 0,
433 .count = 2,
434 .entries = {
435 { 1500000, 125, 0x84, 0x18 },
436 { 9999999, 125, 0x84, 0x08 },
437 }
438};
439
440/* Alps TDEE4 DVB-C NIM, used on Cablestar 2 */
441/* byte 4 : 1 * * AGD R3 R2 R1 R0
442 * byte 5 : C1 * RE RTS BS4 BS3 BS2 BS1
443 * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95
444 * Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5
445 * 47 - 153 0 * 0 0 0 0 0 1 0x01
446 * 153 - 430 0 * 0 0 0 0 1 0 0x02
447 * 430 - 822 0 * 0 0 1 0 0 0 0x08
448 * 822 - 862 1 * 0 0 1 0 0 0 0x88 */
449static struct dvb_pll_desc dvb_pll_alps_tdee4 = {
450 .name = "ALPS TDEE4",
451 .min = 47000000,
452 .max = 862000000,
453 .iffreq = 36125000,
454 .count = 4,
455 .entries = {
456 { 153000000, 62500, 0x95, 0x01 },
457 { 430000000, 62500, 0x95, 0x02 },
458 { 822000000, 62500, 0x95, 0x08 },
459 { 999999999, 62500, 0x95, 0x88 },
460 }
461};
462
392/* ----------------------------------------------------------- */ 463/* ----------------------------------------------------------- */
393 464
394static struct dvb_pll_desc *pll_list[] = { 465static struct dvb_pll_desc *pll_list[] = {
@@ -402,11 +473,15 @@ static struct dvb_pll_desc *pll_list[] = {
402 [DVB_PLL_TUA6034] = &dvb_pll_tua6034, 473 [DVB_PLL_TUA6034] = &dvb_pll_tua6034,
403 [DVB_PLL_TDA665X] = &dvb_pll_tda665x, 474 [DVB_PLL_TDA665X] = &dvb_pll_tda665x,
404 [DVB_PLL_TDED4] = &dvb_pll_tded4, 475 [DVB_PLL_TDED4] = &dvb_pll_tded4,
476 [DVB_PLL_TDEE4] = &dvb_pll_alps_tdee4,
405 [DVB_PLL_TDHU2] = &dvb_pll_tdhu2, 477 [DVB_PLL_TDHU2] = &dvb_pll_tdhu2,
406 [DVB_PLL_SAMSUNG_TBMV] = &dvb_pll_samsung_tbmv, 478 [DVB_PLL_SAMSUNG_TBMV] = &dvb_pll_samsung_tbmv,
407 [DVB_PLL_PHILIPS_SD1878_TDA8261] = &dvb_pll_philips_sd1878_tda8261, 479 [DVB_PLL_PHILIPS_SD1878_TDA8261] = &dvb_pll_philips_sd1878_tda8261,
408 [DVB_PLL_OPERA1] = &dvb_pll_opera1, 480 [DVB_PLL_OPERA1] = &dvb_pll_opera1,
409 [DVB_PLL_SAMSUNG_DTOS403IH102A] = &dvb_pll_samsung_dtos403ih102a, 481 [DVB_PLL_SAMSUNG_DTOS403IH102A] = &dvb_pll_samsung_dtos403ih102a,
482 [DVB_PLL_SAMSUNG_TDTC9251DH0] = &dvb_pll_samsung_tdtc9251dh0,
483 [DVB_PLL_SAMSUNG_TBDU18132] = &dvb_pll_samsung_tbdu18132,
484 [DVB_PLL_SAMSUNG_TBMU24112] = &dvb_pll_samsung_tbmu24112,
410}; 485};
411 486
412/* ----------------------------------------------------------- */ 487/* ----------------------------------------------------------- */
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index 05239f579ccf..086964344c38 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -23,6 +23,10 @@
23#define DVB_PLL_PHILIPS_SD1878_TDA8261 12 23#define DVB_PLL_PHILIPS_SD1878_TDA8261 12
24#define DVB_PLL_OPERA1 13 24#define DVB_PLL_OPERA1 13
25#define DVB_PLL_SAMSUNG_DTOS403IH102A 14 25#define DVB_PLL_SAMSUNG_DTOS403IH102A 14
26#define DVB_PLL_SAMSUNG_TDTC9251DH0 15
27#define DVB_PLL_SAMSUNG_TBDU18132 16
28#define DVB_PLL_SAMSUNG_TBMU24112 17
29#define DVB_PLL_TDEE4 18
26 30
27/** 31/**
28 * Attach a dvb-pll to the supplied frontend structure. 32 * Attach a dvb-pll to the supplied frontend structure.
diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb/frontends/lgs8gxx.c
index fde27645bbed..eabcadc425d5 100644
--- a/drivers/media/dvb/frontends/lgs8gxx.c
+++ b/drivers/media/dvb/frontends/lgs8gxx.c
@@ -1,9 +1,9 @@
1/* 1/*
2 * Support for Legend Silicon DMB-TH demodulator 2 * Support for Legend Silicon GB20600 (a.k.a DMB-TH) demodulator
3 * LGS8913, LGS8GL5 3 * LGS8913, LGS8GL5, LGS8G75
4 * experimental support LGS8G42, LGS8G52 4 * experimental support LGS8G42, LGS8G52
5 * 5 *
6 * Copyright (C) 2007,2008 David T.L. Wong <davidtlwong@gmail.com> 6 * Copyright (C) 2007-2009 David T.L. Wong <davidtlwong@gmail.com>
7 * Copyright (C) 2008 Sirius International (Hong Kong) Limited 7 * Copyright (C) 2008 Sirius International (Hong Kong) Limited
8 * Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5) 8 * Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
9 * 9 *
@@ -46,6 +46,42 @@ module_param(fake_signal_str, int, 0644);
46MODULE_PARM_DESC(fake_signal_str, "fake signal strength for LGS8913." 46MODULE_PARM_DESC(fake_signal_str, "fake signal strength for LGS8913."
47"Signal strength calculation is slow.(default:on)."); 47"Signal strength calculation is slow.(default:on).");
48 48
49static const u8 lgs8g75_initdat[] = {
50 0x01, 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
51 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
52 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
53 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
54 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
55 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
56 0xE4, 0xF5, 0xA8, 0xF5, 0xB8, 0xF5, 0x88, 0xF5,
57 0x89, 0xF5, 0x87, 0x75, 0xD0, 0x00, 0x11, 0x50,
58 0x11, 0x50, 0xF4, 0xF5, 0x80, 0xF5, 0x90, 0xF5,
59 0xA0, 0xF5, 0xB0, 0x75, 0x81, 0x30, 0x80, 0x01,
60 0x32, 0x90, 0x80, 0x12, 0x74, 0xFF, 0xF0, 0x90,
61 0x80, 0x13, 0x74, 0x1F, 0xF0, 0x90, 0x80, 0x23,
62 0x74, 0x01, 0xF0, 0x90, 0x80, 0x22, 0xF0, 0x90,
63 0x00, 0x48, 0x74, 0x00, 0xF0, 0x90, 0x80, 0x4D,
64 0x74, 0x05, 0xF0, 0x90, 0x80, 0x09, 0xE0, 0x60,
65 0x21, 0x12, 0x00, 0xDD, 0x14, 0x60, 0x1B, 0x12,
66 0x00, 0xDD, 0x14, 0x60, 0x15, 0x12, 0x00, 0xDD,
67 0x14, 0x60, 0x0F, 0x12, 0x00, 0xDD, 0x14, 0x60,
68 0x09, 0x12, 0x00, 0xDD, 0x14, 0x60, 0x03, 0x12,
69 0x00, 0xDD, 0x90, 0x80, 0x42, 0xE0, 0x60, 0x0B,
70 0x14, 0x60, 0x0C, 0x14, 0x60, 0x0D, 0x14, 0x60,
71 0x0E, 0x01, 0xB3, 0x74, 0x04, 0x01, 0xB9, 0x74,
72 0x05, 0x01, 0xB9, 0x74, 0x07, 0x01, 0xB9, 0x74,
73 0x0A, 0xC0, 0xE0, 0x74, 0xC8, 0x12, 0x00, 0xE2,
74 0xD0, 0xE0, 0x14, 0x70, 0xF4, 0x90, 0x80, 0x09,
75 0xE0, 0x70, 0xAE, 0x12, 0x00, 0xF6, 0x12, 0x00,
76 0xFE, 0x90, 0x00, 0x48, 0xE0, 0x04, 0xF0, 0x90,
77 0x80, 0x4E, 0xF0, 0x01, 0x73, 0x90, 0x80, 0x08,
78 0xF0, 0x22, 0xF8, 0x7A, 0x0C, 0x79, 0xFD, 0x00,
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9,
80 0xF6, 0xDA, 0xF2, 0xD8, 0xEE, 0x22, 0x90, 0x80,
81 0x65, 0xE0, 0x54, 0xFD, 0xF0, 0x22, 0x90, 0x80,
82 0x65, 0xE0, 0x44, 0xC2, 0xF0, 0x22
83};
84
49/* LGS8GXX internal helper functions */ 85/* LGS8GXX internal helper functions */
50 86
51static int lgs8gxx_write_reg(struct lgs8gxx_state *priv, u8 reg, u8 data) 87static int lgs8gxx_write_reg(struct lgs8gxx_state *priv, u8 reg, u8 data)
@@ -55,7 +91,7 @@ static int lgs8gxx_write_reg(struct lgs8gxx_state *priv, u8 reg, u8 data)
55 struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 }; 91 struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 };
56 92
57 msg.addr = priv->config->demod_address; 93 msg.addr = priv->config->demod_address;
58 if (reg >= 0xC0) 94 if (priv->config->prod != LGS8GXX_PROD_LGS8G75 && reg >= 0xC0)
59 msg.addr += 0x02; 95 msg.addr += 0x02;
60 96
61 if (debug >= 2) 97 if (debug >= 2)
@@ -84,7 +120,7 @@ static int lgs8gxx_read_reg(struct lgs8gxx_state *priv, u8 reg, u8 *p_data)
84 }; 120 };
85 121
86 dev_addr = priv->config->demod_address; 122 dev_addr = priv->config->demod_address;
87 if (reg >= 0xC0) 123 if (priv->config->prod != LGS8GXX_PROD_LGS8G75 && reg >= 0xC0)
88 dev_addr += 0x02; 124 dev_addr += 0x02;
89 msg[1].addr = msg[0].addr = dev_addr; 125 msg[1].addr = msg[0].addr = dev_addr;
90 126
@@ -112,19 +148,36 @@ static int lgs8gxx_soft_reset(struct lgs8gxx_state *priv)
112 return 0; 148 return 0;
113} 149}
114 150
151static int wait_reg_mask(struct lgs8gxx_state *priv, u8 reg, u8 mask,
152 u8 val, u8 delay, u8 tries)
153{
154 u8 t;
155 int i;
156
157 for (i = 0; i < tries; i++) {
158 lgs8gxx_read_reg(priv, reg, &t);
159
160 if ((t & mask) == val)
161 return 0;
162 msleep(delay);
163 }
164
165 return 1;
166}
167
115static int lgs8gxx_set_ad_mode(struct lgs8gxx_state *priv) 168static int lgs8gxx_set_ad_mode(struct lgs8gxx_state *priv)
116{ 169{
117 const struct lgs8gxx_config *config = priv->config; 170 const struct lgs8gxx_config *config = priv->config;
118 u8 if_conf; 171 u8 if_conf;
119 172
120 if_conf = 0x10; /* AGC output on; */ 173 if_conf = 0x10; /* AGC output on, RF_AGC output off; */
121 174
122 if_conf |= 175 if_conf |=
123 ((config->ext_adc) ? 0x80 : 0x00) | 176 ((config->ext_adc) ? 0x80 : 0x00) |
124 ((config->if_neg_center) ? 0x04 : 0x00) | 177 ((config->if_neg_center) ? 0x04 : 0x00) |
125 ((config->if_freq == 0) ? 0x08 : 0x00) | /* Baseband */ 178 ((config->if_freq == 0) ? 0x08 : 0x00) | /* Baseband */
126 ((config->ext_adc && config->adc_signed) ? 0x02 : 0x00) | 179 ((config->adc_signed) ? 0x02 : 0x00) |
127 ((config->ext_adc && config->if_neg_edge) ? 0x01 : 0x00); 180 ((config->if_neg_edge) ? 0x01 : 0x00);
128 181
129 if (config->ext_adc && 182 if (config->ext_adc &&
130 (config->prod == LGS8GXX_PROD_LGS8G52)) { 183 (config->prod == LGS8GXX_PROD_LGS8G52)) {
@@ -157,39 +210,82 @@ static int lgs8gxx_set_if_freq(struct lgs8gxx_state *priv, u32 freq /*in kHz*/)
157 } 210 }
158 dprintk("AFC_INIT_FREQ = 0x%08X\n", v32); 211 dprintk("AFC_INIT_FREQ = 0x%08X\n", v32);
159 212
160 lgs8gxx_write_reg(priv, 0x09, 0xFF & (v32)); 213 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
161 lgs8gxx_write_reg(priv, 0x0A, 0xFF & (v32 >> 8)); 214 lgs8gxx_write_reg(priv, 0x08, 0xFF & (v32));
162 lgs8gxx_write_reg(priv, 0x0B, 0xFF & (v32 >> 16)); 215 lgs8gxx_write_reg(priv, 0x09, 0xFF & (v32 >> 8));
163 lgs8gxx_write_reg(priv, 0x0C, 0xFF & (v32 >> 24)); 216 lgs8gxx_write_reg(priv, 0x0A, 0xFF & (v32 >> 16));
217 lgs8gxx_write_reg(priv, 0x0B, 0xFF & (v32 >> 24));
218 } else {
219 lgs8gxx_write_reg(priv, 0x09, 0xFF & (v32));
220 lgs8gxx_write_reg(priv, 0x0A, 0xFF & (v32 >> 8));
221 lgs8gxx_write_reg(priv, 0x0B, 0xFF & (v32 >> 16));
222 lgs8gxx_write_reg(priv, 0x0C, 0xFF & (v32 >> 24));
223 }
224
225 return 0;
226}
227
228static int lgs8gxx_get_afc_phase(struct lgs8gxx_state *priv)
229{
230 u64 val;
231 u32 v32 = 0;
232 u8 reg_addr, t;
233 int i;
234
235 if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
236 reg_addr = 0x23;
237 else
238 reg_addr = 0x48;
239
240 for (i = 0; i < 4; i++) {
241 lgs8gxx_read_reg(priv, reg_addr, &t);
242 v32 <<= 8;
243 v32 |= t;
244 reg_addr--;
245 }
164 246
247 val = v32;
248 val *= priv->config->if_clk_freq;
249 val /= (u64)1 << 32;
250 dprintk("AFC = %u kHz\n", (u32)val);
165 return 0; 251 return 0;
166} 252}
167 253
168static int lgs8gxx_set_mode_auto(struct lgs8gxx_state *priv) 254static int lgs8gxx_set_mode_auto(struct lgs8gxx_state *priv)
169{ 255{
170 u8 t; 256 u8 t;
257 u8 prod = priv->config->prod;
171 258
172 if (priv->config->prod == LGS8GXX_PROD_LGS8913) 259 if (prod == LGS8GXX_PROD_LGS8913)
173 lgs8gxx_write_reg(priv, 0xC6, 0x01); 260 lgs8gxx_write_reg(priv, 0xC6, 0x01);
174 261
175 lgs8gxx_read_reg(priv, 0x7E, &t); 262 if (prod == LGS8GXX_PROD_LGS8G75) {
176 lgs8gxx_write_reg(priv, 0x7E, t | 0x01); 263 lgs8gxx_read_reg(priv, 0x0C, &t);
177 264 t &= (~0x04);
178 /* clear FEC self reset */ 265 lgs8gxx_write_reg(priv, 0x0C, t | 0x80);
179 lgs8gxx_read_reg(priv, 0xC5, &t); 266 lgs8gxx_write_reg(priv, 0x39, 0x00);
180 lgs8gxx_write_reg(priv, 0xC5, t & 0xE0); 267 lgs8gxx_write_reg(priv, 0x3D, 0x04);
268 } else if (prod == LGS8GXX_PROD_LGS8913 ||
269 prod == LGS8GXX_PROD_LGS8GL5 ||
270 prod == LGS8GXX_PROD_LGS8G42 ||
271 prod == LGS8GXX_PROD_LGS8G52 ||
272 prod == LGS8GXX_PROD_LGS8G54) {
273 lgs8gxx_read_reg(priv, 0x7E, &t);
274 lgs8gxx_write_reg(priv, 0x7E, t | 0x01);
275
276 /* clear FEC self reset */
277 lgs8gxx_read_reg(priv, 0xC5, &t);
278 lgs8gxx_write_reg(priv, 0xC5, t & 0xE0);
279 }
181 280
182 if (priv->config->prod == LGS8GXX_PROD_LGS8913) { 281 if (prod == LGS8GXX_PROD_LGS8913) {
183 /* FEC auto detect */ 282 /* FEC auto detect */
184 lgs8gxx_write_reg(priv, 0xC1, 0x03); 283 lgs8gxx_write_reg(priv, 0xC1, 0x03);
185 284
186 lgs8gxx_read_reg(priv, 0x7C, &t); 285 lgs8gxx_read_reg(priv, 0x7C, &t);
187 t = (t & 0x8C) | 0x03; 286 t = (t & 0x8C) | 0x03;
188 lgs8gxx_write_reg(priv, 0x7C, t); 287 lgs8gxx_write_reg(priv, 0x7C, t);
189 }
190
191 288
192 if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
193 /* BER test mode */ 289 /* BER test mode */
194 lgs8gxx_read_reg(priv, 0xC3, &t); 290 lgs8gxx_read_reg(priv, 0xC3, &t);
195 t = (t & 0xEF) | 0x10; 291 t = (t & 0xEF) | 0x10;
@@ -207,6 +303,32 @@ static int lgs8gxx_set_mode_manual(struct lgs8gxx_state *priv)
207 int ret = 0; 303 int ret = 0;
208 u8 t; 304 u8 t;
209 305
306 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
307 u8 t2;
308 lgs8gxx_read_reg(priv, 0x0C, &t);
309 t &= (~0x80);
310 lgs8gxx_write_reg(priv, 0x0C, t);
311
312 lgs8gxx_read_reg(priv, 0x0C, &t);
313 lgs8gxx_read_reg(priv, 0x19, &t2);
314
315 if (((t&0x03) == 0x01) && (t2&0x01)) {
316 lgs8gxx_write_reg(priv, 0x6E, 0x05);
317 lgs8gxx_write_reg(priv, 0x39, 0x02);
318 lgs8gxx_write_reg(priv, 0x39, 0x03);
319 lgs8gxx_write_reg(priv, 0x3D, 0x05);
320 lgs8gxx_write_reg(priv, 0x3E, 0x28);
321 lgs8gxx_write_reg(priv, 0x53, 0x80);
322 } else {
323 lgs8gxx_write_reg(priv, 0x6E, 0x3F);
324 lgs8gxx_write_reg(priv, 0x39, 0x00);
325 lgs8gxx_write_reg(priv, 0x3D, 0x04);
326 }
327
328 lgs8gxx_soft_reset(priv);
329 return 0;
330 }
331
210 /* turn off auto-detect; manual settings */ 332 /* turn off auto-detect; manual settings */
211 lgs8gxx_write_reg(priv, 0x7E, 0); 333 lgs8gxx_write_reg(priv, 0x7E, 0);
212 if (priv->config->prod == LGS8GXX_PROD_LGS8913) 334 if (priv->config->prod == LGS8GXX_PROD_LGS8913)
@@ -226,11 +348,39 @@ static int lgs8gxx_is_locked(struct lgs8gxx_state *priv, u8 *locked)
226 int ret = 0; 348 int ret = 0;
227 u8 t; 349 u8 t;
228 350
229 ret = lgs8gxx_read_reg(priv, 0x4B, &t); 351 if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
352 ret = lgs8gxx_read_reg(priv, 0x13, &t);
353 else
354 ret = lgs8gxx_read_reg(priv, 0x4B, &t);
230 if (ret != 0) 355 if (ret != 0)
231 return ret; 356 return ret;
232 357
233 *locked = ((t & 0xC0) == 0xC0) ? 1 : 0; 358 if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
359 *locked = ((t & 0x80) == 0x80) ? 1 : 0;
360 else
361 *locked = ((t & 0xC0) == 0xC0) ? 1 : 0;
362 return 0;
363}
364
365/* Wait for Code Acquisition Lock */
366static int lgs8gxx_wait_ca_lock(struct lgs8gxx_state *priv, u8 *locked)
367{
368 int ret = 0;
369 u8 reg, mask, val;
370
371 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
372 reg = 0x13;
373 mask = 0x80;
374 val = 0x80;
375 } else {
376 reg = 0x4B;
377 mask = 0xC0;
378 val = 0xC0;
379 }
380
381 ret = wait_reg_mask(priv, reg, mask, val, 50, 40);
382 *locked = (ret == 0) ? 1 : 0;
383
234 return 0; 384 return 0;
235} 385}
236 386
@@ -238,21 +388,30 @@ static int lgs8gxx_is_autodetect_finished(struct lgs8gxx_state *priv,
238 u8 *finished) 388 u8 *finished)
239{ 389{
240 int ret = 0; 390 int ret = 0;
241 u8 t; 391 u8 reg, mask, val;
242 392
243 ret = lgs8gxx_read_reg(priv, 0xA4, &t); 393 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
244 if (ret != 0) 394 reg = 0x1f;
245 return ret; 395 mask = 0xC0;
396 val = 0x80;
397 } else {
398 reg = 0xA4;
399 mask = 0x03;
400 val = 0x01;
401 }
246 402
247 *finished = ((t & 0x3) == 0x1) ? 1 : 0; 403 ret = wait_reg_mask(priv, reg, mask, val, 10, 20);
404 *finished = (ret == 0) ? 1 : 0;
248 405
249 return 0; 406 return 0;
250} 407}
251 408
252static int lgs8gxx_autolock_gi(struct lgs8gxx_state *priv, u8 gi, u8 *locked) 409static int lgs8gxx_autolock_gi(struct lgs8gxx_state *priv, u8 gi, u8 cpn,
410 u8 *locked)
253{ 411{
254 int err; 412 int err = 0;
255 u8 ad_fini = 0; 413 u8 ad_fini = 0;
414 u8 t1, t2;
256 415
257 if (gi == GI_945) 416 if (gi == GI_945)
258 dprintk("try GI 945\n"); 417 dprintk("try GI 945\n");
@@ -260,17 +419,29 @@ static int lgs8gxx_autolock_gi(struct lgs8gxx_state *priv, u8 gi, u8 *locked)
260 dprintk("try GI 595\n"); 419 dprintk("try GI 595\n");
261 else if (gi == GI_420) 420 else if (gi == GI_420)
262 dprintk("try GI 420\n"); 421 dprintk("try GI 420\n");
263 lgs8gxx_write_reg(priv, 0x04, gi); 422 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
423 lgs8gxx_read_reg(priv, 0x0C, &t1);
424 lgs8gxx_read_reg(priv, 0x18, &t2);
425 t1 &= ~(GI_MASK);
426 t1 |= gi;
427 t2 &= 0xFE;
428 t2 |= cpn ? 0x01 : 0x00;
429 lgs8gxx_write_reg(priv, 0x0C, t1);
430 lgs8gxx_write_reg(priv, 0x18, t2);
431 } else {
432 lgs8gxx_write_reg(priv, 0x04, gi);
433 }
264 lgs8gxx_soft_reset(priv); 434 lgs8gxx_soft_reset(priv);
265 msleep(50); 435 err = lgs8gxx_wait_ca_lock(priv, locked);
436 if (err || !(*locked))
437 return err;
266 err = lgs8gxx_is_autodetect_finished(priv, &ad_fini); 438 err = lgs8gxx_is_autodetect_finished(priv, &ad_fini);
267 if (err != 0) 439 if (err != 0)
268 return err; 440 return err;
269 if (ad_fini) { 441 if (ad_fini) {
270 err = lgs8gxx_is_locked(priv, locked); 442 dprintk("auto detect finished\n");
271 if (err != 0) 443 } else
272 return err; 444 *locked = 0;
273 }
274 445
275 return 0; 446 return 0;
276} 447}
@@ -285,13 +456,18 @@ static int lgs8gxx_auto_detect(struct lgs8gxx_state *priv,
285 dprintk("%s\n", __func__); 456 dprintk("%s\n", __func__);
286 457
287 lgs8gxx_set_mode_auto(priv); 458 lgs8gxx_set_mode_auto(priv);
288 /* Guard Interval */ 459 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
289 lgs8gxx_write_reg(priv, 0x03, 00); 460 lgs8gxx_write_reg(priv, 0x67, 0xAA);
461 lgs8gxx_write_reg(priv, 0x6E, 0x3F);
462 } else {
463 /* Guard Interval */
464 lgs8gxx_write_reg(priv, 0x03, 00);
465 }
290 466
291 for (i = 0; i < 2; i++) { 467 for (i = 0; i < 2; i++) {
292 for (j = 0; j < 2; j++) { 468 for (j = 0; j < 2; j++) {
293 tmp_gi = GI_945; 469 tmp_gi = GI_945;
294 err = lgs8gxx_autolock_gi(priv, GI_945, &locked); 470 err = lgs8gxx_autolock_gi(priv, GI_945, j, &locked);
295 if (err) 471 if (err)
296 goto out; 472 goto out;
297 if (locked) 473 if (locked)
@@ -299,14 +475,14 @@ static int lgs8gxx_auto_detect(struct lgs8gxx_state *priv,
299 } 475 }
300 for (j = 0; j < 2; j++) { 476 for (j = 0; j < 2; j++) {
301 tmp_gi = GI_420; 477 tmp_gi = GI_420;
302 err = lgs8gxx_autolock_gi(priv, GI_420, &locked); 478 err = lgs8gxx_autolock_gi(priv, GI_420, j, &locked);
303 if (err) 479 if (err)
304 goto out; 480 goto out;
305 if (locked) 481 if (locked)
306 goto locked; 482 goto locked;
307 } 483 }
308 tmp_gi = GI_595; 484 tmp_gi = GI_595;
309 err = lgs8gxx_autolock_gi(priv, GI_595, &locked); 485 err = lgs8gxx_autolock_gi(priv, GI_595, 1, &locked);
310 if (err) 486 if (err)
311 goto out; 487 goto out;
312 if (locked) 488 if (locked)
@@ -317,8 +493,13 @@ locked:
317 if ((err == 0) && (locked == 1)) { 493 if ((err == 0) && (locked == 1)) {
318 u8 t; 494 u8 t;
319 495
320 lgs8gxx_read_reg(priv, 0xA2, &t); 496 if (priv->config->prod != LGS8GXX_PROD_LGS8G75) {
321 *detected_param = t; 497 lgs8gxx_read_reg(priv, 0xA2, &t);
498 *detected_param = t;
499 } else {
500 lgs8gxx_read_reg(priv, 0x1F, &t);
501 *detected_param = t & 0x3F;
502 }
322 503
323 if (tmp_gi == GI_945) 504 if (tmp_gi == GI_945)
324 dprintk("GI 945 locked\n"); 505 dprintk("GI 945 locked\n");
@@ -345,18 +526,28 @@ static void lgs8gxx_auto_lock(struct lgs8gxx_state *priv)
345 526
346 if (err != 0) { 527 if (err != 0) {
347 dprintk("lgs8gxx_auto_detect failed\n"); 528 dprintk("lgs8gxx_auto_detect failed\n");
348 } 529 } else
530 dprintk("detected param = 0x%02X\n", detected_param);
349 531
350 /* Apply detected parameters */ 532 /* Apply detected parameters */
351 if (priv->config->prod == LGS8GXX_PROD_LGS8913) { 533 if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
352 u8 inter_leave_len = detected_param & TIM_MASK ; 534 u8 inter_leave_len = detected_param & TIM_MASK ;
353 inter_leave_len = (inter_leave_len == TIM_LONG) ? 0x60 : 0x40; 535 /* Fix 8913 time interleaver detection bug */
536 inter_leave_len = (inter_leave_len == TIM_MIDDLE) ? 0x60 : 0x40;
354 detected_param &= CF_MASK | SC_MASK | LGS_FEC_MASK; 537 detected_param &= CF_MASK | SC_MASK | LGS_FEC_MASK;
355 detected_param |= inter_leave_len; 538 detected_param |= inter_leave_len;
356 } 539 }
357 lgs8gxx_write_reg(priv, 0x7D, detected_param); 540 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
358 if (priv->config->prod == LGS8GXX_PROD_LGS8913) 541 u8 t;
359 lgs8gxx_write_reg(priv, 0xC0, detected_param); 542 lgs8gxx_read_reg(priv, 0x19, &t);
543 t &= 0x81;
544 t |= detected_param << 1;
545 lgs8gxx_write_reg(priv, 0x19, t);
546 } else {
547 lgs8gxx_write_reg(priv, 0x7D, detected_param);
548 if (priv->config->prod == LGS8GXX_PROD_LGS8913)
549 lgs8gxx_write_reg(priv, 0xC0, detected_param);
550 }
360 /* lgs8gxx_soft_reset(priv); */ 551 /* lgs8gxx_soft_reset(priv); */
361 552
362 /* Enter manual mode */ 553 /* Enter manual mode */
@@ -378,9 +569,10 @@ static int lgs8gxx_set_mpeg_mode(struct lgs8gxx_state *priv,
378 u8 serial, u8 clk_pol, u8 clk_gated) 569 u8 serial, u8 clk_pol, u8 clk_gated)
379{ 570{
380 int ret = 0; 571 int ret = 0;
381 u8 t; 572 u8 t, reg_addr;
382 573
383 ret = lgs8gxx_read_reg(priv, 0xC2, &t); 574 reg_addr = (priv->config->prod == LGS8GXX_PROD_LGS8G75) ? 0x30 : 0xC2;
575 ret = lgs8gxx_read_reg(priv, reg_addr, &t);
384 if (ret != 0) 576 if (ret != 0)
385 return ret; 577 return ret;
386 578
@@ -389,13 +581,29 @@ static int lgs8gxx_set_mpeg_mode(struct lgs8gxx_state *priv,
389 t |= clk_pol ? TS_CLK_INVERTED : TS_CLK_NORMAL; 581 t |= clk_pol ? TS_CLK_INVERTED : TS_CLK_NORMAL;
390 t |= clk_gated ? TS_CLK_GATED : TS_CLK_FREERUN; 582 t |= clk_gated ? TS_CLK_GATED : TS_CLK_FREERUN;
391 583
392 ret = lgs8gxx_write_reg(priv, 0xC2, t); 584 ret = lgs8gxx_write_reg(priv, reg_addr, t);
393 if (ret != 0) 585 if (ret != 0)
394 return ret; 586 return ret;
395 587
396 return 0; 588 return 0;
397} 589}
398 590
591/* A/D input peak-to-peak voltage range */
592static int lgs8g75_set_adc_vpp(struct lgs8gxx_state *priv,
593 u8 sel)
594{
595 u8 r26 = 0x73, r27 = 0x90;
596
597 if (priv->config->prod != LGS8GXX_PROD_LGS8G75)
598 return 0;
599
600 r26 |= (sel & 0x01) << 7;
601 r27 |= (sel & 0x02) >> 1;
602 lgs8gxx_write_reg(priv, 0x26, r26);
603 lgs8gxx_write_reg(priv, 0x27, r27);
604
605 return 0;
606}
399 607
400/* LGS8913 demod frontend functions */ 608/* LGS8913 demod frontend functions */
401 609
@@ -417,6 +625,34 @@ static int lgs8913_init(struct lgs8gxx_state *priv)
417 return 0; 625 return 0;
418} 626}
419 627
628static int lgs8g75_init_data(struct lgs8gxx_state *priv)
629{
630 const u8 *p = lgs8g75_initdat;
631 int i;
632
633 lgs8gxx_write_reg(priv, 0xC6, 0x40);
634
635 lgs8gxx_write_reg(priv, 0x3D, 0x04);
636 lgs8gxx_write_reg(priv, 0x39, 0x00);
637
638 lgs8gxx_write_reg(priv, 0x3A, 0x00);
639 lgs8gxx_write_reg(priv, 0x38, 0x00);
640 lgs8gxx_write_reg(priv, 0x3B, 0x00);
641 lgs8gxx_write_reg(priv, 0x38, 0x00);
642
643 for (i = 0; i < sizeof(lgs8g75_initdat); i++) {
644 lgs8gxx_write_reg(priv, 0x38, 0x00);
645 lgs8gxx_write_reg(priv, 0x3A, (u8)(i&0xff));
646 lgs8gxx_write_reg(priv, 0x3B, (u8)(i>>8));
647 lgs8gxx_write_reg(priv, 0x3C, *p);
648 p++;
649 }
650
651 lgs8gxx_write_reg(priv, 0x38, 0x00);
652
653 return 0;
654}
655
420static int lgs8gxx_init(struct dvb_frontend *fe) 656static int lgs8gxx_init(struct dvb_frontend *fe)
421{ 657{
422 struct lgs8gxx_state *priv = 658 struct lgs8gxx_state *priv =
@@ -429,6 +665,9 @@ static int lgs8gxx_init(struct dvb_frontend *fe)
429 lgs8gxx_read_reg(priv, 0, &data); 665 lgs8gxx_read_reg(priv, 0, &data);
430 dprintk("reg 0 = 0x%02X\n", data); 666 dprintk("reg 0 = 0x%02X\n", data);
431 667
668 if (config->prod == LGS8GXX_PROD_LGS8G75)
669 lgs8g75_set_adc_vpp(priv, config->adc_vpp);
670
432 /* Setup MPEG output format */ 671 /* Setup MPEG output format */
433 err = lgs8gxx_set_mpeg_mode(priv, config->serial_ts, 672 err = lgs8gxx_set_mpeg_mode(priv, config->serial_ts,
434 config->ts_clk_pol, 673 config->ts_clk_pol,
@@ -439,8 +678,7 @@ static int lgs8gxx_init(struct dvb_frontend *fe)
439 if (config->prod == LGS8GXX_PROD_LGS8913) 678 if (config->prod == LGS8GXX_PROD_LGS8913)
440 lgs8913_init(priv); 679 lgs8913_init(priv);
441 lgs8gxx_set_if_freq(priv, priv->config->if_freq); 680 lgs8gxx_set_if_freq(priv, priv->config->if_freq);
442 if (config->prod != LGS8GXX_PROD_LGS8913) 681 lgs8gxx_set_ad_mode(priv);
443 lgs8gxx_set_ad_mode(priv);
444 682
445 return 0; 683 return 0;
446} 684}
@@ -489,9 +727,6 @@ static int lgs8gxx_set_fe(struct dvb_frontend *fe,
489static int lgs8gxx_get_fe(struct dvb_frontend *fe, 727static int lgs8gxx_get_fe(struct dvb_frontend *fe,
490 struct dvb_frontend_parameters *fe_params) 728 struct dvb_frontend_parameters *fe_params)
491{ 729{
492 struct lgs8gxx_state *priv = fe->demodulator_priv;
493 u8 t;
494
495 dprintk("%s\n", __func__); 730 dprintk("%s\n", __func__);
496 731
497 /* TODO: get real readings from device */ 732 /* TODO: get real readings from device */
@@ -501,29 +736,10 @@ static int lgs8gxx_get_fe(struct dvb_frontend *fe,
501 /* bandwidth */ 736 /* bandwidth */
502 fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; 737 fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
503 738
504
505 lgs8gxx_read_reg(priv, 0x7D, &t);
506 fe_params->u.ofdm.code_rate_HP = FEC_AUTO; 739 fe_params->u.ofdm.code_rate_HP = FEC_AUTO;
507 fe_params->u.ofdm.code_rate_LP = FEC_AUTO; 740 fe_params->u.ofdm.code_rate_LP = FEC_AUTO;
508 741
509 /* constellation */ 742 fe_params->u.ofdm.constellation = QAM_AUTO;
510 switch (t & SC_MASK) {
511 case SC_QAM64:
512 fe_params->u.ofdm.constellation = QAM_64;
513 break;
514 case SC_QAM32:
515 fe_params->u.ofdm.constellation = QAM_32;
516 break;
517 case SC_QAM16:
518 fe_params->u.ofdm.constellation = QAM_16;
519 break;
520 case SC_QAM4:
521 case SC_QAM4NR:
522 fe_params->u.ofdm.constellation = QPSK;
523 break;
524 default:
525 fe_params->u.ofdm.constellation = QAM_64;
526 }
527 743
528 /* transmission mode */ 744 /* transmission mode */
529 fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO; 745 fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
@@ -552,9 +768,19 @@ static int lgs8gxx_read_status(struct dvb_frontend *fe, fe_status_t *fe_status)
552{ 768{
553 struct lgs8gxx_state *priv = fe->demodulator_priv; 769 struct lgs8gxx_state *priv = fe->demodulator_priv;
554 s8 ret; 770 s8 ret;
555 u8 t; 771 u8 t, locked = 0;
556 772
557 dprintk("%s\n", __func__); 773 dprintk("%s\n", __func__);
774 *fe_status = 0;
775
776 lgs8gxx_get_afc_phase(priv);
777 lgs8gxx_is_locked(priv, &locked);
778 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
779 if (locked)
780 *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
781 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
782 return 0;
783 }
558 784
559 ret = lgs8gxx_read_reg(priv, 0x4B, &t); 785 ret = lgs8gxx_read_reg(priv, 0x4B, &t);
560 if (ret != 0) 786 if (ret != 0)
@@ -658,12 +884,33 @@ static int lgs8913_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal)
658 return 0; 884 return 0;
659} 885}
660 886
887static int lgs8g75_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal)
888{
889 u8 t;
890 s16 v = 0;
891
892 dprintk("%s\n", __func__);
893
894 lgs8gxx_read_reg(priv, 0xB1, &t);
895 v |= t;
896 v <<= 8;
897 lgs8gxx_read_reg(priv, 0xB0, &t);
898 v |= t;
899
900 *signal = v;
901 dprintk("%s: signal=0x%02X\n", __func__, *signal);
902
903 return 0;
904}
905
661static int lgs8gxx_read_signal_strength(struct dvb_frontend *fe, u16 *signal) 906static int lgs8gxx_read_signal_strength(struct dvb_frontend *fe, u16 *signal)
662{ 907{
663 struct lgs8gxx_state *priv = fe->demodulator_priv; 908 struct lgs8gxx_state *priv = fe->demodulator_priv;
664 909
665 if (priv->config->prod == LGS8GXX_PROD_LGS8913) 910 if (priv->config->prod == LGS8GXX_PROD_LGS8913)
666 return lgs8913_read_signal_strength(priv, signal); 911 return lgs8913_read_signal_strength(priv, signal);
912 else if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
913 return lgs8g75_read_signal_strength(priv, signal);
667 else 914 else
668 return lgs8gxx_read_signal_agc(priv, signal); 915 return lgs8gxx_read_signal_agc(priv, signal);
669} 916}
@@ -674,7 +921,10 @@ static int lgs8gxx_read_snr(struct dvb_frontend *fe, u16 *snr)
674 u8 t; 921 u8 t;
675 *snr = 0; 922 *snr = 0;
676 923
677 lgs8gxx_read_reg(priv, 0x95, &t); 924 if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
925 lgs8gxx_read_reg(priv, 0x34, &t);
926 else
927 lgs8gxx_read_reg(priv, 0x95, &t);
678 dprintk("AVG Noise=0x%02X\n", t); 928 dprintk("AVG Noise=0x%02X\n", t);
679 *snr = 256 - t; 929 *snr = 256 - t;
680 *snr <<= 8; 930 *snr <<= 8;
@@ -690,31 +940,68 @@ static int lgs8gxx_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
690 return 0; 940 return 0;
691} 941}
692 942
943static void packet_counter_start(struct lgs8gxx_state *priv)
944{
945 u8 orig, t;
946
947 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
948 lgs8gxx_read_reg(priv, 0x30, &orig);
949 orig &= 0xE7;
950 t = orig | 0x10;
951 lgs8gxx_write_reg(priv, 0x30, t);
952 t = orig | 0x18;
953 lgs8gxx_write_reg(priv, 0x30, t);
954 t = orig | 0x10;
955 lgs8gxx_write_reg(priv, 0x30, t);
956 } else {
957 lgs8gxx_write_reg(priv, 0xC6, 0x01);
958 lgs8gxx_write_reg(priv, 0xC6, 0x41);
959 lgs8gxx_write_reg(priv, 0xC6, 0x01);
960 }
961}
962
963static void packet_counter_stop(struct lgs8gxx_state *priv)
964{
965 u8 t;
966
967 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
968 lgs8gxx_read_reg(priv, 0x30, &t);
969 t &= 0xE7;
970 lgs8gxx_write_reg(priv, 0x30, t);
971 } else {
972 lgs8gxx_write_reg(priv, 0xC6, 0x81);
973 }
974}
975
693static int lgs8gxx_read_ber(struct dvb_frontend *fe, u32 *ber) 976static int lgs8gxx_read_ber(struct dvb_frontend *fe, u32 *ber)
694{ 977{
695 struct lgs8gxx_state *priv = fe->demodulator_priv; 978 struct lgs8gxx_state *priv = fe->demodulator_priv;
696 u8 r0, r1, r2, r3; 979 u8 reg_err, reg_total, t;
697 u32 total_cnt, err_cnt; 980 u32 total_cnt = 0, err_cnt = 0;
981 int i;
698 982
699 dprintk("%s\n", __func__); 983 dprintk("%s\n", __func__);
700 984
701 lgs8gxx_write_reg(priv, 0xc6, 0x01); 985 packet_counter_start(priv);
702 lgs8gxx_write_reg(priv, 0xc6, 0x41);
703 lgs8gxx_write_reg(priv, 0xc6, 0x01);
704
705 msleep(200); 986 msleep(200);
987 packet_counter_stop(priv);
988
989 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
990 reg_total = 0x28; reg_err = 0x2C;
991 } else {
992 reg_total = 0xD0; reg_err = 0xD4;
993 }
706 994
707 lgs8gxx_write_reg(priv, 0xc6, 0x81); 995 for (i = 0; i < 4; i++) {
708 lgs8gxx_read_reg(priv, 0xd0, &r0); 996 total_cnt <<= 8;
709 lgs8gxx_read_reg(priv, 0xd1, &r1); 997 lgs8gxx_read_reg(priv, reg_total+3-i, &t);
710 lgs8gxx_read_reg(priv, 0xd2, &r2); 998 total_cnt |= t;
711 lgs8gxx_read_reg(priv, 0xd3, &r3); 999 }
712 total_cnt = (r3 << 24) | (r2 << 16) | (r1 << 8) | (r0); 1000 for (i = 0; i < 4; i++) {
713 lgs8gxx_read_reg(priv, 0xd4, &r0); 1001 err_cnt <<= 8;
714 lgs8gxx_read_reg(priv, 0xd5, &r1); 1002 lgs8gxx_read_reg(priv, reg_err+3-i, &t);
715 lgs8gxx_read_reg(priv, 0xd6, &r2); 1003 err_cnt |= t;
716 lgs8gxx_read_reg(priv, 0xd7, &r3); 1004 }
717 err_cnt = (r3 << 24) | (r2 << 16) | (r1 << 8) | (r0);
718 dprintk("error=%d total=%d\n", err_cnt, total_cnt); 1005 dprintk("error=%d total=%d\n", err_cnt, total_cnt);
719 1006
720 if (total_cnt == 0) 1007 if (total_cnt == 0)
@@ -801,6 +1088,9 @@ struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config,
801 sizeof(struct dvb_frontend_ops)); 1088 sizeof(struct dvb_frontend_ops));
802 priv->frontend.demodulator_priv = priv; 1089 priv->frontend.demodulator_priv = priv;
803 1090
1091 if (config->prod == LGS8GXX_PROD_LGS8G75)
1092 lgs8g75_init_data(priv);
1093
804 return &priv->frontend; 1094 return &priv->frontend;
805 1095
806error_out: 1096error_out:
diff --git a/drivers/media/dvb/frontends/lgs8gxx.h b/drivers/media/dvb/frontends/lgs8gxx.h
index 321d366a8307..33c3c5e162fa 100644
--- a/drivers/media/dvb/frontends/lgs8gxx.h
+++ b/drivers/media/dvb/frontends/lgs8gxx.h
@@ -1,9 +1,9 @@
1/* 1/*
2 * Support for Legend Silicon DMB-TH demodulator 2 * Support for Legend Silicon GB20600 (a.k.a DMB-TH) demodulator
3 * LGS8913, LGS8GL5 3 * LGS8913, LGS8GL5, LGS8G75
4 * experimental support LGS8G42, LGS8G52 4 * experimental support LGS8G42, LGS8G52
5 * 5 *
6 * Copyright (C) 2007,2008 David T.L. Wong <davidtlwong@gmail.com> 6 * Copyright (C) 2007-2009 David T.L. Wong <davidtlwong@gmail.com>
7 * Copyright (C) 2008 Sirius International (Hong Kong) Limited 7 * Copyright (C) 2008 Sirius International (Hong Kong) Limited
8 * Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5) 8 * Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
9 * 9 *
@@ -34,6 +34,7 @@
34#define LGS8GXX_PROD_LGS8G42 3 34#define LGS8GXX_PROD_LGS8G42 3
35#define LGS8GXX_PROD_LGS8G52 4 35#define LGS8GXX_PROD_LGS8G52 4
36#define LGS8GXX_PROD_LGS8G54 5 36#define LGS8GXX_PROD_LGS8G54 5
37#define LGS8GXX_PROD_LGS8G75 6
37 38
38struct lgs8gxx_config { 39struct lgs8gxx_config {
39 40
@@ -70,6 +71,10 @@ struct lgs8gxx_config {
70 /*IF use Negative center frequency*/ 71 /*IF use Negative center frequency*/
71 u8 if_neg_center; 72 u8 if_neg_center;
72 73
74 /*8G75 internal ADC input range selection*/
75 /*0: 0.8Vpp, 1: 1.0Vpp, 2: 1.6Vpp, 3: 2.0Vpp*/
76 u8 adc_vpp;
77
73 /* slave address and configuration of the tuner */ 78 /* slave address and configuration of the tuner */
74 u8 tuner_address; 79 u8 tuner_address;
75}; 80};
diff --git a/drivers/media/dvb/frontends/lgs8gxx_priv.h b/drivers/media/dvb/frontends/lgs8gxx_priv.h
index 9776d30686dc..8ef376f1414d 100644
--- a/drivers/media/dvb/frontends/lgs8gxx_priv.h
+++ b/drivers/media/dvb/frontends/lgs8gxx_priv.h
@@ -1,9 +1,9 @@
1/* 1/*
2 * Support for Legend Silicon DMB-TH demodulator 2 * Support for Legend Silicon GB20600 (a.k.a DMB-TH) demodulator
3 * LGS8913, LGS8GL5 3 * LGS8913, LGS8GL5, LGS8G75
4 * experimental support LGS8G42, LGS8G52 4 * experimental support LGS8G42, LGS8G52
5 * 5 *
6 * Copyright (C) 2007,2008 David T.L. Wong <davidtlwong@gmail.com> 6 * Copyright (C) 2007-2009 David T.L. Wong <davidtlwong@gmail.com>
7 * Copyright (C) 2008 Sirius International (Hong Kong) Limited 7 * Copyright (C) 2008 Sirius International (Hong Kong) Limited
8 * Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5) 8 * Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
9 * 9 *
@@ -38,7 +38,7 @@ struct lgs8gxx_state {
38#define SC_QAM64 0x10 /* 64QAM modulation */ 38#define SC_QAM64 0x10 /* 64QAM modulation */
39#define SC_QAM32 0x0C /* 32QAM modulation */ 39#define SC_QAM32 0x0C /* 32QAM modulation */
40#define SC_QAM16 0x08 /* 16QAM modulation */ 40#define SC_QAM16 0x08 /* 16QAM modulation */
41#define SC_QAM4NR 0x04 /* 4QAM modulation */ 41#define SC_QAM4NR 0x04 /* 4QAM-NR modulation */
42#define SC_QAM4 0x00 /* 4QAM modulation */ 42#define SC_QAM4 0x00 /* 4QAM modulation */
43 43
44#define LGS_FEC_MASK 0x03 /* FEC Rate Mask */ 44#define LGS_FEC_MASK 0x03 /* FEC Rate Mask */
@@ -47,8 +47,8 @@ struct lgs8gxx_state {
47#define LGS_FEC_0_8 0x02 /* FEC Rate 0.8 */ 47#define LGS_FEC_0_8 0x02 /* FEC Rate 0.8 */
48 48
49#define TIM_MASK 0x20 /* Time Interleave Length Mask */ 49#define TIM_MASK 0x20 /* Time Interleave Length Mask */
50#define TIM_LONG 0x00 /* Time Interleave Length = 720 */ 50#define TIM_LONG 0x20 /* Time Interleave Length = 720 */
51#define TIM_MIDDLE 0x20 /* Time Interleave Length = 240 */ 51#define TIM_MIDDLE 0x00 /* Time Interleave Length = 240 */
52 52
53#define CF_MASK 0x80 /* Control Frame Mask */ 53#define CF_MASK 0x80 /* Control Frame Mask */
54#define CF_EN 0x80 /* Control Frame On */ 54#define CF_EN 0x80 /* Control Frame On */
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
index f69daaac78c9..472907d43460 100644
--- a/drivers/media/dvb/frontends/mt312.c
+++ b/drivers/media/dvb/frontends/mt312.c
@@ -85,7 +85,7 @@ static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg,
85 int i; 85 int i;
86 dprintk("R(%d):", reg & 0x7f); 86 dprintk("R(%d):", reg & 0x7f);
87 for (i = 0; i < count; i++) 87 for (i = 0; i < count; i++)
88 printk(" %02x", buf[i]); 88 printk(KERN_CONT " %02x", buf[i]);
89 printk("\n"); 89 printk("\n");
90 } 90 }
91 91
@@ -103,7 +103,7 @@ static int mt312_write(struct mt312_state *state, const enum mt312_reg_addr reg,
103 int i; 103 int i;
104 dprintk("W(%d):", reg & 0x7f); 104 dprintk("W(%d):", reg & 0x7f);
105 for (i = 0; i < count; i++) 105 for (i = 0; i < count; i++)
106 printk(" %02x", src[i]); 106 printk(KERN_CONT " %02x", src[i]);
107 printk("\n"); 107 printk("\n");
108 } 108 }
109 109
@@ -744,7 +744,8 @@ static struct dvb_frontend_ops mt312_ops = {
744 .type = FE_QPSK, 744 .type = FE_QPSK,
745 .frequency_min = 950000, 745 .frequency_min = 950000,
746 .frequency_max = 2150000, 746 .frequency_max = 2150000,
747 .frequency_stepsize = (MT312_PLL_CLK / 1000) / 128, /* FIXME: adjust freq to real used xtal */ 747 /* FIXME: adjust freq to real used xtal */
748 .frequency_stepsize = (MT312_PLL_CLK / 1000) / 128,
748 .symbol_rate_min = MT312_SYS_CLK / 128, /* FIXME as above */ 749 .symbol_rate_min = MT312_SYS_CLK / 128, /* FIXME as above */
749 .symbol_rate_max = MT312_SYS_CLK / 2, 750 .symbol_rate_max = MT312_SYS_CLK / 2,
750 .caps = 751 .caps =
diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb/frontends/stb6100.c
index 1ed5a7db4c5e..60ee18a94f43 100644
--- a/drivers/media/dvb/frontends/stb6100.c
+++ b/drivers/media/dvb/frontends/stb6100.c
@@ -367,7 +367,9 @@ static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
367 /* N(I) = floor(f(VCO) / (f(XTAL) * (PSD2 ? 2 : 1))) */ 367 /* N(I) = floor(f(VCO) / (f(XTAL) * (PSD2 ? 2 : 1))) */
368 nint = fvco / (state->reference << psd2); 368 nint = fvco / (state->reference << psd2);
369 /* N(F) = round(f(VCO) / f(XTAL) * (PSD2 ? 2 : 1) - N(I)) * 2 ^ 9 */ 369 /* N(F) = round(f(VCO) / f(XTAL) * (PSD2 ? 2 : 1) - N(I)) * 2 ^ 9 */
370 nfrac = (((fvco - (nint * state->reference << psd2)) << (9 - psd2)) + state->reference / 2) / state->reference; 370 nfrac = DIV_ROUND_CLOSEST((fvco - (nint * state->reference << psd2))
371 << (9 - psd2),
372 state->reference);
371 dprintk(verbose, FE_DEBUG, 1, 373 dprintk(verbose, FE_DEBUG, 1,
372 "frequency = %u, srate = %u, g = %u, odiv = %u, psd2 = %u, fxtal = %u, osm = %u, fvco = %u, N(I) = %u, N(F) = %u", 374 "frequency = %u, srate = %u, g = %u, odiv = %u, psd2 = %u, fxtal = %u, osm = %u, fvco = %u, N(I) = %u, N(F) = %u",
373 frequency, srate, (unsigned int)g, (unsigned int)odiv, 375 frequency, srate, (unsigned int)g, (unsigned int)odiv,
diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c
index 1da045fbb4ef..3bde3324a032 100644
--- a/drivers/media/dvb/frontends/stv0900_core.c
+++ b/drivers/media/dvb/frontends/stv0900_core.c
@@ -230,8 +230,8 @@ enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *i_params)
230 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5c); 230 stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5c);
231 stv0900_write_reg(i_params, R0900_P1_TNRCFG, 0x6c); 231 stv0900_write_reg(i_params, R0900_P1_TNRCFG, 0x6c);
232 stv0900_write_reg(i_params, R0900_P2_TNRCFG, 0x6f); 232 stv0900_write_reg(i_params, R0900_P2_TNRCFG, 0x6f);
233 stv0900_write_reg(i_params, R0900_P1_I2CRPT, 0x24); 233 stv0900_write_reg(i_params, R0900_P1_I2CRPT, 0x20);
234 stv0900_write_reg(i_params, R0900_P2_I2CRPT, 0x24); 234 stv0900_write_reg(i_params, R0900_P2_I2CRPT, 0x20);
235 stv0900_write_reg(i_params, R0900_NCOARSE, 0x13); 235 stv0900_write_reg(i_params, R0900_NCOARSE, 0x13);
236 msleep(3); 236 msleep(3);
237 stv0900_write_reg(i_params, R0900_I2CCFG, 0x08); 237 stv0900_write_reg(i_params, R0900_I2CCFG, 0x08);
@@ -370,8 +370,8 @@ static int stv0900_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
370 u32 fi2c; 370 u32 fi2c;
371 371
372 dmd_reg(fi2c, F0900_P1_I2CT_ON, F0900_P2_I2CT_ON); 372 dmd_reg(fi2c, F0900_P1_I2CT_ON, F0900_P2_I2CT_ON);
373 if (enable) 373
374 stv0900_write_bits(i_params, fi2c, 1); 374 stv0900_write_bits(i_params, fi2c, enable);
375 375
376 return 0; 376 return 0;
377} 377}
diff --git a/drivers/media/dvb/frontends/stv0900_sw.c b/drivers/media/dvb/frontends/stv0900_sw.c
index a5a31536cbcb..962fde1437ce 100644
--- a/drivers/media/dvb/frontends/stv0900_sw.c
+++ b/drivers/media/dvb/frontends/stv0900_sw.c
@@ -1721,7 +1721,7 @@ static enum fe_stv0900_signal_type stv0900_dvbs1_acq_workaround(struct dvb_front
1721 1721
1722 s32 srate, demod_timeout, 1722 s32 srate, demod_timeout,
1723 fec_timeout, freq1, freq0; 1723 fec_timeout, freq1, freq0;
1724 enum fe_stv0900_signal_type signal_type = STV0900_NODATA;; 1724 enum fe_stv0900_signal_type signal_type = STV0900_NODATA;
1725 1725
1726 switch (demod) { 1726 switch (demod) {
1727 case STV0900_DEMOD_1: 1727 case STV0900_DEMOD_1:
diff --git a/drivers/media/dvb/frontends/stv6110.c b/drivers/media/dvb/frontends/stv6110.c
index 70efac869d28..dcf1b21ea974 100644
--- a/drivers/media/dvb/frontends/stv6110.c
+++ b/drivers/media/dvb/frontends/stv6110.c
@@ -36,6 +36,7 @@ struct stv6110_priv {
36 struct i2c_adapter *i2c; 36 struct i2c_adapter *i2c;
37 37
38 u32 mclk; 38 u32 mclk;
39 u8 clk_div;
39 u8 regs[8]; 40 u8 regs[8];
40}; 41};
41 42
@@ -100,35 +101,25 @@ static int stv6110_read_regs(struct dvb_frontend *fe, u8 regs[],
100 struct stv6110_priv *priv = fe->tuner_priv; 101 struct stv6110_priv *priv = fe->tuner_priv;
101 int rc; 102 int rc;
102 u8 reg[] = { start }; 103 u8 reg[] = { start };
103 struct i2c_msg msg_wr = { 104 struct i2c_msg msg[] = {
104 .addr = priv->i2c_address, 105 {
105 .flags = 0, 106 .addr = priv->i2c_address,
106 .buf = reg, 107 .flags = 0,
107 .len = 1, 108 .buf = reg,
109 .len = 1,
110 }, {
111 .addr = priv->i2c_address,
112 .flags = I2C_M_RD,
113 .buf = regs,
114 .len = len,
115 },
108 }; 116 };
109 117
110 struct i2c_msg msg_rd = {
111 .addr = priv->i2c_address,
112 .flags = I2C_M_RD,
113 .buf = regs,
114 .len = len,
115 };
116 /* write subaddr */
117 if (fe->ops.i2c_gate_ctrl) 118 if (fe->ops.i2c_gate_ctrl)
118 fe->ops.i2c_gate_ctrl(fe, 1); 119 fe->ops.i2c_gate_ctrl(fe, 1);
119 120
120 rc = i2c_transfer(priv->i2c, &msg_wr, 1); 121 rc = i2c_transfer(priv->i2c, msg, 2);
121 if (rc != 1) 122 if (rc != 2)
122 dprintk("%s: i2c error\n", __func__);
123
124 if (fe->ops.i2c_gate_ctrl)
125 fe->ops.i2c_gate_ctrl(fe, 0);
126 /* read registers */
127 if (fe->ops.i2c_gate_ctrl)
128 fe->ops.i2c_gate_ctrl(fe, 1);
129
130 rc = i2c_transfer(priv->i2c, &msg_rd, 1);
131 if (rc != 1)
132 dprintk("%s: i2c error\n", __func__); 123 dprintk("%s: i2c error\n", __func__);
133 124
134 if (fe->ops.i2c_gate_ctrl) 125 if (fe->ops.i2c_gate_ctrl)
@@ -221,6 +212,10 @@ static int stv6110_init(struct dvb_frontend *fe)
221 priv->regs[RSTV6110_CTRL1] |= 212 priv->regs[RSTV6110_CTRL1] |=
222 ((((priv->mclk / 1000000) - 16) & 0x1f) << 3); 213 ((((priv->mclk / 1000000) - 16) & 0x1f) << 3);
223 214
215 /* divisor value for the output clock */
216 priv->regs[RSTV6110_CTRL2] &= ~0xc0;
217 priv->regs[RSTV6110_CTRL2] |= (priv->clk_div << 6);
218
224 stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1], RSTV6110_CTRL1, 8); 219 stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1], RSTV6110_CTRL1, 8);
225 msleep(1); 220 msleep(1);
226 stv6110_set_bandwidth(fe, 72000000); 221 stv6110_set_bandwidth(fe, 72000000);
@@ -418,6 +413,10 @@ struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
418 }; 413 };
419 int ret; 414 int ret;
420 415
416 /* divisor value for the output clock */
417 reg0[2] &= ~0xc0;
418 reg0[2] |= (config->clk_div << 6);
419
421 if (fe->ops.i2c_gate_ctrl) 420 if (fe->ops.i2c_gate_ctrl)
422 fe->ops.i2c_gate_ctrl(fe, 1); 421 fe->ops.i2c_gate_ctrl(fe, 1);
423 422
@@ -436,6 +435,7 @@ struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
436 priv->i2c_address = config->i2c_address; 435 priv->i2c_address = config->i2c_address;
437 priv->i2c = i2c; 436 priv->i2c = i2c;
438 priv->mclk = config->mclk; 437 priv->mclk = config->mclk;
438 priv->clk_div = config->clk_div;
439 439
440 memcpy(&priv->regs, &reg0[1], 8); 440 memcpy(&priv->regs, &reg0[1], 8);
441 441
diff --git a/drivers/media/dvb/frontends/stv6110.h b/drivers/media/dvb/frontends/stv6110.h
index 1c0314d6aa55..9db2402410f6 100644
--- a/drivers/media/dvb/frontends/stv6110.h
+++ b/drivers/media/dvb/frontends/stv6110.h
@@ -41,7 +41,7 @@
41struct stv6110_config { 41struct stv6110_config {
42 u8 i2c_address; 42 u8 i2c_address;
43 u32 mclk; 43 u32 mclk;
44 int iq_wiring; 44 u8 clk_div; /* divisor value for the output clock */
45}; 45};
46 46
47#if defined(CONFIG_DVB_STV6110) || (defined(CONFIG_DVB_STV6110_MODULE) \ 47#if defined(CONFIG_DVB_STV6110) || (defined(CONFIG_DVB_STV6110_MODULE) \
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c
index f5d7b3277a2f..6c1dbf9288d8 100644
--- a/drivers/media/dvb/frontends/tda10021.c
+++ b/drivers/media/dvb/frontends/tda10021.c
@@ -176,7 +176,7 @@ static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate
176 tmp = ((symbolrate << 4) % FIN) << 8; 176 tmp = ((symbolrate << 4) % FIN) << 8;
177 ratio = (ratio << 8) + tmp / FIN; 177 ratio = (ratio << 8) + tmp / FIN;
178 tmp = (tmp % FIN) << 8; 178 tmp = (tmp % FIN) << 8;
179 ratio = (ratio << 8) + (tmp + FIN/2) / FIN; 179 ratio = (ratio << 8) + DIV_ROUND_CLOSEST(tmp, FIN);
180 180
181 BDR = ratio; 181 BDR = ratio;
182 BDRI = (((XIN << 5) / symbolrate) + 1) / 2; 182 BDRI = (((XIN << 5) / symbolrate) + 1) / 2;
diff --git a/drivers/media/dvb/frontends/tda8261.c b/drivers/media/dvb/frontends/tda8261.c
index b6d177799104..320c3c36d8b2 100644
--- a/drivers/media/dvb/frontends/tda8261.c
+++ b/drivers/media/dvb/frontends/tda8261.c
@@ -136,9 +136,9 @@ static int tda8261_set_state(struct dvb_frontend *fe,
136 136
137 if (frequency < 1450000) 137 if (frequency < 1450000)
138 buf[3] = 0x00; 138 buf[3] = 0x00;
139 if (frequency < 2000000) 139 else if (frequency < 2000000)
140 buf[3] = 0x40; 140 buf[3] = 0x40;
141 if (frequency < 2150000) 141 else if (frequency < 2150000)
142 buf[3] = 0x80; 142 buf[3] = 0x80;
143 143
144 /* Set params */ 144 /* Set params */
diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c
index 6e78e4865515..550a07a8a997 100644
--- a/drivers/media/dvb/frontends/ves1820.c
+++ b/drivers/media/dvb/frontends/ves1820.c
@@ -165,7 +165,7 @@ static int ves1820_set_symbolrate(struct ves1820_state *state, u32 symbolrate)
165 tmp = ((symbolrate << 4) % fin) << 8; 165 tmp = ((symbolrate << 4) % fin) << 8;
166 ratio = (ratio << 8) + tmp / fin; 166 ratio = (ratio << 8) + tmp / fin;
167 tmp = (tmp % fin) << 8; 167 tmp = (tmp % fin) << 8;
168 ratio = (ratio << 8) + (tmp + fin / 2) / fin; 168 ratio = (ratio << 8) + DIV_ROUND_CLOSEST(tmp, fin);
169 169
170 BDR = ratio; 170 BDR = ratio;
171 BDRI = (((state->config->xin << 5) / symbolrate) + 1) / 2; 171 BDRI = (((state->config->xin << 5) / symbolrate) + 1) / 2;
diff --git a/drivers/media/dvb/frontends/zl10036.c b/drivers/media/dvb/frontends/zl10036.c
index e22a0b381dc4..4e814ff22b23 100644
--- a/drivers/media/dvb/frontends/zl10036.c
+++ b/drivers/media/dvb/frontends/zl10036.c
@@ -29,7 +29,7 @@
29 29
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/dvb/frontend.h> 31#include <linux/dvb/frontend.h>
32#include <asm/types.h> 32#include <linux/types.h>
33 33
34#include "zl10036.h" 34#include "zl10036.h"
35 35
diff --git a/drivers/media/dvb/frontends/zl10039.c b/drivers/media/dvb/frontends/zl10039.c
new file mode 100644
index 000000000000..11b29cb883e6
--- /dev/null
+++ b/drivers/media/dvb/frontends/zl10039.c
@@ -0,0 +1,308 @@
1/*
2 * Driver for Zarlink ZL10039 DVB-S tuner
3 *
4 * Copyright 2007 Jan D. Louw <jd.louw@mweb.co.za>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/string.h>
25#include <linux/slab.h>
26#include <linux/dvb/frontend.h>
27
28#include "dvb_frontend.h"
29#include "zl10039.h"
30
31static int debug;
32
33#define dprintk(args...) \
34 do { \
35 if (debug) \
36 printk(KERN_DEBUG args); \
37 } while (0)
38
39enum zl10039_model_id {
40 ID_ZL10039 = 1
41};
42
43struct zl10039_state {
44 struct i2c_adapter *i2c;
45 u8 i2c_addr;
46 u8 id;
47};
48
49enum zl10039_reg_addr {
50 PLL0 = 0,
51 PLL1,
52 PLL2,
53 PLL3,
54 RFFE,
55 BASE0,
56 BASE1,
57 BASE2,
58 LO0,
59 LO1,
60 LO2,
61 LO3,
62 LO4,
63 LO5,
64 LO6,
65 GENERAL
66};
67
68static int zl10039_read(const struct zl10039_state *state,
69 const enum zl10039_reg_addr reg, u8 *buf,
70 const size_t count)
71{
72 u8 regbuf[] = { reg };
73 struct i2c_msg msg[] = {
74 {/* Write register address */
75 .addr = state->i2c_addr,
76 .flags = 0,
77 .buf = regbuf,
78 .len = 1,
79 }, {/* Read count bytes */
80 .addr = state->i2c_addr,
81 .flags = I2C_M_RD,
82 .buf = buf,
83 .len = count,
84 },
85 };
86
87 dprintk("%s\n", __func__);
88
89 if (i2c_transfer(state->i2c, msg, 2) != 2) {
90 dprintk("%s: i2c read error\n", __func__);
91 return -EREMOTEIO;
92 }
93
94 return 0; /* Success */
95}
96
97static int zl10039_write(struct zl10039_state *state,
98 const enum zl10039_reg_addr reg, const u8 *src,
99 const size_t count)
100{
101 u8 buf[count + 1];
102 struct i2c_msg msg = {
103 .addr = state->i2c_addr,
104 .flags = 0,
105 .buf = buf,
106 .len = count + 1,
107 };
108
109 dprintk("%s\n", __func__);
110 /* Write register address and data in one go */
111 buf[0] = reg;
112 memcpy(&buf[1], src, count);
113 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
114 dprintk("%s: i2c write error\n", __func__);
115 return -EREMOTEIO;
116 }
117
118 return 0; /* Success */
119}
120
121static inline int zl10039_readreg(struct zl10039_state *state,
122 const enum zl10039_reg_addr reg, u8 *val)
123{
124 return zl10039_read(state, reg, val, 1);
125}
126
127static inline int zl10039_writereg(struct zl10039_state *state,
128 const enum zl10039_reg_addr reg,
129 const u8 val)
130{
131 return zl10039_write(state, reg, &val, 1);
132}
133
134static int zl10039_init(struct dvb_frontend *fe)
135{
136 struct zl10039_state *state = fe->tuner_priv;
137 int ret;
138
139 dprintk("%s\n", __func__);
140 if (fe->ops.i2c_gate_ctrl)
141 fe->ops.i2c_gate_ctrl(fe, 1);
142 /* Reset logic */
143 ret = zl10039_writereg(state, GENERAL, 0x40);
144 if (ret < 0) {
145 dprintk("Note: i2c write error normal when resetting the "
146 "tuner\n");
147 }
148 /* Wake up */
149 ret = zl10039_writereg(state, GENERAL, 0x01);
150 if (ret < 0) {
151 dprintk("Tuner power up failed\n");
152 return ret;
153 }
154 if (fe->ops.i2c_gate_ctrl)
155 fe->ops.i2c_gate_ctrl(fe, 0);
156
157 return 0;
158}
159
160static int zl10039_sleep(struct dvb_frontend *fe)
161{
162 struct zl10039_state *state = fe->tuner_priv;
163 int ret;
164
165 dprintk("%s\n", __func__);
166 if (fe->ops.i2c_gate_ctrl)
167 fe->ops.i2c_gate_ctrl(fe, 1);
168 ret = zl10039_writereg(state, GENERAL, 0x80);
169 if (ret < 0) {
170 dprintk("Tuner sleep failed\n");
171 return ret;
172 }
173 if (fe->ops.i2c_gate_ctrl)
174 fe->ops.i2c_gate_ctrl(fe, 0);
175
176 return 0;
177}
178
179static int zl10039_set_params(struct dvb_frontend *fe,
180 struct dvb_frontend_parameters *params)
181{
182 struct zl10039_state *state = fe->tuner_priv;
183 u8 buf[6];
184 u8 bf;
185 u32 fbw;
186 u32 div;
187 int ret;
188
189 dprintk("%s\n", __func__);
190 dprintk("Set frequency = %d, symbol rate = %d\n",
191 params->frequency, params->u.qpsk.symbol_rate);
192
193 /* Assumed 10.111 MHz crystal oscillator */
194 /* Cancelled num/den 80 to prevent overflow */
195 div = (params->frequency * 1000) / 126387;
196 fbw = (params->u.qpsk.symbol_rate * 27) / 32000;
197 /* Cancelled num/den 10 to prevent overflow */
198 bf = ((fbw * 5088) / 1011100) - 1;
199
200 /*PLL divider*/
201 buf[0] = (div >> 8) & 0x7f;
202 buf[1] = (div >> 0) & 0xff;
203 /*Reference divider*/
204 /* Select reference ratio of 80 */
205 buf[2] = 0x1D;
206 /*PLL test modes*/
207 buf[3] = 0x40;
208 /*RF Control register*/
209 buf[4] = 0x6E; /* Bypass enable */
210 /*Baseband filter cutoff */
211 buf[5] = bf;
212
213 /* Open i2c gate */
214 if (fe->ops.i2c_gate_ctrl)
215 fe->ops.i2c_gate_ctrl(fe, 1);
216 /* BR = 10, Enable filter adjustment */
217 ret = zl10039_writereg(state, BASE1, 0x0A);
218 if (ret < 0)
219 goto error;
220 /* Write new config values */
221 ret = zl10039_write(state, PLL0, buf, sizeof(buf));
222 if (ret < 0)
223 goto error;
224 /* BR = 10, Disable filter adjustment */
225 ret = zl10039_writereg(state, BASE1, 0x6A);
226 if (ret < 0)
227 goto error;
228
229 /* Close i2c gate */
230 if (fe->ops.i2c_gate_ctrl)
231 fe->ops.i2c_gate_ctrl(fe, 0);
232 return 0;
233error:
234 dprintk("Error setting tuner\n");
235 return ret;
236}
237
238static int zl10039_release(struct dvb_frontend *fe)
239{
240 struct zl10039_state *state = fe->tuner_priv;
241
242 dprintk("%s\n", __func__);
243 kfree(state);
244 fe->tuner_priv = NULL;
245 return 0;
246}
247
248static struct dvb_tuner_ops zl10039_ops = {
249 .release = zl10039_release,
250 .init = zl10039_init,
251 .sleep = zl10039_sleep,
252 .set_params = zl10039_set_params,
253};
254
255struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
256 u8 i2c_addr, struct i2c_adapter *i2c)
257{
258 struct zl10039_state *state = NULL;
259
260 dprintk("%s\n", __func__);
261 state = kmalloc(sizeof(struct zl10039_state), GFP_KERNEL);
262 if (state == NULL)
263 goto error;
264
265 state->i2c = i2c;
266 state->i2c_addr = i2c_addr;
267
268 /* Open i2c gate */
269 if (fe->ops.i2c_gate_ctrl)
270 fe->ops.i2c_gate_ctrl(fe, 1);
271 /* check if this is a valid tuner */
272 if (zl10039_readreg(state, GENERAL, &state->id) < 0) {
273 /* Close i2c gate */
274 if (fe->ops.i2c_gate_ctrl)
275 fe->ops.i2c_gate_ctrl(fe, 0);
276 goto error;
277 }
278 /* Close i2c gate */
279 if (fe->ops.i2c_gate_ctrl)
280 fe->ops.i2c_gate_ctrl(fe, 0);
281
282 state->id = state->id & 0x0f;
283 switch (state->id) {
284 case ID_ZL10039:
285 strcpy(fe->ops.tuner_ops.info.name,
286 "Zarlink ZL10039 DVB-S tuner");
287 break;
288 default:
289 dprintk("Chip ID=%x does not match a known type\n", state->id);
290 break;
291 goto error;
292 }
293
294 memcpy(&fe->ops.tuner_ops, &zl10039_ops, sizeof(struct dvb_tuner_ops));
295 fe->tuner_priv = state;
296 dprintk("Tuner attached @ i2c address 0x%02x\n", i2c_addr);
297 return fe;
298error:
299 kfree(state);
300 return NULL;
301}
302EXPORT_SYMBOL(zl10039_attach);
303
304module_param(debug, int, 0644);
305MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
306MODULE_DESCRIPTION("Zarlink ZL10039 DVB-S tuner driver");
307MODULE_AUTHOR("Jan D. Louw <jd.louw@mweb.co.za>");
308MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/zl10039.h b/drivers/media/dvb/frontends/zl10039.h
new file mode 100644
index 000000000000..5eee7ea162a1
--- /dev/null
+++ b/drivers/media/dvb/frontends/zl10039.h
@@ -0,0 +1,40 @@
1/*
2 Driver for Zarlink ZL10039 DVB-S tuner
3
4 Copyright (C) 2007 Jan D. Louw <jd.louw@mweb.co.za>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#ifndef ZL10039_H
23#define ZL10039_H
24
25#if defined(CONFIG_DVB_ZL10039) || (defined(CONFIG_DVB_ZL10039_MODULE) \
26 && defined(MODULE))
27struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
28 u8 i2c_addr,
29 struct i2c_adapter *i2c);
30#else
31static inline struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
32 u8 i2c_addr,
33 struct i2c_adapter *i2c)
34{
35 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
36 return NULL;
37}
38#endif /* CONFIG_DVB_ZL10039 */
39
40#endif /* ZL10039_H */
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c
index 66f5c1fb3074..8c612719adfc 100644
--- a/drivers/media/dvb/frontends/zl10353.c
+++ b/drivers/media/dvb/frontends/zl10353.c
@@ -38,6 +38,8 @@ struct zl10353_state {
38 struct zl10353_config config; 38 struct zl10353_config config;
39 39
40 enum fe_bandwidth bandwidth; 40 enum fe_bandwidth bandwidth;
41 u32 ucblocks;
42 u32 frequency;
41}; 43};
42 44
43static int debug; 45static int debug;
@@ -199,6 +201,8 @@ static int zl10353_set_parameters(struct dvb_frontend *fe,
199 u16 tps = 0; 201 u16 tps = 0;
200 struct dvb_ofdm_parameters *op = &param->u.ofdm; 202 struct dvb_ofdm_parameters *op = &param->u.ofdm;
201 203
204 state->frequency = param->frequency;
205
202 zl10353_single_write(fe, RESET, 0x80); 206 zl10353_single_write(fe, RESET, 0x80);
203 udelay(200); 207 udelay(200);
204 zl10353_single_write(fe, 0xEA, 0x01); 208 zl10353_single_write(fe, 0xEA, 0x01);
@@ -464,7 +468,7 @@ static int zl10353_get_parameters(struct dvb_frontend *fe,
464 break; 468 break;
465 } 469 }
466 470
467 param->frequency = 0; 471 param->frequency = state->frequency;
468 op->bandwidth = state->bandwidth; 472 op->bandwidth = state->bandwidth;
469 param->inversion = INVERSION_AUTO; 473 param->inversion = INVERSION_AUTO;
470 474
@@ -542,9 +546,13 @@ static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr)
542static int zl10353_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 546static int zl10353_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
543{ 547{
544 struct zl10353_state *state = fe->demodulator_priv; 548 struct zl10353_state *state = fe->demodulator_priv;
549 u32 ubl = 0;
550
551 ubl = zl10353_read_register(state, RS_UBC_1) << 8 |
552 zl10353_read_register(state, RS_UBC_0);
545 553
546 *ucblocks = zl10353_read_register(state, RS_UBC_1) << 8 | 554 state->ucblocks += ubl;
547 zl10353_read_register(state, RS_UBC_0); 555 *ucblocks = state->ucblocks;
548 556
549 return 0; 557 return 0;
550} 558}
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
index 598eaf8acc6e..80d14a065bad 100644
--- a/drivers/media/dvb/pluto2/pluto2.c
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -439,7 +439,7 @@ static inline u32 divide(u32 numerator, u32 denominator)
439 if (denominator == 0) 439 if (denominator == 0)
440 return ~0; 440 return ~0;
441 441
442 return (numerator + denominator / 2) / denominator; 442 return DIV_ROUND_CLOSEST(numerator, denominator);
443} 443}
444 444
445/* LG Innotek TDTE-E001P (Infineon TUA6034) */ 445/* LG Innotek TDTE-E001P (Infineon TUA6034) */
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index ce64c6214cc4..8986d967d2f4 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -490,7 +490,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
490 if (!av7110->analog_tuner_flags) 490 if (!av7110->analog_tuner_flags)
491 return 0; 491 return 0;
492 492
493 if (input < 0 || input >= 4) 493 if (input >= 4)
494 return -EINVAL; 494 return -EINVAL;
495 495
496 av7110->current_input = input; 496 av7110->current_input = input;
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 371a71616810..b5c681372b6c 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -225,7 +225,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
225 case 0x1012: 225 case 0x1012:
226 /* The hauppauge keymap is a superset of these remotes */ 226 /* The hauppauge keymap is a superset of these remotes */
227 ir_input_init(input_dev, &budget_ci->ir.state, 227 ir_input_init(input_dev, &budget_ci->ir.state,
228 IR_TYPE_RC5, ir_codes_hauppauge_new); 228 IR_TYPE_RC5, &ir_codes_hauppauge_new_table);
229 229
230 if (rc5_device < 0) 230 if (rc5_device < 0)
231 budget_ci->ir.rc5_device = 0x1f; 231 budget_ci->ir.rc5_device = 0x1f;
@@ -237,7 +237,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
237 case 0x101a: 237 case 0x101a:
238 /* for the Technotrend 1500 bundled remote */ 238 /* for the Technotrend 1500 bundled remote */
239 ir_input_init(input_dev, &budget_ci->ir.state, 239 ir_input_init(input_dev, &budget_ci->ir.state,
240 IR_TYPE_RC5, ir_codes_tt_1500); 240 IR_TYPE_RC5, &ir_codes_tt_1500_table);
241 241
242 if (rc5_device < 0) 242 if (rc5_device < 0)
243 budget_ci->ir.rc5_device = IR_DEVICE_ANY; 243 budget_ci->ir.rc5_device = IR_DEVICE_ANY;
@@ -247,7 +247,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
247 default: 247 default:
248 /* unknown remote */ 248 /* unknown remote */
249 ir_input_init(input_dev, &budget_ci->ir.state, 249 ir_input_init(input_dev, &budget_ci->ir.state,
250 IR_TYPE_RC5, ir_codes_budget_ci_old); 250 IR_TYPE_RC5, &ir_codes_budget_ci_old_table);
251 251
252 if (rc5_device < 0) 252 if (rc5_device < 0)
253 budget_ci->ir.rc5_device = IR_DEVICE_ANY; 253 budget_ci->ir.rc5_device = IR_DEVICE_ANY;
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 3315cac875e5..25a36ad60c5e 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -288,16 +288,6 @@ config RADIO_TYPHOON
288 To compile this driver as a module, choose M here: the 288 To compile this driver as a module, choose M here: the
289 module will be called radio-typhoon. 289 module will be called radio-typhoon.
290 290
291config RADIO_TYPHOON_PROC_FS
292 bool "Support for /proc/radio-typhoon"
293 depends on PROC_FS && RADIO_TYPHOON
294 help
295 Say Y here if you want the typhoon radio card driver to write
296 status information (frequency, volume, muted, mute frequency,
297 base address) to /proc/radio-typhoon. The file can be viewed with
298 your favorite pager (i.e. use "more /proc/radio-typhoon" or "less
299 /proc/radio-typhoon" or simply "cat /proc/radio-typhoon").
300
301config RADIO_TYPHOON_PORT 291config RADIO_TYPHOON_PORT
302 hex "Typhoon I/O port (0x316 or 0x336)" 292 hex "Typhoon I/O port (0x316 or 0x336)"
303 depends on RADIO_TYPHOON=y 293 depends on RADIO_TYPHOON=y
@@ -339,6 +329,29 @@ config RADIO_ZOLTRIX_PORT
339 help 329 help
340 Enter the I/O port of your Zoltrix radio card. 330 Enter the I/O port of your Zoltrix radio card.
341 331
332config I2C_SI4713
333 tristate "I2C driver for Silicon Labs Si4713 device"
334 depends on I2C && VIDEO_V4L2
335 ---help---
336 Say Y here if you want support to Si4713 I2C device.
337 This device driver supports only i2c bus.
338
339 To compile this driver as a module, choose M here: the
340 module will be called si4713.
341
342config RADIO_SI4713
343 tristate "Silicon Labs Si4713 FM Radio Transmitter support"
344 depends on I2C && VIDEO_V4L2
345 select I2C_SI4713
346 ---help---
347 Say Y here if you want support to Si4713 FM Radio Transmitter.
348 This device can transmit audio through FM. It can transmit
349 EDS and EBDS signals as well. This module is the v4l2 radio
350 interface for the i2c driver of this device.
351
352 To compile this driver as a module, choose M here: the
353 module will be called radio-si4713.
354
342config USB_DSBR 355config USB_DSBR
343 tristate "D-Link/GemTek USB FM radio support" 356 tristate "D-Link/GemTek USB FM radio support"
344 depends on USB && VIDEO_V4L2 357 depends on USB && VIDEO_V4L2
@@ -351,29 +364,11 @@ config USB_DSBR
351 To compile this driver as a module, choose M here: the 364 To compile this driver as a module, choose M here: the
352 module will be called dsbr100. 365 module will be called dsbr100.
353 366
354config USB_SI470X 367config RADIO_SI470X
355 tristate "Silicon Labs Si470x FM Radio Receiver support" 368 bool "Silicon Labs Si470x FM Radio Receiver support"
356 depends on USB && VIDEO_V4L2 369 depends on VIDEO_V4L2
357 ---help---
358 This is a driver for USB devices with the Silicon Labs SI470x
359 chip. Currently these devices are known to work:
360 - 10c4:818a: Silicon Labs USB FM Radio Reference Design
361 - 06e1:a155: ADS/Tech FM Radio Receiver (formerly Instant FM Music)
362 - 1b80:d700: KWorld USB FM Radio SnapMusic Mobile 700 (FM700)
363
364 Sound is provided by the ALSA USB Audio/MIDI driver. Therefore
365 if you don't want to use the device solely for RDS receiving,
366 it is recommended to also select SND_USB_AUDIO.
367
368 Please have a look at the documentation, especially on how
369 to redirect the audio stream from the radio to your sound device:
370 Documentation/video4linux/si470x.txt
371
372 Say Y here if you want to connect this type of radio to your
373 computer's USB port.
374 370
375 To compile this driver as a module, choose M here: the 371source "drivers/media/radio/si470x/Kconfig"
376 module will be called radio-si470x.
377 372
378config USB_MR800 373config USB_MR800
379 tristate "AverMedia MR 800 USB FM radio support" 374 tristate "AverMedia MR 800 USB FM radio support"
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 0f2b35b3e560..2a1be3bf4f7c 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -15,9 +15,11 @@ obj-$(CONFIG_RADIO_ZOLTRIX) += radio-zoltrix.o
15obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o 15obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o
16obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o 16obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o
17obj-$(CONFIG_RADIO_TRUST) += radio-trust.o 17obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
18obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o
19obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o
18obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o 20obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o
19obj-$(CONFIG_USB_DSBR) += dsbr100.o 21obj-$(CONFIG_USB_DSBR) += dsbr100.o
20obj-$(CONFIG_USB_SI470X) += radio-si470x.o 22obj-$(CONFIG_RADIO_SI470X) += si470x/
21obj-$(CONFIG_USB_MR800) += radio-mr800.o 23obj-$(CONFIG_USB_MR800) += radio-mr800.o
22obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o 24obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o
23 25
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index d30fc0ce82c0..8b1440136c45 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -359,7 +359,8 @@ static int vidioc_querycap(struct file *file, void *priv,
359 strlcpy(v->card, "ADS Cadet", sizeof(v->card)); 359 strlcpy(v->card, "ADS Cadet", sizeof(v->card));
360 strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); 360 strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
361 v->version = CADET_VERSION; 361 v->version = CADET_VERSION;
362 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_READWRITE; 362 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO |
363 V4L2_CAP_READWRITE | V4L2_CAP_RDS_CAPTURE;
363 return 0; 364 return 0;
364} 365}
365 366
@@ -372,7 +373,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
372 switch (v->index) { 373 switch (v->index) {
373 case 0: 374 case 0:
374 strlcpy(v->name, "FM", sizeof(v->name)); 375 strlcpy(v->name, "FM", sizeof(v->name));
375 v->capability = V4L2_TUNER_CAP_STEREO; 376 v->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS;
376 v->rangelow = 1400; /* 87.5 MHz */ 377 v->rangelow = 1400; /* 87.5 MHz */
377 v->rangehigh = 1728; /* 108.0 MHz */ 378 v->rangehigh = 1728; /* 108.0 MHz */
378 v->rxsubchans = cadet_getstereo(dev); 379 v->rxsubchans = cadet_getstereo(dev);
@@ -386,6 +387,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
386 default: 387 default:
387 break; 388 break;
388 } 389 }
390 v->rxsubchans |= V4L2_TUNER_SUB_RDS;
389 break; 391 break;
390 case 1: 392 case 1:
391 strlcpy(v->name, "AM", sizeof(v->name)); 393 strlcpy(v->name, "AM", sizeof(v->name));
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
deleted file mode 100644
index e85f318b4d2b..000000000000
--- a/drivers/media/radio/radio-si470x.c
+++ /dev/null
@@ -1,1863 +0,0 @@
1/*
2 * drivers/media/radio/radio-si470x.c
3 *
4 * Driver for USB radios for the Silicon Labs Si470x FM Radio Receivers:
5 * - Silicon Labs USB FM Radio Reference Design
6 * - ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF)
7 * - KWorld USB FM Radio SnapMusic Mobile 700 (FM700)
8 * - Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear)
9 *
10 * Copyright (c) 2009 Tobias Lorenz <tobias.lorenz@gmx.net>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27
28/*
29 * History:
30 * 2008-01-12 Tobias Lorenz <tobias.lorenz@gmx.net>
31 * Version 1.0.0
32 * - First working version
33 * 2008-01-13 Tobias Lorenz <tobias.lorenz@gmx.net>
34 * Version 1.0.1
35 * - Improved error handling, every function now returns errno
36 * - Improved multi user access (start/mute/stop)
37 * - Channel doesn't get lost anymore after start/mute/stop
38 * - RDS support added (polling mode via interrupt EP 1)
39 * - marked default module parameters with *value*
40 * - switched from bit structs to bit masks
41 * - header file cleaned and integrated
42 * 2008-01-14 Tobias Lorenz <tobias.lorenz@gmx.net>
43 * Version 1.0.2
44 * - hex values are now lower case
45 * - commented USB ID for ADS/Tech moved on todo list
46 * - blacklisted si470x in hid-quirks.c
47 * - rds buffer handling functions integrated into *_work, *_read
48 * - rds_command in si470x_poll exchanged against simple retval
49 * - check for firmware version 15
50 * - code order and prototypes still remain the same
51 * - spacing and bottom of band codes remain the same
52 * 2008-01-16 Tobias Lorenz <tobias.lorenz@gmx.net>
53 * Version 1.0.3
54 * - code reordered to avoid function prototypes
55 * - switch/case defaults are now more user-friendly
56 * - unified comment style
57 * - applied all checkpatch.pl v1.12 suggestions
58 * except the warning about the too long lines with bit comments
59 * - renamed FMRADIO to RADIO to cut line length (checkpatch.pl)
60 * 2008-01-22 Tobias Lorenz <tobias.lorenz@gmx.net>
61 * Version 1.0.4
62 * - avoid poss. locking when doing copy_to_user which may sleep
63 * - RDS is automatically activated on read now
64 * - code cleaned of unnecessary rds_commands
65 * - USB Vendor/Product ID for ADS/Tech FM Radio Receiver verified
66 * (thanks to Guillaume RAMOUSSE)
67 * 2008-01-27 Tobias Lorenz <tobias.lorenz@gmx.net>
68 * Version 1.0.5
69 * - number of seek_retries changed to tune_timeout
70 * - fixed problem with incomplete tune operations by own buffers
71 * - optimization of variables and printf types
72 * - improved error logging
73 * 2008-01-31 Tobias Lorenz <tobias.lorenz@gmx.net>
74 * Oliver Neukum <oliver@neukum.org>
75 * Version 1.0.6
76 * - fixed coverity checker warnings in *_usb_driver_disconnect
77 * - probe()/open() race by correct ordering in probe()
78 * - DMA coherency rules by separate allocation of all buffers
79 * - use of endianness macros
80 * - abuse of spinlock, replaced by mutex
81 * - racy handling of timer in disconnect,
82 * replaced by delayed_work
83 * - racy interruptible_sleep_on(),
84 * replaced with wait_event_interruptible()
85 * - handle signals in read()
86 * 2008-02-08 Tobias Lorenz <tobias.lorenz@gmx.net>
87 * Oliver Neukum <oliver@neukum.org>
88 * Version 1.0.7
89 * - usb autosuspend support
90 * - unplugging fixed
91 * 2008-05-07 Tobias Lorenz <tobias.lorenz@gmx.net>
92 * Version 1.0.8
93 * - hardware frequency seek support
94 * - afc indication
95 * - more safety checks, let si470x_get_freq return errno
96 * - vidioc behavior corrected according to v4l2 spec
97 * 2008-10-20 Alexey Klimov <klimov.linux@gmail.com>
98 * - add support for KWorld USB FM Radio FM700
99 * - blacklisted KWorld radio in hid-core.c and hid-ids.h
100 * 2008-12-03 Mark Lord <mlord@pobox.com>
101 * - add support for DealExtreme USB Radio
102 * 2009-01-31 Bob Ross <pigiron@gmx.com>
103 * - correction of stereo detection/setting
104 * - correction of signal strength indicator scaling
105 * 2009-01-31 Rick Bronson <rick@efn.org>
106 * Tobias Lorenz <tobias.lorenz@gmx.net>
107 * - add LED status output
108 * - get HW/SW version from scratchpad
109 *
110 * ToDo:
111 * - add firmware download/update support
112 * - RDS support: interrupt mode, instead of polling
113 */
114
115
116/* driver definitions */
117#define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>"
118#define DRIVER_NAME "radio-si470x"
119#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 9)
120#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
121#define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers"
122#define DRIVER_VERSION "1.0.9"
123
124
125/* kernel includes */
126#include <linux/kernel.h>
127#include <linux/module.h>
128#include <linux/init.h>
129#include <linux/slab.h>
130#include <linux/smp_lock.h>
131#include <linux/input.h>
132#include <linux/usb.h>
133#include <linux/hid.h>
134#include <linux/version.h>
135#include <linux/videodev2.h>
136#include <linux/mutex.h>
137#include <media/v4l2-common.h>
138#include <media/v4l2-ioctl.h>
139#include <media/rds.h>
140#include <asm/unaligned.h>
141
142
143/* USB Device ID List */
144static struct usb_device_id si470x_usb_driver_id_table[] = {
145 /* Silicon Labs USB FM Radio Reference Design */
146 { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) },
147 /* ADS/Tech FM Radio Receiver (formerly Instant FM Music) */
148 { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) },
149 /* KWorld USB FM Radio SnapMusic Mobile 700 (FM700) */
150 { USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) },
151 /* Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear) */
152 { USB_DEVICE_AND_INTERFACE_INFO(0x10c5, 0x819a, USB_CLASS_HID, 0, 0) },
153 /* Terminating entry */
154 { }
155};
156MODULE_DEVICE_TABLE(usb, si470x_usb_driver_id_table);
157
158
159
160/**************************************************************************
161 * Module Parameters
162 **************************************************************************/
163
164/* Radio Nr */
165static int radio_nr = -1;
166module_param(radio_nr, int, 0444);
167MODULE_PARM_DESC(radio_nr, "Radio Nr");
168
169/* Spacing (kHz) */
170/* 0: 200 kHz (USA, Australia) */
171/* 1: 100 kHz (Europe, Japan) */
172/* 2: 50 kHz */
173static unsigned short space = 2;
174module_param(space, ushort, 0444);
175MODULE_PARM_DESC(space, "Spacing: 0=200kHz 1=100kHz *2=50kHz*");
176
177/* Bottom of Band (MHz) */
178/* 0: 87.5 - 108 MHz (USA, Europe)*/
179/* 1: 76 - 108 MHz (Japan wide band) */
180/* 2: 76 - 90 MHz (Japan) */
181static unsigned short band = 1;
182module_param(band, ushort, 0444);
183MODULE_PARM_DESC(band, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz");
184
185/* De-emphasis */
186/* 0: 75 us (USA) */
187/* 1: 50 us (Europe, Australia, Japan) */
188static unsigned short de = 1;
189module_param(de, ushort, 0444);
190MODULE_PARM_DESC(de, "De-emphasis: 0=75us *1=50us*");
191
192/* USB timeout */
193static unsigned int usb_timeout = 500;
194module_param(usb_timeout, uint, 0644);
195MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*");
196
197/* Tune timeout */
198static unsigned int tune_timeout = 3000;
199module_param(tune_timeout, uint, 0644);
200MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*");
201
202/* Seek timeout */
203static unsigned int seek_timeout = 5000;
204module_param(seek_timeout, uint, 0644);
205MODULE_PARM_DESC(seek_timeout, "Seek timeout: *5000*");
206
207/* RDS buffer blocks */
208static unsigned int rds_buf = 100;
209module_param(rds_buf, uint, 0444);
210MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
211
212/* RDS maximum block errors */
213static unsigned short max_rds_errors = 1;
214/* 0 means 0 errors requiring correction */
215/* 1 means 1-2 errors requiring correction (used by original USBRadio.exe) */
216/* 2 means 3-5 errors requiring correction */
217/* 3 means 6+ errors or errors in checkword, correction not possible */
218module_param(max_rds_errors, ushort, 0644);
219MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
220
221/* RDS poll frequency */
222static unsigned int rds_poll_time = 40;
223/* 40 is used by the original USBRadio.exe */
224/* 50 is used by radio-cadet */
225/* 75 should be okay */
226/* 80 is the usual RDS receive interval */
227module_param(rds_poll_time, uint, 0644);
228MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
229
230
231
232/**************************************************************************
233 * Register Definitions
234 **************************************************************************/
235#define RADIO_REGISTER_SIZE 2 /* 16 register bit width */
236#define RADIO_REGISTER_NUM 16 /* DEVICEID ... RDSD */
237#define RDS_REGISTER_NUM 6 /* STATUSRSSI ... RDSD */
238
239#define DEVICEID 0 /* Device ID */
240#define DEVICEID_PN 0xf000 /* bits 15..12: Part Number */
241#define DEVICEID_MFGID 0x0fff /* bits 11..00: Manufacturer ID */
242
243#define CHIPID 1 /* Chip ID */
244#define CHIPID_REV 0xfc00 /* bits 15..10: Chip Version */
245#define CHIPID_DEV 0x0200 /* bits 09..09: Device */
246#define CHIPID_FIRMWARE 0x01ff /* bits 08..00: Firmware Version */
247
248#define POWERCFG 2 /* Power Configuration */
249#define POWERCFG_DSMUTE 0x8000 /* bits 15..15: Softmute Disable */
250#define POWERCFG_DMUTE 0x4000 /* bits 14..14: Mute Disable */
251#define POWERCFG_MONO 0x2000 /* bits 13..13: Mono Select */
252#define POWERCFG_RDSM 0x0800 /* bits 11..11: RDS Mode (Si4701 only) */
253#define POWERCFG_SKMODE 0x0400 /* bits 10..10: Seek Mode */
254#define POWERCFG_SEEKUP 0x0200 /* bits 09..09: Seek Direction */
255#define POWERCFG_SEEK 0x0100 /* bits 08..08: Seek */
256#define POWERCFG_DISABLE 0x0040 /* bits 06..06: Powerup Disable */
257#define POWERCFG_ENABLE 0x0001 /* bits 00..00: Powerup Enable */
258
259#define CHANNEL 3 /* Channel */
260#define CHANNEL_TUNE 0x8000 /* bits 15..15: Tune */
261#define CHANNEL_CHAN 0x03ff /* bits 09..00: Channel Select */
262
263#define SYSCONFIG1 4 /* System Configuration 1 */
264#define SYSCONFIG1_RDSIEN 0x8000 /* bits 15..15: RDS Interrupt Enable (Si4701 only) */
265#define SYSCONFIG1_STCIEN 0x4000 /* bits 14..14: Seek/Tune Complete Interrupt Enable */
266#define SYSCONFIG1_RDS 0x1000 /* bits 12..12: RDS Enable (Si4701 only) */
267#define SYSCONFIG1_DE 0x0800 /* bits 11..11: De-emphasis (0=75us 1=50us) */
268#define SYSCONFIG1_AGCD 0x0400 /* bits 10..10: AGC Disable */
269#define SYSCONFIG1_BLNDADJ 0x00c0 /* bits 07..06: Stereo/Mono Blend Level Adjustment */
270#define SYSCONFIG1_GPIO3 0x0030 /* bits 05..04: General Purpose I/O 3 */
271#define SYSCONFIG1_GPIO2 0x000c /* bits 03..02: General Purpose I/O 2 */
272#define SYSCONFIG1_GPIO1 0x0003 /* bits 01..00: General Purpose I/O 1 */
273
274#define SYSCONFIG2 5 /* System Configuration 2 */
275#define SYSCONFIG2_SEEKTH 0xff00 /* bits 15..08: RSSI Seek Threshold */
276#define SYSCONFIG2_BAND 0x0080 /* bits 07..06: Band Select */
277#define SYSCONFIG2_SPACE 0x0030 /* bits 05..04: Channel Spacing */
278#define SYSCONFIG2_VOLUME 0x000f /* bits 03..00: Volume */
279
280#define SYSCONFIG3 6 /* System Configuration 3 */
281#define SYSCONFIG3_SMUTER 0xc000 /* bits 15..14: Softmute Attack/Recover Rate */
282#define SYSCONFIG3_SMUTEA 0x3000 /* bits 13..12: Softmute Attenuation */
283#define SYSCONFIG3_SKSNR 0x00f0 /* bits 07..04: Seek SNR Threshold */
284#define SYSCONFIG3_SKCNT 0x000f /* bits 03..00: Seek FM Impulse Detection Threshold */
285
286#define TEST1 7 /* Test 1 */
287#define TEST1_AHIZEN 0x4000 /* bits 14..14: Audio High-Z Enable */
288
289#define TEST2 8 /* Test 2 */
290/* TEST2 only contains reserved bits */
291
292#define BOOTCONFIG 9 /* Boot Configuration */
293/* BOOTCONFIG only contains reserved bits */
294
295#define STATUSRSSI 10 /* Status RSSI */
296#define STATUSRSSI_RDSR 0x8000 /* bits 15..15: RDS Ready (Si4701 only) */
297#define STATUSRSSI_STC 0x4000 /* bits 14..14: Seek/Tune Complete */
298#define STATUSRSSI_SF 0x2000 /* bits 13..13: Seek Fail/Band Limit */
299#define STATUSRSSI_AFCRL 0x1000 /* bits 12..12: AFC Rail */
300#define STATUSRSSI_RDSS 0x0800 /* bits 11..11: RDS Synchronized (Si4701 only) */
301#define STATUSRSSI_BLERA 0x0600 /* bits 10..09: RDS Block A Errors (Si4701 only) */
302#define STATUSRSSI_ST 0x0100 /* bits 08..08: Stereo Indicator */
303#define STATUSRSSI_RSSI 0x00ff /* bits 07..00: RSSI (Received Signal Strength Indicator) */
304
305#define READCHAN 11 /* Read Channel */
306#define READCHAN_BLERB 0xc000 /* bits 15..14: RDS Block D Errors (Si4701 only) */
307#define READCHAN_BLERC 0x3000 /* bits 13..12: RDS Block C Errors (Si4701 only) */
308#define READCHAN_BLERD 0x0c00 /* bits 11..10: RDS Block B Errors (Si4701 only) */
309#define READCHAN_READCHAN 0x03ff /* bits 09..00: Read Channel */
310
311#define RDSA 12 /* RDSA */
312#define RDSA_RDSA 0xffff /* bits 15..00: RDS Block A Data (Si4701 only) */
313
314#define RDSB 13 /* RDSB */
315#define RDSB_RDSB 0xffff /* bits 15..00: RDS Block B Data (Si4701 only) */
316
317#define RDSC 14 /* RDSC */
318#define RDSC_RDSC 0xffff /* bits 15..00: RDS Block C Data (Si4701 only) */
319
320#define RDSD 15 /* RDSD */
321#define RDSD_RDSD 0xffff /* bits 15..00: RDS Block D Data (Si4701 only) */
322
323
324
325/**************************************************************************
326 * USB HID Reports
327 **************************************************************************/
328
329/* Reports 1-16 give direct read/write access to the 16 Si470x registers */
330/* with the (REPORT_ID - 1) corresponding to the register address across USB */
331/* endpoint 0 using GET_REPORT and SET_REPORT */
332#define REGISTER_REPORT_SIZE (RADIO_REGISTER_SIZE + 1)
333#define REGISTER_REPORT(reg) ((reg) + 1)
334
335/* Report 17 gives direct read/write access to the entire Si470x register */
336/* map across endpoint 0 using GET_REPORT and SET_REPORT */
337#define ENTIRE_REPORT_SIZE (RADIO_REGISTER_NUM * RADIO_REGISTER_SIZE + 1)
338#define ENTIRE_REPORT 17
339
340/* Report 18 is used to send the lowest 6 Si470x registers up the HID */
341/* interrupt endpoint 1 to Windows every 20 milliseconds for status */
342#define RDS_REPORT_SIZE (RDS_REGISTER_NUM * RADIO_REGISTER_SIZE + 1)
343#define RDS_REPORT 18
344
345/* Report 19: LED state */
346#define LED_REPORT_SIZE 3
347#define LED_REPORT 19
348
349/* Report 19: stream */
350#define STREAM_REPORT_SIZE 3
351#define STREAM_REPORT 19
352
353/* Report 20: scratch */
354#define SCRATCH_PAGE_SIZE 63
355#define SCRATCH_REPORT_SIZE (SCRATCH_PAGE_SIZE + 1)
356#define SCRATCH_REPORT 20
357
358/* Reports 19-22: flash upgrade of the C8051F321 */
359#define WRITE_REPORT_SIZE 4
360#define WRITE_REPORT 19
361#define FLASH_REPORT_SIZE 64
362#define FLASH_REPORT 20
363#define CRC_REPORT_SIZE 3
364#define CRC_REPORT 21
365#define RESPONSE_REPORT_SIZE 2
366#define RESPONSE_REPORT 22
367
368/* Report 23: currently unused, but can accept 60 byte reports on the HID */
369/* interrupt out endpoint 2 every 1 millisecond */
370#define UNUSED_REPORT 23
371
372
373
374/**************************************************************************
375 * Software/Hardware Versions
376 **************************************************************************/
377#define RADIO_SW_VERSION_NOT_BOOTLOADABLE 6
378#define RADIO_SW_VERSION 7
379#define RADIO_SW_VERSION_CURRENT 15
380#define RADIO_HW_VERSION 1
381
382#define SCRATCH_PAGE_SW_VERSION 1
383#define SCRATCH_PAGE_HW_VERSION 2
384
385
386
387/**************************************************************************
388 * LED State Definitions
389 **************************************************************************/
390#define LED_COMMAND 0x35
391
392#define NO_CHANGE_LED 0x00
393#define ALL_COLOR_LED 0x01 /* streaming state */
394#define BLINK_GREEN_LED 0x02 /* connect state */
395#define BLINK_RED_LED 0x04
396#define BLINK_ORANGE_LED 0x10 /* disconnect state */
397#define SOLID_GREEN_LED 0x20 /* tuning/seeking state */
398#define SOLID_RED_LED 0x40 /* bootload state */
399#define SOLID_ORANGE_LED 0x80
400
401
402
403/**************************************************************************
404 * Stream State Definitions
405 **************************************************************************/
406#define STREAM_COMMAND 0x36
407#define STREAM_VIDPID 0x00
408#define STREAM_AUDIO 0xff
409
410
411
412/**************************************************************************
413 * Bootloader / Flash Commands
414 **************************************************************************/
415
416/* unique id sent to bootloader and required to put into a bootload state */
417#define UNIQUE_BL_ID 0x34
418
419/* mask for the flash data */
420#define FLASH_DATA_MASK 0x55
421
422/* bootloader commands */
423#define GET_SW_VERSION_COMMAND 0x00
424#define SET_PAGE_COMMAND 0x01
425#define ERASE_PAGE_COMMAND 0x02
426#define WRITE_PAGE_COMMAND 0x03
427#define CRC_ON_PAGE_COMMAND 0x04
428#define READ_FLASH_BYTE_COMMAND 0x05
429#define RESET_DEVICE_COMMAND 0x06
430#define GET_HW_VERSION_COMMAND 0x07
431#define BLANK 0xff
432
433/* bootloader command responses */
434#define COMMAND_OK 0x01
435#define COMMAND_FAILED 0x02
436#define COMMAND_PENDING 0x03
437
438
439
440/**************************************************************************
441 * General Driver Definitions
442 **************************************************************************/
443
444/*
445 * si470x_device - private data
446 */
447struct si470x_device {
448 /* reference to USB and video device */
449 struct usb_device *usbdev;
450 struct usb_interface *intf;
451 struct video_device *videodev;
452
453 /* driver management */
454 unsigned int users;
455 unsigned char disconnected;
456 struct mutex disconnect_lock;
457
458 /* Silabs internal registers (0..15) */
459 unsigned short registers[RADIO_REGISTER_NUM];
460
461 /* RDS receive buffer */
462 struct delayed_work work;
463 wait_queue_head_t read_queue;
464 struct mutex lock; /* buffer locking */
465 unsigned char *buffer; /* size is always multiple of three */
466 unsigned int buf_size;
467 unsigned int rd_index;
468 unsigned int wr_index;
469
470 /* scratch page */
471 unsigned char software_version;
472 unsigned char hardware_version;
473};
474
475
476/*
477 * The frequency is set in units of 62.5 Hz when using V4L2_TUNER_CAP_LOW,
478 * 62.5 kHz otherwise.
479 * The tuner is able to have a channel spacing of 50, 100 or 200 kHz.
480 * tuner->capability is therefore set to V4L2_TUNER_CAP_LOW
481 * The FREQ_MUL is then: 1 MHz / 62.5 Hz = 16000
482 */
483#define FREQ_MUL (1000000 / 62.5)
484
485
486
487/**************************************************************************
488 * General Driver Functions - REGISTER_REPORTs
489 **************************************************************************/
490
491/*
492 * si470x_get_report - receive a HID report
493 */
494static int si470x_get_report(struct si470x_device *radio, void *buf, int size)
495{
496 unsigned char *report = (unsigned char *) buf;
497 int retval;
498
499 retval = usb_control_msg(radio->usbdev,
500 usb_rcvctrlpipe(radio->usbdev, 0),
501 HID_REQ_GET_REPORT,
502 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
503 report[0], 2,
504 buf, size, usb_timeout);
505
506 if (retval < 0)
507 printk(KERN_WARNING DRIVER_NAME
508 ": si470x_get_report: usb_control_msg returned %d\n",
509 retval);
510 return retval;
511}
512
513
514/*
515 * si470x_set_report - send a HID report
516 */
517static int si470x_set_report(struct si470x_device *radio, void *buf, int size)
518{
519 unsigned char *report = (unsigned char *) buf;
520 int retval;
521
522 retval = usb_control_msg(radio->usbdev,
523 usb_sndctrlpipe(radio->usbdev, 0),
524 HID_REQ_SET_REPORT,
525 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
526 report[0], 2,
527 buf, size, usb_timeout);
528
529 if (retval < 0)
530 printk(KERN_WARNING DRIVER_NAME
531 ": si470x_set_report: usb_control_msg returned %d\n",
532 retval);
533 return retval;
534}
535
536
537/*
538 * si470x_get_register - read register
539 */
540static int si470x_get_register(struct si470x_device *radio, int regnr)
541{
542 unsigned char buf[REGISTER_REPORT_SIZE];
543 int retval;
544
545 buf[0] = REGISTER_REPORT(regnr);
546
547 retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
548
549 if (retval >= 0)
550 radio->registers[regnr] = get_unaligned_be16(&buf[1]);
551
552 return (retval < 0) ? -EINVAL : 0;
553}
554
555
556/*
557 * si470x_set_register - write register
558 */
559static int si470x_set_register(struct si470x_device *radio, int regnr)
560{
561 unsigned char buf[REGISTER_REPORT_SIZE];
562 int retval;
563
564 buf[0] = REGISTER_REPORT(regnr);
565 put_unaligned_be16(radio->registers[regnr], &buf[1]);
566
567 retval = si470x_set_report(radio, (void *) &buf, sizeof(buf));
568
569 return (retval < 0) ? -EINVAL : 0;
570}
571
572
573/*
574 * si470x_set_chan - set the channel
575 */
576static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
577{
578 int retval;
579 unsigned long timeout;
580 bool timed_out = 0;
581
582 /* start tuning */
583 radio->registers[CHANNEL] &= ~CHANNEL_CHAN;
584 radio->registers[CHANNEL] |= CHANNEL_TUNE | chan;
585 retval = si470x_set_register(radio, CHANNEL);
586 if (retval < 0)
587 goto done;
588
589 /* wait till tune operation has completed */
590 timeout = jiffies + msecs_to_jiffies(tune_timeout);
591 do {
592 retval = si470x_get_register(radio, STATUSRSSI);
593 if (retval < 0)
594 goto stop;
595 timed_out = time_after(jiffies, timeout);
596 } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
597 (!timed_out));
598 if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
599 printk(KERN_WARNING DRIVER_NAME ": tune does not complete\n");
600 if (timed_out)
601 printk(KERN_WARNING DRIVER_NAME
602 ": tune timed out after %u ms\n", tune_timeout);
603
604stop:
605 /* stop tuning */
606 radio->registers[CHANNEL] &= ~CHANNEL_TUNE;
607 retval = si470x_set_register(radio, CHANNEL);
608
609done:
610 return retval;
611}
612
613
614/*
615 * si470x_get_freq - get the frequency
616 */
617static int si470x_get_freq(struct si470x_device *radio, unsigned int *freq)
618{
619 unsigned int spacing, band_bottom;
620 unsigned short chan;
621 int retval;
622
623 /* Spacing (kHz) */
624 switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_SPACE) >> 4) {
625 /* 0: 200 kHz (USA, Australia) */
626 case 0:
627 spacing = 0.200 * FREQ_MUL; break;
628 /* 1: 100 kHz (Europe, Japan) */
629 case 1:
630 spacing = 0.100 * FREQ_MUL; break;
631 /* 2: 50 kHz */
632 default:
633 spacing = 0.050 * FREQ_MUL; break;
634 };
635
636 /* Bottom of Band (MHz) */
637 switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
638 /* 0: 87.5 - 108 MHz (USA, Europe) */
639 case 0:
640 band_bottom = 87.5 * FREQ_MUL; break;
641 /* 1: 76 - 108 MHz (Japan wide band) */
642 default:
643 band_bottom = 76 * FREQ_MUL; break;
644 /* 2: 76 - 90 MHz (Japan) */
645 case 2:
646 band_bottom = 76 * FREQ_MUL; break;
647 };
648
649 /* read channel */
650 retval = si470x_get_register(radio, READCHAN);
651 chan = radio->registers[READCHAN] & READCHAN_READCHAN;
652
653 /* Frequency (MHz) = Spacing (kHz) x Channel + Bottom of Band (MHz) */
654 *freq = chan * spacing + band_bottom;
655
656 return retval;
657}
658
659
660/*
661 * si470x_set_freq - set the frequency
662 */
663static int si470x_set_freq(struct si470x_device *radio, unsigned int freq)
664{
665 unsigned int spacing, band_bottom;
666 unsigned short chan;
667
668 /* Spacing (kHz) */
669 switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_SPACE) >> 4) {
670 /* 0: 200 kHz (USA, Australia) */
671 case 0:
672 spacing = 0.200 * FREQ_MUL; break;
673 /* 1: 100 kHz (Europe, Japan) */
674 case 1:
675 spacing = 0.100 * FREQ_MUL; break;
676 /* 2: 50 kHz */
677 default:
678 spacing = 0.050 * FREQ_MUL; break;
679 };
680
681 /* Bottom of Band (MHz) */
682 switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
683 /* 0: 87.5 - 108 MHz (USA, Europe) */
684 case 0:
685 band_bottom = 87.5 * FREQ_MUL; break;
686 /* 1: 76 - 108 MHz (Japan wide band) */
687 default:
688 band_bottom = 76 * FREQ_MUL; break;
689 /* 2: 76 - 90 MHz (Japan) */
690 case 2:
691 band_bottom = 76 * FREQ_MUL; break;
692 };
693
694 /* Chan = [ Freq (Mhz) - Bottom of Band (MHz) ] / Spacing (kHz) */
695 chan = (freq - band_bottom) / spacing;
696
697 return si470x_set_chan(radio, chan);
698}
699
700
701/*
702 * si470x_set_seek - set seek
703 */
704static int si470x_set_seek(struct si470x_device *radio,
705 unsigned int wrap_around, unsigned int seek_upward)
706{
707 int retval = 0;
708 unsigned long timeout;
709 bool timed_out = 0;
710
711 /* start seeking */
712 radio->registers[POWERCFG] |= POWERCFG_SEEK;
713 if (wrap_around == 1)
714 radio->registers[POWERCFG] &= ~POWERCFG_SKMODE;
715 else
716 radio->registers[POWERCFG] |= POWERCFG_SKMODE;
717 if (seek_upward == 1)
718 radio->registers[POWERCFG] |= POWERCFG_SEEKUP;
719 else
720 radio->registers[POWERCFG] &= ~POWERCFG_SEEKUP;
721 retval = si470x_set_register(radio, POWERCFG);
722 if (retval < 0)
723 goto done;
724
725 /* wait till seek operation has completed */
726 timeout = jiffies + msecs_to_jiffies(seek_timeout);
727 do {
728 retval = si470x_get_register(radio, STATUSRSSI);
729 if (retval < 0)
730 goto stop;
731 timed_out = time_after(jiffies, timeout);
732 } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
733 (!timed_out));
734 if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
735 printk(KERN_WARNING DRIVER_NAME ": seek does not complete\n");
736 if (radio->registers[STATUSRSSI] & STATUSRSSI_SF)
737 printk(KERN_WARNING DRIVER_NAME
738 ": seek failed / band limit reached\n");
739 if (timed_out)
740 printk(KERN_WARNING DRIVER_NAME
741 ": seek timed out after %u ms\n", seek_timeout);
742
743stop:
744 /* stop seeking */
745 radio->registers[POWERCFG] &= ~POWERCFG_SEEK;
746 retval = si470x_set_register(radio, POWERCFG);
747
748done:
749 /* try again, if timed out */
750 if ((retval == 0) && timed_out)
751 retval = -EAGAIN;
752
753 return retval;
754}
755
756
757/*
758 * si470x_start - switch on radio
759 */
760static int si470x_start(struct si470x_device *radio)
761{
762 int retval;
763
764 /* powercfg */
765 radio->registers[POWERCFG] =
766 POWERCFG_DMUTE | POWERCFG_ENABLE | POWERCFG_RDSM;
767 retval = si470x_set_register(radio, POWERCFG);
768 if (retval < 0)
769 goto done;
770
771 /* sysconfig 1 */
772 radio->registers[SYSCONFIG1] = SYSCONFIG1_DE;
773 retval = si470x_set_register(radio, SYSCONFIG1);
774 if (retval < 0)
775 goto done;
776
777 /* sysconfig 2 */
778 radio->registers[SYSCONFIG2] =
779 (0x3f << 8) | /* SEEKTH */
780 ((band << 6) & SYSCONFIG2_BAND) | /* BAND */
781 ((space << 4) & SYSCONFIG2_SPACE) | /* SPACE */
782 15; /* VOLUME (max) */
783 retval = si470x_set_register(radio, SYSCONFIG2);
784 if (retval < 0)
785 goto done;
786
787 /* reset last channel */
788 retval = si470x_set_chan(radio,
789 radio->registers[CHANNEL] & CHANNEL_CHAN);
790
791done:
792 return retval;
793}
794
795
796/*
797 * si470x_stop - switch off radio
798 */
799static int si470x_stop(struct si470x_device *radio)
800{
801 int retval;
802
803 /* sysconfig 1 */
804 radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS;
805 retval = si470x_set_register(radio, SYSCONFIG1);
806 if (retval < 0)
807 goto done;
808
809 /* powercfg */
810 radio->registers[POWERCFG] &= ~POWERCFG_DMUTE;
811 /* POWERCFG_ENABLE has to automatically go low */
812 radio->registers[POWERCFG] |= POWERCFG_ENABLE | POWERCFG_DISABLE;
813 retval = si470x_set_register(radio, POWERCFG);
814
815done:
816 return retval;
817}
818
819
820/*
821 * si470x_rds_on - switch on rds reception
822 */
823static int si470x_rds_on(struct si470x_device *radio)
824{
825 int retval;
826
827 /* sysconfig 1 */
828 mutex_lock(&radio->lock);
829 radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDS;
830 retval = si470x_set_register(radio, SYSCONFIG1);
831 if (retval < 0)
832 radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS;
833 mutex_unlock(&radio->lock);
834
835 return retval;
836}
837
838
839
840/**************************************************************************
841 * General Driver Functions - ENTIRE_REPORT
842 **************************************************************************/
843
844/*
845 * si470x_get_all_registers - read entire registers
846 */
847static int si470x_get_all_registers(struct si470x_device *radio)
848{
849 unsigned char buf[ENTIRE_REPORT_SIZE];
850 int retval;
851 unsigned char regnr;
852
853 buf[0] = ENTIRE_REPORT;
854
855 retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
856
857 if (retval >= 0)
858 for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
859 radio->registers[regnr] = get_unaligned_be16(
860 &buf[regnr * RADIO_REGISTER_SIZE + 1]);
861
862 return (retval < 0) ? -EINVAL : 0;
863}
864
865
866
867/**************************************************************************
868 * General Driver Functions - RDS_REPORT
869 **************************************************************************/
870
871/*
872 * si470x_get_rds_registers - read rds registers
873 */
874static int si470x_get_rds_registers(struct si470x_device *radio)
875{
876 unsigned char buf[RDS_REPORT_SIZE];
877 int retval;
878 int size;
879 unsigned char regnr;
880
881 buf[0] = RDS_REPORT;
882
883 retval = usb_interrupt_msg(radio->usbdev,
884 usb_rcvintpipe(radio->usbdev, 1),
885 (void *) &buf, sizeof(buf), &size, usb_timeout);
886 if (size != sizeof(buf))
887 printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
888 "return size differs: %d != %zu\n", size, sizeof(buf));
889 if (retval < 0)
890 printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
891 "usb_interrupt_msg returned %d\n", retval);
892
893 if (retval >= 0)
894 for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
895 radio->registers[STATUSRSSI + regnr] =
896 get_unaligned_be16(
897 &buf[regnr * RADIO_REGISTER_SIZE + 1]);
898
899 return (retval < 0) ? -EINVAL : 0;
900}
901
902
903
904/**************************************************************************
905 * General Driver Functions - LED_REPORT
906 **************************************************************************/
907
908/*
909 * si470x_set_led_state - sets the led state
910 */
911static int si470x_set_led_state(struct si470x_device *radio,
912 unsigned char led_state)
913{
914 unsigned char buf[LED_REPORT_SIZE];
915 int retval;
916
917 buf[0] = LED_REPORT;
918 buf[1] = LED_COMMAND;
919 buf[2] = led_state;
920
921 retval = si470x_set_report(radio, (void *) &buf, sizeof(buf));
922
923 return (retval < 0) ? -EINVAL : 0;
924}
925
926
927
928/**************************************************************************
929 * General Driver Functions - SCRATCH_REPORT
930 **************************************************************************/
931
932/*
933 * si470x_get_scratch_versions - gets the scratch page and version infos
934 */
935static int si470x_get_scratch_page_versions(struct si470x_device *radio)
936{
937 unsigned char buf[SCRATCH_REPORT_SIZE];
938 int retval;
939
940 buf[0] = SCRATCH_REPORT;
941
942 retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
943
944 if (retval < 0)
945 printk(KERN_WARNING DRIVER_NAME ": si470x_get_scratch: "
946 "si470x_get_report returned %d\n", retval);
947 else {
948 radio->software_version = buf[1];
949 radio->hardware_version = buf[2];
950 }
951
952 return (retval < 0) ? -EINVAL : 0;
953}
954
955
956
957/**************************************************************************
958 * RDS Driver Functions
959 **************************************************************************/
960
961/*
962 * si470x_rds - rds processing function
963 */
964static void si470x_rds(struct si470x_device *radio)
965{
966 unsigned char blocknum;
967 unsigned short bler; /* rds block errors */
968 unsigned short rds;
969 unsigned char tmpbuf[3];
970
971 /* get rds blocks */
972 if (si470x_get_rds_registers(radio) < 0)
973 return;
974 if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0) {
975 /* No RDS group ready */
976 return;
977 }
978 if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSS) == 0) {
979 /* RDS decoder not synchronized */
980 return;
981 }
982
983 /* copy all four RDS blocks to internal buffer */
984 mutex_lock(&radio->lock);
985 for (blocknum = 0; blocknum < 4; blocknum++) {
986 switch (blocknum) {
987 default:
988 bler = (radio->registers[STATUSRSSI] &
989 STATUSRSSI_BLERA) >> 9;
990 rds = radio->registers[RDSA];
991 break;
992 case 1:
993 bler = (radio->registers[READCHAN] &
994 READCHAN_BLERB) >> 14;
995 rds = radio->registers[RDSB];
996 break;
997 case 2:
998 bler = (radio->registers[READCHAN] &
999 READCHAN_BLERC) >> 12;
1000 rds = radio->registers[RDSC];
1001 break;
1002 case 3:
1003 bler = (radio->registers[READCHAN] &
1004 READCHAN_BLERD) >> 10;
1005 rds = radio->registers[RDSD];
1006 break;
1007 };
1008
1009 /* Fill the V4L2 RDS buffer */
1010 put_unaligned_le16(rds, &tmpbuf);
1011 tmpbuf[2] = blocknum; /* offset name */
1012 tmpbuf[2] |= blocknum << 3; /* received offset */
1013 if (bler > max_rds_errors)
1014 tmpbuf[2] |= 0x80; /* uncorrectable errors */
1015 else if (bler > 0)
1016 tmpbuf[2] |= 0x40; /* corrected error(s) */
1017
1018 /* copy RDS block to internal buffer */
1019 memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3);
1020 radio->wr_index += 3;
1021
1022 /* wrap write pointer */
1023 if (radio->wr_index >= radio->buf_size)
1024 radio->wr_index = 0;
1025
1026 /* check for overflow */
1027 if (radio->wr_index == radio->rd_index) {
1028 /* increment and wrap read pointer */
1029 radio->rd_index += 3;
1030 if (radio->rd_index >= radio->buf_size)
1031 radio->rd_index = 0;
1032 }
1033 }
1034 mutex_unlock(&radio->lock);
1035
1036 /* wake up read queue */
1037 if (radio->wr_index != radio->rd_index)
1038 wake_up_interruptible(&radio->read_queue);
1039}
1040
1041
1042/*
1043 * si470x_work - rds work function
1044 */
1045static void si470x_work(struct work_struct *work)
1046{
1047 struct si470x_device *radio = container_of(work, struct si470x_device,
1048 work.work);
1049
1050 /* safety checks */
1051 if (radio->disconnected)
1052 return;
1053 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
1054 return;
1055
1056 si470x_rds(radio);
1057 schedule_delayed_work(&radio->work, msecs_to_jiffies(rds_poll_time));
1058}
1059
1060
1061
1062/**************************************************************************
1063 * File Operations Interface
1064 **************************************************************************/
1065
1066/*
1067 * si470x_fops_read - read RDS data
1068 */
1069static ssize_t si470x_fops_read(struct file *file, char __user *buf,
1070 size_t count, loff_t *ppos)
1071{
1072 struct si470x_device *radio = video_drvdata(file);
1073 int retval = 0;
1074 unsigned int block_count = 0;
1075
1076 /* switch on rds reception */
1077 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) {
1078 si470x_rds_on(radio);
1079 schedule_delayed_work(&radio->work,
1080 msecs_to_jiffies(rds_poll_time));
1081 }
1082
1083 /* block if no new data available */
1084 while (radio->wr_index == radio->rd_index) {
1085 if (file->f_flags & O_NONBLOCK) {
1086 retval = -EWOULDBLOCK;
1087 goto done;
1088 }
1089 if (wait_event_interruptible(radio->read_queue,
1090 radio->wr_index != radio->rd_index) < 0) {
1091 retval = -EINTR;
1092 goto done;
1093 }
1094 }
1095
1096 /* calculate block count from byte count */
1097 count /= 3;
1098
1099 /* copy RDS block out of internal buffer and to user buffer */
1100 mutex_lock(&radio->lock);
1101 while (block_count < count) {
1102 if (radio->rd_index == radio->wr_index)
1103 break;
1104
1105 /* always transfer rds complete blocks */
1106 if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3))
1107 /* retval = -EFAULT; */
1108 break;
1109
1110 /* increment and wrap read pointer */
1111 radio->rd_index += 3;
1112 if (radio->rd_index >= radio->buf_size)
1113 radio->rd_index = 0;
1114
1115 /* increment counters */
1116 block_count++;
1117 buf += 3;
1118 retval += 3;
1119 }
1120 mutex_unlock(&radio->lock);
1121
1122done:
1123 return retval;
1124}
1125
1126
1127/*
1128 * si470x_fops_poll - poll RDS data
1129 */
1130static unsigned int si470x_fops_poll(struct file *file,
1131 struct poll_table_struct *pts)
1132{
1133 struct si470x_device *radio = video_drvdata(file);
1134 int retval = 0;
1135
1136 /* switch on rds reception */
1137 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) {
1138 si470x_rds_on(radio);
1139 schedule_delayed_work(&radio->work,
1140 msecs_to_jiffies(rds_poll_time));
1141 }
1142
1143 poll_wait(file, &radio->read_queue, pts);
1144
1145 if (radio->rd_index != radio->wr_index)
1146 retval = POLLIN | POLLRDNORM;
1147
1148 return retval;
1149}
1150
1151
1152/*
1153 * si470x_fops_open - file open
1154 */
1155static int si470x_fops_open(struct file *file)
1156{
1157 struct si470x_device *radio = video_drvdata(file);
1158 int retval;
1159
1160 lock_kernel();
1161 radio->users++;
1162
1163 retval = usb_autopm_get_interface(radio->intf);
1164 if (retval < 0) {
1165 radio->users--;
1166 retval = -EIO;
1167 goto done;
1168 }
1169
1170 if (radio->users == 1) {
1171 /* start radio */
1172 retval = si470x_start(radio);
1173 if (retval < 0)
1174 usb_autopm_put_interface(radio->intf);
1175 }
1176
1177done:
1178 unlock_kernel();
1179 return retval;
1180}
1181
1182
1183/*
1184 * si470x_fops_release - file release
1185 */
1186static int si470x_fops_release(struct file *file)
1187{
1188 struct si470x_device *radio = video_drvdata(file);
1189 int retval = 0;
1190
1191 /* safety check */
1192 if (!radio) {
1193 retval = -ENODEV;
1194 goto done;
1195 }
1196
1197 mutex_lock(&radio->disconnect_lock);
1198 radio->users--;
1199 if (radio->users == 0) {
1200 if (radio->disconnected) {
1201 video_unregister_device(radio->videodev);
1202 kfree(radio->buffer);
1203 kfree(radio);
1204 goto unlock;
1205 }
1206
1207 /* stop rds reception */
1208 cancel_delayed_work_sync(&radio->work);
1209
1210 /* cancel read processes */
1211 wake_up_interruptible(&radio->read_queue);
1212
1213 /* stop radio */
1214 retval = si470x_stop(radio);
1215 usb_autopm_put_interface(radio->intf);
1216 }
1217unlock:
1218 mutex_unlock(&radio->disconnect_lock);
1219done:
1220 return retval;
1221}
1222
1223
1224/*
1225 * si470x_fops - file operations interface
1226 */
1227static const struct v4l2_file_operations si470x_fops = {
1228 .owner = THIS_MODULE,
1229 .read = si470x_fops_read,
1230 .poll = si470x_fops_poll,
1231 .ioctl = video_ioctl2,
1232 .open = si470x_fops_open,
1233 .release = si470x_fops_release,
1234};
1235
1236
1237
1238/**************************************************************************
1239 * Video4Linux Interface
1240 **************************************************************************/
1241
1242/*
1243 * si470x_v4l2_queryctrl - query control
1244 */
1245static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = {
1246 {
1247 .id = V4L2_CID_AUDIO_VOLUME,
1248 .type = V4L2_CTRL_TYPE_INTEGER,
1249 .name = "Volume",
1250 .minimum = 0,
1251 .maximum = 15,
1252 .step = 1,
1253 .default_value = 15,
1254 },
1255 {
1256 .id = V4L2_CID_AUDIO_MUTE,
1257 .type = V4L2_CTRL_TYPE_BOOLEAN,
1258 .name = "Mute",
1259 .minimum = 0,
1260 .maximum = 1,
1261 .step = 1,
1262 .default_value = 1,
1263 },
1264};
1265
1266
1267/*
1268 * si470x_vidioc_querycap - query device capabilities
1269 */
1270static int si470x_vidioc_querycap(struct file *file, void *priv,
1271 struct v4l2_capability *capability)
1272{
1273 struct si470x_device *radio = video_drvdata(file);
1274
1275 strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
1276 strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
1277 usb_make_path(radio->usbdev, capability->bus_info, sizeof(capability->bus_info));
1278 capability->version = DRIVER_KERNEL_VERSION;
1279 capability->capabilities = V4L2_CAP_HW_FREQ_SEEK |
1280 V4L2_CAP_TUNER | V4L2_CAP_RADIO;
1281
1282 return 0;
1283}
1284
1285
1286/*
1287 * si470x_vidioc_queryctrl - enumerate control items
1288 */
1289static int si470x_vidioc_queryctrl(struct file *file, void *priv,
1290 struct v4l2_queryctrl *qc)
1291{
1292 unsigned char i = 0;
1293 int retval = -EINVAL;
1294
1295 /* abort if qc->id is below V4L2_CID_BASE */
1296 if (qc->id < V4L2_CID_BASE)
1297 goto done;
1298
1299 /* search video control */
1300 for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) {
1301 if (qc->id == si470x_v4l2_queryctrl[i].id) {
1302 memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc));
1303 retval = 0; /* found */
1304 break;
1305 }
1306 }
1307
1308 /* disable unsupported base controls */
1309 /* to satisfy kradio and such apps */
1310 if ((retval == -EINVAL) && (qc->id < V4L2_CID_LASTP1)) {
1311 qc->flags = V4L2_CTRL_FLAG_DISABLED;
1312 retval = 0;
1313 }
1314
1315done:
1316 if (retval < 0)
1317 printk(KERN_WARNING DRIVER_NAME
1318 ": query controls failed with %d\n", retval);
1319 return retval;
1320}
1321
1322
1323/*
1324 * si470x_vidioc_g_ctrl - get the value of a control
1325 */
1326static int si470x_vidioc_g_ctrl(struct file *file, void *priv,
1327 struct v4l2_control *ctrl)
1328{
1329 struct si470x_device *radio = video_drvdata(file);
1330 int retval = 0;
1331
1332 /* safety checks */
1333 if (radio->disconnected) {
1334 retval = -EIO;
1335 goto done;
1336 }
1337
1338 switch (ctrl->id) {
1339 case V4L2_CID_AUDIO_VOLUME:
1340 ctrl->value = radio->registers[SYSCONFIG2] &
1341 SYSCONFIG2_VOLUME;
1342 break;
1343 case V4L2_CID_AUDIO_MUTE:
1344 ctrl->value = ((radio->registers[POWERCFG] &
1345 POWERCFG_DMUTE) == 0) ? 1 : 0;
1346 break;
1347 default:
1348 retval = -EINVAL;
1349 }
1350
1351done:
1352 if (retval < 0)
1353 printk(KERN_WARNING DRIVER_NAME
1354 ": get control failed with %d\n", retval);
1355 return retval;
1356}
1357
1358
1359/*
1360 * si470x_vidioc_s_ctrl - set the value of a control
1361 */
1362static int si470x_vidioc_s_ctrl(struct file *file, void *priv,
1363 struct v4l2_control *ctrl)
1364{
1365 struct si470x_device *radio = video_drvdata(file);
1366 int retval = 0;
1367
1368 /* safety checks */
1369 if (radio->disconnected) {
1370 retval = -EIO;
1371 goto done;
1372 }
1373
1374 switch (ctrl->id) {
1375 case V4L2_CID_AUDIO_VOLUME:
1376 radio->registers[SYSCONFIG2] &= ~SYSCONFIG2_VOLUME;
1377 radio->registers[SYSCONFIG2] |= ctrl->value;
1378 retval = si470x_set_register(radio, SYSCONFIG2);
1379 break;
1380 case V4L2_CID_AUDIO_MUTE:
1381 if (ctrl->value == 1)
1382 radio->registers[POWERCFG] &= ~POWERCFG_DMUTE;
1383 else
1384 radio->registers[POWERCFG] |= POWERCFG_DMUTE;
1385 retval = si470x_set_register(radio, POWERCFG);
1386 break;
1387 default:
1388 retval = -EINVAL;
1389 }
1390
1391done:
1392 if (retval < 0)
1393 printk(KERN_WARNING DRIVER_NAME
1394 ": set control failed with %d\n", retval);
1395 return retval;
1396}
1397
1398
1399/*
1400 * si470x_vidioc_g_audio - get audio attributes
1401 */
1402static int si470x_vidioc_g_audio(struct file *file, void *priv,
1403 struct v4l2_audio *audio)
1404{
1405 /* driver constants */
1406 audio->index = 0;
1407 strcpy(audio->name, "Radio");
1408 audio->capability = V4L2_AUDCAP_STEREO;
1409 audio->mode = 0;
1410
1411 return 0;
1412}
1413
1414
1415/*
1416 * si470x_vidioc_g_tuner - get tuner attributes
1417 */
1418static int si470x_vidioc_g_tuner(struct file *file, void *priv,
1419 struct v4l2_tuner *tuner)
1420{
1421 struct si470x_device *radio = video_drvdata(file);
1422 int retval = 0;
1423
1424 /* safety checks */
1425 if (radio->disconnected) {
1426 retval = -EIO;
1427 goto done;
1428 }
1429 if (tuner->index != 0) {
1430 retval = -EINVAL;
1431 goto done;
1432 }
1433
1434 retval = si470x_get_register(radio, STATUSRSSI);
1435 if (retval < 0)
1436 goto done;
1437
1438 /* driver constants */
1439 strcpy(tuner->name, "FM");
1440 tuner->type = V4L2_TUNER_RADIO;
1441 tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
1442
1443 /* range limits */
1444 switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
1445 /* 0: 87.5 - 108 MHz (USA, Europe, default) */
1446 default:
1447 tuner->rangelow = 87.5 * FREQ_MUL;
1448 tuner->rangehigh = 108 * FREQ_MUL;
1449 break;
1450 /* 1: 76 - 108 MHz (Japan wide band) */
1451 case 1 :
1452 tuner->rangelow = 76 * FREQ_MUL;
1453 tuner->rangehigh = 108 * FREQ_MUL;
1454 break;
1455 /* 2: 76 - 90 MHz (Japan) */
1456 case 2 :
1457 tuner->rangelow = 76 * FREQ_MUL;
1458 tuner->rangehigh = 90 * FREQ_MUL;
1459 break;
1460 };
1461
1462 /* stereo indicator == stereo (instead of mono) */
1463 if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 0)
1464 tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
1465 else
1466 tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
1467
1468 /* mono/stereo selector */
1469 if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 0)
1470 tuner->audmode = V4L2_TUNER_MODE_STEREO;
1471 else
1472 tuner->audmode = V4L2_TUNER_MODE_MONO;
1473
1474 /* min is worst, max is best; signal:0..0xffff; rssi: 0..0xff */
1475 /* measured in units of dbµV in 1 db increments (max at ~75 dbµV) */
1476 tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI);
1477 /* the ideal factor is 0xffff/75 = 873,8 */
1478 tuner->signal = (tuner->signal * 873) + (8 * tuner->signal / 10);
1479
1480 /* automatic frequency control: -1: freq to low, 1 freq to high */
1481 /* AFCRL does only indicate that freq. differs, not if too low/high */
1482 tuner->afc = (radio->registers[STATUSRSSI] & STATUSRSSI_AFCRL) ? 1 : 0;
1483
1484done:
1485 if (retval < 0)
1486 printk(KERN_WARNING DRIVER_NAME
1487 ": get tuner failed with %d\n", retval);
1488 return retval;
1489}
1490
1491
1492/*
1493 * si470x_vidioc_s_tuner - set tuner attributes
1494 */
1495static int si470x_vidioc_s_tuner(struct file *file, void *priv,
1496 struct v4l2_tuner *tuner)
1497{
1498 struct si470x_device *radio = video_drvdata(file);
1499 int retval = -EINVAL;
1500
1501 /* safety checks */
1502 if (radio->disconnected) {
1503 retval = -EIO;
1504 goto done;
1505 }
1506 if (tuner->index != 0)
1507 goto done;
1508
1509 /* mono/stereo selector */
1510 switch (tuner->audmode) {
1511 case V4L2_TUNER_MODE_MONO:
1512 radio->registers[POWERCFG] |= POWERCFG_MONO; /* force mono */
1513 break;
1514 case V4L2_TUNER_MODE_STEREO:
1515 radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */
1516 break;
1517 default:
1518 goto done;
1519 }
1520
1521 retval = si470x_set_register(radio, POWERCFG);
1522
1523done:
1524 if (retval < 0)
1525 printk(KERN_WARNING DRIVER_NAME
1526 ": set tuner failed with %d\n", retval);
1527 return retval;
1528}
1529
1530
1531/*
1532 * si470x_vidioc_g_frequency - get tuner or modulator radio frequency
1533 */
1534static int si470x_vidioc_g_frequency(struct file *file, void *priv,
1535 struct v4l2_frequency *freq)
1536{
1537 struct si470x_device *radio = video_drvdata(file);
1538 int retval = 0;
1539
1540 /* safety checks */
1541 if (radio->disconnected) {
1542 retval = -EIO;
1543 goto done;
1544 }
1545 if (freq->tuner != 0) {
1546 retval = -EINVAL;
1547 goto done;
1548 }
1549
1550 freq->type = V4L2_TUNER_RADIO;
1551 retval = si470x_get_freq(radio, &freq->frequency);
1552
1553done:
1554 if (retval < 0)
1555 printk(KERN_WARNING DRIVER_NAME
1556 ": get frequency failed with %d\n", retval);
1557 return retval;
1558}
1559
1560
1561/*
1562 * si470x_vidioc_s_frequency - set tuner or modulator radio frequency
1563 */
1564static int si470x_vidioc_s_frequency(struct file *file, void *priv,
1565 struct v4l2_frequency *freq)
1566{
1567 struct si470x_device *radio = video_drvdata(file);
1568 int retval = 0;
1569
1570 /* safety checks */
1571 if (radio->disconnected) {
1572 retval = -EIO;
1573 goto done;
1574 }
1575 if (freq->tuner != 0) {
1576 retval = -EINVAL;
1577 goto done;
1578 }
1579
1580 retval = si470x_set_freq(radio, freq->frequency);
1581
1582done:
1583 if (retval < 0)
1584 printk(KERN_WARNING DRIVER_NAME
1585 ": set frequency failed with %d\n", retval);
1586 return retval;
1587}
1588
1589
1590/*
1591 * si470x_vidioc_s_hw_freq_seek - set hardware frequency seek
1592 */
1593static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv,
1594 struct v4l2_hw_freq_seek *seek)
1595{
1596 struct si470x_device *radio = video_drvdata(file);
1597 int retval = 0;
1598
1599 /* safety checks */
1600 if (radio->disconnected) {
1601 retval = -EIO;
1602 goto done;
1603 }
1604 if (seek->tuner != 0) {
1605 retval = -EINVAL;
1606 goto done;
1607 }
1608
1609 retval = si470x_set_seek(radio, seek->wrap_around, seek->seek_upward);
1610
1611done:
1612 if (retval < 0)
1613 printk(KERN_WARNING DRIVER_NAME
1614 ": set hardware frequency seek failed with %d\n",
1615 retval);
1616 return retval;
1617}
1618
1619
1620/*
1621 * si470x_ioctl_ops - video device ioctl operations
1622 */
1623static const struct v4l2_ioctl_ops si470x_ioctl_ops = {
1624 .vidioc_querycap = si470x_vidioc_querycap,
1625 .vidioc_queryctrl = si470x_vidioc_queryctrl,
1626 .vidioc_g_ctrl = si470x_vidioc_g_ctrl,
1627 .vidioc_s_ctrl = si470x_vidioc_s_ctrl,
1628 .vidioc_g_audio = si470x_vidioc_g_audio,
1629 .vidioc_g_tuner = si470x_vidioc_g_tuner,
1630 .vidioc_s_tuner = si470x_vidioc_s_tuner,
1631 .vidioc_g_frequency = si470x_vidioc_g_frequency,
1632 .vidioc_s_frequency = si470x_vidioc_s_frequency,
1633 .vidioc_s_hw_freq_seek = si470x_vidioc_s_hw_freq_seek,
1634};
1635
1636
1637/*
1638 * si470x_viddev_template - video device interface
1639 */
1640static struct video_device si470x_viddev_template = {
1641 .fops = &si470x_fops,
1642 .name = DRIVER_NAME,
1643 .release = video_device_release,
1644 .ioctl_ops = &si470x_ioctl_ops,
1645};
1646
1647
1648
1649/**************************************************************************
1650 * USB Interface
1651 **************************************************************************/
1652
1653/*
1654 * si470x_usb_driver_probe - probe for the device
1655 */
1656static int si470x_usb_driver_probe(struct usb_interface *intf,
1657 const struct usb_device_id *id)
1658{
1659 struct si470x_device *radio;
1660 int retval = 0;
1661
1662 /* private data allocation and initialization */
1663 radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL);
1664 if (!radio) {
1665 retval = -ENOMEM;
1666 goto err_initial;
1667 }
1668 radio->users = 0;
1669 radio->disconnected = 0;
1670 radio->usbdev = interface_to_usbdev(intf);
1671 radio->intf = intf;
1672 mutex_init(&radio->disconnect_lock);
1673 mutex_init(&radio->lock);
1674
1675 /* video device allocation and initialization */
1676 radio->videodev = video_device_alloc();
1677 if (!radio->videodev) {
1678 retval = -ENOMEM;
1679 goto err_radio;
1680 }
1681 memcpy(radio->videodev, &si470x_viddev_template,
1682 sizeof(si470x_viddev_template));
1683 video_set_drvdata(radio->videodev, radio);
1684
1685 /* show some infos about the specific si470x device */
1686 if (si470x_get_all_registers(radio) < 0) {
1687 retval = -EIO;
1688 goto err_video;
1689 }
1690 printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
1691 radio->registers[DEVICEID], radio->registers[CHIPID]);
1692
1693 /* get software and hardware versions */
1694 if (si470x_get_scratch_page_versions(radio) < 0) {
1695 retval = -EIO;
1696 goto err_video;
1697 }
1698 printk(KERN_INFO DRIVER_NAME
1699 ": software version %d, hardware version %d\n",
1700 radio->software_version, radio->hardware_version);
1701
1702 /* check if device and firmware is current */
1703 if ((radio->registers[CHIPID] & CHIPID_FIRMWARE)
1704 < RADIO_SW_VERSION_CURRENT) {
1705 printk(KERN_WARNING DRIVER_NAME
1706 ": This driver is known to work with "
1707 "firmware version %hu,\n", RADIO_SW_VERSION_CURRENT);
1708 printk(KERN_WARNING DRIVER_NAME
1709 ": but the device has firmware version %hu.\n",
1710 radio->registers[CHIPID] & CHIPID_FIRMWARE);
1711 printk(KERN_WARNING DRIVER_NAME
1712 ": If you have some trouble using this driver,\n");
1713 printk(KERN_WARNING DRIVER_NAME
1714 ": please report to V4L ML at "
1715 "linux-media@vger.kernel.org\n");
1716 }
1717
1718 /* set initial frequency */
1719 si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
1720
1721 /* set led to connect state */
1722 si470x_set_led_state(radio, BLINK_GREEN_LED);
1723
1724 /* rds buffer allocation */
1725 radio->buf_size = rds_buf * 3;
1726 radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
1727 if (!radio->buffer) {
1728 retval = -EIO;
1729 goto err_video;
1730 }
1731
1732 /* rds buffer configuration */
1733 radio->wr_index = 0;
1734 radio->rd_index = 0;
1735 init_waitqueue_head(&radio->read_queue);
1736
1737 /* prepare rds work function */
1738 INIT_DELAYED_WORK(&radio->work, si470x_work);
1739
1740 /* register video device */
1741 retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
1742 if (retval) {
1743 printk(KERN_WARNING DRIVER_NAME
1744 ": Could not register video device\n");
1745 goto err_all;
1746 }
1747 usb_set_intfdata(intf, radio);
1748
1749 return 0;
1750err_all:
1751 kfree(radio->buffer);
1752err_video:
1753 video_device_release(radio->videodev);
1754err_radio:
1755 kfree(radio);
1756err_initial:
1757 return retval;
1758}
1759
1760
1761/*
1762 * si470x_usb_driver_suspend - suspend the device
1763 */
1764static int si470x_usb_driver_suspend(struct usb_interface *intf,
1765 pm_message_t message)
1766{
1767 struct si470x_device *radio = usb_get_intfdata(intf);
1768
1769 printk(KERN_INFO DRIVER_NAME ": suspending now...\n");
1770
1771 cancel_delayed_work_sync(&radio->work);
1772
1773 return 0;
1774}
1775
1776
1777/*
1778 * si470x_usb_driver_resume - resume the device
1779 */
1780static int si470x_usb_driver_resume(struct usb_interface *intf)
1781{
1782 struct si470x_device *radio = usb_get_intfdata(intf);
1783
1784 printk(KERN_INFO DRIVER_NAME ": resuming now...\n");
1785
1786 mutex_lock(&radio->lock);
1787 if (radio->users && radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS)
1788 schedule_delayed_work(&radio->work,
1789 msecs_to_jiffies(rds_poll_time));
1790 mutex_unlock(&radio->lock);
1791
1792 return 0;
1793}
1794
1795
1796/*
1797 * si470x_usb_driver_disconnect - disconnect the device
1798 */
1799static void si470x_usb_driver_disconnect(struct usb_interface *intf)
1800{
1801 struct si470x_device *radio = usb_get_intfdata(intf);
1802
1803 mutex_lock(&radio->disconnect_lock);
1804 radio->disconnected = 1;
1805 cancel_delayed_work_sync(&radio->work);
1806 usb_set_intfdata(intf, NULL);
1807 if (radio->users == 0) {
1808 /* set led to disconnect state */
1809 si470x_set_led_state(radio, BLINK_ORANGE_LED);
1810
1811 video_unregister_device(radio->videodev);
1812 kfree(radio->buffer);
1813 kfree(radio);
1814 }
1815 mutex_unlock(&radio->disconnect_lock);
1816}
1817
1818
1819/*
1820 * si470x_usb_driver - usb driver interface
1821 */
1822static struct usb_driver si470x_usb_driver = {
1823 .name = DRIVER_NAME,
1824 .probe = si470x_usb_driver_probe,
1825 .disconnect = si470x_usb_driver_disconnect,
1826 .suspend = si470x_usb_driver_suspend,
1827 .resume = si470x_usb_driver_resume,
1828 .id_table = si470x_usb_driver_id_table,
1829 .supports_autosuspend = 1,
1830};
1831
1832
1833
1834/**************************************************************************
1835 * Module Interface
1836 **************************************************************************/
1837
1838/*
1839 * si470x_module_init - module init
1840 */
1841static int __init si470x_module_init(void)
1842{
1843 printk(KERN_INFO DRIVER_DESC ", Version " DRIVER_VERSION "\n");
1844 return usb_register(&si470x_usb_driver);
1845}
1846
1847
1848/*
1849 * si470x_module_exit - module exit
1850 */
1851static void __exit si470x_module_exit(void)
1852{
1853 usb_deregister(&si470x_usb_driver);
1854}
1855
1856
1857module_init(si470x_module_init);
1858module_exit(si470x_module_exit);
1859
1860MODULE_LICENSE("GPL");
1861MODULE_AUTHOR(DRIVER_AUTHOR);
1862MODULE_DESCRIPTION(DRIVER_DESC);
1863MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c
new file mode 100644
index 000000000000..65c14b704586
--- /dev/null
+++ b/drivers/media/radio/radio-si4713.c
@@ -0,0 +1,367 @@
1/*
2 * drivers/media/radio/radio-si4713.c
3 *
4 * Platform Driver for Silicon Labs Si4713 FM Radio Transmitter:
5 *
6 * Copyright (c) 2008 Instituto Nokia de Tecnologia - INdT
7 * Contact: Eduardo Valentin <eduardo.valentin@nokia.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 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/version.h>
28#include <linux/platform_device.h>
29#include <linux/i2c.h>
30#include <linux/videodev2.h>
31#include <media/v4l2-device.h>
32#include <media/v4l2-common.h>
33#include <media/v4l2-ioctl.h>
34#include <media/radio-si4713.h>
35
36/* module parameters */
37static int radio_nr = -1; /* radio device minor (-1 ==> auto assign) */
38module_param(radio_nr, int, 0);
39MODULE_PARM_DESC(radio_nr,
40 "Minor number for radio device (-1 ==> auto assign)");
41
42MODULE_LICENSE("GPL");
43MODULE_AUTHOR("Eduardo Valentin <eduardo.valentin@nokia.com>");
44MODULE_DESCRIPTION("Platform driver for Si4713 FM Radio Transmitter");
45MODULE_VERSION("0.0.1");
46
47/* Driver state struct */
48struct radio_si4713_device {
49 struct v4l2_device v4l2_dev;
50 struct video_device *radio_dev;
51};
52
53/* radio_si4713_fops - file operations interface */
54static const struct v4l2_file_operations radio_si4713_fops = {
55 .owner = THIS_MODULE,
56 .ioctl = video_ioctl2,
57};
58
59/* Video4Linux Interface */
60static int radio_si4713_fill_audout(struct v4l2_audioout *vao)
61{
62 /* TODO: check presence of audio output */
63 strlcpy(vao->name, "FM Modulator Audio Out", 32);
64
65 return 0;
66}
67
68static int radio_si4713_enumaudout(struct file *file, void *priv,
69 struct v4l2_audioout *vao)
70{
71 return radio_si4713_fill_audout(vao);
72}
73
74static int radio_si4713_g_audout(struct file *file, void *priv,
75 struct v4l2_audioout *vao)
76{
77 int rval = radio_si4713_fill_audout(vao);
78
79 vao->index = 0;
80
81 return rval;
82}
83
84static int radio_si4713_s_audout(struct file *file, void *priv,
85 struct v4l2_audioout *vao)
86{
87 return vao->index ? -EINVAL : 0;
88}
89
90/* radio_si4713_querycap - query device capabilities */
91static int radio_si4713_querycap(struct file *file, void *priv,
92 struct v4l2_capability *capability)
93{
94 struct radio_si4713_device *rsdev;
95
96 rsdev = video_get_drvdata(video_devdata(file));
97
98 strlcpy(capability->driver, "radio-si4713", sizeof(capability->driver));
99 strlcpy(capability->card, "Silicon Labs Si4713 Modulator",
100 sizeof(capability->card));
101 capability->capabilities = V4L2_CAP_MODULATOR | V4L2_CAP_RDS_OUTPUT;
102
103 return 0;
104}
105
106/* radio_si4713_queryctrl - enumerate control items */
107static int radio_si4713_queryctrl(struct file *file, void *priv,
108 struct v4l2_queryctrl *qc)
109{
110 /* Must be sorted from low to high control ID! */
111 static const u32 user_ctrls[] = {
112 V4L2_CID_USER_CLASS,
113 V4L2_CID_AUDIO_MUTE,
114 0
115 };
116
117 /* Must be sorted from low to high control ID! */
118 static const u32 fmtx_ctrls[] = {
119 V4L2_CID_FM_TX_CLASS,
120 V4L2_CID_RDS_TX_DEVIATION,
121 V4L2_CID_RDS_TX_PI,
122 V4L2_CID_RDS_TX_PTY,
123 V4L2_CID_RDS_TX_PS_NAME,
124 V4L2_CID_RDS_TX_RADIO_TEXT,
125 V4L2_CID_AUDIO_LIMITER_ENABLED,
126 V4L2_CID_AUDIO_LIMITER_RELEASE_TIME,
127 V4L2_CID_AUDIO_LIMITER_DEVIATION,
128 V4L2_CID_AUDIO_COMPRESSION_ENABLED,
129 V4L2_CID_AUDIO_COMPRESSION_GAIN,
130 V4L2_CID_AUDIO_COMPRESSION_THRESHOLD,
131 V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME,
132 V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME,
133 V4L2_CID_PILOT_TONE_ENABLED,
134 V4L2_CID_PILOT_TONE_DEVIATION,
135 V4L2_CID_PILOT_TONE_FREQUENCY,
136 V4L2_CID_TUNE_PREEMPHASIS,
137 V4L2_CID_TUNE_POWER_LEVEL,
138 V4L2_CID_TUNE_ANTENNA_CAPACITOR,
139 0
140 };
141 static const u32 *ctrl_classes[] = {
142 user_ctrls,
143 fmtx_ctrls,
144 NULL
145 };
146 struct radio_si4713_device *rsdev;
147
148 rsdev = video_get_drvdata(video_devdata(file));
149
150 qc->id = v4l2_ctrl_next(ctrl_classes, qc->id);
151 if (qc->id == 0)
152 return -EINVAL;
153
154 if (qc->id == V4L2_CID_USER_CLASS || qc->id == V4L2_CID_FM_TX_CLASS)
155 return v4l2_ctrl_query_fill(qc, 0, 0, 0, 0);
156
157 return v4l2_device_call_until_err(&rsdev->v4l2_dev, 0, core,
158 queryctrl, qc);
159}
160
161/*
162 * v4l2 ioctl call backs.
163 * we are just a wrapper for v4l2_sub_devs.
164 */
165static inline struct v4l2_device *get_v4l2_dev(struct file *file)
166{
167 return &((struct radio_si4713_device *)video_drvdata(file))->v4l2_dev;
168}
169
170static int radio_si4713_g_ext_ctrls(struct file *file, void *p,
171 struct v4l2_ext_controls *vecs)
172{
173 return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core,
174 g_ext_ctrls, vecs);
175}
176
177static int radio_si4713_s_ext_ctrls(struct file *file, void *p,
178 struct v4l2_ext_controls *vecs)
179{
180 return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core,
181 s_ext_ctrls, vecs);
182}
183
184static int radio_si4713_g_ctrl(struct file *file, void *p,
185 struct v4l2_control *vc)
186{
187 return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core,
188 g_ctrl, vc);
189}
190
191static int radio_si4713_s_ctrl(struct file *file, void *p,
192 struct v4l2_control *vc)
193{
194 return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core,
195 s_ctrl, vc);
196}
197
198static int radio_si4713_g_modulator(struct file *file, void *p,
199 struct v4l2_modulator *vm)
200{
201 return v4l2_device_call_until_err(get_v4l2_dev(file), 0, tuner,
202 g_modulator, vm);
203}
204
205static int radio_si4713_s_modulator(struct file *file, void *p,
206 struct v4l2_modulator *vm)
207{
208 return v4l2_device_call_until_err(get_v4l2_dev(file), 0, tuner,
209 s_modulator, vm);
210}
211
212static int radio_si4713_g_frequency(struct file *file, void *p,
213 struct v4l2_frequency *vf)
214{
215 return v4l2_device_call_until_err(get_v4l2_dev(file), 0, tuner,
216 g_frequency, vf);
217}
218
219static int radio_si4713_s_frequency(struct file *file, void *p,
220 struct v4l2_frequency *vf)
221{
222 return v4l2_device_call_until_err(get_v4l2_dev(file), 0, tuner,
223 s_frequency, vf);
224}
225
226static long radio_si4713_default(struct file *file, void *p, int cmd, void *arg)
227{
228 return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core,
229 ioctl, cmd, arg);
230}
231
232static struct v4l2_ioctl_ops radio_si4713_ioctl_ops = {
233 .vidioc_enumaudout = radio_si4713_enumaudout,
234 .vidioc_g_audout = radio_si4713_g_audout,
235 .vidioc_s_audout = radio_si4713_s_audout,
236 .vidioc_querycap = radio_si4713_querycap,
237 .vidioc_queryctrl = radio_si4713_queryctrl,
238 .vidioc_g_ext_ctrls = radio_si4713_g_ext_ctrls,
239 .vidioc_s_ext_ctrls = radio_si4713_s_ext_ctrls,
240 .vidioc_g_ctrl = radio_si4713_g_ctrl,
241 .vidioc_s_ctrl = radio_si4713_s_ctrl,
242 .vidioc_g_modulator = radio_si4713_g_modulator,
243 .vidioc_s_modulator = radio_si4713_s_modulator,
244 .vidioc_g_frequency = radio_si4713_g_frequency,
245 .vidioc_s_frequency = radio_si4713_s_frequency,
246 .vidioc_default = radio_si4713_default,
247};
248
249/* radio_si4713_vdev_template - video device interface */
250static struct video_device radio_si4713_vdev_template = {
251 .fops = &radio_si4713_fops,
252 .name = "radio-si4713",
253 .release = video_device_release,
254 .ioctl_ops = &radio_si4713_ioctl_ops,
255};
256
257/* Platform driver interface */
258/* radio_si4713_pdriver_probe - probe for the device */
259static int radio_si4713_pdriver_probe(struct platform_device *pdev)
260{
261 struct radio_si4713_platform_data *pdata = pdev->dev.platform_data;
262 struct radio_si4713_device *rsdev;
263 struct i2c_adapter *adapter;
264 struct v4l2_subdev *sd;
265 int rval = 0;
266
267 if (!pdata) {
268 dev_err(&pdev->dev, "Cannot proceed without platform data.\n");
269 rval = -EINVAL;
270 goto exit;
271 }
272
273 rsdev = kzalloc(sizeof *rsdev, GFP_KERNEL);
274 if (!rsdev) {
275 dev_err(&pdev->dev, "Failed to alloc video device.\n");
276 rval = -ENOMEM;
277 goto exit;
278 }
279
280 rval = v4l2_device_register(&pdev->dev, &rsdev->v4l2_dev);
281 if (rval) {
282 dev_err(&pdev->dev, "Failed to register v4l2 device.\n");
283 goto free_rsdev;
284 }
285
286 adapter = i2c_get_adapter(pdata->i2c_bus);
287 if (!adapter) {
288 dev_err(&pdev->dev, "Cannot get i2c adapter %d\n",
289 pdata->i2c_bus);
290 rval = -ENODEV;
291 goto unregister_v4l2_dev;
292 }
293
294 sd = v4l2_i2c_new_subdev_board(&rsdev->v4l2_dev, adapter, "si4713_i2c",
295 pdata->subdev_board_info, NULL);
296 if (!sd) {
297 dev_err(&pdev->dev, "Cannot get v4l2 subdevice\n");
298 rval = -ENODEV;
299 goto unregister_v4l2_dev;
300 }
301
302 rsdev->radio_dev = video_device_alloc();
303 if (!rsdev->radio_dev) {
304 dev_err(&pdev->dev, "Failed to alloc video device.\n");
305 rval = -ENOMEM;
306 goto unregister_v4l2_dev;
307 }
308
309 memcpy(rsdev->radio_dev, &radio_si4713_vdev_template,
310 sizeof(radio_si4713_vdev_template));
311 video_set_drvdata(rsdev->radio_dev, rsdev);
312 if (video_register_device(rsdev->radio_dev, VFL_TYPE_RADIO, radio_nr)) {
313 dev_err(&pdev->dev, "Could not register video device.\n");
314 rval = -EIO;
315 goto free_vdev;
316 }
317 dev_info(&pdev->dev, "New device successfully probed\n");
318
319 goto exit;
320
321free_vdev:
322 video_device_release(rsdev->radio_dev);
323unregister_v4l2_dev:
324 v4l2_device_unregister(&rsdev->v4l2_dev);
325free_rsdev:
326 kfree(rsdev);
327exit:
328 return rval;
329}
330
331/* radio_si4713_pdriver_remove - remove the device */
332static int __exit radio_si4713_pdriver_remove(struct platform_device *pdev)
333{
334 struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
335 struct radio_si4713_device *rsdev = container_of(v4l2_dev,
336 struct radio_si4713_device,
337 v4l2_dev);
338
339 video_unregister_device(rsdev->radio_dev);
340 v4l2_device_unregister(&rsdev->v4l2_dev);
341 kfree(rsdev);
342
343 return 0;
344}
345
346static struct platform_driver radio_si4713_pdriver = {
347 .driver = {
348 .name = "radio-si4713",
349 },
350 .probe = radio_si4713_pdriver_probe,
351 .remove = __exit_p(radio_si4713_pdriver_remove),
352};
353
354/* Module Interface */
355static int __init radio_si4713_module_init(void)
356{
357 return platform_driver_register(&radio_si4713_pdriver);
358}
359
360static void __exit radio_si4713_module_exit(void)
361{
362 platform_driver_unregister(&radio_si4713_pdriver);
363}
364
365module_init(radio_si4713_module_init);
366module_exit(radio_si4713_module_exit);
367
diff --git a/drivers/media/radio/si470x/Kconfig b/drivers/media/radio/si470x/Kconfig
new file mode 100644
index 000000000000..a466654ee5c9
--- /dev/null
+++ b/drivers/media/radio/si470x/Kconfig
@@ -0,0 +1,37 @@
1config USB_SI470X
2 tristate "Silicon Labs Si470x FM Radio Receiver support with USB"
3 depends on USB && RADIO_SI470X
4 ---help---
5 This is a driver for USB devices with the Silicon Labs SI470x
6 chip. Currently these devices are known to work:
7 - 10c4:818a: Silicon Labs USB FM Radio Reference Design
8 - 06e1:a155: ADS/Tech FM Radio Receiver (formerly Instant FM Music)
9 - 1b80:d700: KWorld USB FM Radio SnapMusic Mobile 700 (FM700)
10 - 10c5:819a: Sanei Electric FM USB Radio (aka DealExtreme.com PCear)
11
12 Sound is provided by the ALSA USB Audio/MIDI driver. Therefore
13 if you don't want to use the device solely for RDS receiving,
14 it is recommended to also select SND_USB_AUDIO.
15
16 Please have a look at the documentation, especially on how
17 to redirect the audio stream from the radio to your sound device:
18 Documentation/video4linux/si470x.txt
19
20 Say Y here if you want to connect this type of radio to your
21 computer's USB port.
22
23 To compile this driver as a module, choose M here: the
24 module will be called radio-usb-si470x.
25
26config I2C_SI470X
27 tristate "Silicon Labs Si470x FM Radio Receiver support with I2C"
28 depends on I2C && RADIO_SI470X && !USB_SI470X
29 ---help---
30 This is a driver for I2C devices with the Silicon Labs SI470x
31 chip.
32
33 Say Y here if you want to connect this type of radio to your
34 computer's I2C port.
35
36 To compile this driver as a module, choose M here: the
37 module will be called radio-i2c-si470x.
diff --git a/drivers/media/radio/si470x/Makefile b/drivers/media/radio/si470x/Makefile
new file mode 100644
index 000000000000..06964816cfd6
--- /dev/null
+++ b/drivers/media/radio/si470x/Makefile
@@ -0,0 +1,9 @@
1#
2# Makefile for radios with Silicon Labs Si470x FM Radio Receivers
3#
4
5radio-usb-si470x-objs := radio-si470x-usb.o radio-si470x-common.o
6radio-i2c-si470x-objs := radio-si470x-i2c.o radio-si470x-common.o
7
8obj-$(CONFIG_USB_SI470X) += radio-usb-si470x.o
9obj-$(CONFIG_I2C_SI470X) += radio-i2c-si470x.o
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c
new file mode 100644
index 000000000000..f33315f2c543
--- /dev/null
+++ b/drivers/media/radio/si470x/radio-si470x-common.c
@@ -0,0 +1,798 @@
1/*
2 * drivers/media/radio/si470x/radio-si470x-common.c
3 *
4 * Driver for radios with Silicon Labs Si470x FM Radio Receivers
5 *
6 * Copyright (c) 2009 Tobias Lorenz <tobias.lorenz@gmx.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23
24/*
25 * History:
26 * 2008-01-12 Tobias Lorenz <tobias.lorenz@gmx.net>
27 * Version 1.0.0
28 * - First working version
29 * 2008-01-13 Tobias Lorenz <tobias.lorenz@gmx.net>
30 * Version 1.0.1
31 * - Improved error handling, every function now returns errno
32 * - Improved multi user access (start/mute/stop)
33 * - Channel doesn't get lost anymore after start/mute/stop
34 * - RDS support added (polling mode via interrupt EP 1)
35 * - marked default module parameters with *value*
36 * - switched from bit structs to bit masks
37 * - header file cleaned and integrated
38 * 2008-01-14 Tobias Lorenz <tobias.lorenz@gmx.net>
39 * Version 1.0.2
40 * - hex values are now lower case
41 * - commented USB ID for ADS/Tech moved on todo list
42 * - blacklisted si470x in hid-quirks.c
43 * - rds buffer handling functions integrated into *_work, *_read
44 * - rds_command in si470x_poll exchanged against simple retval
45 * - check for firmware version 15
46 * - code order and prototypes still remain the same
47 * - spacing and bottom of band codes remain the same
48 * 2008-01-16 Tobias Lorenz <tobias.lorenz@gmx.net>
49 * Version 1.0.3
50 * - code reordered to avoid function prototypes
51 * - switch/case defaults are now more user-friendly
52 * - unified comment style
53 * - applied all checkpatch.pl v1.12 suggestions
54 * except the warning about the too long lines with bit comments
55 * - renamed FMRADIO to RADIO to cut line length (checkpatch.pl)
56 * 2008-01-22 Tobias Lorenz <tobias.lorenz@gmx.net>
57 * Version 1.0.4
58 * - avoid poss. locking when doing copy_to_user which may sleep
59 * - RDS is automatically activated on read now
60 * - code cleaned of unnecessary rds_commands
61 * - USB Vendor/Product ID for ADS/Tech FM Radio Receiver verified
62 * (thanks to Guillaume RAMOUSSE)
63 * 2008-01-27 Tobias Lorenz <tobias.lorenz@gmx.net>
64 * Version 1.0.5
65 * - number of seek_retries changed to tune_timeout
66 * - fixed problem with incomplete tune operations by own buffers
67 * - optimization of variables and printf types
68 * - improved error logging
69 * 2008-01-31 Tobias Lorenz <tobias.lorenz@gmx.net>
70 * Oliver Neukum <oliver@neukum.org>
71 * Version 1.0.6
72 * - fixed coverity checker warnings in *_usb_driver_disconnect
73 * - probe()/open() race by correct ordering in probe()
74 * - DMA coherency rules by separate allocation of all buffers
75 * - use of endianness macros
76 * - abuse of spinlock, replaced by mutex
77 * - racy handling of timer in disconnect,
78 * replaced by delayed_work
79 * - racy interruptible_sleep_on(),
80 * replaced with wait_event_interruptible()
81 * - handle signals in read()
82 * 2008-02-08 Tobias Lorenz <tobias.lorenz@gmx.net>
83 * Oliver Neukum <oliver@neukum.org>
84 * Version 1.0.7
85 * - usb autosuspend support
86 * - unplugging fixed
87 * 2008-05-07 Tobias Lorenz <tobias.lorenz@gmx.net>
88 * Version 1.0.8
89 * - hardware frequency seek support
90 * - afc indication
91 * - more safety checks, let si470x_get_freq return errno
92 * - vidioc behavior corrected according to v4l2 spec
93 * 2008-10-20 Alexey Klimov <klimov.linux@gmail.com>
94 * - add support for KWorld USB FM Radio FM700
95 * - blacklisted KWorld radio in hid-core.c and hid-ids.h
96 * 2008-12-03 Mark Lord <mlord@pobox.com>
97 * - add support for DealExtreme USB Radio
98 * 2009-01-31 Bob Ross <pigiron@gmx.com>
99 * - correction of stereo detection/setting
100 * - correction of signal strength indicator scaling
101 * 2009-01-31 Rick Bronson <rick@efn.org>
102 * Tobias Lorenz <tobias.lorenz@gmx.net>
103 * - add LED status output
104 * - get HW/SW version from scratchpad
105 * 2009-06-16 Edouard Lafargue <edouard@lafargue.name>
106 * Version 1.0.10
107 * - add support for interrupt mode for RDS endpoint,
108 * instead of polling.
109 * Improves RDS reception significantly
110 */
111
112
113/* kernel includes */
114#include "radio-si470x.h"
115
116
117
118/**************************************************************************
119 * Module Parameters
120 **************************************************************************/
121
122/* Spacing (kHz) */
123/* 0: 200 kHz (USA, Australia) */
124/* 1: 100 kHz (Europe, Japan) */
125/* 2: 50 kHz */
126static unsigned short space = 2;
127module_param(space, ushort, 0444);
128MODULE_PARM_DESC(space, "Spacing: 0=200kHz 1=100kHz *2=50kHz*");
129
130/* Bottom of Band (MHz) */
131/* 0: 87.5 - 108 MHz (USA, Europe)*/
132/* 1: 76 - 108 MHz (Japan wide band) */
133/* 2: 76 - 90 MHz (Japan) */
134static unsigned short band = 1;
135module_param(band, ushort, 0444);
136MODULE_PARM_DESC(band, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz");
137
138/* De-emphasis */
139/* 0: 75 us (USA) */
140/* 1: 50 us (Europe, Australia, Japan) */
141static unsigned short de = 1;
142module_param(de, ushort, 0444);
143MODULE_PARM_DESC(de, "De-emphasis: 0=75us *1=50us*");
144
145/* Tune timeout */
146static unsigned int tune_timeout = 3000;
147module_param(tune_timeout, uint, 0644);
148MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*");
149
150/* Seek timeout */
151static unsigned int seek_timeout = 5000;
152module_param(seek_timeout, uint, 0644);
153MODULE_PARM_DESC(seek_timeout, "Seek timeout: *5000*");
154
155
156
157/**************************************************************************
158 * Generic Functions
159 **************************************************************************/
160
161/*
162 * si470x_set_chan - set the channel
163 */
164static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
165{
166 int retval;
167 unsigned long timeout;
168 bool timed_out = 0;
169
170 /* start tuning */
171 radio->registers[CHANNEL] &= ~CHANNEL_CHAN;
172 radio->registers[CHANNEL] |= CHANNEL_TUNE | chan;
173 retval = si470x_set_register(radio, CHANNEL);
174 if (retval < 0)
175 goto done;
176
177 /* wait till tune operation has completed */
178 timeout = jiffies + msecs_to_jiffies(tune_timeout);
179 do {
180 retval = si470x_get_register(radio, STATUSRSSI);
181 if (retval < 0)
182 goto stop;
183 timed_out = time_after(jiffies, timeout);
184 } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
185 (!timed_out));
186 if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
187 dev_warn(&radio->videodev->dev, "tune does not complete\n");
188 if (timed_out)
189 dev_warn(&radio->videodev->dev,
190 "tune timed out after %u ms\n", tune_timeout);
191
192stop:
193 /* stop tuning */
194 radio->registers[CHANNEL] &= ~CHANNEL_TUNE;
195 retval = si470x_set_register(radio, CHANNEL);
196
197done:
198 return retval;
199}
200
201
202/*
203 * si470x_get_freq - get the frequency
204 */
205static int si470x_get_freq(struct si470x_device *radio, unsigned int *freq)
206{
207 unsigned int spacing, band_bottom;
208 unsigned short chan;
209 int retval;
210
211 /* Spacing (kHz) */
212 switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_SPACE) >> 4) {
213 /* 0: 200 kHz (USA, Australia) */
214 case 0:
215 spacing = 0.200 * FREQ_MUL; break;
216 /* 1: 100 kHz (Europe, Japan) */
217 case 1:
218 spacing = 0.100 * FREQ_MUL; break;
219 /* 2: 50 kHz */
220 default:
221 spacing = 0.050 * FREQ_MUL; break;
222 };
223
224 /* Bottom of Band (MHz) */
225 switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
226 /* 0: 87.5 - 108 MHz (USA, Europe) */
227 case 0:
228 band_bottom = 87.5 * FREQ_MUL; break;
229 /* 1: 76 - 108 MHz (Japan wide band) */
230 default:
231 band_bottom = 76 * FREQ_MUL; break;
232 /* 2: 76 - 90 MHz (Japan) */
233 case 2:
234 band_bottom = 76 * FREQ_MUL; break;
235 };
236
237 /* read channel */
238 retval = si470x_get_register(radio, READCHAN);
239 chan = radio->registers[READCHAN] & READCHAN_READCHAN;
240
241 /* Frequency (MHz) = Spacing (kHz) x Channel + Bottom of Band (MHz) */
242 *freq = chan * spacing + band_bottom;
243
244 return retval;
245}
246
247
248/*
249 * si470x_set_freq - set the frequency
250 */
251int si470x_set_freq(struct si470x_device *radio, unsigned int freq)
252{
253 unsigned int spacing, band_bottom;
254 unsigned short chan;
255
256 /* Spacing (kHz) */
257 switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_SPACE) >> 4) {
258 /* 0: 200 kHz (USA, Australia) */
259 case 0:
260 spacing = 0.200 * FREQ_MUL; break;
261 /* 1: 100 kHz (Europe, Japan) */
262 case 1:
263 spacing = 0.100 * FREQ_MUL; break;
264 /* 2: 50 kHz */
265 default:
266 spacing = 0.050 * FREQ_MUL; break;
267 };
268
269 /* Bottom of Band (MHz) */
270 switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
271 /* 0: 87.5 - 108 MHz (USA, Europe) */
272 case 0:
273 band_bottom = 87.5 * FREQ_MUL; break;
274 /* 1: 76 - 108 MHz (Japan wide band) */
275 default:
276 band_bottom = 76 * FREQ_MUL; break;
277 /* 2: 76 - 90 MHz (Japan) */
278 case 2:
279 band_bottom = 76 * FREQ_MUL; break;
280 };
281
282 /* Chan = [ Freq (Mhz) - Bottom of Band (MHz) ] / Spacing (kHz) */
283 chan = (freq - band_bottom) / spacing;
284
285 return si470x_set_chan(radio, chan);
286}
287
288
289/*
290 * si470x_set_seek - set seek
291 */
292static int si470x_set_seek(struct si470x_device *radio,
293 unsigned int wrap_around, unsigned int seek_upward)
294{
295 int retval = 0;
296 unsigned long timeout;
297 bool timed_out = 0;
298
299 /* start seeking */
300 radio->registers[POWERCFG] |= POWERCFG_SEEK;
301 if (wrap_around == 1)
302 radio->registers[POWERCFG] &= ~POWERCFG_SKMODE;
303 else
304 radio->registers[POWERCFG] |= POWERCFG_SKMODE;
305 if (seek_upward == 1)
306 radio->registers[POWERCFG] |= POWERCFG_SEEKUP;
307 else
308 radio->registers[POWERCFG] &= ~POWERCFG_SEEKUP;
309 retval = si470x_set_register(radio, POWERCFG);
310 if (retval < 0)
311 goto done;
312
313 /* wait till seek operation has completed */
314 timeout = jiffies + msecs_to_jiffies(seek_timeout);
315 do {
316 retval = si470x_get_register(radio, STATUSRSSI);
317 if (retval < 0)
318 goto stop;
319 timed_out = time_after(jiffies, timeout);
320 } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
321 (!timed_out));
322 if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
323 dev_warn(&radio->videodev->dev, "seek does not complete\n");
324 if (radio->registers[STATUSRSSI] & STATUSRSSI_SF)
325 dev_warn(&radio->videodev->dev,
326 "seek failed / band limit reached\n");
327 if (timed_out)
328 dev_warn(&radio->videodev->dev,
329 "seek timed out after %u ms\n", seek_timeout);
330
331stop:
332 /* stop seeking */
333 radio->registers[POWERCFG] &= ~POWERCFG_SEEK;
334 retval = si470x_set_register(radio, POWERCFG);
335
336done:
337 /* try again, if timed out */
338 if ((retval == 0) && timed_out)
339 retval = -EAGAIN;
340
341 return retval;
342}
343
344
345/*
346 * si470x_start - switch on radio
347 */
348int si470x_start(struct si470x_device *radio)
349{
350 int retval;
351
352 /* powercfg */
353 radio->registers[POWERCFG] =
354 POWERCFG_DMUTE | POWERCFG_ENABLE | POWERCFG_RDSM;
355 retval = si470x_set_register(radio, POWERCFG);
356 if (retval < 0)
357 goto done;
358
359 /* sysconfig 1 */
360 radio->registers[SYSCONFIG1] = SYSCONFIG1_DE;
361 retval = si470x_set_register(radio, SYSCONFIG1);
362 if (retval < 0)
363 goto done;
364
365 /* sysconfig 2 */
366 radio->registers[SYSCONFIG2] =
367 (0x3f << 8) | /* SEEKTH */
368 ((band << 6) & SYSCONFIG2_BAND) | /* BAND */
369 ((space << 4) & SYSCONFIG2_SPACE) | /* SPACE */
370 15; /* VOLUME (max) */
371 retval = si470x_set_register(radio, SYSCONFIG2);
372 if (retval < 0)
373 goto done;
374
375 /* reset last channel */
376 retval = si470x_set_chan(radio,
377 radio->registers[CHANNEL] & CHANNEL_CHAN);
378
379done:
380 return retval;
381}
382
383
384/*
385 * si470x_stop - switch off radio
386 */
387int si470x_stop(struct si470x_device *radio)
388{
389 int retval;
390
391 /* sysconfig 1 */
392 radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS;
393 retval = si470x_set_register(radio, SYSCONFIG1);
394 if (retval < 0)
395 goto done;
396
397 /* powercfg */
398 radio->registers[POWERCFG] &= ~POWERCFG_DMUTE;
399 /* POWERCFG_ENABLE has to automatically go low */
400 radio->registers[POWERCFG] |= POWERCFG_ENABLE | POWERCFG_DISABLE;
401 retval = si470x_set_register(radio, POWERCFG);
402
403done:
404 return retval;
405}
406
407
408/*
409 * si470x_rds_on - switch on rds reception
410 */
411int si470x_rds_on(struct si470x_device *radio)
412{
413 int retval;
414
415 /* sysconfig 1 */
416 mutex_lock(&radio->lock);
417 radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDS;
418 retval = si470x_set_register(radio, SYSCONFIG1);
419 if (retval < 0)
420 radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS;
421 mutex_unlock(&radio->lock);
422
423 return retval;
424}
425
426
427
428/**************************************************************************
429 * Video4Linux Interface
430 **************************************************************************/
431
432/*
433 * si470x_vidioc_queryctrl - enumerate control items
434 */
435static int si470x_vidioc_queryctrl(struct file *file, void *priv,
436 struct v4l2_queryctrl *qc)
437{
438 struct si470x_device *radio = video_drvdata(file);
439 int retval = -EINVAL;
440
441 /* abort if qc->id is below V4L2_CID_BASE */
442 if (qc->id < V4L2_CID_BASE)
443 goto done;
444
445 /* search video control */
446 switch (qc->id) {
447 case V4L2_CID_AUDIO_VOLUME:
448 return v4l2_ctrl_query_fill(qc, 0, 15, 1, 15);
449 case V4L2_CID_AUDIO_MUTE:
450 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
451 }
452
453 /* disable unsupported base controls */
454 /* to satisfy kradio and such apps */
455 if ((retval == -EINVAL) && (qc->id < V4L2_CID_LASTP1)) {
456 qc->flags = V4L2_CTRL_FLAG_DISABLED;
457 retval = 0;
458 }
459
460done:
461 if (retval < 0)
462 dev_warn(&radio->videodev->dev,
463 "query controls failed with %d\n", retval);
464 return retval;
465}
466
467
468/*
469 * si470x_vidioc_g_ctrl - get the value of a control
470 */
471static int si470x_vidioc_g_ctrl(struct file *file, void *priv,
472 struct v4l2_control *ctrl)
473{
474 struct si470x_device *radio = video_drvdata(file);
475 int retval = 0;
476
477 /* safety checks */
478 retval = si470x_disconnect_check(radio);
479 if (retval)
480 goto done;
481
482 switch (ctrl->id) {
483 case V4L2_CID_AUDIO_VOLUME:
484 ctrl->value = radio->registers[SYSCONFIG2] &
485 SYSCONFIG2_VOLUME;
486 break;
487 case V4L2_CID_AUDIO_MUTE:
488 ctrl->value = ((radio->registers[POWERCFG] &
489 POWERCFG_DMUTE) == 0) ? 1 : 0;
490 break;
491 default:
492 retval = -EINVAL;
493 }
494
495done:
496 if (retval < 0)
497 dev_warn(&radio->videodev->dev,
498 "get control failed with %d\n", retval);
499 return retval;
500}
501
502
503/*
504 * si470x_vidioc_s_ctrl - set the value of a control
505 */
506static int si470x_vidioc_s_ctrl(struct file *file, void *priv,
507 struct v4l2_control *ctrl)
508{
509 struct si470x_device *radio = video_drvdata(file);
510 int retval = 0;
511
512 /* safety checks */
513 retval = si470x_disconnect_check(radio);
514 if (retval)
515 goto done;
516
517 switch (ctrl->id) {
518 case V4L2_CID_AUDIO_VOLUME:
519 radio->registers[SYSCONFIG2] &= ~SYSCONFIG2_VOLUME;
520 radio->registers[SYSCONFIG2] |= ctrl->value;
521 retval = si470x_set_register(radio, SYSCONFIG2);
522 break;
523 case V4L2_CID_AUDIO_MUTE:
524 if (ctrl->value == 1)
525 radio->registers[POWERCFG] &= ~POWERCFG_DMUTE;
526 else
527 radio->registers[POWERCFG] |= POWERCFG_DMUTE;
528 retval = si470x_set_register(radio, POWERCFG);
529 break;
530 default:
531 retval = -EINVAL;
532 }
533
534done:
535 if (retval < 0)
536 dev_warn(&radio->videodev->dev,
537 "set control failed with %d\n", retval);
538 return retval;
539}
540
541
542/*
543 * si470x_vidioc_g_audio - get audio attributes
544 */
545static int si470x_vidioc_g_audio(struct file *file, void *priv,
546 struct v4l2_audio *audio)
547{
548 /* driver constants */
549 audio->index = 0;
550 strcpy(audio->name, "Radio");
551 audio->capability = V4L2_AUDCAP_STEREO;
552 audio->mode = 0;
553
554 return 0;
555}
556
557
558/*
559 * si470x_vidioc_g_tuner - get tuner attributes
560 */
561static int si470x_vidioc_g_tuner(struct file *file, void *priv,
562 struct v4l2_tuner *tuner)
563{
564 struct si470x_device *radio = video_drvdata(file);
565 int retval = 0;
566
567 /* safety checks */
568 retval = si470x_disconnect_check(radio);
569 if (retval)
570 goto done;
571
572 if (tuner->index != 0) {
573 retval = -EINVAL;
574 goto done;
575 }
576
577 retval = si470x_get_register(radio, STATUSRSSI);
578 if (retval < 0)
579 goto done;
580
581 /* driver constants */
582 strcpy(tuner->name, "FM");
583 tuner->type = V4L2_TUNER_RADIO;
584#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE)
585 tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
586 V4L2_TUNER_CAP_RDS;
587#else
588 tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
589#endif
590
591 /* range limits */
592 switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
593 /* 0: 87.5 - 108 MHz (USA, Europe, default) */
594 default:
595 tuner->rangelow = 87.5 * FREQ_MUL;
596 tuner->rangehigh = 108 * FREQ_MUL;
597 break;
598 /* 1: 76 - 108 MHz (Japan wide band) */
599 case 1:
600 tuner->rangelow = 76 * FREQ_MUL;
601 tuner->rangehigh = 108 * FREQ_MUL;
602 break;
603 /* 2: 76 - 90 MHz (Japan) */
604 case 2:
605 tuner->rangelow = 76 * FREQ_MUL;
606 tuner->rangehigh = 90 * FREQ_MUL;
607 break;
608 };
609
610 /* stereo indicator == stereo (instead of mono) */
611 if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 0)
612 tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
613 else
614 tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
615#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE)
616 /* If there is a reliable method of detecting an RDS channel,
617 then this code should check for that before setting this
618 RDS subchannel. */
619 tuner->rxsubchans |= V4L2_TUNER_SUB_RDS;
620#endif
621
622 /* mono/stereo selector */
623 if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 0)
624 tuner->audmode = V4L2_TUNER_MODE_STEREO;
625 else
626 tuner->audmode = V4L2_TUNER_MODE_MONO;
627
628 /* min is worst, max is best; signal:0..0xffff; rssi: 0..0xff */
629 /* measured in units of db쨉V in 1 db increments (max at ~75 db쨉V) */
630 tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI);
631 /* the ideal factor is 0xffff/75 = 873,8 */
632 tuner->signal = (tuner->signal * 873) + (8 * tuner->signal / 10);
633
634 /* automatic frequency control: -1: freq to low, 1 freq to high */
635 /* AFCRL does only indicate that freq. differs, not if too low/high */
636 tuner->afc = (radio->registers[STATUSRSSI] & STATUSRSSI_AFCRL) ? 1 : 0;
637
638done:
639 if (retval < 0)
640 dev_warn(&radio->videodev->dev,
641 "get tuner failed with %d\n", retval);
642 return retval;
643}
644
645
646/*
647 * si470x_vidioc_s_tuner - set tuner attributes
648 */
649static int si470x_vidioc_s_tuner(struct file *file, void *priv,
650 struct v4l2_tuner *tuner)
651{
652 struct si470x_device *radio = video_drvdata(file);
653 int retval = -EINVAL;
654
655 /* safety checks */
656 retval = si470x_disconnect_check(radio);
657 if (retval)
658 goto done;
659
660 if (tuner->index != 0)
661 goto done;
662
663 /* mono/stereo selector */
664 switch (tuner->audmode) {
665 case V4L2_TUNER_MODE_MONO:
666 radio->registers[POWERCFG] |= POWERCFG_MONO; /* force mono */
667 break;
668 case V4L2_TUNER_MODE_STEREO:
669 radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */
670 break;
671 default:
672 goto done;
673 }
674
675 retval = si470x_set_register(radio, POWERCFG);
676
677done:
678 if (retval < 0)
679 dev_warn(&radio->videodev->dev,
680 "set tuner failed with %d\n", retval);
681 return retval;
682}
683
684
685/*
686 * si470x_vidioc_g_frequency - get tuner or modulator radio frequency
687 */
688static int si470x_vidioc_g_frequency(struct file *file, void *priv,
689 struct v4l2_frequency *freq)
690{
691 struct si470x_device *radio = video_drvdata(file);
692 int retval = 0;
693
694 /* safety checks */
695 retval = si470x_disconnect_check(radio);
696 if (retval)
697 goto done;
698
699 if (freq->tuner != 0) {
700 retval = -EINVAL;
701 goto done;
702 }
703
704 freq->type = V4L2_TUNER_RADIO;
705 retval = si470x_get_freq(radio, &freq->frequency);
706
707done:
708 if (retval < 0)
709 dev_warn(&radio->videodev->dev,
710 "get frequency failed with %d\n", retval);
711 return retval;
712}
713
714
715/*
716 * si470x_vidioc_s_frequency - set tuner or modulator radio frequency
717 */
718static int si470x_vidioc_s_frequency(struct file *file, void *priv,
719 struct v4l2_frequency *freq)
720{
721 struct si470x_device *radio = video_drvdata(file);
722 int retval = 0;
723
724 /* safety checks */
725 retval = si470x_disconnect_check(radio);
726 if (retval)
727 goto done;
728
729 if (freq->tuner != 0) {
730 retval = -EINVAL;
731 goto done;
732 }
733
734 retval = si470x_set_freq(radio, freq->frequency);
735
736done:
737 if (retval < 0)
738 dev_warn(&radio->videodev->dev,
739 "set frequency failed with %d\n", retval);
740 return retval;
741}
742
743
744/*
745 * si470x_vidioc_s_hw_freq_seek - set hardware frequency seek
746 */
747static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv,
748 struct v4l2_hw_freq_seek *seek)
749{
750 struct si470x_device *radio = video_drvdata(file);
751 int retval = 0;
752
753 /* safety checks */
754 retval = si470x_disconnect_check(radio);
755 if (retval)
756 goto done;
757
758 if (seek->tuner != 0) {
759 retval = -EINVAL;
760 goto done;
761 }
762
763 retval = si470x_set_seek(radio, seek->wrap_around, seek->seek_upward);
764
765done:
766 if (retval < 0)
767 dev_warn(&radio->videodev->dev,
768 "set hardware frequency seek failed with %d\n", retval);
769 return retval;
770}
771
772
773/*
774 * si470x_ioctl_ops - video device ioctl operations
775 */
776static const struct v4l2_ioctl_ops si470x_ioctl_ops = {
777 .vidioc_querycap = si470x_vidioc_querycap,
778 .vidioc_queryctrl = si470x_vidioc_queryctrl,
779 .vidioc_g_ctrl = si470x_vidioc_g_ctrl,
780 .vidioc_s_ctrl = si470x_vidioc_s_ctrl,
781 .vidioc_g_audio = si470x_vidioc_g_audio,
782 .vidioc_g_tuner = si470x_vidioc_g_tuner,
783 .vidioc_s_tuner = si470x_vidioc_s_tuner,
784 .vidioc_g_frequency = si470x_vidioc_g_frequency,
785 .vidioc_s_frequency = si470x_vidioc_s_frequency,
786 .vidioc_s_hw_freq_seek = si470x_vidioc_s_hw_freq_seek,
787};
788
789
790/*
791 * si470x_viddev_template - video device interface
792 */
793struct video_device si470x_viddev_template = {
794 .fops = &si470x_fops,
795 .name = DRIVER_NAME,
796 .release = video_device_release,
797 .ioctl_ops = &si470x_ioctl_ops,
798};
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c
new file mode 100644
index 000000000000..2d53b6a9409b
--- /dev/null
+++ b/drivers/media/radio/si470x/radio-si470x-i2c.c
@@ -0,0 +1,401 @@
1/*
2 * drivers/media/radio/si470x/radio-si470x-i2c.c
3 *
4 * I2C driver for radios with Silicon Labs Si470x FM Radio Receivers
5 *
6 * Copyright (c) 2009 Samsung Electronics Co.Ltd
7 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24
25/*
26 * ToDo:
27 * - RDS support
28 */
29
30
31/* driver definitions */
32#define DRIVER_AUTHOR "Joonyoung Shim <jy0922.shim@samsung.com>";
33#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 0)
34#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
35#define DRIVER_DESC "I2C radio driver for Si470x FM Radio Receivers"
36#define DRIVER_VERSION "1.0.0"
37
38/* kernel includes */
39#include <linux/i2c.h>
40#include <linux/delay.h>
41
42#include "radio-si470x.h"
43
44
45/* I2C Device ID List */
46static const struct i2c_device_id si470x_i2c_id[] = {
47 /* Generic Entry */
48 { "si470x", 0 },
49 /* Terminating entry */
50 { }
51};
52MODULE_DEVICE_TABLE(i2c, si470x_i2c_id);
53
54
55
56/**************************************************************************
57 * Module Parameters
58 **************************************************************************/
59
60/* Radio Nr */
61static int radio_nr = -1;
62module_param(radio_nr, int, 0444);
63MODULE_PARM_DESC(radio_nr, "Radio Nr");
64
65
66
67/**************************************************************************
68 * I2C Definitions
69 **************************************************************************/
70
71/* Write starts with the upper byte of register 0x02 */
72#define WRITE_REG_NUM 8
73#define WRITE_INDEX(i) (i + 0x02)
74
75/* Read starts with the upper byte of register 0x0a */
76#define READ_REG_NUM RADIO_REGISTER_NUM
77#define READ_INDEX(i) ((i + RADIO_REGISTER_NUM - 0x0a) % READ_REG_NUM)
78
79
80
81/**************************************************************************
82 * General Driver Functions - REGISTERs
83 **************************************************************************/
84
85/*
86 * si470x_get_register - read register
87 */
88int si470x_get_register(struct si470x_device *radio, int regnr)
89{
90 u16 buf[READ_REG_NUM];
91 struct i2c_msg msgs[1] = {
92 { radio->client->addr, I2C_M_RD, sizeof(u16) * READ_REG_NUM,
93 (void *)buf },
94 };
95
96 if (i2c_transfer(radio->client->adapter, msgs, 1) != 1)
97 return -EIO;
98
99 radio->registers[regnr] = __be16_to_cpu(buf[READ_INDEX(regnr)]);
100
101 return 0;
102}
103
104
105/*
106 * si470x_set_register - write register
107 */
108int si470x_set_register(struct si470x_device *radio, int regnr)
109{
110 int i;
111 u16 buf[WRITE_REG_NUM];
112 struct i2c_msg msgs[1] = {
113 { radio->client->addr, 0, sizeof(u16) * WRITE_REG_NUM,
114 (void *)buf },
115 };
116
117 for (i = 0; i < WRITE_REG_NUM; i++)
118 buf[i] = __cpu_to_be16(radio->registers[WRITE_INDEX(i)]);
119
120 if (i2c_transfer(radio->client->adapter, msgs, 1) != 1)
121 return -EIO;
122
123 return 0;
124}
125
126
127
128/**************************************************************************
129 * General Driver Functions - ENTIRE REGISTERS
130 **************************************************************************/
131
132/*
133 * si470x_get_all_registers - read entire registers
134 */
135static int si470x_get_all_registers(struct si470x_device *radio)
136{
137 int i;
138 u16 buf[READ_REG_NUM];
139 struct i2c_msg msgs[1] = {
140 { radio->client->addr, I2C_M_RD, sizeof(u16) * READ_REG_NUM,
141 (void *)buf },
142 };
143
144 if (i2c_transfer(radio->client->adapter, msgs, 1) != 1)
145 return -EIO;
146
147 for (i = 0; i < READ_REG_NUM; i++)
148 radio->registers[i] = __be16_to_cpu(buf[READ_INDEX(i)]);
149
150 return 0;
151}
152
153
154
155/**************************************************************************
156 * General Driver Functions - DISCONNECT_CHECK
157 **************************************************************************/
158
159/*
160 * si470x_disconnect_check - check whether radio disconnects
161 */
162int si470x_disconnect_check(struct si470x_device *radio)
163{
164 return 0;
165}
166
167
168
169/**************************************************************************
170 * File Operations Interface
171 **************************************************************************/
172
173/*
174 * si470x_fops_open - file open
175 */
176static int si470x_fops_open(struct file *file)
177{
178 struct si470x_device *radio = video_drvdata(file);
179 int retval = 0;
180
181 mutex_lock(&radio->lock);
182 radio->users++;
183
184 if (radio->users == 1)
185 /* start radio */
186 retval = si470x_start(radio);
187
188 mutex_unlock(&radio->lock);
189
190 return retval;
191}
192
193
194/*
195 * si470x_fops_release - file release
196 */
197static int si470x_fops_release(struct file *file)
198{
199 struct si470x_device *radio = video_drvdata(file);
200 int retval = 0;
201
202 /* safety check */
203 if (!radio)
204 return -ENODEV;
205
206 mutex_lock(&radio->lock);
207 radio->users--;
208 if (radio->users == 0)
209 /* stop radio */
210 retval = si470x_stop(radio);
211
212 mutex_unlock(&radio->lock);
213
214 return retval;
215}
216
217
218/*
219 * si470x_fops - file operations interface
220 */
221const struct v4l2_file_operations si470x_fops = {
222 .owner = THIS_MODULE,
223 .ioctl = video_ioctl2,
224 .open = si470x_fops_open,
225 .release = si470x_fops_release,
226};
227
228
229
230/**************************************************************************
231 * Video4Linux Interface
232 **************************************************************************/
233
234/*
235 * si470x_vidioc_querycap - query device capabilities
236 */
237int si470x_vidioc_querycap(struct file *file, void *priv,
238 struct v4l2_capability *capability)
239{
240 strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
241 strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
242 capability->version = DRIVER_KERNEL_VERSION;
243 capability->capabilities = V4L2_CAP_HW_FREQ_SEEK |
244 V4L2_CAP_TUNER | V4L2_CAP_RADIO;
245
246 return 0;
247}
248
249
250
251/**************************************************************************
252 * I2C Interface
253 **************************************************************************/
254
255/*
256 * si470x_i2c_probe - probe for the device
257 */
258static int __devinit si470x_i2c_probe(struct i2c_client *client,
259 const struct i2c_device_id *id)
260{
261 struct si470x_device *radio;
262 int retval = 0;
263 unsigned char version_warning = 0;
264
265 /* private data allocation and initialization */
266 radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL);
267 if (!radio) {
268 retval = -ENOMEM;
269 goto err_initial;
270 }
271 radio->users = 0;
272 radio->client = client;
273 mutex_init(&radio->lock);
274
275 /* video device allocation and initialization */
276 radio->videodev = video_device_alloc();
277 if (!radio->videodev) {
278 retval = -ENOMEM;
279 goto err_radio;
280 }
281 memcpy(radio->videodev, &si470x_viddev_template,
282 sizeof(si470x_viddev_template));
283 video_set_drvdata(radio->videodev, radio);
284
285 /* power up : need 110ms */
286 radio->registers[POWERCFG] = POWERCFG_ENABLE;
287 if (si470x_set_register(radio, POWERCFG) < 0) {
288 retval = -EIO;
289 goto err_all;
290 }
291 msleep(110);
292
293 /* get device and chip versions */
294 if (si470x_get_all_registers(radio) < 0) {
295 retval = -EIO;
296 goto err_video;
297 }
298 dev_info(&client->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
299 radio->registers[DEVICEID], radio->registers[CHIPID]);
300 if ((radio->registers[CHIPID] & CHIPID_FIRMWARE) < RADIO_FW_VERSION) {
301 dev_warn(&client->dev,
302 "This driver is known to work with "
303 "firmware version %hu,\n", RADIO_FW_VERSION);
304 dev_warn(&client->dev,
305 "but the device has firmware version %hu.\n",
306 radio->registers[CHIPID] & CHIPID_FIRMWARE);
307 version_warning = 1;
308 }
309
310 /* give out version warning */
311 if (version_warning == 1) {
312 dev_warn(&client->dev,
313 "If you have some trouble using this driver,\n");
314 dev_warn(&client->dev,
315 "please report to V4L ML at "
316 "linux-media@vger.kernel.org\n");
317 }
318
319 /* set initial frequency */
320 si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
321
322 /* register video device */
323 retval = video_register_device(radio->videodev, VFL_TYPE_RADIO,
324 radio_nr);
325 if (retval) {
326 dev_warn(&client->dev, "Could not register video device\n");
327 goto err_all;
328 }
329 i2c_set_clientdata(client, radio);
330
331 return 0;
332err_all:
333err_video:
334 video_device_release(radio->videodev);
335err_radio:
336 kfree(radio);
337err_initial:
338 return retval;
339}
340
341
342/*
343 * si470x_i2c_remove - remove the device
344 */
345static __devexit int si470x_i2c_remove(struct i2c_client *client)
346{
347 struct si470x_device *radio = i2c_get_clientdata(client);
348
349 video_unregister_device(radio->videodev);
350 kfree(radio);
351 i2c_set_clientdata(client, NULL);
352
353 return 0;
354}
355
356
357/*
358 * si470x_i2c_driver - i2c driver interface
359 */
360static struct i2c_driver si470x_i2c_driver = {
361 .driver = {
362 .name = "si470x",
363 .owner = THIS_MODULE,
364 },
365 .probe = si470x_i2c_probe,
366 .remove = __devexit_p(si470x_i2c_remove),
367 .id_table = si470x_i2c_id,
368};
369
370
371
372/**************************************************************************
373 * Module Interface
374 **************************************************************************/
375
376/*
377 * si470x_i2c_init - module init
378 */
379static int __init si470x_i2c_init(void)
380{
381 printk(KERN_INFO DRIVER_DESC ", Version " DRIVER_VERSION "\n");
382 return i2c_add_driver(&si470x_i2c_driver);
383}
384
385
386/*
387 * si470x_i2c_exit - module exit
388 */
389static void __exit si470x_i2c_exit(void)
390{
391 i2c_del_driver(&si470x_i2c_driver);
392}
393
394
395module_init(si470x_i2c_init);
396module_exit(si470x_i2c_exit);
397
398MODULE_LICENSE("GPL");
399MODULE_AUTHOR(DRIVER_AUTHOR);
400MODULE_DESCRIPTION(DRIVER_DESC);
401MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c
new file mode 100644
index 000000000000..f2d0e1ddb301
--- /dev/null
+++ b/drivers/media/radio/si470x/radio-si470x-usb.c
@@ -0,0 +1,988 @@
1/*
2 * drivers/media/radio/si470x/radio-si470x-usb.c
3 *
4 * USB driver for radios with Silicon Labs Si470x FM Radio Receivers
5 *
6 * Copyright (c) 2009 Tobias Lorenz <tobias.lorenz@gmx.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23
24/*
25 * ToDo:
26 * - add firmware download/update support
27 */
28
29
30/* driver definitions */
31#define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>"
32#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 10)
33#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
34#define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers"
35#define DRIVER_VERSION "1.0.10"
36
37/* kernel includes */
38#include <linux/usb.h>
39#include <linux/hid.h>
40
41#include "radio-si470x.h"
42
43
44/* USB Device ID List */
45static struct usb_device_id si470x_usb_driver_id_table[] = {
46 /* Silicon Labs USB FM Radio Reference Design */
47 { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) },
48 /* ADS/Tech FM Radio Receiver (formerly Instant FM Music) */
49 { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) },
50 /* KWorld USB FM Radio SnapMusic Mobile 700 (FM700) */
51 { USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) },
52 /* Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear) */
53 { USB_DEVICE_AND_INTERFACE_INFO(0x10c5, 0x819a, USB_CLASS_HID, 0, 0) },
54 /* Terminating entry */
55 { }
56};
57MODULE_DEVICE_TABLE(usb, si470x_usb_driver_id_table);
58
59
60
61/**************************************************************************
62 * Module Parameters
63 **************************************************************************/
64
65/* Radio Nr */
66static int radio_nr = -1;
67module_param(radio_nr, int, 0444);
68MODULE_PARM_DESC(radio_nr, "Radio Nr");
69
70/* USB timeout */
71static unsigned int usb_timeout = 500;
72module_param(usb_timeout, uint, 0644);
73MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*");
74
75/* RDS buffer blocks */
76static unsigned int rds_buf = 100;
77module_param(rds_buf, uint, 0444);
78MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
79
80/* RDS maximum block errors */
81static unsigned short max_rds_errors = 1;
82/* 0 means 0 errors requiring correction */
83/* 1 means 1-2 errors requiring correction (used by original USBRadio.exe) */
84/* 2 means 3-5 errors requiring correction */
85/* 3 means 6+ errors or errors in checkword, correction not possible */
86module_param(max_rds_errors, ushort, 0644);
87MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
88
89
90
91/**************************************************************************
92 * USB HID Reports
93 **************************************************************************/
94
95/* Reports 1-16 give direct read/write access to the 16 Si470x registers */
96/* with the (REPORT_ID - 1) corresponding to the register address across USB */
97/* endpoint 0 using GET_REPORT and SET_REPORT */
98#define REGISTER_REPORT_SIZE (RADIO_REGISTER_SIZE + 1)
99#define REGISTER_REPORT(reg) ((reg) + 1)
100
101/* Report 17 gives direct read/write access to the entire Si470x register */
102/* map across endpoint 0 using GET_REPORT and SET_REPORT */
103#define ENTIRE_REPORT_SIZE (RADIO_REGISTER_NUM * RADIO_REGISTER_SIZE + 1)
104#define ENTIRE_REPORT 17
105
106/* Report 18 is used to send the lowest 6 Si470x registers up the HID */
107/* interrupt endpoint 1 to Windows every 20 milliseconds for status */
108#define RDS_REPORT_SIZE (RDS_REGISTER_NUM * RADIO_REGISTER_SIZE + 1)
109#define RDS_REPORT 18
110
111/* Report 19: LED state */
112#define LED_REPORT_SIZE 3
113#define LED_REPORT 19
114
115/* Report 19: stream */
116#define STREAM_REPORT_SIZE 3
117#define STREAM_REPORT 19
118
119/* Report 20: scratch */
120#define SCRATCH_PAGE_SIZE 63
121#define SCRATCH_REPORT_SIZE (SCRATCH_PAGE_SIZE + 1)
122#define SCRATCH_REPORT 20
123
124/* Reports 19-22: flash upgrade of the C8051F321 */
125#define WRITE_REPORT_SIZE 4
126#define WRITE_REPORT 19
127#define FLASH_REPORT_SIZE 64
128#define FLASH_REPORT 20
129#define CRC_REPORT_SIZE 3
130#define CRC_REPORT 21
131#define RESPONSE_REPORT_SIZE 2
132#define RESPONSE_REPORT 22
133
134/* Report 23: currently unused, but can accept 60 byte reports on the HID */
135/* interrupt out endpoint 2 every 1 millisecond */
136#define UNUSED_REPORT 23
137
138
139
140/**************************************************************************
141 * Software/Hardware Versions from Scratch Page
142 **************************************************************************/
143#define RADIO_SW_VERSION_NOT_BOOTLOADABLE 6
144#define RADIO_SW_VERSION 7
145#define RADIO_HW_VERSION 1
146
147
148
149/**************************************************************************
150 * LED State Definitions
151 **************************************************************************/
152#define LED_COMMAND 0x35
153
154#define NO_CHANGE_LED 0x00
155#define ALL_COLOR_LED 0x01 /* streaming state */
156#define BLINK_GREEN_LED 0x02 /* connect state */
157#define BLINK_RED_LED 0x04
158#define BLINK_ORANGE_LED 0x10 /* disconnect state */
159#define SOLID_GREEN_LED 0x20 /* tuning/seeking state */
160#define SOLID_RED_LED 0x40 /* bootload state */
161#define SOLID_ORANGE_LED 0x80
162
163
164
165/**************************************************************************
166 * Stream State Definitions
167 **************************************************************************/
168#define STREAM_COMMAND 0x36
169#define STREAM_VIDPID 0x00
170#define STREAM_AUDIO 0xff
171
172
173
174/**************************************************************************
175 * Bootloader / Flash Commands
176 **************************************************************************/
177
178/* unique id sent to bootloader and required to put into a bootload state */
179#define UNIQUE_BL_ID 0x34
180
181/* mask for the flash data */
182#define FLASH_DATA_MASK 0x55
183
184/* bootloader commands */
185#define GET_SW_VERSION_COMMAND 0x00
186#define SET_PAGE_COMMAND 0x01
187#define ERASE_PAGE_COMMAND 0x02
188#define WRITE_PAGE_COMMAND 0x03
189#define CRC_ON_PAGE_COMMAND 0x04
190#define READ_FLASH_BYTE_COMMAND 0x05
191#define RESET_DEVICE_COMMAND 0x06
192#define GET_HW_VERSION_COMMAND 0x07
193#define BLANK 0xff
194
195/* bootloader command responses */
196#define COMMAND_OK 0x01
197#define COMMAND_FAILED 0x02
198#define COMMAND_PENDING 0x03
199
200
201
202/**************************************************************************
203 * General Driver Functions - REGISTER_REPORTs
204 **************************************************************************/
205
206/*
207 * si470x_get_report - receive a HID report
208 */
209static int si470x_get_report(struct si470x_device *radio, void *buf, int size)
210{
211 unsigned char *report = (unsigned char *) buf;
212 int retval;
213
214 retval = usb_control_msg(radio->usbdev,
215 usb_rcvctrlpipe(radio->usbdev, 0),
216 HID_REQ_GET_REPORT,
217 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
218 report[0], 2,
219 buf, size, usb_timeout);
220
221 if (retval < 0)
222 dev_warn(&radio->intf->dev,
223 "si470x_get_report: usb_control_msg returned %d\n",
224 retval);
225 return retval;
226}
227
228
229/*
230 * si470x_set_report - send a HID report
231 */
232static int si470x_set_report(struct si470x_device *radio, void *buf, int size)
233{
234 unsigned char *report = (unsigned char *) buf;
235 int retval;
236
237 retval = usb_control_msg(radio->usbdev,
238 usb_sndctrlpipe(radio->usbdev, 0),
239 HID_REQ_SET_REPORT,
240 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
241 report[0], 2,
242 buf, size, usb_timeout);
243
244 if (retval < 0)
245 dev_warn(&radio->intf->dev,
246 "si470x_set_report: usb_control_msg returned %d\n",
247 retval);
248 return retval;
249}
250
251
252/*
253 * si470x_get_register - read register
254 */
255int si470x_get_register(struct si470x_device *radio, int regnr)
256{
257 unsigned char buf[REGISTER_REPORT_SIZE];
258 int retval;
259
260 buf[0] = REGISTER_REPORT(regnr);
261
262 retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
263
264 if (retval >= 0)
265 radio->registers[regnr] = get_unaligned_be16(&buf[1]);
266
267 return (retval < 0) ? -EINVAL : 0;
268}
269
270
271/*
272 * si470x_set_register - write register
273 */
274int si470x_set_register(struct si470x_device *radio, int regnr)
275{
276 unsigned char buf[REGISTER_REPORT_SIZE];
277 int retval;
278
279 buf[0] = REGISTER_REPORT(regnr);
280 put_unaligned_be16(radio->registers[regnr], &buf[1]);
281
282 retval = si470x_set_report(radio, (void *) &buf, sizeof(buf));
283
284 return (retval < 0) ? -EINVAL : 0;
285}
286
287
288
289/**************************************************************************
290 * General Driver Functions - ENTIRE_REPORT
291 **************************************************************************/
292
293/*
294 * si470x_get_all_registers - read entire registers
295 */
296static int si470x_get_all_registers(struct si470x_device *radio)
297{
298 unsigned char buf[ENTIRE_REPORT_SIZE];
299 int retval;
300 unsigned char regnr;
301
302 buf[0] = ENTIRE_REPORT;
303
304 retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
305
306 if (retval >= 0)
307 for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
308 radio->registers[regnr] = get_unaligned_be16(
309 &buf[regnr * RADIO_REGISTER_SIZE + 1]);
310
311 return (retval < 0) ? -EINVAL : 0;
312}
313
314
315
316/**************************************************************************
317 * General Driver Functions - LED_REPORT
318 **************************************************************************/
319
320/*
321 * si470x_set_led_state - sets the led state
322 */
323static int si470x_set_led_state(struct si470x_device *radio,
324 unsigned char led_state)
325{
326 unsigned char buf[LED_REPORT_SIZE];
327 int retval;
328
329 buf[0] = LED_REPORT;
330 buf[1] = LED_COMMAND;
331 buf[2] = led_state;
332
333 retval = si470x_set_report(radio, (void *) &buf, sizeof(buf));
334
335 return (retval < 0) ? -EINVAL : 0;
336}
337
338
339
340/**************************************************************************
341 * General Driver Functions - SCRATCH_REPORT
342 **************************************************************************/
343
344/*
345 * si470x_get_scratch_versions - gets the scratch page and version infos
346 */
347static int si470x_get_scratch_page_versions(struct si470x_device *radio)
348{
349 unsigned char buf[SCRATCH_REPORT_SIZE];
350 int retval;
351
352 buf[0] = SCRATCH_REPORT;
353
354 retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
355
356 if (retval < 0)
357 dev_warn(&radio->intf->dev, "si470x_get_scratch: "
358 "si470x_get_report returned %d\n", retval);
359 else {
360 radio->software_version = buf[1];
361 radio->hardware_version = buf[2];
362 }
363
364 return (retval < 0) ? -EINVAL : 0;
365}
366
367
368
369/**************************************************************************
370 * General Driver Functions - DISCONNECT_CHECK
371 **************************************************************************/
372
373/*
374 * si470x_disconnect_check - check whether radio disconnects
375 */
376int si470x_disconnect_check(struct si470x_device *radio)
377{
378 if (radio->disconnected)
379 return -EIO;
380 else
381 return 0;
382}
383
384
385
386/**************************************************************************
387 * RDS Driver Functions
388 **************************************************************************/
389
390/*
391 * si470x_int_in_callback - rds callback and processing function
392 *
393 * TODO: do we need to use mutex locks in some sections?
394 */
395static void si470x_int_in_callback(struct urb *urb)
396{
397 struct si470x_device *radio = urb->context;
398 unsigned char buf[RDS_REPORT_SIZE];
399 int retval;
400 unsigned char regnr;
401 unsigned char blocknum;
402 unsigned short bler; /* rds block errors */
403 unsigned short rds;
404 unsigned char tmpbuf[3];
405
406 if (urb->status) {
407 if (urb->status == -ENOENT ||
408 urb->status == -ECONNRESET ||
409 urb->status == -ESHUTDOWN) {
410 return;
411 } else {
412 dev_warn(&radio->intf->dev,
413 "non-zero urb status (%d)\n", urb->status);
414 goto resubmit; /* Maybe we can recover. */
415 }
416 }
417
418 /* safety checks */
419 if (radio->disconnected)
420 return;
421 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
422 goto resubmit;
423
424 if (urb->actual_length > 0) {
425 /* Update RDS registers with URB data */
426 buf[0] = RDS_REPORT;
427 for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
428 radio->registers[STATUSRSSI + regnr] =
429 get_unaligned_be16(&radio->int_in_buffer[
430 regnr * RADIO_REGISTER_SIZE + 1]);
431 /* get rds blocks */
432 if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0) {
433 /* No RDS group ready, better luck next time */
434 goto resubmit;
435 }
436 if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSS) == 0) {
437 /* RDS decoder not synchronized */
438 goto resubmit;
439 }
440 for (blocknum = 0; blocknum < 4; blocknum++) {
441 switch (blocknum) {
442 default:
443 bler = (radio->registers[STATUSRSSI] &
444 STATUSRSSI_BLERA) >> 9;
445 rds = radio->registers[RDSA];
446 break;
447 case 1:
448 bler = (radio->registers[READCHAN] &
449 READCHAN_BLERB) >> 14;
450 rds = radio->registers[RDSB];
451 break;
452 case 2:
453 bler = (radio->registers[READCHAN] &
454 READCHAN_BLERC) >> 12;
455 rds = radio->registers[RDSC];
456 break;
457 case 3:
458 bler = (radio->registers[READCHAN] &
459 READCHAN_BLERD) >> 10;
460 rds = radio->registers[RDSD];
461 break;
462 };
463
464 /* Fill the V4L2 RDS buffer */
465 put_unaligned_le16(rds, &tmpbuf);
466 tmpbuf[2] = blocknum; /* offset name */
467 tmpbuf[2] |= blocknum << 3; /* received offset */
468 if (bler > max_rds_errors)
469 tmpbuf[2] |= 0x80; /* uncorrectable errors */
470 else if (bler > 0)
471 tmpbuf[2] |= 0x40; /* corrected error(s) */
472
473 /* copy RDS block to internal buffer */
474 memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3);
475 radio->wr_index += 3;
476
477 /* wrap write pointer */
478 if (radio->wr_index >= radio->buf_size)
479 radio->wr_index = 0;
480
481 /* check for overflow */
482 if (radio->wr_index == radio->rd_index) {
483 /* increment and wrap read pointer */
484 radio->rd_index += 3;
485 if (radio->rd_index >= radio->buf_size)
486 radio->rd_index = 0;
487 }
488 }
489 if (radio->wr_index != radio->rd_index)
490 wake_up_interruptible(&radio->read_queue);
491 }
492
493resubmit:
494 /* Resubmit if we're still running. */
495 if (radio->int_in_running && radio->usbdev) {
496 retval = usb_submit_urb(radio->int_in_urb, GFP_ATOMIC);
497 if (retval) {
498 dev_warn(&radio->intf->dev,
499 "resubmitting urb failed (%d)", retval);
500 radio->int_in_running = 0;
501 }
502 }
503}
504
505
506
507/**************************************************************************
508 * File Operations Interface
509 **************************************************************************/
510
511/*
512 * si470x_fops_read - read RDS data
513 */
514static ssize_t si470x_fops_read(struct file *file, char __user *buf,
515 size_t count, loff_t *ppos)
516{
517 struct si470x_device *radio = video_drvdata(file);
518 int retval = 0;
519 unsigned int block_count = 0;
520
521 /* switch on rds reception */
522 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
523 si470x_rds_on(radio);
524
525 /* block if no new data available */
526 while (radio->wr_index == radio->rd_index) {
527 if (file->f_flags & O_NONBLOCK) {
528 retval = -EWOULDBLOCK;
529 goto done;
530 }
531 if (wait_event_interruptible(radio->read_queue,
532 radio->wr_index != radio->rd_index) < 0) {
533 retval = -EINTR;
534 goto done;
535 }
536 }
537
538 /* calculate block count from byte count */
539 count /= 3;
540
541 /* copy RDS block out of internal buffer and to user buffer */
542 mutex_lock(&radio->lock);
543 while (block_count < count) {
544 if (radio->rd_index == radio->wr_index)
545 break;
546
547 /* always transfer rds complete blocks */
548 if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3))
549 /* retval = -EFAULT; */
550 break;
551
552 /* increment and wrap read pointer */
553 radio->rd_index += 3;
554 if (radio->rd_index >= radio->buf_size)
555 radio->rd_index = 0;
556
557 /* increment counters */
558 block_count++;
559 buf += 3;
560 retval += 3;
561 }
562 mutex_unlock(&radio->lock);
563
564done:
565 return retval;
566}
567
568
569/*
570 * si470x_fops_poll - poll RDS data
571 */
572static unsigned int si470x_fops_poll(struct file *file,
573 struct poll_table_struct *pts)
574{
575 struct si470x_device *radio = video_drvdata(file);
576 int retval = 0;
577
578 /* switch on rds reception */
579 if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
580 si470x_rds_on(radio);
581
582 poll_wait(file, &radio->read_queue, pts);
583
584 if (radio->rd_index != radio->wr_index)
585 retval = POLLIN | POLLRDNORM;
586
587 return retval;
588}
589
590
591/*
592 * si470x_fops_open - file open
593 */
594static int si470x_fops_open(struct file *file)
595{
596 struct si470x_device *radio = video_drvdata(file);
597 int retval;
598
599 lock_kernel();
600 radio->users++;
601
602 retval = usb_autopm_get_interface(radio->intf);
603 if (retval < 0) {
604 radio->users--;
605 retval = -EIO;
606 goto done;
607 }
608
609 if (radio->users == 1) {
610 /* start radio */
611 retval = si470x_start(radio);
612 if (retval < 0) {
613 usb_autopm_put_interface(radio->intf);
614 goto done;
615 }
616
617 /* initialize interrupt urb */
618 usb_fill_int_urb(radio->int_in_urb, radio->usbdev,
619 usb_rcvintpipe(radio->usbdev,
620 radio->int_in_endpoint->bEndpointAddress),
621 radio->int_in_buffer,
622 le16_to_cpu(radio->int_in_endpoint->wMaxPacketSize),
623 si470x_int_in_callback,
624 radio,
625 radio->int_in_endpoint->bInterval);
626
627 radio->int_in_running = 1;
628 mb();
629
630 retval = usb_submit_urb(radio->int_in_urb, GFP_KERNEL);
631 if (retval) {
632 dev_info(&radio->intf->dev,
633 "submitting int urb failed (%d)\n", retval);
634 radio->int_in_running = 0;
635 usb_autopm_put_interface(radio->intf);
636 }
637 }
638
639done:
640 unlock_kernel();
641 return retval;
642}
643
644
645/*
646 * si470x_fops_release - file release
647 */
648static int si470x_fops_release(struct file *file)
649{
650 struct si470x_device *radio = video_drvdata(file);
651 int retval = 0;
652
653 /* safety check */
654 if (!radio) {
655 retval = -ENODEV;
656 goto done;
657 }
658
659 mutex_lock(&radio->disconnect_lock);
660 radio->users--;
661 if (radio->users == 0) {
662 /* shutdown interrupt handler */
663 if (radio->int_in_running) {
664 radio->int_in_running = 0;
665 if (radio->int_in_urb)
666 usb_kill_urb(radio->int_in_urb);
667 }
668
669 if (radio->disconnected) {
670 video_unregister_device(radio->videodev);
671 kfree(radio->int_in_buffer);
672 kfree(radio->buffer);
673 kfree(radio);
674 goto unlock;
675 }
676
677 /* cancel read processes */
678 wake_up_interruptible(&radio->read_queue);
679
680 /* stop radio */
681 retval = si470x_stop(radio);
682 usb_autopm_put_interface(radio->intf);
683 }
684unlock:
685 mutex_unlock(&radio->disconnect_lock);
686done:
687 return retval;
688}
689
690
691/*
692 * si470x_fops - file operations interface
693 */
694const struct v4l2_file_operations si470x_fops = {
695 .owner = THIS_MODULE,
696 .read = si470x_fops_read,
697 .poll = si470x_fops_poll,
698 .ioctl = video_ioctl2,
699 .open = si470x_fops_open,
700 .release = si470x_fops_release,
701};
702
703
704
705/**************************************************************************
706 * Video4Linux Interface
707 **************************************************************************/
708
709/*
710 * si470x_vidioc_querycap - query device capabilities
711 */
712int si470x_vidioc_querycap(struct file *file, void *priv,
713 struct v4l2_capability *capability)
714{
715 struct si470x_device *radio = video_drvdata(file);
716
717 strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
718 strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
719 usb_make_path(radio->usbdev, capability->bus_info,
720 sizeof(capability->bus_info));
721 capability->version = DRIVER_KERNEL_VERSION;
722 capability->capabilities = V4L2_CAP_HW_FREQ_SEEK |
723 V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE;
724
725 return 0;
726}
727
728
729
730/**************************************************************************
731 * USB Interface
732 **************************************************************************/
733
734/*
735 * si470x_usb_driver_probe - probe for the device
736 */
737static int si470x_usb_driver_probe(struct usb_interface *intf,
738 const struct usb_device_id *id)
739{
740 struct si470x_device *radio;
741 struct usb_host_interface *iface_desc;
742 struct usb_endpoint_descriptor *endpoint;
743 int i, int_end_size, retval = 0;
744 unsigned char version_warning = 0;
745
746 /* private data allocation and initialization */
747 radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL);
748 if (!radio) {
749 retval = -ENOMEM;
750 goto err_initial;
751 }
752 radio->users = 0;
753 radio->disconnected = 0;
754 radio->usbdev = interface_to_usbdev(intf);
755 radio->intf = intf;
756 mutex_init(&radio->disconnect_lock);
757 mutex_init(&radio->lock);
758
759 iface_desc = intf->cur_altsetting;
760
761 /* Set up interrupt endpoint information. */
762 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
763 endpoint = &iface_desc->endpoint[i].desc;
764 if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==
765 USB_DIR_IN) && ((endpoint->bmAttributes &
766 USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT))
767 radio->int_in_endpoint = endpoint;
768 }
769 if (!radio->int_in_endpoint) {
770 dev_info(&intf->dev, "could not find interrupt in endpoint\n");
771 retval = -EIO;
772 goto err_radio;
773 }
774
775 int_end_size = le16_to_cpu(radio->int_in_endpoint->wMaxPacketSize);
776
777 radio->int_in_buffer = kmalloc(int_end_size, GFP_KERNEL);
778 if (!radio->int_in_buffer) {
779 dev_info(&intf->dev, "could not allocate int_in_buffer");
780 retval = -ENOMEM;
781 goto err_radio;
782 }
783
784 radio->int_in_urb = usb_alloc_urb(0, GFP_KERNEL);
785 if (!radio->int_in_urb) {
786 dev_info(&intf->dev, "could not allocate int_in_urb");
787 retval = -ENOMEM;
788 goto err_intbuffer;
789 }
790
791 /* video device allocation and initialization */
792 radio->videodev = video_device_alloc();
793 if (!radio->videodev) {
794 retval = -ENOMEM;
795 goto err_intbuffer;
796 }
797 memcpy(radio->videodev, &si470x_viddev_template,
798 sizeof(si470x_viddev_template));
799 video_set_drvdata(radio->videodev, radio);
800
801 /* get device and chip versions */
802 if (si470x_get_all_registers(radio) < 0) {
803 retval = -EIO;
804 goto err_video;
805 }
806 dev_info(&intf->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
807 radio->registers[DEVICEID], radio->registers[CHIPID]);
808 if ((radio->registers[CHIPID] & CHIPID_FIRMWARE) < RADIO_FW_VERSION) {
809 dev_warn(&intf->dev,
810 "This driver is known to work with "
811 "firmware version %hu,\n", RADIO_FW_VERSION);
812 dev_warn(&intf->dev,
813 "but the device has firmware version %hu.\n",
814 radio->registers[CHIPID] & CHIPID_FIRMWARE);
815 version_warning = 1;
816 }
817
818 /* get software and hardware versions */
819 if (si470x_get_scratch_page_versions(radio) < 0) {
820 retval = -EIO;
821 goto err_video;
822 }
823 dev_info(&intf->dev, "software version %d, hardware version %d\n",
824 radio->software_version, radio->hardware_version);
825 if (radio->software_version < RADIO_SW_VERSION) {
826 dev_warn(&intf->dev,
827 "This driver is known to work with "
828 "software version %hu,\n", RADIO_SW_VERSION);
829 dev_warn(&intf->dev,
830 "but the device has software version %hu.\n",
831 radio->software_version);
832 version_warning = 1;
833 }
834 if (radio->hardware_version < RADIO_HW_VERSION) {
835 dev_warn(&intf->dev,
836 "This driver is known to work with "
837 "hardware version %hu,\n", RADIO_HW_VERSION);
838 dev_warn(&intf->dev,
839 "but the device has hardware version %hu.\n",
840 radio->hardware_version);
841 version_warning = 1;
842 }
843
844 /* give out version warning */
845 if (version_warning == 1) {
846 dev_warn(&intf->dev,
847 "If you have some trouble using this driver,\n");
848 dev_warn(&intf->dev,
849 "please report to V4L ML at "
850 "linux-media@vger.kernel.org\n");
851 }
852
853 /* set initial frequency */
854 si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
855
856 /* set led to connect state */
857 si470x_set_led_state(radio, BLINK_GREEN_LED);
858
859 /* rds buffer allocation */
860 radio->buf_size = rds_buf * 3;
861 radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
862 if (!radio->buffer) {
863 retval = -EIO;
864 goto err_video;
865 }
866
867 /* rds buffer configuration */
868 radio->wr_index = 0;
869 radio->rd_index = 0;
870 init_waitqueue_head(&radio->read_queue);
871
872 /* register video device */
873 retval = video_register_device(radio->videodev, VFL_TYPE_RADIO,
874 radio_nr);
875 if (retval) {
876 dev_warn(&intf->dev, "Could not register video device\n");
877 goto err_all;
878 }
879 usb_set_intfdata(intf, radio);
880
881 return 0;
882err_all:
883 kfree(radio->buffer);
884err_video:
885 video_device_release(radio->videodev);
886err_intbuffer:
887 kfree(radio->int_in_buffer);
888err_radio:
889 kfree(radio);
890err_initial:
891 return retval;
892}
893
894
895/*
896 * si470x_usb_driver_suspend - suspend the device
897 */
898static int si470x_usb_driver_suspend(struct usb_interface *intf,
899 pm_message_t message)
900{
901 dev_info(&intf->dev, "suspending now...\n");
902
903 return 0;
904}
905
906
907/*
908 * si470x_usb_driver_resume - resume the device
909 */
910static int si470x_usb_driver_resume(struct usb_interface *intf)
911{
912 dev_info(&intf->dev, "resuming now...\n");
913
914 return 0;
915}
916
917
918/*
919 * si470x_usb_driver_disconnect - disconnect the device
920 */
921static void si470x_usb_driver_disconnect(struct usb_interface *intf)
922{
923 struct si470x_device *radio = usb_get_intfdata(intf);
924
925 mutex_lock(&radio->disconnect_lock);
926 radio->disconnected = 1;
927 usb_set_intfdata(intf, NULL);
928 if (radio->users == 0) {
929 /* set led to disconnect state */
930 si470x_set_led_state(radio, BLINK_ORANGE_LED);
931
932 /* Free data structures. */
933 usb_free_urb(radio->int_in_urb);
934
935 kfree(radio->int_in_buffer);
936 video_unregister_device(radio->videodev);
937 kfree(radio->buffer);
938 kfree(radio);
939 }
940 mutex_unlock(&radio->disconnect_lock);
941}
942
943
944/*
945 * si470x_usb_driver - usb driver interface
946 */
947static struct usb_driver si470x_usb_driver = {
948 .name = DRIVER_NAME,
949 .probe = si470x_usb_driver_probe,
950 .disconnect = si470x_usb_driver_disconnect,
951 .suspend = si470x_usb_driver_suspend,
952 .resume = si470x_usb_driver_resume,
953 .id_table = si470x_usb_driver_id_table,
954 .supports_autosuspend = 1,
955};
956
957
958
959/**************************************************************************
960 * Module Interface
961 **************************************************************************/
962
963/*
964 * si470x_module_init - module init
965 */
966static int __init si470x_module_init(void)
967{
968 printk(KERN_INFO DRIVER_DESC ", Version " DRIVER_VERSION "\n");
969 return usb_register(&si470x_usb_driver);
970}
971
972
973/*
974 * si470x_module_exit - module exit
975 */
976static void __exit si470x_module_exit(void)
977{
978 usb_deregister(&si470x_usb_driver);
979}
980
981
982module_init(si470x_module_init);
983module_exit(si470x_module_exit);
984
985MODULE_LICENSE("GPL");
986MODULE_AUTHOR(DRIVER_AUTHOR);
987MODULE_DESCRIPTION(DRIVER_DESC);
988MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h
new file mode 100644
index 000000000000..d0af194d194c
--- /dev/null
+++ b/drivers/media/radio/si470x/radio-si470x.h
@@ -0,0 +1,225 @@
1/*
2 * drivers/media/radio/si470x/radio-si470x.h
3 *
4 * Driver for radios with Silicon Labs Si470x FM Radio Receivers
5 *
6 * Copyright (c) 2009 Tobias Lorenz <tobias.lorenz@gmx.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23
24/* driver definitions */
25#define DRIVER_NAME "radio-si470x"
26
27
28/* kernel includes */
29#include <linux/kernel.h>
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/slab.h>
33#include <linux/smp_lock.h>
34#include <linux/input.h>
35#include <linux/version.h>
36#include <linux/videodev2.h>
37#include <linux/mutex.h>
38#include <media/v4l2-common.h>
39#include <media/v4l2-ioctl.h>
40#include <media/rds.h>
41#include <asm/unaligned.h>
42
43
44
45/**************************************************************************
46 * Register Definitions
47 **************************************************************************/
48#define RADIO_REGISTER_SIZE 2 /* 16 register bit width */
49#define RADIO_REGISTER_NUM 16 /* DEVICEID ... RDSD */
50#define RDS_REGISTER_NUM 6 /* STATUSRSSI ... RDSD */
51
52#define DEVICEID 0 /* Device ID */
53#define DEVICEID_PN 0xf000 /* bits 15..12: Part Number */
54#define DEVICEID_MFGID 0x0fff /* bits 11..00: Manufacturer ID */
55
56#define CHIPID 1 /* Chip ID */
57#define CHIPID_REV 0xfc00 /* bits 15..10: Chip Version */
58#define CHIPID_DEV 0x0200 /* bits 09..09: Device */
59#define CHIPID_FIRMWARE 0x01ff /* bits 08..00: Firmware Version */
60
61#define POWERCFG 2 /* Power Configuration */
62#define POWERCFG_DSMUTE 0x8000 /* bits 15..15: Softmute Disable */
63#define POWERCFG_DMUTE 0x4000 /* bits 14..14: Mute Disable */
64#define POWERCFG_MONO 0x2000 /* bits 13..13: Mono Select */
65#define POWERCFG_RDSM 0x0800 /* bits 11..11: RDS Mode (Si4701 only) */
66#define POWERCFG_SKMODE 0x0400 /* bits 10..10: Seek Mode */
67#define POWERCFG_SEEKUP 0x0200 /* bits 09..09: Seek Direction */
68#define POWERCFG_SEEK 0x0100 /* bits 08..08: Seek */
69#define POWERCFG_DISABLE 0x0040 /* bits 06..06: Powerup Disable */
70#define POWERCFG_ENABLE 0x0001 /* bits 00..00: Powerup Enable */
71
72#define CHANNEL 3 /* Channel */
73#define CHANNEL_TUNE 0x8000 /* bits 15..15: Tune */
74#define CHANNEL_CHAN 0x03ff /* bits 09..00: Channel Select */
75
76#define SYSCONFIG1 4 /* System Configuration 1 */
77#define SYSCONFIG1_RDSIEN 0x8000 /* bits 15..15: RDS Interrupt Enable (Si4701 only) */
78#define SYSCONFIG1_STCIEN 0x4000 /* bits 14..14: Seek/Tune Complete Interrupt Enable */
79#define SYSCONFIG1_RDS 0x1000 /* bits 12..12: RDS Enable (Si4701 only) */
80#define SYSCONFIG1_DE 0x0800 /* bits 11..11: De-emphasis (0=75us 1=50us) */
81#define SYSCONFIG1_AGCD 0x0400 /* bits 10..10: AGC Disable */
82#define SYSCONFIG1_BLNDADJ 0x00c0 /* bits 07..06: Stereo/Mono Blend Level Adjustment */
83#define SYSCONFIG1_GPIO3 0x0030 /* bits 05..04: General Purpose I/O 3 */
84#define SYSCONFIG1_GPIO2 0x000c /* bits 03..02: General Purpose I/O 2 */
85#define SYSCONFIG1_GPIO1 0x0003 /* bits 01..00: General Purpose I/O 1 */
86
87#define SYSCONFIG2 5 /* System Configuration 2 */
88#define SYSCONFIG2_SEEKTH 0xff00 /* bits 15..08: RSSI Seek Threshold */
89#define SYSCONFIG2_BAND 0x0080 /* bits 07..06: Band Select */
90#define SYSCONFIG2_SPACE 0x0030 /* bits 05..04: Channel Spacing */
91#define SYSCONFIG2_VOLUME 0x000f /* bits 03..00: Volume */
92
93#define SYSCONFIG3 6 /* System Configuration 3 */
94#define SYSCONFIG3_SMUTER 0xc000 /* bits 15..14: Softmute Attack/Recover Rate */
95#define SYSCONFIG3_SMUTEA 0x3000 /* bits 13..12: Softmute Attenuation */
96#define SYSCONFIG3_SKSNR 0x00f0 /* bits 07..04: Seek SNR Threshold */
97#define SYSCONFIG3_SKCNT 0x000f /* bits 03..00: Seek FM Impulse Detection Threshold */
98
99#define TEST1 7 /* Test 1 */
100#define TEST1_AHIZEN 0x4000 /* bits 14..14: Audio High-Z Enable */
101
102#define TEST2 8 /* Test 2 */
103/* TEST2 only contains reserved bits */
104
105#define BOOTCONFIG 9 /* Boot Configuration */
106/* BOOTCONFIG only contains reserved bits */
107
108#define STATUSRSSI 10 /* Status RSSI */
109#define STATUSRSSI_RDSR 0x8000 /* bits 15..15: RDS Ready (Si4701 only) */
110#define STATUSRSSI_STC 0x4000 /* bits 14..14: Seek/Tune Complete */
111#define STATUSRSSI_SF 0x2000 /* bits 13..13: Seek Fail/Band Limit */
112#define STATUSRSSI_AFCRL 0x1000 /* bits 12..12: AFC Rail */
113#define STATUSRSSI_RDSS 0x0800 /* bits 11..11: RDS Synchronized (Si4701 only) */
114#define STATUSRSSI_BLERA 0x0600 /* bits 10..09: RDS Block A Errors (Si4701 only) */
115#define STATUSRSSI_ST 0x0100 /* bits 08..08: Stereo Indicator */
116#define STATUSRSSI_RSSI 0x00ff /* bits 07..00: RSSI (Received Signal Strength Indicator) */
117
118#define READCHAN 11 /* Read Channel */
119#define READCHAN_BLERB 0xc000 /* bits 15..14: RDS Block D Errors (Si4701 only) */
120#define READCHAN_BLERC 0x3000 /* bits 13..12: RDS Block C Errors (Si4701 only) */
121#define READCHAN_BLERD 0x0c00 /* bits 11..10: RDS Block B Errors (Si4701 only) */
122#define READCHAN_READCHAN 0x03ff /* bits 09..00: Read Channel */
123
124#define RDSA 12 /* RDSA */
125#define RDSA_RDSA 0xffff /* bits 15..00: RDS Block A Data (Si4701 only) */
126
127#define RDSB 13 /* RDSB */
128#define RDSB_RDSB 0xffff /* bits 15..00: RDS Block B Data (Si4701 only) */
129
130#define RDSC 14 /* RDSC */
131#define RDSC_RDSC 0xffff /* bits 15..00: RDS Block C Data (Si4701 only) */
132
133#define RDSD 15 /* RDSD */
134#define RDSD_RDSD 0xffff /* bits 15..00: RDS Block D Data (Si4701 only) */
135
136
137
138/**************************************************************************
139 * General Driver Definitions
140 **************************************************************************/
141
142/*
143 * si470x_device - private data
144 */
145struct si470x_device {
146 struct video_device *videodev;
147
148 /* driver management */
149 unsigned int users;
150
151 /* Silabs internal registers (0..15) */
152 unsigned short registers[RADIO_REGISTER_NUM];
153
154 /* RDS receive buffer */
155 wait_queue_head_t read_queue;
156 struct mutex lock; /* buffer locking */
157 unsigned char *buffer; /* size is always multiple of three */
158 unsigned int buf_size;
159 unsigned int rd_index;
160 unsigned int wr_index;
161
162#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE)
163 /* reference to USB and video device */
164 struct usb_device *usbdev;
165 struct usb_interface *intf;
166
167 /* Interrupt endpoint handling */
168 char *int_in_buffer;
169 struct usb_endpoint_descriptor *int_in_endpoint;
170 struct urb *int_in_urb;
171 int int_in_running;
172
173 /* scratch page */
174 unsigned char software_version;
175 unsigned char hardware_version;
176
177 /* driver management */
178 unsigned char disconnected;
179 struct mutex disconnect_lock;
180#endif
181
182#if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE)
183 struct i2c_client *client;
184#endif
185};
186
187
188
189/**************************************************************************
190 * Firmware Versions
191 **************************************************************************/
192
193#define RADIO_FW_VERSION 15
194
195
196
197/**************************************************************************
198 * Frequency Multiplicator
199 **************************************************************************/
200
201/*
202 * The frequency is set in units of 62.5 Hz when using V4L2_TUNER_CAP_LOW,
203 * 62.5 kHz otherwise.
204 * The tuner is able to have a channel spacing of 50, 100 or 200 kHz.
205 * tuner->capability is therefore set to V4L2_TUNER_CAP_LOW
206 * The FREQ_MUL is then: 1 MHz / 62.5 Hz = 16000
207 */
208#define FREQ_MUL (1000000 / 62.5)
209
210
211
212/**************************************************************************
213 * Common Functions
214 **************************************************************************/
215extern const struct v4l2_file_operations si470x_fops;
216extern struct video_device si470x_viddev_template;
217int si470x_get_register(struct si470x_device *radio, int regnr);
218int si470x_set_register(struct si470x_device *radio, int regnr);
219int si470x_disconnect_check(struct si470x_device *radio);
220int si470x_set_freq(struct si470x_device *radio, unsigned int freq);
221int si470x_start(struct si470x_device *radio);
222int si470x_stop(struct si470x_device *radio);
223int si470x_rds_on(struct si470x_device *radio);
224int si470x_vidioc_querycap(struct file *file, void *priv,
225 struct v4l2_capability *capability);
diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c
new file mode 100644
index 000000000000..6a0028eb461f
--- /dev/null
+++ b/drivers/media/radio/si4713-i2c.c
@@ -0,0 +1,2060 @@
1/*
2 * drivers/media/radio/si4713-i2c.c
3 *
4 * Silicon Labs Si4713 FM Radio Transmitter I2C commands.
5 *
6 * Copyright (c) 2009 Nokia Corporation
7 * Contact: Eduardo Valentin <eduardo.valentin@nokia.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 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <linux/mutex.h>
25#include <linux/completion.h>
26#include <linux/delay.h>
27#include <linux/interrupt.h>
28#include <linux/i2c.h>
29#include <media/v4l2-device.h>
30#include <media/v4l2-ioctl.h>
31#include <media/v4l2-common.h>
32
33#include "si4713-i2c.h"
34
35/* module parameters */
36static int debug;
37module_param(debug, int, S_IRUGO | S_IWUSR);
38MODULE_PARM_DESC(debug, "Debug level (0 - 2)");
39
40MODULE_LICENSE("GPL");
41MODULE_AUTHOR("Eduardo Valentin <eduardo.valentin@nokia.com>");
42MODULE_DESCRIPTION("I2C driver for Si4713 FM Radio Transmitter");
43MODULE_VERSION("0.0.1");
44
45#define DEFAULT_RDS_PI 0x00
46#define DEFAULT_RDS_PTY 0x00
47#define DEFAULT_RDS_PS_NAME ""
48#define DEFAULT_RDS_RADIO_TEXT DEFAULT_RDS_PS_NAME
49#define DEFAULT_RDS_DEVIATION 0x00C8
50#define DEFAULT_RDS_PS_REPEAT_COUNT 0x0003
51#define DEFAULT_LIMITER_RTIME 0x1392
52#define DEFAULT_LIMITER_DEV 0x102CA
53#define DEFAULT_PILOT_FREQUENCY 0x4A38
54#define DEFAULT_PILOT_DEVIATION 0x1A5E
55#define DEFAULT_ACOMP_ATIME 0x0000
56#define DEFAULT_ACOMP_RTIME 0xF4240L
57#define DEFAULT_ACOMP_GAIN 0x0F
58#define DEFAULT_ACOMP_THRESHOLD (-0x28)
59#define DEFAULT_MUTE 0x01
60#define DEFAULT_POWER_LEVEL 88
61#define DEFAULT_FREQUENCY 8800
62#define DEFAULT_PREEMPHASIS FMPE_EU
63#define DEFAULT_TUNE_RNL 0xFF
64
65#define to_si4713_device(sd) container_of(sd, struct si4713_device, sd)
66
67/* frequency domain transformation (using times 10 to avoid floats) */
68#define FREQDEV_UNIT 100000
69#define FREQV4L2_MULTI 625
70#define si4713_to_v4l2(f) ((f * FREQDEV_UNIT) / FREQV4L2_MULTI)
71#define v4l2_to_si4713(f) ((f * FREQV4L2_MULTI) / FREQDEV_UNIT)
72#define FREQ_RANGE_LOW 7600
73#define FREQ_RANGE_HIGH 10800
74
75#define MAX_ARGS 7
76
77#define RDS_BLOCK 8
78#define RDS_BLOCK_CLEAR 0x03
79#define RDS_BLOCK_LOAD 0x04
80#define RDS_RADIOTEXT_2A 0x20
81#define RDS_RADIOTEXT_BLK_SIZE 4
82#define RDS_RADIOTEXT_INDEX_MAX 0x0F
83#define RDS_CARRIAGE_RETURN 0x0D
84
85#define rds_ps_nblocks(len) ((len / RDS_BLOCK) + (len % RDS_BLOCK ? 1 : 0))
86
87#define get_status_bit(p, b, m) (((p) & (m)) >> (b))
88#define set_bits(p, v, b, m) (((p) & ~(m)) | ((v) << (b)))
89
90#define ATTACK_TIME_UNIT 500
91
92#define POWER_OFF 0x00
93#define POWER_ON 0x01
94
95#define msb(x) ((u8)((u16) x >> 8))
96#define lsb(x) ((u8)((u16) x & 0x00FF))
97#define compose_u16(msb, lsb) (((u16)msb << 8) | lsb)
98#define check_command_failed(status) (!(status & SI4713_CTS) || \
99 (status & SI4713_ERR))
100/* mute definition */
101#define set_mute(p) ((p & 1) | ((p & 1) << 1));
102#define get_mute(p) (p & 0x01)
103
104#ifdef DEBUG
105#define DBG_BUFFER(device, message, buffer, size) \
106 { \
107 int i; \
108 char str[(size)*5]; \
109 for (i = 0; i < size; i++) \
110 sprintf(str + i * 5, " 0x%02x", buffer[i]); \
111 v4l2_dbg(2, debug, device, "%s:%s\n", message, str); \
112 }
113#else
114#define DBG_BUFFER(device, message, buffer, size)
115#endif
116
117/*
118 * Values for limiter release time (sorted by second column)
119 * device release
120 * value time (us)
121 */
122static long limiter_times[] = {
123 2000, 250,
124 1000, 500,
125 510, 1000,
126 255, 2000,
127 170, 3000,
128 127, 4020,
129 102, 5010,
130 85, 6020,
131 73, 7010,
132 64, 7990,
133 57, 8970,
134 51, 10030,
135 25, 20470,
136 17, 30110,
137 13, 39380,
138 10, 51190,
139 8, 63690,
140 7, 73140,
141 6, 85330,
142 5, 102390,
143};
144
145/*
146 * Values for audio compression release time (sorted by second column)
147 * device release
148 * value time (us)
149 */
150static unsigned long acomp_rtimes[] = {
151 0, 100000,
152 1, 200000,
153 2, 350000,
154 3, 525000,
155 4, 1000000,
156};
157
158/*
159 * Values for preemphasis (sorted by second column)
160 * device preemphasis
161 * value value (v4l2)
162 */
163static unsigned long preemphasis_values[] = {
164 FMPE_DISABLED, V4L2_PREEMPHASIS_DISABLED,
165 FMPE_EU, V4L2_PREEMPHASIS_50_uS,
166 FMPE_USA, V4L2_PREEMPHASIS_75_uS,
167};
168
169static int usecs_to_dev(unsigned long usecs, unsigned long const array[],
170 int size)
171{
172 int i;
173 int rval = -EINVAL;
174
175 for (i = 0; i < size / 2; i++)
176 if (array[(i * 2) + 1] >= usecs) {
177 rval = array[i * 2];
178 break;
179 }
180
181 return rval;
182}
183
184static unsigned long dev_to_usecs(int value, unsigned long const array[],
185 int size)
186{
187 int i;
188 int rval = -EINVAL;
189
190 for (i = 0; i < size / 2; i++)
191 if (array[i * 2] == value) {
192 rval = array[(i * 2) + 1];
193 break;
194 }
195
196 return rval;
197}
198
199/* si4713_handler: IRQ handler, just complete work */
200static irqreturn_t si4713_handler(int irq, void *dev)
201{
202 struct si4713_device *sdev = dev;
203
204 v4l2_dbg(2, debug, &sdev->sd,
205 "%s: sending signal to completion work.\n", __func__);
206 complete(&sdev->work);
207
208 return IRQ_HANDLED;
209}
210
211/*
212 * si4713_send_command - sends a command to si4713 and waits its response
213 * @sdev: si4713_device structure for the device we are communicating
214 * @command: command id
215 * @args: command arguments we are sending (up to 7)
216 * @argn: actual size of @args
217 * @response: buffer to place the expected response from the device (up to 15)
218 * @respn: actual size of @response
219 * @usecs: amount of time to wait before reading the response (in usecs)
220 */
221static int si4713_send_command(struct si4713_device *sdev, const u8 command,
222 const u8 args[], const int argn,
223 u8 response[], const int respn, const int usecs)
224{
225 struct i2c_client *client = v4l2_get_subdevdata(&sdev->sd);
226 u8 data1[MAX_ARGS + 1];
227 int err;
228
229 if (!client->adapter)
230 return -ENODEV;
231
232 /* First send the command and its arguments */
233 data1[0] = command;
234 memcpy(data1 + 1, args, argn);
235 DBG_BUFFER(&sdev->sd, "Parameters", data1, argn + 1);
236
237 err = i2c_master_send(client, data1, argn + 1);
238 if (err != argn + 1) {
239 v4l2_err(&sdev->sd, "Error while sending command 0x%02x\n",
240 command);
241 return (err > 0) ? -EIO : err;
242 }
243
244 /* Wait response from interrupt */
245 if (!wait_for_completion_timeout(&sdev->work,
246 usecs_to_jiffies(usecs) + 1))
247 v4l2_warn(&sdev->sd,
248 "(%s) Device took too much time to answer.\n",
249 __func__);
250
251 /* Then get the response */
252 err = i2c_master_recv(client, response, respn);
253 if (err != respn) {
254 v4l2_err(&sdev->sd,
255 "Error while reading response for command 0x%02x\n",
256 command);
257 return (err > 0) ? -EIO : err;
258 }
259
260 DBG_BUFFER(&sdev->sd, "Response", response, respn);
261 if (check_command_failed(response[0]))
262 return -EBUSY;
263
264 return 0;
265}
266
267/*
268 * si4713_read_property - reads a si4713 property
269 * @sdev: si4713_device structure for the device we are communicating
270 * @prop: property identification number
271 * @pv: property value to be returned on success
272 */
273static int si4713_read_property(struct si4713_device *sdev, u16 prop, u32 *pv)
274{
275 int err;
276 u8 val[SI4713_GET_PROP_NRESP];
277 /*
278 * .First byte = 0
279 * .Second byte = property's MSB
280 * .Third byte = property's LSB
281 */
282 const u8 args[SI4713_GET_PROP_NARGS] = {
283 0x00,
284 msb(prop),
285 lsb(prop),
286 };
287
288 err = si4713_send_command(sdev, SI4713_CMD_GET_PROPERTY,
289 args, ARRAY_SIZE(args), val,
290 ARRAY_SIZE(val), DEFAULT_TIMEOUT);
291
292 if (err < 0)
293 return err;
294
295 *pv = compose_u16(val[2], val[3]);
296
297 v4l2_dbg(1, debug, &sdev->sd,
298 "%s: property=0x%02x value=0x%02x status=0x%02x\n",
299 __func__, prop, *pv, val[0]);
300
301 return err;
302}
303
304/*
305 * si4713_write_property - modifies a si4713 property
306 * @sdev: si4713_device structure for the device we are communicating
307 * @prop: property identification number
308 * @val: new value for that property
309 */
310static int si4713_write_property(struct si4713_device *sdev, u16 prop, u16 val)
311{
312 int rval;
313 u8 resp[SI4713_SET_PROP_NRESP];
314 /*
315 * .First byte = 0
316 * .Second byte = property's MSB
317 * .Third byte = property's LSB
318 * .Fourth byte = value's MSB
319 * .Fifth byte = value's LSB
320 */
321 const u8 args[SI4713_SET_PROP_NARGS] = {
322 0x00,
323 msb(prop),
324 lsb(prop),
325 msb(val),
326 lsb(val),
327 };
328
329 rval = si4713_send_command(sdev, SI4713_CMD_SET_PROPERTY,
330 args, ARRAY_SIZE(args),
331 resp, ARRAY_SIZE(resp),
332 DEFAULT_TIMEOUT);
333
334 if (rval < 0)
335 return rval;
336
337 v4l2_dbg(1, debug, &sdev->sd,
338 "%s: property=0x%02x value=0x%02x status=0x%02x\n",
339 __func__, prop, val, resp[0]);
340
341 /*
342 * As there is no command response for SET_PROPERTY,
343 * wait Tcomp time to finish before proceed, in order
344 * to have property properly set.
345 */
346 msleep(TIMEOUT_SET_PROPERTY);
347
348 return rval;
349}
350
351/*
352 * si4713_powerup - Powers the device up
353 * @sdev: si4713_device structure for the device we are communicating
354 */
355static int si4713_powerup(struct si4713_device *sdev)
356{
357 int err;
358 u8 resp[SI4713_PWUP_NRESP];
359 /*
360 * .First byte = Enabled interrupts and boot function
361 * .Second byte = Input operation mode
362 */
363 const u8 args[SI4713_PWUP_NARGS] = {
364 SI4713_PWUP_CTSIEN | SI4713_PWUP_GPO2OEN | SI4713_PWUP_FUNC_TX,
365 SI4713_PWUP_OPMOD_ANALOG,
366 };
367
368 if (sdev->power_state)
369 return 0;
370
371 sdev->platform_data->set_power(1);
372 err = si4713_send_command(sdev, SI4713_CMD_POWER_UP,
373 args, ARRAY_SIZE(args),
374 resp, ARRAY_SIZE(resp),
375 TIMEOUT_POWER_UP);
376
377 if (!err) {
378 v4l2_dbg(1, debug, &sdev->sd, "Powerup response: 0x%02x\n",
379 resp[0]);
380 v4l2_dbg(1, debug, &sdev->sd, "Device in power up mode\n");
381 sdev->power_state = POWER_ON;
382
383 err = si4713_write_property(sdev, SI4713_GPO_IEN,
384 SI4713_STC_INT | SI4713_CTS);
385 } else {
386 sdev->platform_data->set_power(0);
387 }
388
389 return err;
390}
391
392/*
393 * si4713_powerdown - Powers the device down
394 * @sdev: si4713_device structure for the device we are communicating
395 */
396static int si4713_powerdown(struct si4713_device *sdev)
397{
398 int err;
399 u8 resp[SI4713_PWDN_NRESP];
400
401 if (!sdev->power_state)
402 return 0;
403
404 err = si4713_send_command(sdev, SI4713_CMD_POWER_DOWN,
405 NULL, 0,
406 resp, ARRAY_SIZE(resp),
407 DEFAULT_TIMEOUT);
408
409 if (!err) {
410 v4l2_dbg(1, debug, &sdev->sd, "Power down response: 0x%02x\n",
411 resp[0]);
412 v4l2_dbg(1, debug, &sdev->sd, "Device in reset mode\n");
413 sdev->platform_data->set_power(0);
414 sdev->power_state = POWER_OFF;
415 }
416
417 return err;
418}
419
420/*
421 * si4713_checkrev - Checks if we are treating a device with the correct rev.
422 * @sdev: si4713_device structure for the device we are communicating
423 */
424static int si4713_checkrev(struct si4713_device *sdev)
425{
426 struct i2c_client *client = v4l2_get_subdevdata(&sdev->sd);
427 int rval;
428 u8 resp[SI4713_GETREV_NRESP];
429
430 mutex_lock(&sdev->mutex);
431
432 rval = si4713_send_command(sdev, SI4713_CMD_GET_REV,
433 NULL, 0,
434 resp, ARRAY_SIZE(resp),
435 DEFAULT_TIMEOUT);
436
437 if (rval < 0)
438 goto unlock;
439
440 if (resp[1] == SI4713_PRODUCT_NUMBER) {
441 v4l2_info(&sdev->sd, "chip found @ 0x%02x (%s)\n",
442 client->addr << 1, client->adapter->name);
443 } else {
444 v4l2_err(&sdev->sd, "Invalid product number\n");
445 rval = -EINVAL;
446 }
447
448unlock:
449 mutex_unlock(&sdev->mutex);
450 return rval;
451}
452
453/*
454 * si4713_wait_stc - Waits STC interrupt and clears status bits. Usefull
455 * for TX_TUNE_POWER, TX_TUNE_FREQ and TX_TUNE_MEAS
456 * @sdev: si4713_device structure for the device we are communicating
457 * @usecs: timeout to wait for STC interrupt signal
458 */
459static int si4713_wait_stc(struct si4713_device *sdev, const int usecs)
460{
461 int err;
462 u8 resp[SI4713_GET_STATUS_NRESP];
463
464 /* Wait response from STC interrupt */
465 if (!wait_for_completion_timeout(&sdev->work,
466 usecs_to_jiffies(usecs) + 1))
467 v4l2_warn(&sdev->sd,
468 "%s: device took too much time to answer (%d usec).\n",
469 __func__, usecs);
470
471 /* Clear status bits */
472 err = si4713_send_command(sdev, SI4713_CMD_GET_INT_STATUS,
473 NULL, 0,
474 resp, ARRAY_SIZE(resp),
475 DEFAULT_TIMEOUT);
476
477 if (err < 0)
478 goto exit;
479
480 v4l2_dbg(1, debug, &sdev->sd,
481 "%s: status bits: 0x%02x\n", __func__, resp[0]);
482
483 if (!(resp[0] & SI4713_STC_INT))
484 err = -EIO;
485
486exit:
487 return err;
488}
489
490/*
491 * si4713_tx_tune_freq - Sets the state of the RF carrier and sets the tuning
492 * frequency between 76 and 108 MHz in 10 kHz units and
493 * steps of 50 kHz.
494 * @sdev: si4713_device structure for the device we are communicating
495 * @frequency: desired frequency (76 - 108 MHz, unit 10 KHz, step 50 kHz)
496 */
497static int si4713_tx_tune_freq(struct si4713_device *sdev, u16 frequency)
498{
499 int err;
500 u8 val[SI4713_TXFREQ_NRESP];
501 /*
502 * .First byte = 0
503 * .Second byte = frequency's MSB
504 * .Third byte = frequency's LSB
505 */
506 const u8 args[SI4713_TXFREQ_NARGS] = {
507 0x00,
508 msb(frequency),
509 lsb(frequency),
510 };
511
512 err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_FREQ,
513 args, ARRAY_SIZE(args), val,
514 ARRAY_SIZE(val), DEFAULT_TIMEOUT);
515
516 if (err < 0)
517 return err;
518
519 v4l2_dbg(1, debug, &sdev->sd,
520 "%s: frequency=0x%02x status=0x%02x\n", __func__,
521 frequency, val[0]);
522
523 err = si4713_wait_stc(sdev, TIMEOUT_TX_TUNE);
524 if (err < 0)
525 return err;
526
527 return compose_u16(args[1], args[2]);
528}
529
530/*
531 * si4713_tx_tune_power - Sets the RF voltage level between 88 and 115 dBuV in
532 * 1 dB units. A value of 0x00 indicates off. The command
533 * also sets the antenna tuning capacitance. A value of 0
534 * indicates autotuning, and a value of 1 - 191 indicates
535 * a manual override, which results in a tuning
536 * capacitance of 0.25 pF x @antcap.
537 * @sdev: si4713_device structure for the device we are communicating
538 * @power: tuning power (88 - 115 dBuV, unit/step 1 dB)
539 * @antcap: value of antenna tuning capacitor (0 - 191)
540 */
541static int si4713_tx_tune_power(struct si4713_device *sdev, u8 power,
542 u8 antcap)
543{
544 int err;
545 u8 val[SI4713_TXPWR_NRESP];
546 /*
547 * .First byte = 0
548 * .Second byte = 0
549 * .Third byte = power
550 * .Fourth byte = antcap
551 */
552 const u8 args[SI4713_TXPWR_NARGS] = {
553 0x00,
554 0x00,
555 power,
556 antcap,
557 };
558
559 if (((power > 0) && (power < SI4713_MIN_POWER)) ||
560 power > SI4713_MAX_POWER || antcap > SI4713_MAX_ANTCAP)
561 return -EDOM;
562
563 err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_POWER,
564 args, ARRAY_SIZE(args), val,
565 ARRAY_SIZE(val), DEFAULT_TIMEOUT);
566
567 if (err < 0)
568 return err;
569
570 v4l2_dbg(1, debug, &sdev->sd,
571 "%s: power=0x%02x antcap=0x%02x status=0x%02x\n",
572 __func__, power, antcap, val[0]);
573
574 return si4713_wait_stc(sdev, TIMEOUT_TX_TUNE_POWER);
575}
576
577/*
578 * si4713_tx_tune_measure - Enters receive mode and measures the received noise
579 * level in units of dBuV on the selected frequency.
580 * The Frequency must be between 76 and 108 MHz in 10 kHz
581 * units and steps of 50 kHz. The command also sets the
582 * antenna tuning capacitance. A value of 0 means
583 * autotuning, and a value of 1 to 191 indicates manual
584 * override.
585 * @sdev: si4713_device structure for the device we are communicating
586 * @frequency: desired frequency (76 - 108 MHz, unit 10 KHz, step 50 kHz)
587 * @antcap: value of antenna tuning capacitor (0 - 191)
588 */
589static int si4713_tx_tune_measure(struct si4713_device *sdev, u16 frequency,
590 u8 antcap)
591{
592 int err;
593 u8 val[SI4713_TXMEA_NRESP];
594 /*
595 * .First byte = 0
596 * .Second byte = frequency's MSB
597 * .Third byte = frequency's LSB
598 * .Fourth byte = antcap
599 */
600 const u8 args[SI4713_TXMEA_NARGS] = {
601 0x00,
602 msb(frequency),
603 lsb(frequency),
604 antcap,
605 };
606
607 sdev->tune_rnl = DEFAULT_TUNE_RNL;
608
609 if (antcap > SI4713_MAX_ANTCAP)
610 return -EDOM;
611
612 err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_MEASURE,
613 args, ARRAY_SIZE(args), val,
614 ARRAY_SIZE(val), DEFAULT_TIMEOUT);
615
616 if (err < 0)
617 return err;
618
619 v4l2_dbg(1, debug, &sdev->sd,
620 "%s: frequency=0x%02x antcap=0x%02x status=0x%02x\n",
621 __func__, frequency, antcap, val[0]);
622
623 return si4713_wait_stc(sdev, TIMEOUT_TX_TUNE);
624}
625
626/*
627 * si4713_tx_tune_status- Returns the status of the tx_tune_freq, tx_tune_mea or
628 * tx_tune_power commands. This command return the current
629 * frequency, output voltage in dBuV, the antenna tunning
630 * capacitance value and the received noise level. The
631 * command also clears the stcint interrupt bit when the
632 * first bit of its arguments is high.
633 * @sdev: si4713_device structure for the device we are communicating
634 * @intack: 0x01 to clear the seek/tune complete interrupt status indicator.
635 * @frequency: returned frequency
636 * @power: returned power
637 * @antcap: returned antenna capacitance
638 * @noise: returned noise level
639 */
640static int si4713_tx_tune_status(struct si4713_device *sdev, u8 intack,
641 u16 *frequency, u8 *power,
642 u8 *antcap, u8 *noise)
643{
644 int err;
645 u8 val[SI4713_TXSTATUS_NRESP];
646 /*
647 * .First byte = intack bit
648 */
649 const u8 args[SI4713_TXSTATUS_NARGS] = {
650 intack & SI4713_INTACK_MASK,
651 };
652
653 err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_STATUS,
654 args, ARRAY_SIZE(args), val,
655 ARRAY_SIZE(val), DEFAULT_TIMEOUT);
656
657 if (!err) {
658 v4l2_dbg(1, debug, &sdev->sd,
659 "%s: status=0x%02x\n", __func__, val[0]);
660 *frequency = compose_u16(val[2], val[3]);
661 sdev->frequency = *frequency;
662 *power = val[5];
663 *antcap = val[6];
664 *noise = val[7];
665 v4l2_dbg(1, debug, &sdev->sd, "%s: response: %d x 10 kHz "
666 "(power %d, antcap %d, rnl %d)\n", __func__,
667 *frequency, *power, *antcap, *noise);
668 }
669
670 return err;
671}
672
673/*
674 * si4713_tx_rds_buff - Loads the RDS group buffer FIFO or circular buffer.
675 * @sdev: si4713_device structure for the device we are communicating
676 * @mode: the buffer operation mode.
677 * @rdsb: RDS Block B
678 * @rdsc: RDS Block C
679 * @rdsd: RDS Block D
680 * @cbleft: returns the number of available circular buffer blocks minus the
681 * number of used circular buffer blocks.
682 */
683static int si4713_tx_rds_buff(struct si4713_device *sdev, u8 mode, u16 rdsb,
684 u16 rdsc, u16 rdsd, s8 *cbleft)
685{
686 int err;
687 u8 val[SI4713_RDSBUFF_NRESP];
688
689 const u8 args[SI4713_RDSBUFF_NARGS] = {
690 mode & SI4713_RDSBUFF_MODE_MASK,
691 msb(rdsb),
692 lsb(rdsb),
693 msb(rdsc),
694 lsb(rdsc),
695 msb(rdsd),
696 lsb(rdsd),
697 };
698
699 err = si4713_send_command(sdev, SI4713_CMD_TX_RDS_BUFF,
700 args, ARRAY_SIZE(args), val,
701 ARRAY_SIZE(val), DEFAULT_TIMEOUT);
702
703 if (!err) {
704 v4l2_dbg(1, debug, &sdev->sd,
705 "%s: status=0x%02x\n", __func__, val[0]);
706 *cbleft = (s8)val[2] - val[3];
707 v4l2_dbg(1, debug, &sdev->sd, "%s: response: interrupts"
708 " 0x%02x cb avail: %d cb used %d fifo avail"
709 " %d fifo used %d\n", __func__, val[1],
710 val[2], val[3], val[4], val[5]);
711 }
712
713 return err;
714}
715
716/*
717 * si4713_tx_rds_ps - Loads the program service buffer.
718 * @sdev: si4713_device structure for the device we are communicating
719 * @psid: program service id to be loaded.
720 * @pschar: assumed 4 size char array to be loaded into the program service
721 */
722static int si4713_tx_rds_ps(struct si4713_device *sdev, u8 psid,
723 unsigned char *pschar)
724{
725 int err;
726 u8 val[SI4713_RDSPS_NRESP];
727
728 const u8 args[SI4713_RDSPS_NARGS] = {
729 psid & SI4713_RDSPS_PSID_MASK,
730 pschar[0],
731 pschar[1],
732 pschar[2],
733 pschar[3],
734 };
735
736 err = si4713_send_command(sdev, SI4713_CMD_TX_RDS_PS,
737 args, ARRAY_SIZE(args), val,
738 ARRAY_SIZE(val), DEFAULT_TIMEOUT);
739
740 if (err < 0)
741 return err;
742
743 v4l2_dbg(1, debug, &sdev->sd, "%s: status=0x%02x\n", __func__, val[0]);
744
745 return err;
746}
747
748static int si4713_set_power_state(struct si4713_device *sdev, u8 value)
749{
750 int rval;
751
752 mutex_lock(&sdev->mutex);
753
754 if (value)
755 rval = si4713_powerup(sdev);
756 else
757 rval = si4713_powerdown(sdev);
758
759 mutex_unlock(&sdev->mutex);
760 return rval;
761}
762
763static int si4713_set_mute(struct si4713_device *sdev, u16 mute)
764{
765 int rval = 0;
766
767 mute = set_mute(mute);
768
769 mutex_lock(&sdev->mutex);
770
771 if (sdev->power_state)
772 rval = si4713_write_property(sdev,
773 SI4713_TX_LINE_INPUT_MUTE, mute);
774
775 if (rval >= 0)
776 sdev->mute = get_mute(mute);
777
778 mutex_unlock(&sdev->mutex);
779
780 return rval;
781}
782
783static int si4713_set_rds_ps_name(struct si4713_device *sdev, char *ps_name)
784{
785 int rval = 0, i;
786 u8 len = 0;
787
788 /* We want to clear the whole thing */
789 if (!strlen(ps_name))
790 memset(ps_name, 0, MAX_RDS_PS_NAME + 1);
791
792 mutex_lock(&sdev->mutex);
793
794 if (sdev->power_state) {
795 /* Write the new ps name and clear the padding */
796 for (i = 0; i < MAX_RDS_PS_NAME; i += (RDS_BLOCK / 2)) {
797 rval = si4713_tx_rds_ps(sdev, (i / (RDS_BLOCK / 2)),
798 ps_name + i);
799 if (rval < 0)
800 goto unlock;
801 }
802
803 /* Setup the size to be sent */
804 if (strlen(ps_name))
805 len = strlen(ps_name) - 1;
806 else
807 len = 1;
808
809 rval = si4713_write_property(sdev,
810 SI4713_TX_RDS_PS_MESSAGE_COUNT,
811 rds_ps_nblocks(len));
812 if (rval < 0)
813 goto unlock;
814
815 rval = si4713_write_property(sdev,
816 SI4713_TX_RDS_PS_REPEAT_COUNT,
817 DEFAULT_RDS_PS_REPEAT_COUNT * 2);
818 if (rval < 0)
819 goto unlock;
820 }
821
822 strncpy(sdev->rds_info.ps_name, ps_name, MAX_RDS_PS_NAME);
823
824unlock:
825 mutex_unlock(&sdev->mutex);
826 return rval;
827}
828
829static int si4713_set_rds_radio_text(struct si4713_device *sdev, char *rt)
830{
831 int rval = 0, i;
832 u16 t_index = 0;
833 u8 b_index = 0, cr_inserted = 0;
834 s8 left;
835
836 mutex_lock(&sdev->mutex);
837
838 if (!sdev->power_state)
839 goto copy;
840
841 rval = si4713_tx_rds_buff(sdev, RDS_BLOCK_CLEAR, 0, 0, 0, &left);
842 if (rval < 0)
843 goto unlock;
844
845 if (!strlen(rt))
846 goto copy;
847
848 do {
849 /* RDS spec says that if the last block isn't used,
850 * then apply a carriage return
851 */
852 if (t_index < (RDS_RADIOTEXT_INDEX_MAX *
853 RDS_RADIOTEXT_BLK_SIZE)) {
854 for (i = 0; i < RDS_RADIOTEXT_BLK_SIZE; i++) {
855 if (!rt[t_index + i] || rt[t_index + i] ==
856 RDS_CARRIAGE_RETURN) {
857 rt[t_index + i] = RDS_CARRIAGE_RETURN;
858 cr_inserted = 1;
859 break;
860 }
861 }
862 }
863
864 rval = si4713_tx_rds_buff(sdev, RDS_BLOCK_LOAD,
865 compose_u16(RDS_RADIOTEXT_2A, b_index++),
866 compose_u16(rt[t_index], rt[t_index + 1]),
867 compose_u16(rt[t_index + 2], rt[t_index + 3]),
868 &left);
869 if (rval < 0)
870 goto unlock;
871
872 t_index += RDS_RADIOTEXT_BLK_SIZE;
873
874 if (cr_inserted)
875 break;
876 } while (left > 0);
877
878copy:
879 strncpy(sdev->rds_info.radio_text, rt, MAX_RDS_RADIO_TEXT);
880
881unlock:
882 mutex_unlock(&sdev->mutex);
883 return rval;
884}
885
886static int si4713_choose_econtrol_action(struct si4713_device *sdev, u32 id,
887 u32 **shadow, s32 *bit, s32 *mask, u16 *property, int *mul,
888 unsigned long **table, int *size)
889{
890 s32 rval = 0;
891
892 switch (id) {
893 /* FM_TX class controls */
894 case V4L2_CID_RDS_TX_PI:
895 *property = SI4713_TX_RDS_PI;
896 *mul = 1;
897 *shadow = &sdev->rds_info.pi;
898 break;
899 case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD:
900 *property = SI4713_TX_ACOMP_THRESHOLD;
901 *mul = 1;
902 *shadow = &sdev->acomp_info.threshold;
903 break;
904 case V4L2_CID_AUDIO_COMPRESSION_GAIN:
905 *property = SI4713_TX_ACOMP_GAIN;
906 *mul = 1;
907 *shadow = &sdev->acomp_info.gain;
908 break;
909 case V4L2_CID_PILOT_TONE_FREQUENCY:
910 *property = SI4713_TX_PILOT_FREQUENCY;
911 *mul = 1;
912 *shadow = &sdev->pilot_info.frequency;
913 break;
914 case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME:
915 *property = SI4713_TX_ACOMP_ATTACK_TIME;
916 *mul = ATTACK_TIME_UNIT;
917 *shadow = &sdev->acomp_info.attack_time;
918 break;
919 case V4L2_CID_PILOT_TONE_DEVIATION:
920 *property = SI4713_TX_PILOT_DEVIATION;
921 *mul = 10;
922 *shadow = &sdev->pilot_info.deviation;
923 break;
924 case V4L2_CID_AUDIO_LIMITER_DEVIATION:
925 *property = SI4713_TX_AUDIO_DEVIATION;
926 *mul = 10;
927 *shadow = &sdev->limiter_info.deviation;
928 break;
929 case V4L2_CID_RDS_TX_DEVIATION:
930 *property = SI4713_TX_RDS_DEVIATION;
931 *mul = 1;
932 *shadow = &sdev->rds_info.deviation;
933 break;
934
935 case V4L2_CID_RDS_TX_PTY:
936 *property = SI4713_TX_RDS_PS_MISC;
937 *bit = 5;
938 *mask = 0x1F << 5;
939 *shadow = &sdev->rds_info.pty;
940 break;
941 case V4L2_CID_AUDIO_LIMITER_ENABLED:
942 *property = SI4713_TX_ACOMP_ENABLE;
943 *bit = 1;
944 *mask = 1 << 1;
945 *shadow = &sdev->limiter_info.enabled;
946 break;
947 case V4L2_CID_AUDIO_COMPRESSION_ENABLED:
948 *property = SI4713_TX_ACOMP_ENABLE;
949 *bit = 0;
950 *mask = 1 << 0;
951 *shadow = &sdev->acomp_info.enabled;
952 break;
953 case V4L2_CID_PILOT_TONE_ENABLED:
954 *property = SI4713_TX_COMPONENT_ENABLE;
955 *bit = 0;
956 *mask = 1 << 0;
957 *shadow = &sdev->pilot_info.enabled;
958 break;
959
960 case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME:
961 *property = SI4713_TX_LIMITER_RELEASE_TIME;
962 *table = limiter_times;
963 *size = ARRAY_SIZE(limiter_times);
964 *shadow = &sdev->limiter_info.release_time;
965 break;
966 case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME:
967 *property = SI4713_TX_ACOMP_RELEASE_TIME;
968 *table = acomp_rtimes;
969 *size = ARRAY_SIZE(acomp_rtimes);
970 *shadow = &sdev->acomp_info.release_time;
971 break;
972 case V4L2_CID_TUNE_PREEMPHASIS:
973 *property = SI4713_TX_PREEMPHASIS;
974 *table = preemphasis_values;
975 *size = ARRAY_SIZE(preemphasis_values);
976 *shadow = &sdev->preemphasis;
977 break;
978
979 default:
980 rval = -EINVAL;
981 };
982
983 return rval;
984}
985
986static int si4713_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc);
987
988/* write string property */
989static int si4713_write_econtrol_string(struct si4713_device *sdev,
990 struct v4l2_ext_control *control)
991{
992 struct v4l2_queryctrl vqc;
993 int len;
994 s32 rval = 0;
995
996 vqc.id = control->id;
997 rval = si4713_queryctrl(&sdev->sd, &vqc);
998 if (rval < 0)
999 goto exit;
1000
1001 switch (control->id) {
1002 case V4L2_CID_RDS_TX_PS_NAME: {
1003 char ps_name[MAX_RDS_PS_NAME + 1];
1004
1005 len = control->size - 1;
1006 if (len > MAX_RDS_PS_NAME) {
1007 rval = -ERANGE;
1008 goto exit;
1009 }
1010 rval = copy_from_user(ps_name, control->string, len);
1011 if (rval < 0)
1012 goto exit;
1013 ps_name[len] = '\0';
1014
1015 if (strlen(ps_name) % vqc.step) {
1016 rval = -ERANGE;
1017 goto exit;
1018 }
1019
1020 rval = si4713_set_rds_ps_name(sdev, ps_name);
1021 }
1022 break;
1023
1024 case V4L2_CID_RDS_TX_RADIO_TEXT: {
1025 char radio_text[MAX_RDS_RADIO_TEXT + 1];
1026
1027 len = control->size - 1;
1028 if (len > MAX_RDS_RADIO_TEXT) {
1029 rval = -ERANGE;
1030 goto exit;
1031 }
1032 rval = copy_from_user(radio_text, control->string, len);
1033 if (rval < 0)
1034 goto exit;
1035 radio_text[len] = '\0';
1036
1037 if (strlen(radio_text) % vqc.step) {
1038 rval = -ERANGE;
1039 goto exit;
1040 }
1041
1042 rval = si4713_set_rds_radio_text(sdev, radio_text);
1043 }
1044 break;
1045
1046 default:
1047 rval = -EINVAL;
1048 break;
1049 };
1050
1051exit:
1052 return rval;
1053}
1054
1055static int validate_range(struct v4l2_subdev *sd,
1056 struct v4l2_ext_control *control)
1057{
1058 struct v4l2_queryctrl vqc;
1059 int rval;
1060
1061 vqc.id = control->id;
1062 rval = si4713_queryctrl(sd, &vqc);
1063 if (rval < 0)
1064 goto exit;
1065
1066 if (control->value < vqc.minimum || control->value > vqc.maximum)
1067 rval = -ERANGE;
1068
1069exit:
1070 return rval;
1071}
1072
1073/* properties which use tx_tune_power*/
1074static int si4713_write_econtrol_tune(struct si4713_device *sdev,
1075 struct v4l2_ext_control *control)
1076{
1077 s32 rval = 0;
1078 u8 power, antcap;
1079
1080 rval = validate_range(&sdev->sd, control);
1081 if (rval < 0)
1082 goto exit;
1083
1084 mutex_lock(&sdev->mutex);
1085
1086 switch (control->id) {
1087 case V4L2_CID_TUNE_POWER_LEVEL:
1088 power = control->value;
1089 antcap = sdev->antenna_capacitor;
1090 break;
1091 case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
1092 power = sdev->power_level;
1093 antcap = control->value;
1094 break;
1095 default:
1096 rval = -EINVAL;
1097 goto unlock;
1098 };
1099
1100 if (sdev->power_state)
1101 rval = si4713_tx_tune_power(sdev, power, antcap);
1102
1103 if (rval == 0) {
1104 sdev->power_level = power;
1105 sdev->antenna_capacitor = antcap;
1106 }
1107
1108unlock:
1109 mutex_unlock(&sdev->mutex);
1110exit:
1111 return rval;
1112}
1113
1114static int si4713_write_econtrol_integers(struct si4713_device *sdev,
1115 struct v4l2_ext_control *control)
1116{
1117 s32 rval;
1118 u32 *shadow = NULL, val = 0;
1119 s32 bit = 0, mask = 0;
1120 u16 property = 0;
1121 int mul = 0;
1122 unsigned long *table = NULL;
1123 int size = 0;
1124
1125 rval = validate_range(&sdev->sd, control);
1126 if (rval < 0)
1127 goto exit;
1128
1129 rval = si4713_choose_econtrol_action(sdev, control->id, &shadow, &bit,
1130 &mask, &property, &mul, &table, &size);
1131 if (rval < 0)
1132 goto exit;
1133
1134 val = control->value;
1135 if (mul) {
1136 val = control->value / mul;
1137 } else if (table) {
1138 rval = usecs_to_dev(control->value, table, size);
1139 if (rval < 0)
1140 goto exit;
1141 val = rval;
1142 rval = 0;
1143 }
1144
1145 mutex_lock(&sdev->mutex);
1146
1147 if (sdev->power_state) {
1148 if (mask) {
1149 rval = si4713_read_property(sdev, property, &val);
1150 if (rval < 0)
1151 goto unlock;
1152 val = set_bits(val, control->value, bit, mask);
1153 }
1154
1155 rval = si4713_write_property(sdev, property, val);
1156 if (rval < 0)
1157 goto unlock;
1158 if (mask)
1159 val = control->value;
1160 }
1161
1162 if (mul) {
1163 *shadow = val * mul;
1164 } else if (table) {
1165 rval = dev_to_usecs(val, table, size);
1166 if (rval < 0)
1167 goto unlock;
1168 *shadow = rval;
1169 rval = 0;
1170 } else {
1171 *shadow = val;
1172 }
1173
1174unlock:
1175 mutex_unlock(&sdev->mutex);
1176exit:
1177 return rval;
1178}
1179
1180static int si4713_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f);
1181static int si4713_s_modulator(struct v4l2_subdev *sd, struct v4l2_modulator *);
1182/*
1183 * si4713_setup - Sets the device up with current configuration.
1184 * @sdev: si4713_device structure for the device we are communicating
1185 */
1186static int si4713_setup(struct si4713_device *sdev)
1187{
1188 struct v4l2_ext_control ctrl;
1189 struct v4l2_frequency f;
1190 struct v4l2_modulator vm;
1191 struct si4713_device *tmp;
1192 int rval = 0;
1193
1194 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
1195 if (!tmp)
1196 return -ENOMEM;
1197
1198 /* Get a local copy to avoid race */
1199 mutex_lock(&sdev->mutex);
1200 memcpy(tmp, sdev, sizeof(*sdev));
1201 mutex_unlock(&sdev->mutex);
1202
1203 ctrl.id = V4L2_CID_RDS_TX_PI;
1204 ctrl.value = tmp->rds_info.pi;
1205 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1206
1207 ctrl.id = V4L2_CID_AUDIO_COMPRESSION_THRESHOLD;
1208 ctrl.value = tmp->acomp_info.threshold;
1209 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1210
1211 ctrl.id = V4L2_CID_AUDIO_COMPRESSION_GAIN;
1212 ctrl.value = tmp->acomp_info.gain;
1213 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1214
1215 ctrl.id = V4L2_CID_PILOT_TONE_FREQUENCY;
1216 ctrl.value = tmp->pilot_info.frequency;
1217 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1218
1219 ctrl.id = V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME;
1220 ctrl.value = tmp->acomp_info.attack_time;
1221 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1222
1223 ctrl.id = V4L2_CID_PILOT_TONE_DEVIATION;
1224 ctrl.value = tmp->pilot_info.deviation;
1225 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1226
1227 ctrl.id = V4L2_CID_AUDIO_LIMITER_DEVIATION;
1228 ctrl.value = tmp->limiter_info.deviation;
1229 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1230
1231 ctrl.id = V4L2_CID_RDS_TX_DEVIATION;
1232 ctrl.value = tmp->rds_info.deviation;
1233 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1234
1235 ctrl.id = V4L2_CID_RDS_TX_PTY;
1236 ctrl.value = tmp->rds_info.pty;
1237 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1238
1239 ctrl.id = V4L2_CID_AUDIO_LIMITER_ENABLED;
1240 ctrl.value = tmp->limiter_info.enabled;
1241 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1242
1243 ctrl.id = V4L2_CID_AUDIO_COMPRESSION_ENABLED;
1244 ctrl.value = tmp->acomp_info.enabled;
1245 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1246
1247 ctrl.id = V4L2_CID_PILOT_TONE_ENABLED;
1248 ctrl.value = tmp->pilot_info.enabled;
1249 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1250
1251 ctrl.id = V4L2_CID_AUDIO_LIMITER_RELEASE_TIME;
1252 ctrl.value = tmp->limiter_info.release_time;
1253 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1254
1255 ctrl.id = V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME;
1256 ctrl.value = tmp->acomp_info.release_time;
1257 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1258
1259 ctrl.id = V4L2_CID_TUNE_PREEMPHASIS;
1260 ctrl.value = tmp->preemphasis;
1261 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1262
1263 ctrl.id = V4L2_CID_RDS_TX_PS_NAME;
1264 rval |= si4713_set_rds_ps_name(sdev, tmp->rds_info.ps_name);
1265
1266 ctrl.id = V4L2_CID_RDS_TX_RADIO_TEXT;
1267 rval |= si4713_set_rds_radio_text(sdev, tmp->rds_info.radio_text);
1268
1269 /* Device procedure needs to set frequency first */
1270 f.frequency = tmp->frequency ? tmp->frequency : DEFAULT_FREQUENCY;
1271 f.frequency = si4713_to_v4l2(f.frequency);
1272 rval |= si4713_s_frequency(&sdev->sd, &f);
1273
1274 ctrl.id = V4L2_CID_TUNE_POWER_LEVEL;
1275 ctrl.value = tmp->power_level;
1276 rval |= si4713_write_econtrol_tune(sdev, &ctrl);
1277
1278 ctrl.id = V4L2_CID_TUNE_ANTENNA_CAPACITOR;
1279 ctrl.value = tmp->antenna_capacitor;
1280 rval |= si4713_write_econtrol_tune(sdev, &ctrl);
1281
1282 vm.index = 0;
1283 if (tmp->stereo)
1284 vm.txsubchans = V4L2_TUNER_SUB_STEREO;
1285 else
1286 vm.txsubchans = V4L2_TUNER_SUB_MONO;
1287 if (tmp->rds_info.enabled)
1288 vm.txsubchans |= V4L2_TUNER_SUB_RDS;
1289 si4713_s_modulator(&sdev->sd, &vm);
1290
1291 kfree(tmp);
1292
1293 return rval;
1294}
1295
1296/*
1297 * si4713_initialize - Sets the device up with default configuration.
1298 * @sdev: si4713_device structure for the device we are communicating
1299 */
1300static int si4713_initialize(struct si4713_device *sdev)
1301{
1302 int rval;
1303
1304 rval = si4713_set_power_state(sdev, POWER_ON);
1305 if (rval < 0)
1306 goto exit;
1307
1308 rval = si4713_checkrev(sdev);
1309 if (rval < 0)
1310 goto exit;
1311
1312 rval = si4713_set_power_state(sdev, POWER_OFF);
1313 if (rval < 0)
1314 goto exit;
1315
1316 mutex_lock(&sdev->mutex);
1317
1318 sdev->rds_info.pi = DEFAULT_RDS_PI;
1319 sdev->rds_info.pty = DEFAULT_RDS_PTY;
1320 sdev->rds_info.deviation = DEFAULT_RDS_DEVIATION;
1321 strlcpy(sdev->rds_info.ps_name, DEFAULT_RDS_PS_NAME, MAX_RDS_PS_NAME);
1322 strlcpy(sdev->rds_info.radio_text, DEFAULT_RDS_RADIO_TEXT,
1323 MAX_RDS_RADIO_TEXT);
1324 sdev->rds_info.enabled = 1;
1325
1326 sdev->limiter_info.release_time = DEFAULT_LIMITER_RTIME;
1327 sdev->limiter_info.deviation = DEFAULT_LIMITER_DEV;
1328 sdev->limiter_info.enabled = 1;
1329
1330 sdev->pilot_info.deviation = DEFAULT_PILOT_DEVIATION;
1331 sdev->pilot_info.frequency = DEFAULT_PILOT_FREQUENCY;
1332 sdev->pilot_info.enabled = 1;
1333
1334 sdev->acomp_info.release_time = DEFAULT_ACOMP_RTIME;
1335 sdev->acomp_info.attack_time = DEFAULT_ACOMP_ATIME;
1336 sdev->acomp_info.threshold = DEFAULT_ACOMP_THRESHOLD;
1337 sdev->acomp_info.gain = DEFAULT_ACOMP_GAIN;
1338 sdev->acomp_info.enabled = 1;
1339
1340 sdev->frequency = DEFAULT_FREQUENCY;
1341 sdev->preemphasis = DEFAULT_PREEMPHASIS;
1342 sdev->mute = DEFAULT_MUTE;
1343 sdev->power_level = DEFAULT_POWER_LEVEL;
1344 sdev->antenna_capacitor = 0;
1345 sdev->stereo = 1;
1346 sdev->tune_rnl = DEFAULT_TUNE_RNL;
1347
1348 mutex_unlock(&sdev->mutex);
1349
1350exit:
1351 return rval;
1352}
1353
1354/* read string property */
1355static int si4713_read_econtrol_string(struct si4713_device *sdev,
1356 struct v4l2_ext_control *control)
1357{
1358 s32 rval = 0;
1359
1360 switch (control->id) {
1361 case V4L2_CID_RDS_TX_PS_NAME:
1362 if (strlen(sdev->rds_info.ps_name) + 1 > control->size) {
1363 control->size = MAX_RDS_PS_NAME + 1;
1364 rval = -ENOSPC;
1365 goto exit;
1366 }
1367 rval = copy_to_user(control->string, sdev->rds_info.ps_name,
1368 strlen(sdev->rds_info.ps_name) + 1);
1369 break;
1370
1371 case V4L2_CID_RDS_TX_RADIO_TEXT:
1372 if (strlen(sdev->rds_info.radio_text) + 1 > control->size) {
1373 control->size = MAX_RDS_RADIO_TEXT + 1;
1374 rval = -ENOSPC;
1375 goto exit;
1376 }
1377 rval = copy_to_user(control->string, sdev->rds_info.radio_text,
1378 strlen(sdev->rds_info.radio_text) + 1);
1379 break;
1380
1381 default:
1382 rval = -EINVAL;
1383 break;
1384 };
1385
1386exit:
1387 return rval;
1388}
1389
1390/*
1391 * si4713_update_tune_status - update properties from tx_tune_status
1392 * command. Must be called with sdev->mutex held.
1393 * @sdev: si4713_device structure for the device we are communicating
1394 */
1395static int si4713_update_tune_status(struct si4713_device *sdev)
1396{
1397 int rval;
1398 u16 f = 0;
1399 u8 p = 0, a = 0, n = 0;
1400
1401 rval = si4713_tx_tune_status(sdev, 0x00, &f, &p, &a, &n);
1402
1403 if (rval < 0)
1404 goto exit;
1405
1406 sdev->power_level = p;
1407 sdev->antenna_capacitor = a;
1408 sdev->tune_rnl = n;
1409
1410exit:
1411 return rval;
1412}
1413
1414/* properties which use tx_tune_status */
1415static int si4713_read_econtrol_tune(struct si4713_device *sdev,
1416 struct v4l2_ext_control *control)
1417{
1418 s32 rval = 0;
1419
1420 mutex_lock(&sdev->mutex);
1421
1422 if (sdev->power_state) {
1423 rval = si4713_update_tune_status(sdev);
1424 if (rval < 0)
1425 goto unlock;
1426 }
1427
1428 switch (control->id) {
1429 case V4L2_CID_TUNE_POWER_LEVEL:
1430 control->value = sdev->power_level;
1431 break;
1432 case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
1433 control->value = sdev->antenna_capacitor;
1434 break;
1435 default:
1436 rval = -EINVAL;
1437 };
1438
1439unlock:
1440 mutex_unlock(&sdev->mutex);
1441 return rval;
1442}
1443
1444static int si4713_read_econtrol_integers(struct si4713_device *sdev,
1445 struct v4l2_ext_control *control)
1446{
1447 s32 rval;
1448 u32 *shadow = NULL, val = 0;
1449 s32 bit = 0, mask = 0;
1450 u16 property = 0;
1451 int mul = 0;
1452 unsigned long *table = NULL;
1453 int size = 0;
1454
1455 rval = si4713_choose_econtrol_action(sdev, control->id, &shadow, &bit,
1456 &mask, &property, &mul, &table, &size);
1457 if (rval < 0)
1458 goto exit;
1459
1460 mutex_lock(&sdev->mutex);
1461
1462 if (sdev->power_state) {
1463 rval = si4713_read_property(sdev, property, &val);
1464 if (rval < 0)
1465 goto unlock;
1466
1467 /* Keep negative values for threshold */
1468 if (control->id == V4L2_CID_AUDIO_COMPRESSION_THRESHOLD)
1469 *shadow = (s16)val;
1470 else if (mask)
1471 *shadow = get_status_bit(val, bit, mask);
1472 else if (mul)
1473 *shadow = val * mul;
1474 else
1475 *shadow = dev_to_usecs(val, table, size);
1476 }
1477
1478 control->value = *shadow;
1479
1480unlock:
1481 mutex_unlock(&sdev->mutex);
1482exit:
1483 return rval;
1484}
1485
1486/*
1487 * Video4Linux Subdev Interface
1488 */
1489/* si4713_s_ext_ctrls - set extended controls value */
1490static int si4713_s_ext_ctrls(struct v4l2_subdev *sd,
1491 struct v4l2_ext_controls *ctrls)
1492{
1493 struct si4713_device *sdev = to_si4713_device(sd);
1494 int i;
1495
1496 if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX)
1497 return -EINVAL;
1498
1499 for (i = 0; i < ctrls->count; i++) {
1500 int err;
1501
1502 switch ((ctrls->controls + i)->id) {
1503 case V4L2_CID_RDS_TX_PS_NAME:
1504 case V4L2_CID_RDS_TX_RADIO_TEXT:
1505 err = si4713_write_econtrol_string(sdev,
1506 ctrls->controls + i);
1507 break;
1508 case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
1509 case V4L2_CID_TUNE_POWER_LEVEL:
1510 err = si4713_write_econtrol_tune(sdev,
1511 ctrls->controls + i);
1512 break;
1513 default:
1514 err = si4713_write_econtrol_integers(sdev,
1515 ctrls->controls + i);
1516 }
1517
1518 if (err < 0) {
1519 ctrls->error_idx = i;
1520 return err;
1521 }
1522 }
1523
1524 return 0;
1525}
1526
1527/* si4713_g_ext_ctrls - get extended controls value */
1528static int si4713_g_ext_ctrls(struct v4l2_subdev *sd,
1529 struct v4l2_ext_controls *ctrls)
1530{
1531 struct si4713_device *sdev = to_si4713_device(sd);
1532 int i;
1533
1534 if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX)
1535 return -EINVAL;
1536
1537 for (i = 0; i < ctrls->count; i++) {
1538 int err;
1539
1540 switch ((ctrls->controls + i)->id) {
1541 case V4L2_CID_RDS_TX_PS_NAME:
1542 case V4L2_CID_RDS_TX_RADIO_TEXT:
1543 err = si4713_read_econtrol_string(sdev,
1544 ctrls->controls + i);
1545 break;
1546 case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
1547 case V4L2_CID_TUNE_POWER_LEVEL:
1548 err = si4713_read_econtrol_tune(sdev,
1549 ctrls->controls + i);
1550 break;
1551 default:
1552 err = si4713_read_econtrol_integers(sdev,
1553 ctrls->controls + i);
1554 }
1555
1556 if (err < 0) {
1557 ctrls->error_idx = i;
1558 return err;
1559 }
1560 }
1561
1562 return 0;
1563}
1564
1565/* si4713_queryctrl - enumerate control items */
1566static int si4713_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1567{
1568 int rval = 0;
1569
1570 switch (qc->id) {
1571 /* User class controls */
1572 case V4L2_CID_AUDIO_MUTE:
1573 rval = v4l2_ctrl_query_fill(qc, 0, 1, 1, DEFAULT_MUTE);
1574 break;
1575 /* FM_TX class controls */
1576 case V4L2_CID_RDS_TX_PI:
1577 rval = v4l2_ctrl_query_fill(qc, 0, 0xFFFF, 1, DEFAULT_RDS_PI);
1578 break;
1579 case V4L2_CID_RDS_TX_PTY:
1580 rval = v4l2_ctrl_query_fill(qc, 0, 31, 1, DEFAULT_RDS_PTY);
1581 break;
1582 case V4L2_CID_RDS_TX_DEVIATION:
1583 rval = v4l2_ctrl_query_fill(qc, 0, MAX_RDS_DEVIATION,
1584 10, DEFAULT_RDS_DEVIATION);
1585 break;
1586 case V4L2_CID_RDS_TX_PS_NAME:
1587 /*
1588 * Report step as 8. From RDS spec, psname
1589 * should be 8. But there are receivers which scroll strings
1590 * sized as 8xN.
1591 */
1592 rval = v4l2_ctrl_query_fill(qc, 0, MAX_RDS_PS_NAME, 8, 0);
1593 break;
1594 case V4L2_CID_RDS_TX_RADIO_TEXT:
1595 /*
1596 * Report step as 32 (2A block). From RDS spec,
1597 * radio text should be 32 for 2A block. But there are receivers
1598 * which scroll strings sized as 32xN. Setting default to 32.
1599 */
1600 rval = v4l2_ctrl_query_fill(qc, 0, MAX_RDS_RADIO_TEXT, 32, 0);
1601 break;
1602
1603 case V4L2_CID_AUDIO_LIMITER_ENABLED:
1604 rval = v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
1605 break;
1606 case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME:
1607 rval = v4l2_ctrl_query_fill(qc, 250, MAX_LIMITER_RELEASE_TIME,
1608 50, DEFAULT_LIMITER_RTIME);
1609 break;
1610 case V4L2_CID_AUDIO_LIMITER_DEVIATION:
1611 rval = v4l2_ctrl_query_fill(qc, 0, MAX_LIMITER_DEVIATION,
1612 10, DEFAULT_LIMITER_DEV);
1613 break;
1614
1615 case V4L2_CID_AUDIO_COMPRESSION_ENABLED:
1616 rval = v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
1617 break;
1618 case V4L2_CID_AUDIO_COMPRESSION_GAIN:
1619 rval = v4l2_ctrl_query_fill(qc, 0, MAX_ACOMP_GAIN, 1,
1620 DEFAULT_ACOMP_GAIN);
1621 break;
1622 case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD:
1623 rval = v4l2_ctrl_query_fill(qc, MIN_ACOMP_THRESHOLD,
1624 MAX_ACOMP_THRESHOLD, 1,
1625 DEFAULT_ACOMP_THRESHOLD);
1626 break;
1627 case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME:
1628 rval = v4l2_ctrl_query_fill(qc, 0, MAX_ACOMP_ATTACK_TIME,
1629 500, DEFAULT_ACOMP_ATIME);
1630 break;
1631 case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME:
1632 rval = v4l2_ctrl_query_fill(qc, 100000, MAX_ACOMP_RELEASE_TIME,
1633 100000, DEFAULT_ACOMP_RTIME);
1634 break;
1635
1636 case V4L2_CID_PILOT_TONE_ENABLED:
1637 rval = v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
1638 break;
1639 case V4L2_CID_PILOT_TONE_DEVIATION:
1640 rval = v4l2_ctrl_query_fill(qc, 0, MAX_PILOT_DEVIATION,
1641 10, DEFAULT_PILOT_DEVIATION);
1642 break;
1643 case V4L2_CID_PILOT_TONE_FREQUENCY:
1644 rval = v4l2_ctrl_query_fill(qc, 0, MAX_PILOT_FREQUENCY,
1645 1, DEFAULT_PILOT_FREQUENCY);
1646 break;
1647
1648 case V4L2_CID_TUNE_PREEMPHASIS:
1649 rval = v4l2_ctrl_query_fill(qc, V4L2_PREEMPHASIS_DISABLED,
1650 V4L2_PREEMPHASIS_75_uS, 1,
1651 V4L2_PREEMPHASIS_50_uS);
1652 break;
1653 case V4L2_CID_TUNE_POWER_LEVEL:
1654 rval = v4l2_ctrl_query_fill(qc, 0, 120, 1, DEFAULT_POWER_LEVEL);
1655 break;
1656 case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
1657 rval = v4l2_ctrl_query_fill(qc, 0, 191, 1, 0);
1658 break;
1659 default:
1660 rval = -EINVAL;
1661 break;
1662 };
1663
1664 return rval;
1665}
1666
1667/* si4713_g_ctrl - get the value of a control */
1668static int si4713_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
1669{
1670 struct si4713_device *sdev = to_si4713_device(sd);
1671 int rval = 0;
1672
1673 if (!sdev)
1674 return -ENODEV;
1675
1676 mutex_lock(&sdev->mutex);
1677
1678 if (sdev->power_state) {
1679 rval = si4713_read_property(sdev, SI4713_TX_LINE_INPUT_MUTE,
1680 &sdev->mute);
1681
1682 if (rval < 0)
1683 goto unlock;
1684 }
1685
1686 switch (ctrl->id) {
1687 case V4L2_CID_AUDIO_MUTE:
1688 ctrl->value = get_mute(sdev->mute);
1689 break;
1690 }
1691
1692unlock:
1693 mutex_unlock(&sdev->mutex);
1694 return rval;
1695}
1696
1697/* si4713_s_ctrl - set the value of a control */
1698static int si4713_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
1699{
1700 struct si4713_device *sdev = to_si4713_device(sd);
1701 int rval = 0;
1702
1703 if (!sdev)
1704 return -ENODEV;
1705
1706 switch (ctrl->id) {
1707 case V4L2_CID_AUDIO_MUTE:
1708 if (ctrl->value) {
1709 rval = si4713_set_mute(sdev, ctrl->value);
1710 if (rval < 0)
1711 goto exit;
1712
1713 rval = si4713_set_power_state(sdev, POWER_DOWN);
1714 } else {
1715 rval = si4713_set_power_state(sdev, POWER_UP);
1716 if (rval < 0)
1717 goto exit;
1718
1719 rval = si4713_setup(sdev);
1720 if (rval < 0)
1721 goto exit;
1722
1723 rval = si4713_set_mute(sdev, ctrl->value);
1724 }
1725 break;
1726 }
1727
1728exit:
1729 return rval;
1730}
1731
1732/* si4713_ioctl - deal with private ioctls (only rnl for now) */
1733long si4713_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
1734{
1735 struct si4713_device *sdev = to_si4713_device(sd);
1736 struct si4713_rnl *rnl = arg;
1737 u16 frequency;
1738 int rval = 0;
1739
1740 if (!arg)
1741 return -EINVAL;
1742
1743 mutex_lock(&sdev->mutex);
1744 switch (cmd) {
1745 case SI4713_IOC_MEASURE_RNL:
1746 frequency = v4l2_to_si4713(rnl->frequency);
1747
1748 if (sdev->power_state) {
1749 /* Set desired measurement frequency */
1750 rval = si4713_tx_tune_measure(sdev, frequency, 0);
1751 if (rval < 0)
1752 goto unlock;
1753 /* get results from tune status */
1754 rval = si4713_update_tune_status(sdev);
1755 if (rval < 0)
1756 goto unlock;
1757 }
1758 rnl->rnl = sdev->tune_rnl;
1759 break;
1760
1761 default:
1762 /* nothing */
1763 rval = -ENOIOCTLCMD;
1764 }
1765
1766unlock:
1767 mutex_unlock(&sdev->mutex);
1768 return rval;
1769}
1770
1771static const struct v4l2_subdev_core_ops si4713_subdev_core_ops = {
1772 .queryctrl = si4713_queryctrl,
1773 .g_ext_ctrls = si4713_g_ext_ctrls,
1774 .s_ext_ctrls = si4713_s_ext_ctrls,
1775 .g_ctrl = si4713_g_ctrl,
1776 .s_ctrl = si4713_s_ctrl,
1777 .ioctl = si4713_ioctl,
1778};
1779
1780/* si4713_g_modulator - get modulator attributes */
1781static int si4713_g_modulator(struct v4l2_subdev *sd, struct v4l2_modulator *vm)
1782{
1783 struct si4713_device *sdev = to_si4713_device(sd);
1784 int rval = 0;
1785
1786 if (!sdev) {
1787 rval = -ENODEV;
1788 goto exit;
1789 }
1790
1791 if (vm->index > 0) {
1792 rval = -EINVAL;
1793 goto exit;
1794 }
1795
1796 strncpy(vm->name, "FM Modulator", 32);
1797 vm->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LOW |
1798 V4L2_TUNER_CAP_RDS;
1799
1800 /* Report current frequency range limits */
1801 vm->rangelow = si4713_to_v4l2(FREQ_RANGE_LOW);
1802 vm->rangehigh = si4713_to_v4l2(FREQ_RANGE_HIGH);
1803
1804 mutex_lock(&sdev->mutex);
1805
1806 if (sdev->power_state) {
1807 u32 comp_en = 0;
1808
1809 rval = si4713_read_property(sdev, SI4713_TX_COMPONENT_ENABLE,
1810 &comp_en);
1811 if (rval < 0)
1812 goto unlock;
1813
1814 sdev->stereo = get_status_bit(comp_en, 1, 1 << 1);
1815 sdev->rds_info.enabled = get_status_bit(comp_en, 2, 1 << 2);
1816 }
1817
1818 /* Report current audio mode: mono or stereo */
1819 if (sdev->stereo)
1820 vm->txsubchans = V4L2_TUNER_SUB_STEREO;
1821 else
1822 vm->txsubchans = V4L2_TUNER_SUB_MONO;
1823
1824 /* Report rds feature status */
1825 if (sdev->rds_info.enabled)
1826 vm->txsubchans |= V4L2_TUNER_SUB_RDS;
1827 else
1828 vm->txsubchans &= ~V4L2_TUNER_SUB_RDS;
1829
1830unlock:
1831 mutex_unlock(&sdev->mutex);
1832exit:
1833 return rval;
1834}
1835
1836/* si4713_s_modulator - set modulator attributes */
1837static int si4713_s_modulator(struct v4l2_subdev *sd, struct v4l2_modulator *vm)
1838{
1839 struct si4713_device *sdev = to_si4713_device(sd);
1840 int rval = 0;
1841 u16 stereo, rds;
1842 u32 p;
1843
1844 if (!sdev)
1845 return -ENODEV;
1846
1847 if (vm->index > 0)
1848 return -EINVAL;
1849
1850 /* Set audio mode: mono or stereo */
1851 if (vm->txsubchans & V4L2_TUNER_SUB_STEREO)
1852 stereo = 1;
1853 else if (vm->txsubchans & V4L2_TUNER_SUB_MONO)
1854 stereo = 0;
1855 else
1856 return -EINVAL;
1857
1858 rds = !!(vm->txsubchans & V4L2_TUNER_SUB_RDS);
1859
1860 mutex_lock(&sdev->mutex);
1861
1862 if (sdev->power_state) {
1863 rval = si4713_read_property(sdev,
1864 SI4713_TX_COMPONENT_ENABLE, &p);
1865 if (rval < 0)
1866 goto unlock;
1867
1868 p = set_bits(p, stereo, 1, 1 << 1);
1869 p = set_bits(p, rds, 2, 1 << 2);
1870
1871 rval = si4713_write_property(sdev,
1872 SI4713_TX_COMPONENT_ENABLE, p);
1873 if (rval < 0)
1874 goto unlock;
1875 }
1876
1877 sdev->stereo = stereo;
1878 sdev->rds_info.enabled = rds;
1879
1880unlock:
1881 mutex_unlock(&sdev->mutex);
1882 return rval;
1883}
1884
1885/* si4713_g_frequency - get tuner or modulator radio frequency */
1886static int si4713_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
1887{
1888 struct si4713_device *sdev = to_si4713_device(sd);
1889 int rval = 0;
1890
1891 f->type = V4L2_TUNER_RADIO;
1892
1893 mutex_lock(&sdev->mutex);
1894
1895 if (sdev->power_state) {
1896 u16 freq;
1897 u8 p, a, n;
1898
1899 rval = si4713_tx_tune_status(sdev, 0x00, &freq, &p, &a, &n);
1900 if (rval < 0)
1901 goto unlock;
1902
1903 sdev->frequency = freq;
1904 }
1905
1906 f->frequency = si4713_to_v4l2(sdev->frequency);
1907
1908unlock:
1909 mutex_unlock(&sdev->mutex);
1910 return rval;
1911}
1912
1913/* si4713_s_frequency - set tuner or modulator radio frequency */
1914static int si4713_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
1915{
1916 struct si4713_device *sdev = to_si4713_device(sd);
1917 int rval = 0;
1918 u16 frequency = v4l2_to_si4713(f->frequency);
1919
1920 /* Check frequency range */
1921 if (frequency < FREQ_RANGE_LOW || frequency > FREQ_RANGE_HIGH)
1922 return -EDOM;
1923
1924 mutex_lock(&sdev->mutex);
1925
1926 if (sdev->power_state) {
1927 rval = si4713_tx_tune_freq(sdev, frequency);
1928 if (rval < 0)
1929 goto unlock;
1930 frequency = rval;
1931 rval = 0;
1932 }
1933 sdev->frequency = frequency;
1934 f->frequency = si4713_to_v4l2(frequency);
1935
1936unlock:
1937 mutex_unlock(&sdev->mutex);
1938 return rval;
1939}
1940
1941static const struct v4l2_subdev_tuner_ops si4713_subdev_tuner_ops = {
1942 .g_frequency = si4713_g_frequency,
1943 .s_frequency = si4713_s_frequency,
1944 .g_modulator = si4713_g_modulator,
1945 .s_modulator = si4713_s_modulator,
1946};
1947
1948static const struct v4l2_subdev_ops si4713_subdev_ops = {
1949 .core = &si4713_subdev_core_ops,
1950 .tuner = &si4713_subdev_tuner_ops,
1951};
1952
1953/*
1954 * I2C driver interface
1955 */
1956/* si4713_probe - probe for the device */
1957static int si4713_probe(struct i2c_client *client,
1958 const struct i2c_device_id *id)
1959{
1960 struct si4713_device *sdev;
1961 int rval;
1962
1963 sdev = kzalloc(sizeof *sdev, GFP_KERNEL);
1964 if (!sdev) {
1965 dev_err(&client->dev, "Failed to alloc video device.\n");
1966 rval = -ENOMEM;
1967 goto exit;
1968 }
1969
1970 sdev->platform_data = client->dev.platform_data;
1971 if (!sdev->platform_data) {
1972 v4l2_err(&sdev->sd, "No platform data registered.\n");
1973 rval = -ENODEV;
1974 goto free_sdev;
1975 }
1976
1977 v4l2_i2c_subdev_init(&sdev->sd, client, &si4713_subdev_ops);
1978
1979 mutex_init(&sdev->mutex);
1980 init_completion(&sdev->work);
1981
1982 if (client->irq) {
1983 rval = request_irq(client->irq,
1984 si4713_handler, IRQF_TRIGGER_FALLING | IRQF_DISABLED,
1985 client->name, sdev);
1986 if (rval < 0) {
1987 v4l2_err(&sdev->sd, "Could not request IRQ\n");
1988 goto free_sdev;
1989 }
1990 v4l2_dbg(1, debug, &sdev->sd, "IRQ requested.\n");
1991 } else {
1992 v4l2_warn(&sdev->sd, "IRQ not configured. Using timeouts.\n");
1993 }
1994
1995 rval = si4713_initialize(sdev);
1996 if (rval < 0) {
1997 v4l2_err(&sdev->sd, "Failed to probe device information.\n");
1998 goto free_irq;
1999 }
2000
2001 return 0;
2002
2003free_irq:
2004 if (client->irq)
2005 free_irq(client->irq, sdev);
2006free_sdev:
2007 kfree(sdev);
2008exit:
2009 return rval;
2010}
2011
2012/* si4713_remove - remove the device */
2013static int si4713_remove(struct i2c_client *client)
2014{
2015 struct v4l2_subdev *sd = i2c_get_clientdata(client);
2016 struct si4713_device *sdev = to_si4713_device(sd);
2017
2018 if (sdev->power_state)
2019 si4713_set_power_state(sdev, POWER_DOWN);
2020
2021 if (client->irq > 0)
2022 free_irq(client->irq, sdev);
2023
2024 v4l2_device_unregister_subdev(sd);
2025
2026 kfree(sdev);
2027
2028 return 0;
2029}
2030
2031/* si4713_i2c_driver - i2c driver interface */
2032static const struct i2c_device_id si4713_id[] = {
2033 { "si4713" , 0 },
2034 { },
2035};
2036MODULE_DEVICE_TABLE(i2c, si4713_id);
2037
2038static struct i2c_driver si4713_i2c_driver = {
2039 .driver = {
2040 .name = "si4713",
2041 },
2042 .probe = si4713_probe,
2043 .remove = si4713_remove,
2044 .id_table = si4713_id,
2045};
2046
2047/* Module Interface */
2048static int __init si4713_module_init(void)
2049{
2050 return i2c_add_driver(&si4713_i2c_driver);
2051}
2052
2053static void __exit si4713_module_exit(void)
2054{
2055 i2c_del_driver(&si4713_i2c_driver);
2056}
2057
2058module_init(si4713_module_init);
2059module_exit(si4713_module_exit);
2060
diff --git a/drivers/media/radio/si4713-i2c.h b/drivers/media/radio/si4713-i2c.h
new file mode 100644
index 000000000000..faf8cff124f1
--- /dev/null
+++ b/drivers/media/radio/si4713-i2c.h
@@ -0,0 +1,237 @@
1/*
2 * drivers/media/radio/si4713-i2c.h
3 *
4 * Property and commands definitions for Si4713 radio transmitter chip.
5 *
6 * Copyright (c) 2008 Instituto Nokia de Tecnologia - INdT
7 * Contact: Eduardo Valentin <eduardo.valentin@nokia.com>
8 *
9 * This file is licensed under the terms of the GNU General Public License
10 * version 2. This program is licensed "as is" without any warranty of any
11 * kind, whether express or implied.
12 *
13 */
14
15#ifndef SI4713_I2C_H
16#define SI4713_I2C_H
17
18#include <media/v4l2-subdev.h>
19#include <media/si4713.h>
20
21#define SI4713_PRODUCT_NUMBER 0x0D
22
23/* Command Timeouts */
24#define DEFAULT_TIMEOUT 500
25#define TIMEOUT_SET_PROPERTY 20
26#define TIMEOUT_TX_TUNE_POWER 30000
27#define TIMEOUT_TX_TUNE 110000
28#define TIMEOUT_POWER_UP 200000
29
30/*
31 * Command and its arguments definitions
32 */
33#define SI4713_PWUP_CTSIEN (1<<7)
34#define SI4713_PWUP_GPO2OEN (1<<6)
35#define SI4713_PWUP_PATCH (1<<5)
36#define SI4713_PWUP_XOSCEN (1<<4)
37#define SI4713_PWUP_FUNC_TX 0x02
38#define SI4713_PWUP_FUNC_PATCH 0x0F
39#define SI4713_PWUP_OPMOD_ANALOG 0x50
40#define SI4713_PWUP_OPMOD_DIGITAL 0x0F
41#define SI4713_PWUP_NARGS 2
42#define SI4713_PWUP_NRESP 1
43#define SI4713_CMD_POWER_UP 0x01
44
45#define SI4713_GETREV_NRESP 9
46#define SI4713_CMD_GET_REV 0x10
47
48#define SI4713_PWDN_NRESP 1
49#define SI4713_CMD_POWER_DOWN 0x11
50
51#define SI4713_SET_PROP_NARGS 5
52#define SI4713_SET_PROP_NRESP 1
53#define SI4713_CMD_SET_PROPERTY 0x12
54
55#define SI4713_GET_PROP_NARGS 3
56#define SI4713_GET_PROP_NRESP 4
57#define SI4713_CMD_GET_PROPERTY 0x13
58
59#define SI4713_GET_STATUS_NRESP 1
60#define SI4713_CMD_GET_INT_STATUS 0x14
61
62#define SI4713_CMD_PATCH_ARGS 0x15
63#define SI4713_CMD_PATCH_DATA 0x16
64
65#define SI4713_MAX_FREQ 10800
66#define SI4713_MIN_FREQ 7600
67#define SI4713_TXFREQ_NARGS 3
68#define SI4713_TXFREQ_NRESP 1
69#define SI4713_CMD_TX_TUNE_FREQ 0x30
70
71#define SI4713_MAX_POWER 120
72#define SI4713_MIN_POWER 88
73#define SI4713_MAX_ANTCAP 191
74#define SI4713_MIN_ANTCAP 0
75#define SI4713_TXPWR_NARGS 4
76#define SI4713_TXPWR_NRESP 1
77#define SI4713_CMD_TX_TUNE_POWER 0x31
78
79#define SI4713_TXMEA_NARGS 4
80#define SI4713_TXMEA_NRESP 1
81#define SI4713_CMD_TX_TUNE_MEASURE 0x32
82
83#define SI4713_INTACK_MASK 0x01
84#define SI4713_TXSTATUS_NARGS 1
85#define SI4713_TXSTATUS_NRESP 8
86#define SI4713_CMD_TX_TUNE_STATUS 0x33
87
88#define SI4713_OVERMOD_BIT (1 << 2)
89#define SI4713_IALH_BIT (1 << 1)
90#define SI4713_IALL_BIT (1 << 0)
91#define SI4713_ASQSTATUS_NARGS 1
92#define SI4713_ASQSTATUS_NRESP 5
93#define SI4713_CMD_TX_ASQ_STATUS 0x34
94
95#define SI4713_RDSBUFF_MODE_MASK 0x87
96#define SI4713_RDSBUFF_NARGS 7
97#define SI4713_RDSBUFF_NRESP 6
98#define SI4713_CMD_TX_RDS_BUFF 0x35
99
100#define SI4713_RDSPS_PSID_MASK 0x1F
101#define SI4713_RDSPS_NARGS 5
102#define SI4713_RDSPS_NRESP 1
103#define SI4713_CMD_TX_RDS_PS 0x36
104
105#define SI4713_CMD_GPO_CTL 0x80
106#define SI4713_CMD_GPO_SET 0x81
107
108/*
109 * Bits from status response
110 */
111#define SI4713_CTS (1<<7)
112#define SI4713_ERR (1<<6)
113#define SI4713_RDS_INT (1<<2)
114#define SI4713_ASQ_INT (1<<1)
115#define SI4713_STC_INT (1<<0)
116
117/*
118 * Property definitions
119 */
120#define SI4713_GPO_IEN 0x0001
121#define SI4713_DIG_INPUT_FORMAT 0x0101
122#define SI4713_DIG_INPUT_SAMPLE_RATE 0x0103
123#define SI4713_REFCLK_FREQ 0x0201
124#define SI4713_REFCLK_PRESCALE 0x0202
125#define SI4713_TX_COMPONENT_ENABLE 0x2100
126#define SI4713_TX_AUDIO_DEVIATION 0x2101
127#define SI4713_TX_PILOT_DEVIATION 0x2102
128#define SI4713_TX_RDS_DEVIATION 0x2103
129#define SI4713_TX_LINE_INPUT_LEVEL 0x2104
130#define SI4713_TX_LINE_INPUT_MUTE 0x2105
131#define SI4713_TX_PREEMPHASIS 0x2106
132#define SI4713_TX_PILOT_FREQUENCY 0x2107
133#define SI4713_TX_ACOMP_ENABLE 0x2200
134#define SI4713_TX_ACOMP_THRESHOLD 0x2201
135#define SI4713_TX_ACOMP_ATTACK_TIME 0x2202
136#define SI4713_TX_ACOMP_RELEASE_TIME 0x2203
137#define SI4713_TX_ACOMP_GAIN 0x2204
138#define SI4713_TX_LIMITER_RELEASE_TIME 0x2205
139#define SI4713_TX_ASQ_INTERRUPT_SOURCE 0x2300
140#define SI4713_TX_ASQ_LEVEL_LOW 0x2301
141#define SI4713_TX_ASQ_DURATION_LOW 0x2302
142#define SI4713_TX_ASQ_LEVEL_HIGH 0x2303
143#define SI4713_TX_ASQ_DURATION_HIGH 0x2304
144#define SI4713_TX_RDS_INTERRUPT_SOURCE 0x2C00
145#define SI4713_TX_RDS_PI 0x2C01
146#define SI4713_TX_RDS_PS_MIX 0x2C02
147#define SI4713_TX_RDS_PS_MISC 0x2C03
148#define SI4713_TX_RDS_PS_REPEAT_COUNT 0x2C04
149#define SI4713_TX_RDS_PS_MESSAGE_COUNT 0x2C05
150#define SI4713_TX_RDS_PS_AF 0x2C06
151#define SI4713_TX_RDS_FIFO_SIZE 0x2C07
152
153#define PREEMPHASIS_USA 75
154#define PREEMPHASIS_EU 50
155#define PREEMPHASIS_DISABLED 0
156#define FMPE_USA 0x00
157#define FMPE_EU 0x01
158#define FMPE_DISABLED 0x02
159
160#define POWER_UP 0x01
161#define POWER_DOWN 0x00
162
163struct rds_info {
164 u32 pi;
165#define MAX_RDS_PTY 31
166 u32 pty;
167#define MAX_RDS_DEVIATION 90000
168 u32 deviation;
169/*
170 * PSNAME is known to be defined as 8 character sized (RDS Spec).
171 * However, there is receivers which scroll PSNAME 8xN sized.
172 */
173#define MAX_RDS_PS_NAME 96
174 u8 ps_name[MAX_RDS_PS_NAME + 1];
175/*
176 * MAX_RDS_RADIO_TEXT is known to be defined as 32 (2A group) or 64 (2B group)
177 * character sized (RDS Spec).
178 * However, there is receivers which scroll them as well.
179 */
180#define MAX_RDS_RADIO_TEXT 384
181 u8 radio_text[MAX_RDS_RADIO_TEXT + 1];
182 u32 enabled;
183};
184
185struct limiter_info {
186#define MAX_LIMITER_RELEASE_TIME 102390
187 u32 release_time;
188#define MAX_LIMITER_DEVIATION 90000
189 u32 deviation;
190 u32 enabled;
191};
192
193struct pilot_info {
194#define MAX_PILOT_DEVIATION 90000
195 u32 deviation;
196#define MAX_PILOT_FREQUENCY 19000
197 u32 frequency;
198 u32 enabled;
199};
200
201struct acomp_info {
202#define MAX_ACOMP_RELEASE_TIME 1000000
203 u32 release_time;
204#define MAX_ACOMP_ATTACK_TIME 5000
205 u32 attack_time;
206#define MAX_ACOMP_THRESHOLD 0
207#define MIN_ACOMP_THRESHOLD (-40)
208 s32 threshold;
209#define MAX_ACOMP_GAIN 20
210 u32 gain;
211 u32 enabled;
212};
213
214/*
215 * si4713_device - private data
216 */
217struct si4713_device {
218 /* v4l2_subdev and i2c reference (v4l2_subdev priv data) */
219 struct v4l2_subdev sd;
220 /* private data structures */
221 struct mutex mutex;
222 struct completion work;
223 struct si4713_platform_data *platform_data;
224 struct rds_info rds_info;
225 struct limiter_info limiter_info;
226 struct pilot_info pilot_info;
227 struct acomp_info acomp_info;
228 u32 frequency;
229 u32 preemphasis;
230 u32 mute;
231 u32 power_level;
232 u32 power_state;
233 u32 antenna_capacitor;
234 u32 stereo;
235 u32 tune_rnl;
236};
237#endif /* ifndef SI4713_I2C_H */
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index dcf9fa9264bb..1d758525d236 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -203,9 +203,9 @@ config VIDEO_CS53L32A
203 module will be called cs53l32a. 203 module will be called cs53l32a.
204 204
205config VIDEO_M52790 205config VIDEO_M52790
206 tristate "Mitsubishi M52790 A/V switch" 206 tristate "Mitsubishi M52790 A/V switch"
207 depends on VIDEO_V4L2 && I2C 207 depends on VIDEO_V4L2 && I2C
208 ---help--- 208 ---help---
209 Support for the Mitsubishi M52790 A/V switch. 209 Support for the Mitsubishi M52790 A/V switch.
210 210
211 To compile this driver as a module, choose M here: the 211 To compile this driver as a module, choose M here: the
diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c
index 14baffc22192..b8a4b52e8d47 100644
--- a/drivers/media/video/au0828/au0828-dvb.c
+++ b/drivers/media/video/au0828/au0828-dvb.c
@@ -151,7 +151,7 @@ static int start_urb_transfer(struct au0828_dev *dev)
151 dprintk(2, "%s()\n", __func__); 151 dprintk(2, "%s()\n", __func__);
152 152
153 if (dev->urb_streaming) { 153 if (dev->urb_streaming) {
154 dprintk(2, "%s: iso xfer already running!\n", __func__); 154 dprintk(2, "%s: bulk xfer already running!\n", __func__);
155 return 0; 155 return 0;
156 } 156 }
157 157
diff --git a/drivers/media/video/au0828/au0828-i2c.c b/drivers/media/video/au0828/au0828-i2c.c
index 13e494365e70..cbdb65c34f21 100644
--- a/drivers/media/video/au0828/au0828-i2c.c
+++ b/drivers/media/video/au0828/au0828-i2c.c
@@ -320,7 +320,6 @@ static struct i2c_algorithm au0828_i2c_algo_template = {
320static struct i2c_adapter au0828_i2c_adap_template = { 320static struct i2c_adapter au0828_i2c_adap_template = {
321 .name = DRIVER_NAME, 321 .name = DRIVER_NAME,
322 .owner = THIS_MODULE, 322 .owner = THIS_MODULE,
323 .id = I2C_HW_B_AU0828,
324 .algo = &au0828_i2c_algo_template, 323 .algo = &au0828_i2c_algo_template,
325}; 324};
326 325
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index ca6558c394be..b42251fa96ba 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -1274,6 +1274,7 @@ struct tvcard bttv_tvcards[] = {
1274 .pll = PLL_28, 1274 .pll = PLL_28,
1275 .tuner_type = TUNER_TEMIC_PAL, 1275 .tuner_type = TUNER_TEMIC_PAL,
1276 .tuner_addr = ADDR_UNSET, 1276 .tuner_addr = ADDR_UNSET,
1277 .has_remote = 1,
1277 }, 1278 },
1278 1279
1279 /* ---- card 0x3c ---------------------------------- */ 1280 /* ---- card 0x3c ---------------------------------- */
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 8cc6dd28d6a7..939d1e512974 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -2652,6 +2652,8 @@ static int bttv_querycap(struct file *file, void *priv,
2652 V4L2_CAP_VBI_CAPTURE | 2652 V4L2_CAP_VBI_CAPTURE |
2653 V4L2_CAP_READWRITE | 2653 V4L2_CAP_READWRITE |
2654 V4L2_CAP_STREAMING; 2654 V4L2_CAP_STREAMING;
2655 if (btv->has_saa6588)
2656 cap->capabilities |= V4L2_CAP_RDS_CAPTURE;
2655 if (no_overlay <= 0) 2657 if (no_overlay <= 0)
2656 cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; 2658 cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
2657 2659
@@ -4593,14 +4595,10 @@ static int bttv_resume(struct pci_dev *pci_dev)
4593#endif 4595#endif
4594 4596
4595static struct pci_device_id bttv_pci_tbl[] = { 4597static struct pci_device_id bttv_pci_tbl[] = {
4596 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848, 4598 {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT848), 0},
4597 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 4599 {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT849), 0},
4598 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849, 4600 {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT878), 0},
4599 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 4601 {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT879), 0},
4600 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878,
4601 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4602 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879,
4603 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4604 {0,} 4602 {0,}
4605}; 4603};
4606 4604
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c
index ebd1ee9dc871..beda363418b0 100644
--- a/drivers/media/video/bt8xx/bttv-i2c.c
+++ b/drivers/media/video/bt8xx/bttv-i2c.c
@@ -352,7 +352,6 @@ int __devinit init_bttv_i2c(struct bttv *btv)
352 /* bt878 */ 352 /* bt878 */
353 strlcpy(btv->c.i2c_adap.name, "bt878", 353 strlcpy(btv->c.i2c_adap.name, "bt878",
354 sizeof(btv->c.i2c_adap.name)); 354 sizeof(btv->c.i2c_adap.name));
355 btv->c.i2c_adap.id = I2C_HW_B_BT848; /* FIXME */
356 btv->c.i2c_adap.algo = &bttv_algo; 355 btv->c.i2c_adap.algo = &bttv_algo;
357 } else { 356 } else {
358 /* bt848 */ 357 /* bt848 */
@@ -362,7 +361,6 @@ int __devinit init_bttv_i2c(struct bttv *btv)
362 361
363 strlcpy(btv->c.i2c_adap.name, "bttv", 362 strlcpy(btv->c.i2c_adap.name, "bttv",
364 sizeof(btv->c.i2c_adap.name)); 363 sizeof(btv->c.i2c_adap.name));
365 btv->c.i2c_adap.id = I2C_HW_B_BT848;
366 memcpy(&btv->i2c_algo, &bttv_i2c_algo_bit_template, 364 memcpy(&btv->i2c_algo, &bttv_i2c_algo_bit_template,
367 sizeof(bttv_i2c_algo_bit_template)); 365 sizeof(bttv_i2c_algo_bit_template));
368 btv->i2c_algo.udelay = i2c_udelay; 366 btv->i2c_algo.udelay = i2c_udelay;
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c
index 2f289d981fe6..ebd51afe8761 100644
--- a/drivers/media/video/bt8xx/bttv-input.c
+++ b/drivers/media/video/bt8xx/bttv-input.c
@@ -245,7 +245,7 @@ static void bttv_ir_stop(struct bttv *btv)
245int bttv_input_init(struct bttv *btv) 245int bttv_input_init(struct bttv *btv)
246{ 246{
247 struct card_ir *ir; 247 struct card_ir *ir;
248 IR_KEYTAB_TYPE *ir_codes = NULL; 248 struct ir_scancode_table *ir_codes = NULL;
249 struct input_dev *input_dev; 249 struct input_dev *input_dev;
250 int ir_type = IR_TYPE_OTHER; 250 int ir_type = IR_TYPE_OTHER;
251 int err = -ENOMEM; 251 int err = -ENOMEM;
@@ -263,7 +263,7 @@ int bttv_input_init(struct bttv *btv)
263 case BTTV_BOARD_AVERMEDIA: 263 case BTTV_BOARD_AVERMEDIA:
264 case BTTV_BOARD_AVPHONE98: 264 case BTTV_BOARD_AVPHONE98:
265 case BTTV_BOARD_AVERMEDIA98: 265 case BTTV_BOARD_AVERMEDIA98:
266 ir_codes = ir_codes_avermedia; 266 ir_codes = &ir_codes_avermedia_table;
267 ir->mask_keycode = 0xf88000; 267 ir->mask_keycode = 0xf88000;
268 ir->mask_keydown = 0x010000; 268 ir->mask_keydown = 0x010000;
269 ir->polling = 50; // ms 269 ir->polling = 50; // ms
@@ -271,14 +271,14 @@ int bttv_input_init(struct bttv *btv)
271 271
272 case BTTV_BOARD_AVDVBT_761: 272 case BTTV_BOARD_AVDVBT_761:
273 case BTTV_BOARD_AVDVBT_771: 273 case BTTV_BOARD_AVDVBT_771:
274 ir_codes = ir_codes_avermedia_dvbt; 274 ir_codes = &ir_codes_avermedia_dvbt_table;
275 ir->mask_keycode = 0x0f00c0; 275 ir->mask_keycode = 0x0f00c0;
276 ir->mask_keydown = 0x000020; 276 ir->mask_keydown = 0x000020;
277 ir->polling = 50; // ms 277 ir->polling = 50; // ms
278 break; 278 break;
279 279
280 case BTTV_BOARD_PXELVWPLTVPAK: 280 case BTTV_BOARD_PXELVWPLTVPAK:
281 ir_codes = ir_codes_pixelview; 281 ir_codes = &ir_codes_pixelview_table;
282 ir->mask_keycode = 0x003e00; 282 ir->mask_keycode = 0x003e00;
283 ir->mask_keyup = 0x010000; 283 ir->mask_keyup = 0x010000;
284 ir->polling = 50; // ms 284 ir->polling = 50; // ms
@@ -286,54 +286,55 @@ int bttv_input_init(struct bttv *btv)
286 case BTTV_BOARD_PV_M4900: 286 case BTTV_BOARD_PV_M4900:
287 case BTTV_BOARD_PV_BT878P_9B: 287 case BTTV_BOARD_PV_BT878P_9B:
288 case BTTV_BOARD_PV_BT878P_PLUS: 288 case BTTV_BOARD_PV_BT878P_PLUS:
289 ir_codes = ir_codes_pixelview; 289 ir_codes = &ir_codes_pixelview_table;
290 ir->mask_keycode = 0x001f00; 290 ir->mask_keycode = 0x001f00;
291 ir->mask_keyup = 0x008000; 291 ir->mask_keyup = 0x008000;
292 ir->polling = 50; // ms 292 ir->polling = 50; // ms
293 break; 293 break;
294 294
295 case BTTV_BOARD_WINFAST2000: 295 case BTTV_BOARD_WINFAST2000:
296 ir_codes = ir_codes_winfast; 296 ir_codes = &ir_codes_winfast_table;
297 ir->mask_keycode = 0x1f8; 297 ir->mask_keycode = 0x1f8;
298 break; 298 break;
299 case BTTV_BOARD_MAGICTVIEW061: 299 case BTTV_BOARD_MAGICTVIEW061:
300 case BTTV_BOARD_MAGICTVIEW063: 300 case BTTV_BOARD_MAGICTVIEW063:
301 ir_codes = ir_codes_winfast; 301 ir_codes = &ir_codes_winfast_table;
302 ir->mask_keycode = 0x0008e000; 302 ir->mask_keycode = 0x0008e000;
303 ir->mask_keydown = 0x00200000; 303 ir->mask_keydown = 0x00200000;
304 break; 304 break;
305 case BTTV_BOARD_APAC_VIEWCOMP: 305 case BTTV_BOARD_APAC_VIEWCOMP:
306 ir_codes = ir_codes_apac_viewcomp; 306 ir_codes = &ir_codes_apac_viewcomp_table;
307 ir->mask_keycode = 0x001f00; 307 ir->mask_keycode = 0x001f00;
308 ir->mask_keyup = 0x008000; 308 ir->mask_keyup = 0x008000;
309 ir->polling = 50; // ms 309 ir->polling = 50; // ms
310 break; 310 break;
311 case BTTV_BOARD_ASKEY_CPH03X:
311 case BTTV_BOARD_CONCEPTRONIC_CTVFMI2: 312 case BTTV_BOARD_CONCEPTRONIC_CTVFMI2:
312 case BTTV_BOARD_CONTVFMI: 313 case BTTV_BOARD_CONTVFMI:
313 ir_codes = ir_codes_pixelview; 314 ir_codes = &ir_codes_pixelview_table;
314 ir->mask_keycode = 0x001F00; 315 ir->mask_keycode = 0x001F00;
315 ir->mask_keyup = 0x006000; 316 ir->mask_keyup = 0x006000;
316 ir->polling = 50; // ms 317 ir->polling = 50; // ms
317 break; 318 break;
318 case BTTV_BOARD_NEBULA_DIGITV: 319 case BTTV_BOARD_NEBULA_DIGITV:
319 ir_codes = ir_codes_nebula; 320 ir_codes = &ir_codes_nebula_table;
320 btv->custom_irq = bttv_rc5_irq; 321 btv->custom_irq = bttv_rc5_irq;
321 ir->rc5_gpio = 1; 322 ir->rc5_gpio = 1;
322 break; 323 break;
323 case BTTV_BOARD_MACHTV_MAGICTV: 324 case BTTV_BOARD_MACHTV_MAGICTV:
324 ir_codes = ir_codes_apac_viewcomp; 325 ir_codes = &ir_codes_apac_viewcomp_table;
325 ir->mask_keycode = 0x001F00; 326 ir->mask_keycode = 0x001F00;
326 ir->mask_keyup = 0x004000; 327 ir->mask_keyup = 0x004000;
327 ir->polling = 50; /* ms */ 328 ir->polling = 50; /* ms */
328 break; 329 break;
329 case BTTV_BOARD_KOZUMI_KTV_01C: 330 case BTTV_BOARD_KOZUMI_KTV_01C:
330 ir_codes = ir_codes_pctv_sedna; 331 ir_codes = &ir_codes_pctv_sedna_table;
331 ir->mask_keycode = 0x001f00; 332 ir->mask_keycode = 0x001f00;
332 ir->mask_keyup = 0x006000; 333 ir->mask_keyup = 0x006000;
333 ir->polling = 50; /* ms */ 334 ir->polling = 50; /* ms */
334 break; 335 break;
335 case BTTV_BOARD_ENLTV_FM_2: 336 case BTTV_BOARD_ENLTV_FM_2:
336 ir_codes = ir_codes_encore_enltv2; 337 ir_codes = &ir_codes_encore_enltv2_table;
337 ir->mask_keycode = 0x00fd00; 338 ir->mask_keycode = 0x00fd00;
338 ir->mask_keyup = 0x000080; 339 ir->mask_keyup = 0x000080;
339 ir->polling = 1; /* ms */ 340 ir->polling = 1; /* ms */
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index c4d181dde1ca..9c149a781294 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -490,7 +490,6 @@ static int cafe_smbus_setup(struct cafe_camera *cam)
490 int ret; 490 int ret;
491 491
492 cafe_smbus_enable_irq(cam); 492 cafe_smbus_enable_irq(cam);
493 adap->id = I2C_HW_SMBUS_CAFE;
494 adap->owner = THIS_MODULE; 493 adap->owner = THIS_MODULE;
495 adap->algo = &cafe_smbus_algo; 494 adap->algo = &cafe_smbus_algo;
496 strcpy(adap->name, "cafe_ccic"); 495 strcpy(adap->name, "cafe_ccic");
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index 36f2d76006fd..f11e47a58286 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -56,7 +56,8 @@ static const struct cx18_card cx18_card_hvr1600_esmt = {
56 .hw_audio_ctrl = CX18_HW_418_AV, 56 .hw_audio_ctrl = CX18_HW_418_AV,
57 .hw_muxer = CX18_HW_CS5345, 57 .hw_muxer = CX18_HW_CS5345,
58 .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER | 58 .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
59 CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL, 59 CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL |
60 CX18_HW_Z8F0811_IR_HAUP,
60 .video_inputs = { 61 .video_inputs = {
61 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 }, 62 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
62 { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 }, 63 { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
@@ -102,7 +103,8 @@ static const struct cx18_card cx18_card_hvr1600_samsung = {
102 .hw_audio_ctrl = CX18_HW_418_AV, 103 .hw_audio_ctrl = CX18_HW_418_AV,
103 .hw_muxer = CX18_HW_CS5345, 104 .hw_muxer = CX18_HW_CS5345,
104 .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER | 105 .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
105 CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL, 106 CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL |
107 CX18_HW_Z8F0811_IR_HAUP,
106 .video_inputs = { 108 .video_inputs = {
107 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 }, 109 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
108 { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 }, 110 { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
@@ -204,7 +206,7 @@ static const struct cx18_card cx18_card_mpc718 = {
204 .v4l2_capabilities = CX18_CAP_ENCODER, 206 .v4l2_capabilities = CX18_CAP_ENCODER,
205 .hw_audio_ctrl = CX18_HW_418_AV, 207 .hw_audio_ctrl = CX18_HW_418_AV,
206 .hw_muxer = CX18_HW_GPIO_MUX, 208 .hw_muxer = CX18_HW_GPIO_MUX,
207 .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | 209 .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
208 CX18_HW_GPIO_MUX | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL, 210 CX18_HW_GPIO_MUX | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
209 .video_inputs = { 211 .video_inputs = {
210 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, 212 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
index 3c552b6b7c4d..444e3c7c563e 100644
--- a/drivers/media/video/cx18/cx18-cards.h
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -22,13 +22,17 @@
22 */ 22 */
23 23
24/* hardware flags */ 24/* hardware flags */
25#define CX18_HW_TUNER (1 << 0) 25#define CX18_HW_TUNER (1 << 0)
26#define CX18_HW_TVEEPROM (1 << 1) 26#define CX18_HW_TVEEPROM (1 << 1)
27#define CX18_HW_CS5345 (1 << 2) 27#define CX18_HW_CS5345 (1 << 2)
28#define CX18_HW_DVB (1 << 3) 28#define CX18_HW_DVB (1 << 3)
29#define CX18_HW_418_AV (1 << 4) 29#define CX18_HW_418_AV (1 << 4)
30#define CX18_HW_GPIO_MUX (1 << 5) 30#define CX18_HW_GPIO_MUX (1 << 5)
31#define CX18_HW_GPIO_RESET_CTRL (1 << 6) 31#define CX18_HW_GPIO_RESET_CTRL (1 << 6)
32#define CX18_HW_Z8F0811_IR_TX_HAUP (1 << 7)
33#define CX18_HW_Z8F0811_IR_RX_HAUP (1 << 8)
34#define CX18_HW_Z8F0811_IR_HAUP (CX18_HW_Z8F0811_IR_RX_HAUP | \
35 CX18_HW_Z8F0811_IR_TX_HAUP)
32 36
33/* video inputs */ 37/* video inputs */
34#define CX18_CARD_INPUT_VID_TUNER 1 38#define CX18_CARD_INPUT_VID_TUNER 1
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 92026e82e10e..dd0224f328ad 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -268,6 +268,20 @@ static void cx18_iounmap(struct cx18 *cx)
268 } 268 }
269} 269}
270 270
271static void cx18_eeprom_dump(struct cx18 *cx, unsigned char *eedata, int len)
272{
273 int i;
274
275 CX18_INFO("eeprom dump:\n");
276 for (i = 0; i < len; i++) {
277 if (0 == (i % 16))
278 CX18_INFO("eeprom %02x:", i);
279 printk(KERN_CONT " %02x", eedata[i]);
280 if (15 == (i % 16))
281 printk(KERN_CONT "\n");
282 }
283}
284
271/* Hauppauge card? get values from tveeprom */ 285/* Hauppauge card? get values from tveeprom */
272void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv) 286void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv)
273{ 287{
@@ -279,8 +293,26 @@ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv)
279 c.adapter = &cx->i2c_adap[0]; 293 c.adapter = &cx->i2c_adap[0];
280 c.addr = 0xA0 >> 1; 294 c.addr = 0xA0 >> 1;
281 295
282 tveeprom_read(&c, eedata, sizeof(eedata)); 296 memset(tv, 0, sizeof(*tv));
283 tveeprom_hauppauge_analog(&c, tv, eedata); 297 if (tveeprom_read(&c, eedata, sizeof(eedata)))
298 return;
299
300 switch (cx->card->type) {
301 case CX18_CARD_HVR_1600_ESMT:
302 case CX18_CARD_HVR_1600_SAMSUNG:
303 tveeprom_hauppauge_analog(&c, tv, eedata);
304 break;
305 case CX18_CARD_YUAN_MPC718:
306 tv->model = 0x718;
307 cx18_eeprom_dump(cx, eedata, sizeof(eedata));
308 CX18_INFO("eeprom PCI ID: %02x%02x:%02x%02x\n",
309 eedata[2], eedata[1], eedata[4], eedata[3]);
310 break;
311 default:
312 tv->model = 0xffffffff;
313 cx18_eeprom_dump(cx, eedata, sizeof(eedata));
314 break;
315 }
284} 316}
285 317
286static void cx18_process_eeprom(struct cx18 *cx) 318static void cx18_process_eeprom(struct cx18 *cx)
@@ -298,6 +330,11 @@ static void cx18_process_eeprom(struct cx18 *cx)
298 case 74000 ... 74999: 330 case 74000 ... 74999:
299 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); 331 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
300 break; 332 break;
333 case 0x718:
334 return;
335 case 0xffffffff:
336 CX18_INFO("Unknown EEPROM encoding\n");
337 return;
301 case 0: 338 case 0:
302 CX18_ERR("Invalid EEPROM\n"); 339 CX18_ERR("Invalid EEPROM\n");
303 return; 340 return;
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index 29969c18949c..04d9c2508b86 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -690,7 +690,7 @@ int cx18_v4l2_open(struct file *filp)
690 int res; 690 int res;
691 struct video_device *video_dev = video_devdata(filp); 691 struct video_device *video_dev = video_devdata(filp);
692 struct cx18_stream *s = video_get_drvdata(video_dev); 692 struct cx18_stream *s = video_get_drvdata(video_dev);
693 struct cx18 *cx = s->cx;; 693 struct cx18 *cx = s->cx;
694 694
695 mutex_lock(&cx->serialize_lock); 695 mutex_lock(&cx->serialize_lock);
696 if (cx18_init_on_first_open(cx)) { 696 if (cx18_init_on_first_open(cx)) {
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index 8591e4fc359f..da395fef50df 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -28,6 +28,7 @@
28#include "cx18-gpio.h" 28#include "cx18-gpio.h"
29#include "cx18-i2c.h" 29#include "cx18-i2c.h"
30#include "cx18-irq.h" 30#include "cx18-irq.h"
31#include <media/ir-kbd-i2c.h>
31 32
32#define CX18_REG_I2C_1_WR 0xf15000 33#define CX18_REG_I2C_1_WR 0xf15000
33#define CX18_REG_I2C_1_RD 0xf15008 34#define CX18_REG_I2C_1_RD 0xf15008
@@ -40,16 +41,20 @@
40#define GETSDL_BIT 0x0008 41#define GETSDL_BIT 0x0008
41 42
42#define CX18_CS5345_I2C_ADDR 0x4c 43#define CX18_CS5345_I2C_ADDR 0x4c
44#define CX18_Z8F0811_IR_TX_I2C_ADDR 0x70
45#define CX18_Z8F0811_IR_RX_I2C_ADDR 0x71
43 46
44/* This array should match the CX18_HW_ defines */ 47/* This array should match the CX18_HW_ defines */
45static const u8 hw_addrs[] = { 48static const u8 hw_addrs[] = {
46 0, /* CX18_HW_TUNER */ 49 0, /* CX18_HW_TUNER */
47 0, /* CX18_HW_TVEEPROM */ 50 0, /* CX18_HW_TVEEPROM */
48 CX18_CS5345_I2C_ADDR, /* CX18_HW_CS5345 */ 51 CX18_CS5345_I2C_ADDR, /* CX18_HW_CS5345 */
49 0, /* CX18_HW_DVB */ 52 0, /* CX18_HW_DVB */
50 0, /* CX18_HW_418_AV */ 53 0, /* CX18_HW_418_AV */
51 0, /* CX18_HW_GPIO_MUX */ 54 0, /* CX18_HW_GPIO_MUX */
52 0, /* CX18_HW_GPIO_RESET_CTRL */ 55 0, /* CX18_HW_GPIO_RESET_CTRL */
56 CX18_Z8F0811_IR_TX_I2C_ADDR, /* CX18_HW_Z8F0811_IR_TX_HAUP */
57 CX18_Z8F0811_IR_RX_I2C_ADDR, /* CX18_HW_Z8F0811_IR_RX_HAUP */
53}; 58};
54 59
55/* This array should match the CX18_HW_ defines */ 60/* This array should match the CX18_HW_ defines */
@@ -62,6 +67,8 @@ static const u8 hw_bus[] = {
62 0, /* CX18_HW_418_AV */ 67 0, /* CX18_HW_418_AV */
63 0, /* CX18_HW_GPIO_MUX */ 68 0, /* CX18_HW_GPIO_MUX */
64 0, /* CX18_HW_GPIO_RESET_CTRL */ 69 0, /* CX18_HW_GPIO_RESET_CTRL */
70 0, /* CX18_HW_Z8F0811_IR_TX_HAUP */
71 0, /* CX18_HW_Z8F0811_IR_RX_HAUP */
65}; 72};
66 73
67/* This array should match the CX18_HW_ defines */ 74/* This array should match the CX18_HW_ defines */
@@ -73,6 +80,8 @@ static const char * const hw_modules[] = {
73 NULL, /* CX18_HW_418_AV */ 80 NULL, /* CX18_HW_418_AV */
74 NULL, /* CX18_HW_GPIO_MUX */ 81 NULL, /* CX18_HW_GPIO_MUX */
75 NULL, /* CX18_HW_GPIO_RESET_CTRL */ 82 NULL, /* CX18_HW_GPIO_RESET_CTRL */
83 NULL, /* CX18_HW_Z8F0811_IR_TX_HAUP */
84 NULL, /* CX18_HW_Z8F0811_IR_RX_HAUP */
76}; 85};
77 86
78/* This array should match the CX18_HW_ defines */ 87/* This array should match the CX18_HW_ defines */
@@ -84,8 +93,38 @@ static const char * const hw_devicenames[] = {
84 "cx23418_AV", 93 "cx23418_AV",
85 "gpio_mux", 94 "gpio_mux",
86 "gpio_reset_ctrl", 95 "gpio_reset_ctrl",
96 "ir_tx_z8f0811_haup",
97 "ir_rx_z8f0811_haup",
87}; 98};
88 99
100static const struct IR_i2c_init_data z8f0811_ir_init_data = {
101 .ir_codes = &ir_codes_hauppauge_new_table,
102 .internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR,
103 .type = IR_TYPE_RC5,
104 .name = "CX23418 Z8F0811 Hauppauge",
105};
106
107static int cx18_i2c_new_ir(struct i2c_adapter *adap, u32 hw, const char *type,
108 u8 addr)
109{
110 struct i2c_board_info info;
111 unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
112
113 memset(&info, 0, sizeof(struct i2c_board_info));
114 strlcpy(info.type, type, I2C_NAME_SIZE);
115
116 /* Our default information for ir-kbd-i2c.c to use */
117 switch (hw) {
118 case CX18_HW_Z8F0811_IR_RX_HAUP:
119 info.platform_data = &z8f0811_ir_init_data;
120 break;
121 default:
122 break;
123 }
124
125 return i2c_new_probed_device(adap, &info, addr_list) == NULL ? -1 : 0;
126}
127
89int cx18_i2c_register(struct cx18 *cx, unsigned idx) 128int cx18_i2c_register(struct cx18 *cx, unsigned idx)
90{ 129{
91 struct v4l2_subdev *sd; 130 struct v4l2_subdev *sd;
@@ -115,11 +154,14 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
115 return sd != NULL ? 0 : -1; 154 return sd != NULL ? 0 : -1;
116 } 155 }
117 156
157 if (hw & CX18_HW_Z8F0811_IR_HAUP)
158 return cx18_i2c_new_ir(adap, hw, type, hw_addrs[idx]);
159
118 /* Is it not an I2C device or one we do not wish to register? */ 160 /* Is it not an I2C device or one we do not wish to register? */
119 if (!hw_addrs[idx]) 161 if (!hw_addrs[idx])
120 return -1; 162 return -1;
121 163
122 /* It's an I2C device other than an analog tuner */ 164 /* It's an I2C device other than an analog tuner or IR chip */
123 sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, mod, type, hw_addrs[idx]); 165 sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, mod, type, hw_addrs[idx]);
124 if (sd != NULL) 166 if (sd != NULL)
125 sd->grp_id = hw; 167 sd->grp_id = hw;
@@ -190,7 +232,6 @@ static int cx18_getsda(void *data)
190/* template for i2c-bit-algo */ 232/* template for i2c-bit-algo */
191static struct i2c_adapter cx18_i2c_adap_template = { 233static struct i2c_adapter cx18_i2c_adap_template = {
192 .name = "cx18 i2c driver", 234 .name = "cx18 i2c driver",
193 .id = I2C_HW_B_CX2341X,
194 .algo = NULL, /* set by i2c-algo-bit */ 235 .algo = NULL, /* set by i2c-algo-bit */
195 .algo_data = NULL, /* filled from template */ 236 .algo_data = NULL, /* filled from template */
196 .owner = THIS_MODULE, 237 .owner = THIS_MODULE,
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index d7b1921e6666..fc76e4d6ffa7 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -605,7 +605,7 @@ int cx18_s_input(struct file *file, void *fh, unsigned int inp)
605 if (ret) 605 if (ret)
606 return ret; 606 return ret;
607 607
608 if (inp < 0 || inp >= cx->nof_inputs) 608 if (inp >= cx->nof_inputs)
609 return -EINVAL; 609 return -EINVAL;
610 610
611 if (inp == cx->active_input) { 611 if (inp == cx->active_input) {
diff --git a/drivers/media/video/cx231xx/cx231xx-conf-reg.h b/drivers/media/video/cx231xx/cx231xx-conf-reg.h
index a6f398a175c5..31a8759f6e54 100644
--- a/drivers/media/video/cx231xx/cx231xx-conf-reg.h
+++ b/drivers/media/video/cx231xx/cx231xx-conf-reg.h
@@ -60,10 +60,10 @@
60#define PWR_RESETOUT_EN 0x100 /* bit8 */ 60#define PWR_RESETOUT_EN 0x100 /* bit8 */
61 61
62enum AV_MODE{ 62enum AV_MODE{
63 POLARIS_AVMODE_DEFAULT = 0, 63 POLARIS_AVMODE_DEFAULT = 0,
64 POLARIS_AVMODE_DIGITAL = 0x10, 64 POLARIS_AVMODE_DIGITAL = 0x10,
65 POLARIS_AVMODE_ANALOGT_TV = 0x20, 65 POLARIS_AVMODE_ANALOGT_TV = 0x20,
66 POLARIS_AVMODE_ENXTERNAL_AV = 0x30, 66 POLARIS_AVMODE_ENXTERNAL_AV = 0x30,
67 67
68}; 68};
69 69
diff --git a/drivers/media/video/cx231xx/cx231xx-i2c.c b/drivers/media/video/cx231xx/cx231xx-i2c.c
index 33219dc4d649..58d9cc0867b9 100644
--- a/drivers/media/video/cx231xx/cx231xx-i2c.c
+++ b/drivers/media/video/cx231xx/cx231xx-i2c.c
@@ -432,7 +432,6 @@ static struct i2c_algorithm cx231xx_algo = {
432static struct i2c_adapter cx231xx_adap_template = { 432static struct i2c_adapter cx231xx_adap_template = {
433 .owner = THIS_MODULE, 433 .owner = THIS_MODULE,
434 .name = "cx231xx", 434 .name = "cx231xx",
435 .id = I2C_HW_B_CX231XX,
436 .algo = &cx231xx_algo, 435 .algo = &cx231xx_algo,
437}; 436};
438 437
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c
index 609bae6098d3..36503725d973 100644
--- a/drivers/media/video/cx231xx/cx231xx-video.c
+++ b/drivers/media/video/cx231xx/cx231xx-video.c
@@ -923,8 +923,8 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
923 923
924 f->fmt.pix.width = dev->width; 924 f->fmt.pix.width = dev->width;
925 f->fmt.pix.height = dev->height; 925 f->fmt.pix.height = dev->height;
926 f->fmt.pix.pixelformat = dev->format->fourcc;; 926 f->fmt.pix.pixelformat = dev->format->fourcc;
927 f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3;; 927 f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3;
928 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height; 928 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height;
929 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 929 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
930 930
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h
index a0f823ac6b8d..64e2ddd3c401 100644
--- a/drivers/media/video/cx231xx/cx231xx.h
+++ b/drivers/media/video/cx231xx/cx231xx.h
@@ -282,7 +282,7 @@ struct cx231xx_board {
282 282
283 struct cx231xx_input input[MAX_CX231XX_INPUT]; 283 struct cx231xx_input input[MAX_CX231XX_INPUT];
284 struct cx231xx_input radio; 284 struct cx231xx_input radio;
285 IR_KEYTAB_TYPE *ir_codes; 285 struct ir_scancode_table *ir_codes;
286}; 286};
287 287
288/* device states */ 288/* device states */
diff --git a/drivers/media/video/cx23885/cimax2.c b/drivers/media/video/cx23885/cimax2.c
index 08582e58bdbf..0316257b7345 100644
--- a/drivers/media/video/cx23885/cimax2.c
+++ b/drivers/media/video/cx23885/cimax2.c
@@ -443,6 +443,7 @@ int netup_ci_init(struct cx23885_tsport *port)
443 goto err; 443 goto err;
444 444
445 INIT_WORK(&state->work, netup_read_ci_status); 445 INIT_WORK(&state->work, netup_read_ci_status);
446 schedule_work(&state->work);
446 447
447 ci_dbg_print("%s: CI initialized!\n", __func__); 448 ci_dbg_print("%s: CI initialized!\n", __func__);
448 449
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index 1a1048b18f70..6c3b51ce3372 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -630,6 +630,39 @@ int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value)
630 return retval; 630 return retval;
631} 631}
632 632
633void mc417_gpio_set(struct cx23885_dev *dev, u32 mask)
634{
635 u32 val;
636
637 /* Set the gpio value */
638 mc417_register_read(dev, 0x900C, &val);
639 val |= (mask & 0x000ffff);
640 mc417_register_write(dev, 0x900C, val);
641}
642
643void mc417_gpio_clear(struct cx23885_dev *dev, u32 mask)
644{
645 u32 val;
646
647 /* Clear the gpio value */
648 mc417_register_read(dev, 0x900C, &val);
649 val &= ~(mask & 0x0000ffff);
650 mc417_register_write(dev, 0x900C, val);
651}
652
653void mc417_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput)
654{
655 u32 val;
656
657 /* Enable GPIO direction bits */
658 mc417_register_read(dev, 0x9020, &val);
659 if (asoutput)
660 val |= (mask & 0x0000ffff);
661 else
662 val &= ~(mask & 0x0000ffff);
663
664 mc417_register_write(dev, 0x9020, val);
665}
633/* ------------------------------------------------------------------ */ 666/* ------------------------------------------------------------------ */
634 667
635/* MPEG encoder API */ 668/* MPEG encoder API */
@@ -955,25 +988,8 @@ static int cx23885_load_firmware(struct cx23885_dev *dev)
955 retval |= mc417_register_write(dev, IVTV_REG_HW_BLOCKS, 988 retval |= mc417_register_write(dev, IVTV_REG_HW_BLOCKS,
956 IVTV_CMD_HW_BLOCKS_RST); 989 IVTV_CMD_HW_BLOCKS_RST);
957 990
958 /* Restore GPIO settings, make sure EIO14 is enabled as an output. */ 991 /* F/W power up disturbs the GPIOs, restore state */
959 dprintk(2, "%s: GPIO output EIO 0-15 was = 0x%x\n", 992 retval |= mc417_register_write(dev, 0x9020, gpio_output);
960 __func__, gpio_output);
961 /* Power-up seems to have GPIOs AFU. This was causing digital side
962 * to fail at power-up. Seems GPIOs should be set to 0x10ff0411 at
963 * power-up.
964 * gpio_output |= (1<<14);
965 */
966 /* Note: GPIO14 is specific to the HVR1800 here */
967 gpio_output = 0x10ff0411 | (1<<14);
968 retval |= mc417_register_write(dev, 0x9020, gpio_output | (1<<14));
969 dprintk(2, "%s: GPIO output EIO 0-15 now = 0x%x\n",
970 __func__, gpio_output);
971
972 dprintk(1, "%s: GPIO value EIO 0-15 was = 0x%x\n",
973 __func__, value);
974 value |= (1<<14);
975 dprintk(1, "%s: GPIO value EIO 0-15 now = 0x%x\n",
976 __func__, value);
977 retval |= mc417_register_write(dev, 0x900C, value); 993 retval |= mc417_register_write(dev, 0x900C, value);
978 994
979 retval |= mc417_register_read(dev, IVTV_REG_VPU, &value); 995 retval |= mc417_register_read(dev, IVTV_REG_VPU, &value);
@@ -1788,9 +1804,6 @@ int cx23885_417_register(struct cx23885_dev *dev)
1788 return err; 1804 return err;
1789 } 1805 }
1790 1806
1791 /* Initialize MC417 registers */
1792 cx23885_mc417_init(dev);
1793
1794 printk(KERN_INFO "%s: registered device video%d [mpeg]\n", 1807 printk(KERN_INFO "%s: registered device video%d [mpeg]\n",
1795 dev->name, dev->v4l_device->num); 1808 dev->name, dev->v4l_device->num);
1796 1809
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index ce29b5e34a11..3143d85ef31d 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -201,6 +201,15 @@ struct cx23885_board cx23885_boards[] = {
201 .name = "Mygica X8506 DMB-TH", 201 .name = "Mygica X8506 DMB-TH",
202 .portb = CX23885_MPEG_DVB, 202 .portb = CX23885_MPEG_DVB,
203 }, 203 },
204 [CX23885_BOARD_MAGICPRO_PROHDTVE2] = {
205 .name = "Magic-Pro ProHDTV Extreme 2",
206 .portb = CX23885_MPEG_DVB,
207 },
208 [CX23885_BOARD_HAUPPAUGE_HVR1850] = {
209 .name = "Hauppauge WinTV-HVR1850",
210 .portb = CX23885_MPEG_ENCODER,
211 .portc = CX23885_MPEG_DVB,
212 },
204}; 213};
205const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); 214const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
206 215
@@ -324,6 +333,14 @@ struct cx23885_subid cx23885_subids[] = {
324 .subvendor = 0x14f1, 333 .subvendor = 0x14f1,
325 .subdevice = 0x8651, 334 .subdevice = 0x8651,
326 .card = CX23885_BOARD_MYGICA_X8506, 335 .card = CX23885_BOARD_MYGICA_X8506,
336 }, {
337 .subvendor = 0x14f1,
338 .subdevice = 0x8657,
339 .card = CX23885_BOARD_MAGICPRO_PROHDTVE2,
340 }, {
341 .subvendor = 0x0070,
342 .subdevice = 0x8541,
343 .card = CX23885_BOARD_HAUPPAUGE_HVR1850,
327 }, 344 },
328}; 345};
329const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); 346const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -483,8 +500,13 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
483 /* WinTV-HVR1700 (PCIe, OEM, No IR, full height) 500 /* WinTV-HVR1700 (PCIe, OEM, No IR, full height)
484 * DVB-T and MPEG2 HW Encoder */ 501 * DVB-T and MPEG2 HW Encoder */
485 break; 502 break;
503 case 85021:
504 /* WinTV-HVR1850 (PCIe, OEM, RCA in, IR, FM,
505 Dual channel ATSC and MPEG2 HW Encoder */
506 break;
486 default: 507 default:
487 printk(KERN_WARNING "%s: warning: unknown hauppauge model #%d\n", 508 printk(KERN_WARNING "%s: warning: "
509 "unknown hauppauge model #%d\n",
488 dev->name, tv.model); 510 dev->name, tv.model);
489 break; 511 break;
490 } 512 }
@@ -574,13 +596,23 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
574 /* CX23417 GPIO's */ 596 /* CX23417 GPIO's */
575 /* EIO15 Zilog Reset */ 597 /* EIO15 Zilog Reset */
576 /* EIO14 S5H1409/CX24227 Reset */ 598 /* EIO14 S5H1409/CX24227 Reset */
599 mc417_gpio_enable(dev, GPIO_15 | GPIO_14, 1);
600
601 /* Put the demod into reset and protect the eeprom */
602 mc417_gpio_clear(dev, GPIO_15 | GPIO_14);
603 mdelay(100);
604
605 /* Bring the demod and blaster out of reset */
606 mc417_gpio_set(dev, GPIO_15 | GPIO_14);
607 mdelay(100);
577 608
578 /* Force the TDA8295A into reset and back */ 609 /* Force the TDA8295A into reset and back */
579 cx_set(GP0_IO, 0x00040004); 610 cx23885_gpio_enable(dev, GPIO_2, 1);
611 cx23885_gpio_set(dev, GPIO_2);
580 mdelay(20); 612 mdelay(20);
581 cx_clear(GP0_IO, 0x00000004); 613 cx23885_gpio_clear(dev, GPIO_2);
582 mdelay(20); 614 mdelay(20);
583 cx_set(GP0_IO, 0x00040004); 615 cx23885_gpio_set(dev, GPIO_2);
584 mdelay(20); 616 mdelay(20);
585 break; 617 break;
586 case CX23885_BOARD_HAUPPAUGE_HVR1200: 618 case CX23885_BOARD_HAUPPAUGE_HVR1200:
@@ -715,14 +747,45 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
715 cx23885_gpio_set(dev, GPIO_9); 747 cx23885_gpio_set(dev, GPIO_9);
716 break; 748 break;
717 case CX23885_BOARD_MYGICA_X8506: 749 case CX23885_BOARD_MYGICA_X8506:
750 case CX23885_BOARD_MAGICPRO_PROHDTVE2:
718 /* GPIO-1 reset XC5000 */ 751 /* GPIO-1 reset XC5000 */
719 /* GPIO-2 reset LGS8GL5 */ 752 /* GPIO-2 reset LGS8GL5 / LGS8G75 */
720 cx_set(GP0_IO, 0x00060000); 753 cx_set(GP0_IO, 0x00060000);
721 cx_clear(GP0_IO, 0x00000006); 754 cx_clear(GP0_IO, 0x00000006);
722 mdelay(100); 755 mdelay(100);
723 cx_set(GP0_IO, 0x00060006); 756 cx_set(GP0_IO, 0x00060006);
724 mdelay(100); 757 mdelay(100);
725 break; 758 break;
759 case CX23885_BOARD_HAUPPAUGE_HVR1850:
760 /* GPIO-0 656_CLK */
761 /* GPIO-1 656_D0 */
762 /* GPIO-2 Wake# */
763 /* GPIO-3-10 cx23417 data0-7 */
764 /* GPIO-11-14 cx23417 addr0-3 */
765 /* GPIO-15-18 cx23417 READY, CS, RD, WR */
766 /* GPIO-19 IR_RX */
767 /* GPIO-20 C_IR_TX */
768 /* GPIO-21 I2S DAT */
769 /* GPIO-22 I2S WCLK */
770 /* GPIO-23 I2S BCLK */
771 /* ALT GPIO: EXP GPIO LATCH */
772
773 /* CX23417 GPIO's */
774 /* GPIO-14 S5H1411/CX24228 Reset */
775 /* GPIO-13 EEPROM write protect */
776 mc417_gpio_enable(dev, GPIO_14 | GPIO_13, 1);
777
778 /* Put the demod into reset and protect the eeprom */
779 mc417_gpio_clear(dev, GPIO_14 | GPIO_13);
780 mdelay(100);
781
782 /* Bring the demod out of reset */
783 mc417_gpio_set(dev, GPIO_14);
784 mdelay(100);
785
786 /* CX24228 GPIO */
787 /* Connected to IF / Mux */
788 break;
726 } 789 }
727} 790}
728 791
@@ -739,6 +802,7 @@ int cx23885_ir_init(struct cx23885_dev *dev)
739 case CX23885_BOARD_HAUPPAUGE_HVR1275: 802 case CX23885_BOARD_HAUPPAUGE_HVR1275:
740 case CX23885_BOARD_HAUPPAUGE_HVR1255: 803 case CX23885_BOARD_HAUPPAUGE_HVR1255:
741 case CX23885_BOARD_HAUPPAUGE_HVR1210: 804 case CX23885_BOARD_HAUPPAUGE_HVR1210:
805 case CX23885_BOARD_HAUPPAUGE_HVR1850:
742 /* FIXME: Implement me */ 806 /* FIXME: Implement me */
743 break; 807 break;
744 case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: 808 case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
@@ -778,6 +842,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
778 case CX23885_BOARD_HAUPPAUGE_HVR1275: 842 case CX23885_BOARD_HAUPPAUGE_HVR1275:
779 case CX23885_BOARD_HAUPPAUGE_HVR1255: 843 case CX23885_BOARD_HAUPPAUGE_HVR1255:
780 case CX23885_BOARD_HAUPPAUGE_HVR1210: 844 case CX23885_BOARD_HAUPPAUGE_HVR1210:
845 case CX23885_BOARD_HAUPPAUGE_HVR1850:
781 if (dev->i2c_bus[0].i2c_rc == 0) 846 if (dev->i2c_bus[0].i2c_rc == 0)
782 hauppauge_eeprom(dev, eeprom+0xc0); 847 hauppauge_eeprom(dev, eeprom+0xc0);
783 break; 848 break;
@@ -827,6 +892,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
827 ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; 892 ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
828 break; 893 break;
829 case CX23885_BOARD_MYGICA_X8506: 894 case CX23885_BOARD_MYGICA_X8506:
895 case CX23885_BOARD_MAGICPRO_PROHDTVE2:
830 ts1->gen_ctrl_val = 0x5; /* Parallel */ 896 ts1->gen_ctrl_val = 0x5; /* Parallel */
831 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 897 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
832 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; 898 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
@@ -844,6 +910,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
844 case CX23885_BOARD_HAUPPAUGE_HVR1275: 910 case CX23885_BOARD_HAUPPAUGE_HVR1275:
845 case CX23885_BOARD_HAUPPAUGE_HVR1255: 911 case CX23885_BOARD_HAUPPAUGE_HVR1255:
846 case CX23885_BOARD_HAUPPAUGE_HVR1210: 912 case CX23885_BOARD_HAUPPAUGE_HVR1210:
913 case CX23885_BOARD_HAUPPAUGE_HVR1850:
847 default: 914 default:
848 ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ 915 ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
849 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 916 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index bf7bb1c412fb..40d438d7234d 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -713,12 +713,26 @@ static void cx23885_dev_checkrevision(struct cx23885_dev *dev)
713 dev->hwrevision = 0xa1; 713 dev->hwrevision = 0xa1;
714 break; 714 break;
715 case 0x02: 715 case 0x02:
716 /* CX23885-13Z */ 716 /* CX23885-13Z/14Z */
717 dev->hwrevision = 0xb0; 717 dev->hwrevision = 0xb0;
718 break; 718 break;
719 case 0x03: 719 case 0x03:
720 /* CX23888-22Z */ 720 if (dev->pci->device == 0x8880) {
721 dev->hwrevision = 0xc0; 721 /* CX23888-21Z/22Z */
722 dev->hwrevision = 0xc0;
723 } else {
724 /* CX23885-14Z */
725 dev->hwrevision = 0xa4;
726 }
727 break;
728 case 0x04:
729 if (dev->pci->device == 0x8880) {
730 /* CX23888-31Z */
731 dev->hwrevision = 0xd0;
732 } else {
733 /* CX23885-15Z, CX23888-31Z */
734 dev->hwrevision = 0xa5;
735 }
722 break; 736 break;
723 case 0x0e: 737 case 0x0e:
724 /* CX23887-15Z */ 738 /* CX23887-15Z */
@@ -756,6 +770,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
756 770
757 /* Configure the internal memory */ 771 /* Configure the internal memory */
758 if (dev->pci->device == 0x8880) { 772 if (dev->pci->device == 0x8880) {
773 /* Could be 887 or 888, assume a default */
759 dev->bridge = CX23885_BRIDGE_887; 774 dev->bridge = CX23885_BRIDGE_887;
760 /* Apply a sensible clock frequency for the PCIe bridge */ 775 /* Apply a sensible clock frequency for the PCIe bridge */
761 dev->clk_freq = 25000000; 776 dev->clk_freq = 25000000;
@@ -868,6 +883,14 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
868 dprintk(1, "%s() radio_type = 0x%x radio_addr = 0x%x\n", 883 dprintk(1, "%s() radio_type = 0x%x radio_addr = 0x%x\n",
869 __func__, dev->radio_type, dev->radio_addr); 884 __func__, dev->radio_type, dev->radio_addr);
870 885
886 /* The cx23417 encoder has GPIO's that need to be initialised
887 * before DVB, so that demodulators and tuners are out of
888 * reset before DVB uses them.
889 */
890 if ((cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) ||
891 (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER))
892 cx23885_mc417_init(dev);
893
871 /* init hardware */ 894 /* init hardware */
872 cx23885_reset(dev); 895 cx23885_reset(dev);
873 896
@@ -1250,6 +1273,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
1250 switch (dev->bridge) { 1273 switch (dev->bridge) {
1251 case CX23885_BRIDGE_885: 1274 case CX23885_BRIDGE_885:
1252 case CX23885_BRIDGE_887: 1275 case CX23885_BRIDGE_887:
1276 case CX23885_BRIDGE_888:
1253 /* enable irqs */ 1277 /* enable irqs */
1254 dprintk(1, "%s() enabling TS int's and DMA\n", __func__); 1278 dprintk(1, "%s() enabling TS int's and DMA\n", __func__);
1255 cx_set(port->reg_ts_int_msk, port->ts_int_msk_val); 1279 cx_set(port->reg_ts_int_msk, port->ts_int_msk_val);
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 86ac529e62be..022fad798fc2 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -396,7 +396,7 @@ static struct stv0900_reg stv0900_ts_regs[] = {
396 396
397static struct stv0900_config netup_stv0900_config = { 397static struct stv0900_config netup_stv0900_config = {
398 .demod_address = 0x68, 398 .demod_address = 0x68,
399 .xtal = 27000000, 399 .xtal = 8000000,
400 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */ 400 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
401 .diseqc_mode = 2,/* 2/3 PWM */ 401 .diseqc_mode = 2,/* 2/3 PWM */
402 .ts_config_regs = stv0900_ts_regs, 402 .ts_config_regs = stv0900_ts_regs,
@@ -408,14 +408,14 @@ static struct stv0900_config netup_stv0900_config = {
408 408
409static struct stv6110_config netup_stv6110_tunerconfig_a = { 409static struct stv6110_config netup_stv6110_tunerconfig_a = {
410 .i2c_address = 0x60, 410 .i2c_address = 0x60,
411 .mclk = 27000000, 411 .mclk = 16000000,
412 .iq_wiring = 0, 412 .clk_div = 1,
413}; 413};
414 414
415static struct stv6110_config netup_stv6110_tunerconfig_b = { 415static struct stv6110_config netup_stv6110_tunerconfig_b = {
416 .i2c_address = 0x63, 416 .i2c_address = 0x63,
417 .mclk = 27000000, 417 .mclk = 16000000,
418 .iq_wiring = 1, 418 .clk_div = 1,
419}; 419};
420 420
421static int tbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) 421static int tbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
@@ -487,6 +487,26 @@ static int cx23885_dvb_set_frontend(struct dvb_frontend *fe,
487 port->set_frontend_save(fe, param) : -ENODEV; 487 port->set_frontend_save(fe, param) : -ENODEV;
488} 488}
489 489
490static struct lgs8gxx_config magicpro_prohdtve2_lgs8g75_config = {
491 .prod = LGS8GXX_PROD_LGS8G75,
492 .demod_address = 0x19,
493 .serial_ts = 0,
494 .ts_clk_pol = 1,
495 .ts_clk_gated = 1,
496 .if_clk_freq = 30400, /* 30.4 MHz */
497 .if_freq = 6500, /* 6.50 MHz */
498 .if_neg_center = 1,
499 .ext_adc = 0,
500 .adc_signed = 1,
501 .adc_vpp = 2, /* 1.6 Vpp */
502 .if_neg_edge = 1,
503};
504
505static struct xc5000_config magicpro_prohdtve2_xc5000_config = {
506 .i2c_address = 0x61,
507 .if_khz = 6500,
508};
509
490static int dvb_register(struct cx23885_tsport *port) 510static int dvb_register(struct cx23885_tsport *port)
491{ 511{
492 struct cx23885_dev *dev = port->dev; 512 struct cx23885_dev *dev = port->dev;
@@ -833,6 +853,30 @@ static int dvb_register(struct cx23885_tsport *port)
833 &mygica_x8506_xc5000_config); 853 &mygica_x8506_xc5000_config);
834 } 854 }
835 break; 855 break;
856 case CX23885_BOARD_MAGICPRO_PROHDTVE2:
857 i2c_bus = &dev->i2c_bus[0];
858 i2c_bus2 = &dev->i2c_bus[1];
859 fe0->dvb.frontend = dvb_attach(lgs8gxx_attach,
860 &magicpro_prohdtve2_lgs8g75_config,
861 &i2c_bus->i2c_adap);
862 if (fe0->dvb.frontend != NULL) {
863 dvb_attach(xc5000_attach,
864 fe0->dvb.frontend,
865 &i2c_bus2->i2c_adap,
866 &magicpro_prohdtve2_xc5000_config);
867 }
868 break;
869 case CX23885_BOARD_HAUPPAUGE_HVR1850:
870 i2c_bus = &dev->i2c_bus[0];
871 fe0->dvb.frontend = dvb_attach(s5h1411_attach,
872 &hcw_s5h1411_config,
873 &i2c_bus->i2c_adap);
874 if (fe0->dvb.frontend != NULL)
875 dvb_attach(tda18271_attach, fe0->dvb.frontend,
876 0x60, &dev->i2c_bus[0].i2c_adap,
877 &hauppauge_tda18271_config);
878 break;
879
836 default: 880 default:
837 printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " 881 printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
838 " isn't supported yet\n", 882 " isn't supported yet\n",
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c
index 384dec34134f..4172cb387420 100644
--- a/drivers/media/video/cx23885/cx23885-i2c.c
+++ b/drivers/media/video/cx23885/cx23885-i2c.c
@@ -283,7 +283,6 @@ static struct i2c_algorithm cx23885_i2c_algo_template = {
283static struct i2c_adapter cx23885_i2c_adap_template = { 283static struct i2c_adapter cx23885_i2c_adap_template = {
284 .name = "cx23885", 284 .name = "cx23885",
285 .owner = THIS_MODULE, 285 .owner = THIS_MODULE,
286 .id = I2C_HW_B_CX23885,
287 .algo = &cx23885_i2c_algo_template, 286 .algo = &cx23885_i2c_algo_template,
288}; 287};
289 288
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 214a55e943b7..86f26947bb78 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -76,6 +76,8 @@
76#define CX23885_BOARD_HAUPPAUGE_HVR1255 20 76#define CX23885_BOARD_HAUPPAUGE_HVR1255 20
77#define CX23885_BOARD_HAUPPAUGE_HVR1210 21 77#define CX23885_BOARD_HAUPPAUGE_HVR1210 21
78#define CX23885_BOARD_MYGICA_X8506 22 78#define CX23885_BOARD_MYGICA_X8506 22
79#define CX23885_BOARD_MAGICPRO_PROHDTVE2 23
80#define CX23885_BOARD_HAUPPAUGE_HVR1850 24
79 81
80#define GPIO_0 0x00000001 82#define GPIO_0 0x00000001
81#define GPIO_1 0x00000002 83#define GPIO_1 0x00000002
@@ -87,6 +89,12 @@
87#define GPIO_7 0x00000080 89#define GPIO_7 0x00000080
88#define GPIO_8 0x00000100 90#define GPIO_8 0x00000100
89#define GPIO_9 0x00000200 91#define GPIO_9 0x00000200
92#define GPIO_10 0x00000400
93#define GPIO_11 0x00000800
94#define GPIO_12 0x00001000
95#define GPIO_13 0x00002000
96#define GPIO_14 0x00004000
97#define GPIO_15 0x00008000
90 98
91/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */ 99/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */
92#define CX23885_NORMS (\ 100#define CX23885_NORMS (\
@@ -331,6 +339,7 @@ struct cx23885_dev {
331 CX23885_BRIDGE_UNDEFINED = 0, 339 CX23885_BRIDGE_UNDEFINED = 0,
332 CX23885_BRIDGE_885 = 885, 340 CX23885_BRIDGE_885 = 885,
333 CX23885_BRIDGE_887 = 887, 341 CX23885_BRIDGE_887 = 887,
342 CX23885_BRIDGE_888 = 888,
334 } bridge; 343 } bridge;
335 344
336 /* Analog video */ 345 /* Analog video */
@@ -395,7 +404,7 @@ struct sram_channel {
395 u32 cmds_start; 404 u32 cmds_start;
396 u32 ctrl_start; 405 u32 ctrl_start;
397 u32 cdt; 406 u32 cdt;
398 u32 fifo_start;; 407 u32 fifo_start;
399 u32 fifo_size; 408 u32 fifo_size;
400 u32 ptr1_reg; 409 u32 ptr1_reg;
401 u32 ptr2_reg; 410 u32 ptr2_reg;
@@ -504,6 +513,9 @@ extern void cx23885_417_check_encoder(struct cx23885_dev *dev);
504extern void cx23885_mc417_init(struct cx23885_dev *dev); 513extern void cx23885_mc417_init(struct cx23885_dev *dev);
505extern int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value); 514extern int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value);
506extern int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value); 515extern int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value);
516extern void mc417_gpio_set(struct cx23885_dev *dev, u32 mask);
517extern void mc417_gpio_clear(struct cx23885_dev *dev, u32 mask);
518extern void mc417_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput);
507 519
508 520
509/* ----------------------------------------------------------- */ 521/* ----------------------------------------------------------- */
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 0be51b65f098..1aeaf18a9bea 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -321,6 +321,15 @@ static void cx23885_initialize(struct i2c_client *client)
321 /* Select AFE clock pad output source */ 321 /* Select AFE clock pad output source */
322 cx25840_write(client, 0x144, 0x05); 322 cx25840_write(client, 0x144, 0x05);
323 323
324 /* Drive GPIO2 direction and values for HVR1700
325 * where an onboard mux selects the output of demodulator
326 * vs the 417. Failure to set this results in no DTV.
327 * It's safe to set this across all Hauppauge boards
328 * currently, regardless of the board type.
329 */
330 cx25840_write(client, 0x160, 0x1d);
331 cx25840_write(client, 0x164, 0x00);
332
324 /* Do the firmware load in a work handler to prevent. 333 /* Do the firmware load in a work handler to prevent.
325 Otherwise the kernel is blocked waiting for the 334 Otherwise the kernel is blocked waiting for the
326 bit-banging i2c interface to finish uploading the 335 bit-banging i2c interface to finish uploading the
@@ -1578,12 +1587,6 @@ static int cx25840_probe(struct i2c_client *client,
1578 state->id = id; 1587 state->id = id;
1579 state->rev = device_id; 1588 state->rev = device_id;
1580 1589
1581 if (state->is_cx23885) {
1582 /* Drive GPIO2 direction and values */
1583 cx25840_write(client, 0x160, 0x1d);
1584 cx25840_write(client, 0x164, 0x00);
1585 }
1586
1587 return 0; 1590 return 0;
1588} 1591}
1589 1592
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c
index 0df53b0d75d9..1f483c1d0dbe 100644
--- a/drivers/media/video/cx25840/cx25840-firmware.c
+++ b/drivers/media/video/cx25840/cx25840-firmware.c
@@ -23,10 +23,6 @@
23 23
24#include "cx25840-core.h" 24#include "cx25840-core.h"
25 25
26#define FWFILE "v4l-cx25840.fw"
27#define FWFILE_CX23885 "v4l-cx23885-avcore-01.fw"
28#define FWFILE_CX231XX "v4l-cx231xx-avcore-01.fw"
29
30/* 26/*
31 * Mike Isely <isely@pobox.com> - The FWSEND parameter controls the 27 * Mike Isely <isely@pobox.com> - The FWSEND parameter controls the
32 * size of the firmware chunks sent down the I2C bus to the chip. 28 * size of the firmware chunks sent down the I2C bus to the chip.
@@ -40,11 +36,11 @@
40 36
41#define FWDEV(x) &((x)->dev) 37#define FWDEV(x) &((x)->dev)
42 38
43static char *firmware = FWFILE; 39static char *firmware = "";
44 40
45module_param(firmware, charp, 0444); 41module_param(firmware, charp, 0444);
46 42
47MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]"); 43MODULE_PARM_DESC(firmware, "Firmware image to load");
48 44
49static void start_fw_load(struct i2c_client *client) 45static void start_fw_load(struct i2c_client *client)
50{ 46{
@@ -65,6 +61,19 @@ static void end_fw_load(struct i2c_client *client)
65 cx25840_write(client, 0x803, 0x03); 61 cx25840_write(client, 0x803, 0x03);
66} 62}
67 63
64static const char *get_fw_name(struct i2c_client *client)
65{
66 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
67
68 if (firmware[0])
69 return firmware;
70 if (state->is_cx23885)
71 return "v4l-cx23885-avcore-01.fw";
72 if (state->is_cx231xx)
73 return "v4l-cx231xx-avcore-01.fw";
74 return "v4l-cx25840.fw";
75}
76
68static int check_fw_load(struct i2c_client *client, int size) 77static int check_fw_load(struct i2c_client *client, int size)
69{ 78{
70 /* DL_ADDR_HB DL_ADDR_LB */ 79 /* DL_ADDR_HB DL_ADDR_LB */
@@ -72,11 +81,13 @@ static int check_fw_load(struct i2c_client *client, int size)
72 s |= cx25840_read(client, 0x800); 81 s |= cx25840_read(client, 0x800);
73 82
74 if (size != s) { 83 if (size != s) {
75 v4l_err(client, "firmware %s load failed\n", firmware); 84 v4l_err(client, "firmware %s load failed\n",
85 get_fw_name(client));
76 return -EINVAL; 86 return -EINVAL;
77 } 87 }
78 88
79 v4l_info(client, "loaded %s firmware (%d bytes)\n", firmware, size); 89 v4l_info(client, "loaded %s firmware (%d bytes)\n",
90 get_fw_name(client), size);
80 return 0; 91 return 0;
81} 92}
82 93
@@ -96,21 +107,24 @@ int cx25840_loadfw(struct i2c_client *client)
96 const struct firmware *fw = NULL; 107 const struct firmware *fw = NULL;
97 u8 buffer[FWSEND]; 108 u8 buffer[FWSEND];
98 const u8 *ptr; 109 const u8 *ptr;
110 const char *fwname = get_fw_name(client);
99 int size, retval; 111 int size, retval;
100 int MAX_BUF_SIZE = FWSEND; 112 int MAX_BUF_SIZE = FWSEND;
113 u32 gpio_oe = 0, gpio_da = 0;
101 114
102 if (state->is_cx23885) 115 if (state->is_cx23885) {
103 firmware = FWFILE_CX23885; 116 /* Preserve the GPIO OE and output bits */
104 else if (state->is_cx231xx) 117 gpio_oe = cx25840_read(client, 0x160);
105 firmware = FWFILE_CX231XX; 118 gpio_da = cx25840_read(client, 0x164);
119 }
106 120
107 if ((state->is_cx231xx) && MAX_BUF_SIZE > 16) { 121 if ((state->is_cx231xx) && MAX_BUF_SIZE > 16) {
108 v4l_err(client, " Firmware download size changed to 16 bytes max length\n"); 122 v4l_err(client, " Firmware download size changed to 16 bytes max length\n");
109 MAX_BUF_SIZE = 16; /* cx231xx cannot accept more than 16 bytes at a time */ 123 MAX_BUF_SIZE = 16; /* cx231xx cannot accept more than 16 bytes at a time */
110 } 124 }
111 125
112 if (request_firmware(&fw, firmware, FWDEV(client)) != 0) { 126 if (request_firmware(&fw, fwname, FWDEV(client)) != 0) {
113 v4l_err(client, "unable to open firmware %s\n", firmware); 127 v4l_err(client, "unable to open firmware %s\n", fwname);
114 return -EINVAL; 128 return -EINVAL;
115 } 129 }
116 130
@@ -142,5 +156,11 @@ int cx25840_loadfw(struct i2c_client *client)
142 size = fw->size; 156 size = fw->size;
143 release_firmware(fw); 157 release_firmware(fw);
144 158
159 if (state->is_cx23885) {
160 /* Restore GPIO configuration after f/w load */
161 cx25840_write(client, 0x160, gpio_oe);
162 cx25840_write(client, 0x164, gpio_da);
163 }
164
145 return check_fw_load(client, size); 165 return check_fw_load(client, size);
146} 166}
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 39465301ec94..e5f07fbd5a35 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1283,6 +1283,51 @@ static const struct cx88_board cx88_boards[] = {
1283 }, 1283 },
1284 .mpeg = CX88_MPEG_DVB, 1284 .mpeg = CX88_MPEG_DVB,
1285 }, 1285 },
1286 [CX88_BOARD_WINFAST_DTV2000H_J] = {
1287 .name = "WinFast DTV2000 H rev. J",
1288 .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
1289 .radio_type = UNSET,
1290 .tuner_addr = ADDR_UNSET,
1291 .radio_addr = ADDR_UNSET,
1292 .tda9887_conf = TDA9887_PRESENT,
1293 .input = {{
1294 .type = CX88_VMUX_TELEVISION,
1295 .vmux = 0,
1296 .gpio0 = 0x00017300,
1297 .gpio1 = 0x00008207,
1298 .gpio2 = 0x00000000,
1299 .gpio3 = 0x02000000,
1300 },{
1301 .type = CX88_VMUX_TELEVISION,
1302 .vmux = 0,
1303 .gpio0 = 0x00018300,
1304 .gpio1 = 0x0000f207,
1305 .gpio2 = 0x00017304,
1306 .gpio3 = 0x02000000,
1307 },{
1308 .type = CX88_VMUX_COMPOSITE1,
1309 .vmux = 1,
1310 .gpio0 = 0x00018301,
1311 .gpio1 = 0x0000f207,
1312 .gpio2 = 0x00017304,
1313 .gpio3 = 0x02000000,
1314 },{
1315 .type = CX88_VMUX_SVIDEO,
1316 .vmux = 2,
1317 .gpio0 = 0x00018301,
1318 .gpio1 = 0x0000f207,
1319 .gpio2 = 0x00017304,
1320 .gpio3 = 0x02000000,
1321 }},
1322 .radio = {
1323 .type = CX88_RADIO,
1324 .gpio0 = 0x00015702,
1325 .gpio1 = 0x0000f207,
1326 .gpio2 = 0x00015702,
1327 .gpio3 = 0x02000000,
1328 },
1329 .mpeg = CX88_MPEG_DVB,
1330 },
1286 [CX88_BOARD_GENIATECH_DVBS] = { 1331 [CX88_BOARD_GENIATECH_DVBS] = {
1287 .name = "Geniatech DVB-S", 1332 .name = "Geniatech DVB-S",
1288 .tuner_type = TUNER_ABSENT, 1333 .tuner_type = TUNER_ABSENT,
@@ -1908,7 +1953,8 @@ static const struct cx88_board cx88_boards[] = {
1908 .radio_addr = ADDR_UNSET, 1953 .radio_addr = ADDR_UNSET,
1909 .input = {{ 1954 .input = {{
1910 .type = CX88_VMUX_DVB, 1955 .type = CX88_VMUX_DVB,
1911 .vmux = 1, 1956 .vmux = 0,
1957 .gpio0 = 0x8080,
1912 } }, 1958 } },
1913 .mpeg = CX88_MPEG_DVB, 1959 .mpeg = CX88_MPEG_DVB,
1914 }, 1960 },
@@ -2282,6 +2328,10 @@ static const struct cx88_subid cx88_subids[] = {
2282 .subdevice = 0x665e, 2328 .subdevice = 0x665e,
2283 .card = CX88_BOARD_WINFAST_DTV2000H, 2329 .card = CX88_BOARD_WINFAST_DTV2000H,
2284 },{ 2330 },{
2331 .subvendor = 0x107d,
2332 .subdevice = 0x6f2b,
2333 .card = CX88_BOARD_WINFAST_DTV2000H_J,
2334 },{
2285 .subvendor = 0x18ac, 2335 .subvendor = 0x18ac,
2286 .subdevice = 0xd800, /* FusionHDTV 3 Gold (original revision) */ 2336 .subdevice = 0xd800, /* FusionHDTV 3 Gold (original revision) */
2287 .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q, 2337 .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q,
@@ -3162,7 +3212,11 @@ static void cx88_card_setup(struct cx88_core *core)
3162 case CX88_BOARD_PROF_6200: 3212 case CX88_BOARD_PROF_6200:
3163 case CX88_BOARD_PROF_7300: 3213 case CX88_BOARD_PROF_7300:
3164 case CX88_BOARD_SATTRADE_ST4200: 3214 case CX88_BOARD_SATTRADE_ST4200:
3215 cx_write(MO_GP0_IO, 0x8000);
3216 msleep(100);
3165 cx_write(MO_SRST_IO, 0); 3217 cx_write(MO_SRST_IO, 0);
3218 msleep(10);
3219 cx_write(MO_GP0_IO, 0x8080);
3166 msleep(100); 3220 msleep(100);
3167 cx_write(MO_SRST_IO, 1); 3221 cx_write(MO_SRST_IO, 1);
3168 msleep(100); 3222 msleep(100);
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index e237b507659b..6e5d142b5b00 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -424,17 +424,16 @@ static int tevii_dvbs_set_voltage(struct dvb_frontend *fe,
424 struct cx8802_dev *dev= fe->dvb->priv; 424 struct cx8802_dev *dev= fe->dvb->priv;
425 struct cx88_core *core = dev->core; 425 struct cx88_core *core = dev->core;
426 426
427 cx_set(MO_GP0_IO, 0x6040);
427 switch (voltage) { 428 switch (voltage) {
428 case SEC_VOLTAGE_13: 429 case SEC_VOLTAGE_13:
429 printk("LNB Voltage SEC_VOLTAGE_13\n"); 430 cx_clear(MO_GP0_IO, 0x20);
430 cx_write(MO_GP0_IO, 0x00006040);
431 break; 431 break;
432 case SEC_VOLTAGE_18: 432 case SEC_VOLTAGE_18:
433 printk("LNB Voltage SEC_VOLTAGE_18\n"); 433 cx_set(MO_GP0_IO, 0x20);
434 cx_write(MO_GP0_IO, 0x00006060);
435 break; 434 break;
436 case SEC_VOLTAGE_OFF: 435 case SEC_VOLTAGE_OFF:
437 printk("LNB Voltage SEC_VOLTAGE_off\n"); 436 cx_clear(MO_GP0_IO, 0x20);
438 break; 437 break;
439 } 438 }
440 439
@@ -499,9 +498,9 @@ static struct zl10353_config cx88_pinnacle_hybrid_pctv = {
499}; 498};
500 499
501static struct zl10353_config cx88_geniatech_x8000_mt = { 500static struct zl10353_config cx88_geniatech_x8000_mt = {
502 .demod_address = (0x1e >> 1), 501 .demod_address = (0x1e >> 1),
503 .no_tuner = 1, 502 .no_tuner = 1,
504 .disable_i2c_gate_ctrl = 1, 503 .disable_i2c_gate_ctrl = 1,
505}; 504};
506 505
507static struct s5h1411_config dvico_fusionhdtv7_config = { 506static struct s5h1411_config dvico_fusionhdtv7_config = {
@@ -696,6 +695,7 @@ static int dvb_register(struct cx8802_dev *dev)
696 } 695 }
697 break; 696 break;
698 case CX88_BOARD_WINFAST_DTV2000H: 697 case CX88_BOARD_WINFAST_DTV2000H:
698 case CX88_BOARD_WINFAST_DTV2000H_J:
699 case CX88_BOARD_HAUPPAUGE_HVR1100: 699 case CX88_BOARD_HAUPPAUGE_HVR1100:
700 case CX88_BOARD_HAUPPAUGE_HVR1100LP: 700 case CX88_BOARD_HAUPPAUGE_HVR1100LP:
701 case CX88_BOARD_HAUPPAUGE_HVR1300: 701 case CX88_BOARD_HAUPPAUGE_HVR1300:
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index d91f5c51206d..78b3635178af 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/delay.h> 26#include <linux/hrtimer.h>
27#include <linux/input.h> 27#include <linux/input.h>
28#include <linux/pci.h> 28#include <linux/pci.h>
29#include <linux/module.h> 29#include <linux/module.h>
@@ -48,7 +48,7 @@ struct cx88_IR {
48 48
49 /* poll external decoder */ 49 /* poll external decoder */
50 int polling; 50 int polling;
51 struct delayed_work work; 51 struct hrtimer timer;
52 u32 gpio_addr; 52 u32 gpio_addr;
53 u32 last_gpio; 53 u32 last_gpio;
54 u32 mask_keycode; 54 u32 mask_keycode;
@@ -144,19 +144,28 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
144 } 144 }
145} 145}
146 146
147static void cx88_ir_work(struct work_struct *work) 147static enum hrtimer_restart cx88_ir_work(struct hrtimer *timer)
148{ 148{
149 struct cx88_IR *ir = container_of(work, struct cx88_IR, work.work); 149 unsigned long missed;
150 struct cx88_IR *ir = container_of(timer, struct cx88_IR, timer);
150 151
151 cx88_ir_handle_key(ir); 152 cx88_ir_handle_key(ir);
152 schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); 153 missed = hrtimer_forward_now(&ir->timer,
154 ktime_set(0, ir->polling * 1000000));
155 if (missed > 1)
156 ir_dprintk("Missed ticks %ld\n", missed - 1);
157
158 return HRTIMER_RESTART;
153} 159}
154 160
155void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir) 161void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir)
156{ 162{
157 if (ir->polling) { 163 if (ir->polling) {
158 INIT_DELAYED_WORK(&ir->work, cx88_ir_work); 164 hrtimer_init(&ir->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
159 schedule_delayed_work(&ir->work, 0); 165 ir->timer.function = cx88_ir_work;
166 hrtimer_start(&ir->timer,
167 ktime_set(0, ir->polling * 1000000),
168 HRTIMER_MODE_REL);
160 } 169 }
161 if (ir->sampling) { 170 if (ir->sampling) {
162 core->pci_irqmask |= PCI_INT_IR_SMPINT; 171 core->pci_irqmask |= PCI_INT_IR_SMPINT;
@@ -173,7 +182,7 @@ void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir)
173 } 182 }
174 183
175 if (ir->polling) 184 if (ir->polling)
176 cancel_delayed_work_sync(&ir->work); 185 hrtimer_cancel(&ir->timer);
177} 186}
178 187
179/* ---------------------------------------------------------------------- */ 188/* ---------------------------------------------------------------------- */
@@ -182,7 +191,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
182{ 191{
183 struct cx88_IR *ir; 192 struct cx88_IR *ir;
184 struct input_dev *input_dev; 193 struct input_dev *input_dev;
185 IR_KEYTAB_TYPE *ir_codes = NULL; 194 struct ir_scancode_table *ir_codes = NULL;
186 int ir_type = IR_TYPE_OTHER; 195 int ir_type = IR_TYPE_OTHER;
187 int err = -ENOMEM; 196 int err = -ENOMEM;
188 197
@@ -198,14 +207,14 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
198 case CX88_BOARD_DNTV_LIVE_DVB_T: 207 case CX88_BOARD_DNTV_LIVE_DVB_T:
199 case CX88_BOARD_KWORLD_DVB_T: 208 case CX88_BOARD_KWORLD_DVB_T:
200 case CX88_BOARD_KWORLD_DVB_T_CX22702: 209 case CX88_BOARD_KWORLD_DVB_T_CX22702:
201 ir_codes = ir_codes_dntv_live_dvb_t; 210 ir_codes = &ir_codes_dntv_live_dvb_t_table;
202 ir->gpio_addr = MO_GP1_IO; 211 ir->gpio_addr = MO_GP1_IO;
203 ir->mask_keycode = 0x1f; 212 ir->mask_keycode = 0x1f;
204 ir->mask_keyup = 0x60; 213 ir->mask_keyup = 0x60;
205 ir->polling = 50; /* ms */ 214 ir->polling = 50; /* ms */
206 break; 215 break;
207 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: 216 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
208 ir_codes = ir_codes_cinergy_1400; 217 ir_codes = &ir_codes_cinergy_1400_table;
209 ir_type = IR_TYPE_PD; 218 ir_type = IR_TYPE_PD;
210 ir->sampling = 0xeb04; /* address */ 219 ir->sampling = 0xeb04; /* address */
211 break; 220 break;
@@ -220,13 +229,14 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
220 case CX88_BOARD_PCHDTV_HD3000: 229 case CX88_BOARD_PCHDTV_HD3000:
221 case CX88_BOARD_PCHDTV_HD5500: 230 case CX88_BOARD_PCHDTV_HD5500:
222 case CX88_BOARD_HAUPPAUGE_IRONLY: 231 case CX88_BOARD_HAUPPAUGE_IRONLY:
223 ir_codes = ir_codes_hauppauge_new; 232 ir_codes = &ir_codes_hauppauge_new_table;
224 ir_type = IR_TYPE_RC5; 233 ir_type = IR_TYPE_RC5;
225 ir->sampling = 1; 234 ir->sampling = 1;
226 break; 235 break;
227 case CX88_BOARD_WINFAST_DTV2000H: 236 case CX88_BOARD_WINFAST_DTV2000H:
237 case CX88_BOARD_WINFAST_DTV2000H_J:
228 case CX88_BOARD_WINFAST_DTV1800H: 238 case CX88_BOARD_WINFAST_DTV1800H:
229 ir_codes = ir_codes_winfast; 239 ir_codes = &ir_codes_winfast_table;
230 ir->gpio_addr = MO_GP0_IO; 240 ir->gpio_addr = MO_GP0_IO;
231 ir->mask_keycode = 0x8f8; 241 ir->mask_keycode = 0x8f8;
232 ir->mask_keyup = 0x100; 242 ir->mask_keyup = 0x100;
@@ -235,14 +245,14 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
235 case CX88_BOARD_WINFAST2000XP_EXPERT: 245 case CX88_BOARD_WINFAST2000XP_EXPERT:
236 case CX88_BOARD_WINFAST_DTV1000: 246 case CX88_BOARD_WINFAST_DTV1000:
237 case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL: 247 case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
238 ir_codes = ir_codes_winfast; 248 ir_codes = &ir_codes_winfast_table;
239 ir->gpio_addr = MO_GP0_IO; 249 ir->gpio_addr = MO_GP0_IO;
240 ir->mask_keycode = 0x8f8; 250 ir->mask_keycode = 0x8f8;
241 ir->mask_keyup = 0x100; 251 ir->mask_keyup = 0x100;
242 ir->polling = 1; /* ms */ 252 ir->polling = 1; /* ms */
243 break; 253 break;
244 case CX88_BOARD_IODATA_GVBCTV7E: 254 case CX88_BOARD_IODATA_GVBCTV7E:
245 ir_codes = ir_codes_iodata_bctv7e; 255 ir_codes = &ir_codes_iodata_bctv7e_table;
246 ir->gpio_addr = MO_GP0_IO; 256 ir->gpio_addr = MO_GP0_IO;
247 ir->mask_keycode = 0xfd; 257 ir->mask_keycode = 0xfd;
248 ir->mask_keydown = 0x02; 258 ir->mask_keydown = 0x02;
@@ -250,7 +260,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
250 break; 260 break;
251 case CX88_BOARD_PROLINK_PLAYTVPVR: 261 case CX88_BOARD_PROLINK_PLAYTVPVR:
252 case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO: 262 case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO:
253 ir_codes = ir_codes_pixelview; 263 ir_codes = &ir_codes_pixelview_table;
254 ir->gpio_addr = MO_GP1_IO; 264 ir->gpio_addr = MO_GP1_IO;
255 ir->mask_keycode = 0x1f; 265 ir->mask_keycode = 0x1f;
256 ir->mask_keyup = 0x80; 266 ir->mask_keyup = 0x80;
@@ -258,28 +268,28 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
258 break; 268 break;
259 case CX88_BOARD_PROLINK_PV_8000GT: 269 case CX88_BOARD_PROLINK_PV_8000GT:
260 case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME: 270 case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
261 ir_codes = ir_codes_pixelview_new; 271 ir_codes = &ir_codes_pixelview_new_table;
262 ir->gpio_addr = MO_GP1_IO; 272 ir->gpio_addr = MO_GP1_IO;
263 ir->mask_keycode = 0x3f; 273 ir->mask_keycode = 0x3f;
264 ir->mask_keyup = 0x80; 274 ir->mask_keyup = 0x80;
265 ir->polling = 1; /* ms */ 275 ir->polling = 1; /* ms */
266 break; 276 break;
267 case CX88_BOARD_KWORLD_LTV883: 277 case CX88_BOARD_KWORLD_LTV883:
268 ir_codes = ir_codes_pixelview; 278 ir_codes = &ir_codes_pixelview_table;
269 ir->gpio_addr = MO_GP1_IO; 279 ir->gpio_addr = MO_GP1_IO;
270 ir->mask_keycode = 0x1f; 280 ir->mask_keycode = 0x1f;
271 ir->mask_keyup = 0x60; 281 ir->mask_keyup = 0x60;
272 ir->polling = 1; /* ms */ 282 ir->polling = 1; /* ms */
273 break; 283 break;
274 case CX88_BOARD_ADSTECH_DVB_T_PCI: 284 case CX88_BOARD_ADSTECH_DVB_T_PCI:
275 ir_codes = ir_codes_adstech_dvb_t_pci; 285 ir_codes = &ir_codes_adstech_dvb_t_pci_table;
276 ir->gpio_addr = MO_GP1_IO; 286 ir->gpio_addr = MO_GP1_IO;
277 ir->mask_keycode = 0xbf; 287 ir->mask_keycode = 0xbf;
278 ir->mask_keyup = 0x40; 288 ir->mask_keyup = 0x40;
279 ir->polling = 50; /* ms */ 289 ir->polling = 50; /* ms */
280 break; 290 break;
281 case CX88_BOARD_MSI_TVANYWHERE_MASTER: 291 case CX88_BOARD_MSI_TVANYWHERE_MASTER:
282 ir_codes = ir_codes_msi_tvanywhere; 292 ir_codes = &ir_codes_msi_tvanywhere_table;
283 ir->gpio_addr = MO_GP1_IO; 293 ir->gpio_addr = MO_GP1_IO;
284 ir->mask_keycode = 0x1f; 294 ir->mask_keycode = 0x1f;
285 ir->mask_keyup = 0x40; 295 ir->mask_keyup = 0x40;
@@ -287,40 +297,40 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
287 break; 297 break;
288 case CX88_BOARD_AVERTV_303: 298 case CX88_BOARD_AVERTV_303:
289 case CX88_BOARD_AVERTV_STUDIO_303: 299 case CX88_BOARD_AVERTV_STUDIO_303:
290 ir_codes = ir_codes_avertv_303; 300 ir_codes = &ir_codes_avertv_303_table;
291 ir->gpio_addr = MO_GP2_IO; 301 ir->gpio_addr = MO_GP2_IO;
292 ir->mask_keycode = 0xfb; 302 ir->mask_keycode = 0xfb;
293 ir->mask_keydown = 0x02; 303 ir->mask_keydown = 0x02;
294 ir->polling = 50; /* ms */ 304 ir->polling = 50; /* ms */
295 break; 305 break;
296 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: 306 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
297 ir_codes = ir_codes_dntv_live_dvbt_pro; 307 ir_codes = &ir_codes_dntv_live_dvbt_pro_table;
298 ir_type = IR_TYPE_PD; 308 ir_type = IR_TYPE_PD;
299 ir->sampling = 0xff00; /* address */ 309 ir->sampling = 0xff00; /* address */
300 break; 310 break;
301 case CX88_BOARD_NORWOOD_MICRO: 311 case CX88_BOARD_NORWOOD_MICRO:
302 ir_codes = ir_codes_norwood; 312 ir_codes = &ir_codes_norwood_table;
303 ir->gpio_addr = MO_GP1_IO; 313 ir->gpio_addr = MO_GP1_IO;
304 ir->mask_keycode = 0x0e; 314 ir->mask_keycode = 0x0e;
305 ir->mask_keyup = 0x80; 315 ir->mask_keyup = 0x80;
306 ir->polling = 50; /* ms */ 316 ir->polling = 50; /* ms */
307 break; 317 break;
308 case CX88_BOARD_NPGTECH_REALTV_TOP10FM: 318 case CX88_BOARD_NPGTECH_REALTV_TOP10FM:
309 ir_codes = ir_codes_npgtech; 319 ir_codes = &ir_codes_npgtech_table;
310 ir->gpio_addr = MO_GP0_IO; 320 ir->gpio_addr = MO_GP0_IO;
311 ir->mask_keycode = 0xfa; 321 ir->mask_keycode = 0xfa;
312 ir->polling = 50; /* ms */ 322 ir->polling = 50; /* ms */
313 break; 323 break;
314 case CX88_BOARD_PINNACLE_PCTV_HD_800i: 324 case CX88_BOARD_PINNACLE_PCTV_HD_800i:
315 ir_codes = ir_codes_pinnacle_pctv_hd; 325 ir_codes = &ir_codes_pinnacle_pctv_hd_table;
316 ir_type = IR_TYPE_RC5; 326 ir_type = IR_TYPE_RC5;
317 ir->sampling = 1; 327 ir->sampling = 1;
318 break; 328 break;
319 case CX88_BOARD_POWERCOLOR_REAL_ANGEL: 329 case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
320 ir_codes = ir_codes_powercolor_real_angel; 330 ir_codes = &ir_codes_powercolor_real_angel_table;
321 ir->gpio_addr = MO_GP2_IO; 331 ir->gpio_addr = MO_GP2_IO;
322 ir->mask_keycode = 0x7e; 332 ir->mask_keycode = 0x7e;
323 ir->polling = 100; /* ms */ 333 ir->polling = 100; /* ms */
324 break; 334 break;
325 } 335 }
326 336
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 9d83762163f5..d5cea41f4207 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -237,6 +237,7 @@ extern struct sram_channel cx88_sram_channels[];
237#define CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII 79 237#define CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII 79
238#define CX88_BOARD_HAUPPAUGE_IRONLY 80 238#define CX88_BOARD_HAUPPAUGE_IRONLY 80
239#define CX88_BOARD_WINFAST_DTV1800H 81 239#define CX88_BOARD_WINFAST_DTV1800H 81
240#define CX88_BOARD_WINFAST_DTV2000H_J 82
240 241
241enum cx88_itype { 242enum cx88_itype {
242 CX88_VMUX_COMPOSITE1 = 1, 243 CX88_VMUX_COMPOSITE1 = 1,
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 1c2e544eda73..7e3c78239fa9 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -299,6 +299,7 @@ struct em28xx_board em28xx_boards[] = {
299 [EM2820_BOARD_TERRATEC_CINERGY_250] = { 299 [EM2820_BOARD_TERRATEC_CINERGY_250] = {
300 .name = "Terratec Cinergy 250 USB", 300 .name = "Terratec Cinergy 250 USB",
301 .tuner_type = TUNER_LG_PAL_NEW_TAPC, 301 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
302 .has_ir_i2c = 1,
302 .tda9887_conf = TDA9887_PRESENT, 303 .tda9887_conf = TDA9887_PRESENT,
303 .decoder = EM28XX_SAA711X, 304 .decoder = EM28XX_SAA711X,
304 .input = { { 305 .input = { {
@@ -318,6 +319,7 @@ struct em28xx_board em28xx_boards[] = {
318 [EM2820_BOARD_PINNACLE_USB_2] = { 319 [EM2820_BOARD_PINNACLE_USB_2] = {
319 .name = "Pinnacle PCTV USB 2", 320 .name = "Pinnacle PCTV USB 2",
320 .tuner_type = TUNER_LG_PAL_NEW_TAPC, 321 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
322 .has_ir_i2c = 1,
321 .tda9887_conf = TDA9887_PRESENT, 323 .tda9887_conf = TDA9887_PRESENT,
322 .decoder = EM28XX_SAA711X, 324 .decoder = EM28XX_SAA711X,
323 .input = { { 325 .input = { {
@@ -342,6 +344,7 @@ struct em28xx_board em28xx_boards[] = {
342 TDA9887_PORT2_ACTIVE, 344 TDA9887_PORT2_ACTIVE,
343 .decoder = EM28XX_TVP5150, 345 .decoder = EM28XX_TVP5150,
344 .has_msp34xx = 1, 346 .has_msp34xx = 1,
347 .has_ir_i2c = 1,
345 .input = { { 348 .input = { {
346 .type = EM28XX_VMUX_TELEVISION, 349 .type = EM28XX_VMUX_TELEVISION,
347 .vmux = TVP5150_COMPOSITE0, 350 .vmux = TVP5150_COMPOSITE0,
@@ -558,6 +561,27 @@ struct em28xx_board em28xx_boards[] = {
558 .amux = EM28XX_AMUX_LINE_IN, 561 .amux = EM28XX_AMUX_LINE_IN,
559 } }, 562 } },
560 }, 563 },
564 [EM2861_BOARD_GADMEI_UTV330PLUS] = {
565 .name = "Gadmei UTV330+",
566 .tuner_type = TUNER_TNF_5335MF,
567 .tda9887_conf = TDA9887_PRESENT,
568 .ir_codes = &ir_codes_gadmei_rm008z_table,
569 .decoder = EM28XX_SAA711X,
570 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
571 .input = { {
572 .type = EM28XX_VMUX_TELEVISION,
573 .vmux = SAA7115_COMPOSITE2,
574 .amux = EM28XX_AMUX_VIDEO,
575 }, {
576 .type = EM28XX_VMUX_COMPOSITE1,
577 .vmux = SAA7115_COMPOSITE0,
578 .amux = EM28XX_AMUX_LINE_IN,
579 }, {
580 .type = EM28XX_VMUX_SVIDEO,
581 .vmux = SAA7115_SVIDEO3,
582 .amux = EM28XX_AMUX_LINE_IN,
583 } },
584 },
561 [EM2860_BOARD_TERRATEC_HYBRID_XS] = { 585 [EM2860_BOARD_TERRATEC_HYBRID_XS] = {
562 .name = "Terratec Cinergy A Hybrid XS", 586 .name = "Terratec Cinergy A Hybrid XS",
563 .valid = EM28XX_BOARD_NOT_VALIDATED, 587 .valid = EM28XX_BOARD_NOT_VALIDATED,
@@ -715,7 +739,7 @@ struct em28xx_board em28xx_boards[] = {
715 .mts_firmware = 1, 739 .mts_firmware = 1,
716 .has_dvb = 1, 740 .has_dvb = 1,
717 .dvb_gpio = hauppauge_wintv_hvr_900_digital, 741 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
718 .ir_codes = ir_codes_hauppauge_new, 742 .ir_codes = &ir_codes_hauppauge_new_table,
719 .decoder = EM28XX_TVP5150, 743 .decoder = EM28XX_TVP5150,
720 .input = { { 744 .input = { {
721 .type = EM28XX_VMUX_TELEVISION, 745 .type = EM28XX_VMUX_TELEVISION,
@@ -740,7 +764,7 @@ struct em28xx_board em28xx_boards[] = {
740 .tuner_type = TUNER_XC2028, 764 .tuner_type = TUNER_XC2028,
741 .tuner_gpio = default_tuner_gpio, 765 .tuner_gpio = default_tuner_gpio,
742 .mts_firmware = 1, 766 .mts_firmware = 1,
743 .ir_codes = ir_codes_hauppauge_new, 767 .ir_codes = &ir_codes_hauppauge_new_table,
744 .decoder = EM28XX_TVP5150, 768 .decoder = EM28XX_TVP5150,
745 .input = { { 769 .input = { {
746 .type = EM28XX_VMUX_TELEVISION, 770 .type = EM28XX_VMUX_TELEVISION,
@@ -766,7 +790,7 @@ struct em28xx_board em28xx_boards[] = {
766 .mts_firmware = 1, 790 .mts_firmware = 1,
767 .has_dvb = 1, 791 .has_dvb = 1,
768 .dvb_gpio = hauppauge_wintv_hvr_900_digital, 792 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
769 .ir_codes = ir_codes_hauppauge_new, 793 .ir_codes = &ir_codes_hauppauge_new_table,
770 .decoder = EM28XX_TVP5150, 794 .decoder = EM28XX_TVP5150,
771 .input = { { 795 .input = { {
772 .type = EM28XX_VMUX_TELEVISION, 796 .type = EM28XX_VMUX_TELEVISION,
@@ -792,7 +816,7 @@ struct em28xx_board em28xx_boards[] = {
792 .mts_firmware = 1, 816 .mts_firmware = 1,
793 .has_dvb = 1, 817 .has_dvb = 1,
794 .dvb_gpio = hauppauge_wintv_hvr_900_digital, 818 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
795 .ir_codes = ir_codes_hauppauge_new, 819 .ir_codes = &ir_codes_hauppauge_new_table,
796 .decoder = EM28XX_TVP5150, 820 .decoder = EM28XX_TVP5150,
797 .input = { { 821 .input = { {
798 .type = EM28XX_VMUX_TELEVISION, 822 .type = EM28XX_VMUX_TELEVISION,
@@ -818,7 +842,7 @@ struct em28xx_board em28xx_boards[] = {
818 .mts_firmware = 1, 842 .mts_firmware = 1,
819 .has_dvb = 1, 843 .has_dvb = 1,
820 .dvb_gpio = hauppauge_wintv_hvr_900_digital, 844 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
821 .ir_codes = ir_codes_pinnacle_pctv_hd, 845 .ir_codes = &ir_codes_pinnacle_pctv_hd_table,
822 .decoder = EM28XX_TVP5150, 846 .decoder = EM28XX_TVP5150,
823 .input = { { 847 .input = { {
824 .type = EM28XX_VMUX_TELEVISION, 848 .type = EM28XX_VMUX_TELEVISION,
@@ -844,7 +868,7 @@ struct em28xx_board em28xx_boards[] = {
844 .mts_firmware = 1, 868 .mts_firmware = 1,
845 .has_dvb = 1, 869 .has_dvb = 1,
846 .dvb_gpio = hauppauge_wintv_hvr_900_digital, 870 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
847 .ir_codes = ir_codes_ati_tv_wonder_hd_600, 871 .ir_codes = &ir_codes_ati_tv_wonder_hd_600_table,
848 .decoder = EM28XX_TVP5150, 872 .decoder = EM28XX_TVP5150,
849 .input = { { 873 .input = { {
850 .type = EM28XX_VMUX_TELEVISION, 874 .type = EM28XX_VMUX_TELEVISION,
@@ -870,6 +894,8 @@ struct em28xx_board em28xx_boards[] = {
870 .decoder = EM28XX_TVP5150, 894 .decoder = EM28XX_TVP5150,
871 .has_dvb = 1, 895 .has_dvb = 1,
872 .dvb_gpio = default_digital, 896 .dvb_gpio = default_digital,
897 .ir_codes = &ir_codes_terratec_cinergy_xs_table,
898 .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */
873 .input = { { 899 .input = { {
874 .type = EM28XX_VMUX_TELEVISION, 900 .type = EM28XX_VMUX_TELEVISION,
875 .vmux = TVP5150_COMPOSITE0, 901 .vmux = TVP5150_COMPOSITE0,
@@ -937,6 +963,7 @@ struct em28xx_board em28xx_boards[] = {
937 [EM2800_BOARD_TERRATEC_CINERGY_200] = { 963 [EM2800_BOARD_TERRATEC_CINERGY_200] = {
938 .name = "Terratec Cinergy 200 USB", 964 .name = "Terratec Cinergy 200 USB",
939 .is_em2800 = 1, 965 .is_em2800 = 1,
966 .has_ir_i2c = 1,
940 .tuner_type = TUNER_LG_PAL_NEW_TAPC, 967 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
941 .tda9887_conf = TDA9887_PRESENT, 968 .tda9887_conf = TDA9887_PRESENT,
942 .decoder = EM28XX_SAA711X, 969 .decoder = EM28XX_SAA711X,
@@ -1010,7 +1037,8 @@ struct em28xx_board em28xx_boards[] = {
1010 } }, 1037 } },
1011 }, 1038 },
1012 [EM2820_BOARD_PINNACLE_DVC_90] = { 1039 [EM2820_BOARD_PINNACLE_DVC_90] = {
1013 .name = "Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker", 1040 .name = "Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker "
1041 "/ Kworld DVD Maker 2",
1014 .tuner_type = TUNER_ABSENT, /* capture only board */ 1042 .tuner_type = TUNER_ABSENT, /* capture only board */
1015 .decoder = EM28XX_SAA711X, 1043 .decoder = EM28XX_SAA711X,
1016 .input = { { 1044 .input = { {
@@ -1420,7 +1448,7 @@ struct em28xx_board em28xx_boards[] = {
1420 .mts_firmware = 1, 1448 .mts_firmware = 1,
1421 .decoder = EM28XX_TVP5150, 1449 .decoder = EM28XX_TVP5150,
1422 .tuner_gpio = default_tuner_gpio, 1450 .tuner_gpio = default_tuner_gpio,
1423 .ir_codes = ir_codes_kaiomy, 1451 .ir_codes = &ir_codes_kaiomy_table,
1424 .input = { { 1452 .input = { {
1425 .type = EM28XX_VMUX_TELEVISION, 1453 .type = EM28XX_VMUX_TELEVISION,
1426 .vmux = TVP5150_COMPOSITE0, 1454 .vmux = TVP5150_COMPOSITE0,
@@ -1520,7 +1548,7 @@ struct em28xx_board em28xx_boards[] = {
1520 .mts_firmware = 1, 1548 .mts_firmware = 1,
1521 .has_dvb = 1, 1549 .has_dvb = 1,
1522 .dvb_gpio = evga_indtube_digital, 1550 .dvb_gpio = evga_indtube_digital,
1523 .ir_codes = ir_codes_evga_indtube, 1551 .ir_codes = &ir_codes_evga_indtube_table,
1524 .input = { { 1552 .input = { {
1525 .type = EM28XX_VMUX_TELEVISION, 1553 .type = EM28XX_VMUX_TELEVISION,
1526 .vmux = TVP5150_COMPOSITE0, 1554 .vmux = TVP5150_COMPOSITE0,
@@ -1591,6 +1619,8 @@ struct usb_device_id em28xx_id_table[] = {
1591 .driver_info = EM2870_BOARD_KWORLD_355U }, 1619 .driver_info = EM2870_BOARD_KWORLD_355U },
1592 { USB_DEVICE(0x1b80, 0xe302), 1620 { USB_DEVICE(0x1b80, 0xe302),
1593 .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, /* Kaiser Baas Video to DVD maker */ 1621 .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, /* Kaiser Baas Video to DVD maker */
1622 { USB_DEVICE(0x1b80, 0xe304),
1623 .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, /* Kworld DVD Maker 2 */
1594 { USB_DEVICE(0x0ccd, 0x0036), 1624 { USB_DEVICE(0x0ccd, 0x0036),
1595 .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 }, 1625 .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 },
1596 { USB_DEVICE(0x0ccd, 0x004c), 1626 { USB_DEVICE(0x0ccd, 0x004c),
@@ -1649,6 +1679,8 @@ struct usb_device_id em28xx_id_table[] = {
1649 .driver_info = EM2861_BOARD_PLEXTOR_PX_TV100U }, 1679 .driver_info = EM2861_BOARD_PLEXTOR_PX_TV100U },
1650 { USB_DEVICE(0x04bb, 0x0515), 1680 { USB_DEVICE(0x04bb, 0x0515),
1651 .driver_info = EM2820_BOARD_IODATA_GVMVP_SZ }, 1681 .driver_info = EM2820_BOARD_IODATA_GVMVP_SZ },
1682 { USB_DEVICE(0xeb1a, 0x50a6),
1683 .driver_info = EM2860_BOARD_GADMEI_UTV330 },
1652 { }, 1684 { },
1653}; 1685};
1654MODULE_DEVICE_TABLE(usb, em28xx_id_table); 1686MODULE_DEVICE_TABLE(usb, em28xx_id_table);
@@ -1661,7 +1693,7 @@ static struct em28xx_hash_table em28xx_eeprom_hash[] = {
1661 {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, 1693 {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF},
1662 {0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF}, 1694 {0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF},
1663 {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028}, 1695 {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028},
1664 {0x9567eb1a, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028}, 1696 {0x166a0441, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028},
1665 {0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028}, 1697 {0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028},
1666 {0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028}, 1698 {0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028},
1667}; 1699};
@@ -1672,6 +1704,7 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = {
1672 {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC}, 1704 {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC},
1673 {0x1ba50080, EM2860_BOARD_SAA711X_REFERENCE_DESIGN, TUNER_ABSENT}, 1705 {0x1ba50080, EM2860_BOARD_SAA711X_REFERENCE_DESIGN, TUNER_ABSENT},
1674 {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC}, 1706 {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC},
1707 {0x4ba50080, EM2861_BOARD_GADMEI_UTV330PLUS, TUNER_TNF_5335MF},
1675}; 1708};
1676 1709
1677/* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */ 1710/* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */
@@ -2170,8 +2203,6 @@ static int em28xx_hint_board(struct em28xx *dev)
2170/* ----------------------------------------------------------------------- */ 2203/* ----------------------------------------------------------------------- */
2171void em28xx_register_i2c_ir(struct em28xx *dev) 2204void em28xx_register_i2c_ir(struct em28xx *dev)
2172{ 2205{
2173 struct i2c_board_info info;
2174 struct IR_i2c_init_data init_data;
2175 const unsigned short addr_list[] = { 2206 const unsigned short addr_list[] = {
2176 0x30, 0x47, I2C_CLIENT_END 2207 0x30, 0x47, I2C_CLIENT_END
2177 }; 2208 };
@@ -2179,45 +2210,33 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
2179 if (disable_ir) 2210 if (disable_ir)
2180 return; 2211 return;
2181 2212
2182 memset(&info, 0, sizeof(struct i2c_board_info)); 2213 memset(&dev->info, 0, sizeof(&dev->info));
2183 memset(&init_data, 0, sizeof(struct IR_i2c_init_data)); 2214 memset(&dev->init_data, 0, sizeof(dev->init_data));
2184 strlcpy(info.type, "ir_video", I2C_NAME_SIZE); 2215 strlcpy(dev->info.type, "ir_video", I2C_NAME_SIZE);
2185 2216
2186 /* detect & configure */ 2217 /* detect & configure */
2187 switch (dev->model) { 2218 switch (dev->model) {
2188 case (EM2800_BOARD_UNKNOWN): 2219 case EM2800_BOARD_TERRATEC_CINERGY_200:
2189 break; 2220 case EM2820_BOARD_TERRATEC_CINERGY_250:
2190 case (EM2820_BOARD_UNKNOWN): 2221 dev->init_data.ir_codes = &ir_codes_em_terratec_table;
2191 break; 2222 dev->init_data.get_key = em28xx_get_key_terratec;
2192 case (EM2800_BOARD_TERRATEC_CINERGY_200): 2223 dev->init_data.name = "i2c IR (EM28XX Terratec)";
2193 case (EM2820_BOARD_TERRATEC_CINERGY_250):
2194 init_data.ir_codes = ir_codes_em_terratec;
2195 init_data.get_key = em28xx_get_key_terratec;
2196 init_data.name = "i2c IR (EM28XX Terratec)";
2197 break;
2198 case (EM2820_BOARD_PINNACLE_USB_2):
2199 init_data.ir_codes = ir_codes_pinnacle_grey;
2200 init_data.get_key = em28xx_get_key_pinnacle_usb_grey;
2201 init_data.name = "i2c IR (EM28XX Pinnacle PCTV)";
2202 break;
2203 case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2):
2204 init_data.ir_codes = ir_codes_hauppauge_new;
2205 init_data.get_key = em28xx_get_key_em_haup;
2206 init_data.name = "i2c IR (EM2840 Hauppauge)";
2207 break; 2224 break;
2208 case (EM2820_BOARD_MSI_VOX_USB_2): 2225 case EM2820_BOARD_PINNACLE_USB_2:
2226 dev->init_data.ir_codes = &ir_codes_pinnacle_grey_table;
2227 dev->init_data.get_key = em28xx_get_key_pinnacle_usb_grey;
2228 dev->init_data.name = "i2c IR (EM28XX Pinnacle PCTV)";
2209 break; 2229 break;
2210 case (EM2800_BOARD_LEADTEK_WINFAST_USBII): 2230 case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
2211 break; 2231 dev->init_data.ir_codes = &ir_codes_hauppauge_new_table;
2212 case (EM2800_BOARD_KWORLD_USB2800): 2232 dev->init_data.get_key = em28xx_get_key_em_haup;
2213 break; 2233 dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
2214 case (EM2800_BOARD_GRABBEEX_USB2800):
2215 break; 2234 break;
2216 } 2235 }
2217 2236
2218 if (init_data.name) 2237 if (dev->init_data.name)
2219 info.platform_data = &init_data; 2238 dev->info.platform_data = &dev->init_data;
2220 i2c_new_probed_device(&dev->i2c_adap, &info, addr_list); 2239 i2c_new_probed_device(&dev->i2c_adap, &dev->info, addr_list);
2221} 2240}
2222 2241
2223void em28xx_card_setup(struct em28xx *dev) 2242void em28xx_card_setup(struct em28xx *dev)
@@ -2253,7 +2272,7 @@ void em28xx_card_setup(struct em28xx *dev)
2253 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: 2272 case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
2254 { 2273 {
2255 struct tveeprom tv; 2274 struct tveeprom tv;
2256#ifdef CONFIG_MODULES 2275#if defined(CONFIG_MODULES) && defined(MODULE)
2257 request_module("tveeprom"); 2276 request_module("tveeprom");
2258#endif 2277#endif
2259 /* Call first TVeeprom */ 2278 /* Call first TVeeprom */
@@ -2267,10 +2286,6 @@ void em28xx_card_setup(struct em28xx *dev)
2267 dev->i2s_speed = 2048000; 2286 dev->i2s_speed = 2048000;
2268 dev->board.has_msp34xx = 1; 2287 dev->board.has_msp34xx = 1;
2269 } 2288 }
2270#ifdef CONFIG_MODULES
2271 if (tv.has_ir)
2272 request_module("ir-kbd-i2c");
2273#endif
2274 break; 2289 break;
2275 } 2290 }
2276 case EM2882_BOARD_KWORLD_ATSC_315U: 2291 case EM2882_BOARD_KWORLD_ATSC_315U:
@@ -2311,6 +2326,10 @@ void em28xx_card_setup(struct em28xx *dev)
2311 break; 2326 break;
2312 } 2327 }
2313 2328
2329#if defined(CONFIG_MODULES) && defined(MODULE)
2330 if (dev->board.has_ir_i2c && !disable_ir)
2331 request_module("ir-kbd-i2c");
2332#endif
2314 if (dev->board.has_snapshot_button) 2333 if (dev->board.has_snapshot_button)
2315 em28xx_register_snapshot_button(dev); 2334 em28xx_register_snapshot_button(dev);
2316 2335
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index 27e33a287dfc..71474d31e155 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -459,7 +459,6 @@ static struct i2c_algorithm em28xx_algo = {
459static struct i2c_adapter em28xx_adap_template = { 459static struct i2c_adapter em28xx_adap_template = {
460 .owner = THIS_MODULE, 460 .owner = THIS_MODULE,
461 .name = "em28xx", 461 .name = "em28xx",
462 .id = I2C_HW_B_EM28XX,
463 .algo = &em28xx_algo, 462 .algo = &em28xx_algo,
464}; 463};
465 464
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index ab079d9256c4..a6bdbc21410e 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -124,7 +124,7 @@ static struct em28xx_fmt format[] = {
124 124
125/* supported controls */ 125/* supported controls */
126/* Common to all boards */ 126/* Common to all boards */
127static struct v4l2_queryctrl em28xx_qctrl[] = { 127static struct v4l2_queryctrl ac97_qctrl[] = {
128 { 128 {
129 .id = V4L2_CID_AUDIO_VOLUME, 129 .id = V4L2_CID_AUDIO_VOLUME,
130 .type = V4L2_CTRL_TYPE_INTEGER, 130 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -133,7 +133,7 @@ static struct v4l2_queryctrl em28xx_qctrl[] = {
133 .maximum = 0x1f, 133 .maximum = 0x1f,
134 .step = 0x1, 134 .step = 0x1,
135 .default_value = 0x1f, 135 .default_value = 0x1f,
136 .flags = 0, 136 .flags = V4L2_CTRL_FLAG_SLIDER,
137 }, { 137 }, {
138 .id = V4L2_CID_AUDIO_MUTE, 138 .id = V4L2_CID_AUDIO_MUTE,
139 .type = V4L2_CTRL_TYPE_BOOLEAN, 139 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -609,10 +609,29 @@ static void res_free(struct em28xx_fh *fh)
609} 609}
610 610
611/* 611/*
612 * em28xx_get_ctrl() 612 * ac97_queryctrl()
613 * return the current saturation, brightness or contrast, mute state 613 * return the ac97 supported controls
614 */ 614 */
615static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) 615static int ac97_queryctrl(struct v4l2_queryctrl *qc)
616{
617 int i;
618
619 for (i = 0; i < ARRAY_SIZE(ac97_qctrl); i++) {
620 if (qc->id && qc->id == ac97_qctrl[i].id) {
621 memcpy(qc, &(ac97_qctrl[i]), sizeof(*qc));
622 return 0;
623 }
624 }
625
626 /* Control is not ac97 related */
627 return 1;
628}
629
630/*
631 * ac97_get_ctrl()
632 * return the current values for ac97 mute and volume
633 */
634static int ac97_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
616{ 635{
617 switch (ctrl->id) { 636 switch (ctrl->id) {
618 case V4L2_CID_AUDIO_MUTE: 637 case V4L2_CID_AUDIO_MUTE:
@@ -622,29 +641,41 @@ static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
622 ctrl->value = dev->volume; 641 ctrl->value = dev->volume;
623 return 0; 642 return 0;
624 default: 643 default:
625 return -EINVAL; 644 /* Control is not ac97 related */
645 return 1;
626 } 646 }
627} 647}
628 648
629/* 649/*
630 * em28xx_set_ctrl() 650 * ac97_set_ctrl()
631 * mute or set new saturation, brightness or contrast 651 * set values for ac97 mute and volume
632 */ 652 */
633static int em28xx_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl) 653static int ac97_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl)
634{ 654{
655 int i;
656
657 for (i = 0; i < ARRAY_SIZE(ac97_qctrl); i++)
658 if (ctrl->id == ac97_qctrl[i].id)
659 goto handle;
660
661 /* Announce that hasn't handle it */
662 return 1;
663
664handle:
665 if (ctrl->value < ac97_qctrl[i].minimum ||
666 ctrl->value > ac97_qctrl[i].maximum)
667 return -ERANGE;
668
635 switch (ctrl->id) { 669 switch (ctrl->id) {
636 case V4L2_CID_AUDIO_MUTE: 670 case V4L2_CID_AUDIO_MUTE:
637 if (ctrl->value != dev->mute) { 671 dev->mute = ctrl->value;
638 dev->mute = ctrl->value; 672 break;
639 return em28xx_audio_analog_set(dev);
640 }
641 return 0;
642 case V4L2_CID_AUDIO_VOLUME: 673 case V4L2_CID_AUDIO_VOLUME:
643 dev->volume = ctrl->value; 674 dev->volume = ctrl->value;
644 return em28xx_audio_analog_set(dev); 675 break;
645 default:
646 return -EINVAL;
647 } 676 }
677
678 return em28xx_audio_analog_set(dev);
648} 679}
649 680
650static int check_dev(struct em28xx *dev) 681static int check_dev(struct em28xx *dev)
@@ -974,6 +1005,9 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
974 struct em28xx_fh *fh = priv; 1005 struct em28xx_fh *fh = priv;
975 struct em28xx *dev = fh->dev; 1006 struct em28xx *dev = fh->dev;
976 1007
1008 if (!dev->audio_mode.has_audio)
1009 return -EINVAL;
1010
977 switch (a->index) { 1011 switch (a->index) {
978 case EM28XX_AMUX_VIDEO: 1012 case EM28XX_AMUX_VIDEO:
979 strcpy(a->name, "Television"); 1013 strcpy(a->name, "Television");
@@ -1015,6 +1049,9 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
1015 struct em28xx *dev = fh->dev; 1049 struct em28xx *dev = fh->dev;
1016 1050
1017 1051
1052 if (!dev->audio_mode.has_audio)
1053 return -EINVAL;
1054
1018 if (a->index >= MAX_EM28XX_INPUT) 1055 if (a->index >= MAX_EM28XX_INPUT)
1019 return -EINVAL; 1056 return -EINVAL;
1020 if (0 == INPUT(a->index)->type) 1057 if (0 == INPUT(a->index)->type)
@@ -1038,7 +1075,6 @@ static int vidioc_queryctrl(struct file *file, void *priv,
1038 struct em28xx_fh *fh = priv; 1075 struct em28xx_fh *fh = priv;
1039 struct em28xx *dev = fh->dev; 1076 struct em28xx *dev = fh->dev;
1040 int id = qc->id; 1077 int id = qc->id;
1041 int i;
1042 int rc; 1078 int rc;
1043 1079
1044 rc = check_dev(dev); 1080 rc = check_dev(dev);
@@ -1049,15 +1085,14 @@ static int vidioc_queryctrl(struct file *file, void *priv,
1049 1085
1050 qc->id = id; 1086 qc->id = id;
1051 1087
1052 if (!dev->board.has_msp34xx) { 1088 /* enumberate AC97 controls */
1053 for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { 1089 if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
1054 if (qc->id && qc->id == em28xx_qctrl[i].id) { 1090 rc = ac97_queryctrl(qc);
1055 memcpy(qc, &(em28xx_qctrl[i]), sizeof(*qc)); 1091 if (!rc)
1056 return 0; 1092 return 0;
1057 }
1058 }
1059 } 1093 }
1060 1094
1095 /* enumberate V4L2 device controls */
1061 mutex_lock(&dev->lock); 1096 mutex_lock(&dev->lock);
1062 v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, qc); 1097 v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, qc);
1063 mutex_unlock(&dev->lock); 1098 mutex_unlock(&dev->lock);
@@ -1082,14 +1117,16 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
1082 1117
1083 mutex_lock(&dev->lock); 1118 mutex_lock(&dev->lock);
1084 1119
1085 if (dev->board.has_msp34xx) 1120 /* Set an AC97 control */
1121 if (dev->audio_mode.ac97 != EM28XX_NO_AC97)
1122 rc = ac97_get_ctrl(dev, ctrl);
1123 else
1124 rc = 1;
1125
1126 /* It were not an AC97 control. Sends it to the v4l2 dev interface */
1127 if (rc == 1) {
1086 v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl); 1128 v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
1087 else { 1129 rc = 0;
1088 rc = em28xx_get_ctrl(dev, ctrl);
1089 if (rc < 0) {
1090 v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
1091 rc = 0;
1092 }
1093 } 1130 }
1094 1131
1095 mutex_unlock(&dev->lock); 1132 mutex_unlock(&dev->lock);
@@ -1101,7 +1138,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1101{ 1138{
1102 struct em28xx_fh *fh = priv; 1139 struct em28xx_fh *fh = priv;
1103 struct em28xx *dev = fh->dev; 1140 struct em28xx *dev = fh->dev;
1104 u8 i;
1105 int rc; 1141 int rc;
1106 1142
1107 rc = check_dev(dev); 1143 rc = check_dev(dev);
@@ -1110,28 +1146,31 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1110 1146
1111 mutex_lock(&dev->lock); 1147 mutex_lock(&dev->lock);
1112 1148
1113 if (dev->board.has_msp34xx) 1149 /* Set an AC97 control */
1114 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl); 1150 if (dev->audio_mode.ac97 != EM28XX_NO_AC97)
1115 else { 1151 rc = ac97_set_ctrl(dev, ctrl);
1152 else
1116 rc = 1; 1153 rc = 1;
1117 for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
1118 if (ctrl->id == em28xx_qctrl[i].id) {
1119 if (ctrl->value < em28xx_qctrl[i].minimum ||
1120 ctrl->value > em28xx_qctrl[i].maximum) {
1121 rc = -ERANGE;
1122 break;
1123 }
1124
1125 rc = em28xx_set_ctrl(dev, ctrl);
1126 break;
1127 }
1128 }
1129 }
1130 1154
1131 /* Control not found - try to send it to the attached devices */ 1155 /* It isn't an AC97 control. Sends it to the v4l2 dev interface */
1132 if (rc == 1) { 1156 if (rc == 1) {
1133 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl); 1157 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl);
1134 rc = 0; 1158
1159 /*
1160 * In the case of non-AC97 volume controls, we still need
1161 * to do some setups at em28xx, in order to mute/unmute
1162 * and to adjust audio volume. However, the value ranges
1163 * should be checked by the corresponding V4L subdriver.
1164 */
1165 switch (ctrl->id) {
1166 case V4L2_CID_AUDIO_MUTE:
1167 dev->mute = ctrl->value;
1168 rc = em28xx_audio_analog_set(dev);
1169 break;
1170 case V4L2_CID_AUDIO_VOLUME:
1171 dev->volume = ctrl->value;
1172 rc = em28xx_audio_analog_set(dev);
1173 }
1135 } 1174 }
1136 1175
1137 mutex_unlock(&dev->lock); 1176 mutex_unlock(&dev->lock);
@@ -1275,8 +1314,9 @@ static int vidioc_g_register(struct file *file, void *priv,
1275 v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg); 1314 v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
1276 return 0; 1315 return 0;
1277 case V4L2_CHIP_MATCH_I2C_ADDR: 1316 case V4L2_CHIP_MATCH_I2C_ADDR:
1278 /* Not supported yet */ 1317 /* TODO: is this correct? */
1279 return -EINVAL; 1318 v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
1319 return 0;
1280 default: 1320 default:
1281 if (!v4l2_chip_match_host(&reg->match)) 1321 if (!v4l2_chip_match_host(&reg->match))
1282 return -EINVAL; 1322 return -EINVAL;
@@ -1327,8 +1367,9 @@ static int vidioc_s_register(struct file *file, void *priv,
1327 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg); 1367 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
1328 return 0; 1368 return 0;
1329 case V4L2_CHIP_MATCH_I2C_ADDR: 1369 case V4L2_CHIP_MATCH_I2C_ADDR:
1330 /* Not supported yet */ 1370 /* TODO: is this correct? */
1331 return -EINVAL; 1371 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
1372 return 0;
1332 default: 1373 default:
1333 if (!v4l2_chip_match_host(&reg->match)) 1374 if (!v4l2_chip_match_host(&reg->match))
1334 return -EINVAL; 1375 return -EINVAL;
@@ -1431,9 +1472,11 @@ static int vidioc_querycap(struct file *file, void *priv,
1431 cap->capabilities = 1472 cap->capabilities =
1432 V4L2_CAP_SLICED_VBI_CAPTURE | 1473 V4L2_CAP_SLICED_VBI_CAPTURE |
1433 V4L2_CAP_VIDEO_CAPTURE | 1474 V4L2_CAP_VIDEO_CAPTURE |
1434 V4L2_CAP_AUDIO |
1435 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; 1475 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
1436 1476
1477 if (dev->audio_mode.has_audio)
1478 cap->capabilities |= V4L2_CAP_AUDIO;
1479
1437 if (dev->tuner_type != TUNER_ABSENT) 1480 if (dev->tuner_type != TUNER_ABSENT)
1438 cap->capabilities |= V4L2_CAP_TUNER; 1481 cap->capabilities |= V4L2_CAP_TUNER;
1439 1482
@@ -1654,9 +1697,9 @@ static int radio_queryctrl(struct file *file, void *priv,
1654 qc->id >= V4L2_CID_LASTP1) 1697 qc->id >= V4L2_CID_LASTP1)
1655 return -EINVAL; 1698 return -EINVAL;
1656 1699
1657 for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { 1700 for (i = 0; i < ARRAY_SIZE(ac97_qctrl); i++) {
1658 if (qc->id && qc->id == em28xx_qctrl[i].id) { 1701 if (qc->id && qc->id == ac97_qctrl[i].id) {
1659 memcpy(qc, &(em28xx_qctrl[i]), sizeof(*qc)); 1702 memcpy(qc, &(ac97_qctrl[i]), sizeof(*qc));
1660 return 0; 1703 return 0;
1661 } 1704 }
1662 } 1705 }
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index a2add61f7d59..0f2ba9a40d17 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -108,6 +108,7 @@
108#define EM2882_BOARD_KWORLD_ATSC_315U 69 108#define EM2882_BOARD_KWORLD_ATSC_315U 69
109#define EM2882_BOARD_EVGA_INDTUBE 70 109#define EM2882_BOARD_EVGA_INDTUBE 70
110#define EM2820_BOARD_SILVERCREST_WEBCAM 71 110#define EM2820_BOARD_SILVERCREST_WEBCAM 71
111#define EM2861_BOARD_GADMEI_UTV330PLUS 72
111 112
112/* Limits minimum and default number of buffers */ 113/* Limits minimum and default number of buffers */
113#define EM28XX_MIN_BUF 4 114#define EM28XX_MIN_BUF 4
@@ -398,6 +399,7 @@ struct em28xx_board {
398 unsigned int has_snapshot_button:1; 399 unsigned int has_snapshot_button:1;
399 unsigned int is_webcam:1; 400 unsigned int is_webcam:1;
400 unsigned int valid:1; 401 unsigned int valid:1;
402 unsigned int has_ir_i2c:1;
401 403
402 unsigned char xclk, i2c_speed; 404 unsigned char xclk, i2c_speed;
403 unsigned char radio_addr; 405 unsigned char radio_addr;
@@ -408,7 +410,7 @@ struct em28xx_board {
408 410
409 struct em28xx_input input[MAX_EM28XX_INPUT]; 411 struct em28xx_input input[MAX_EM28XX_INPUT];
410 struct em28xx_input radio; 412 struct em28xx_input radio;
411 IR_KEYTAB_TYPE *ir_codes; 413 struct ir_scancode_table *ir_codes;
412}; 414};
413 415
414struct em28xx_eeprom { 416struct em28xx_eeprom {
@@ -595,6 +597,10 @@ struct em28xx {
595 struct delayed_work sbutton_query_work; 597 struct delayed_work sbutton_query_work;
596 598
597 struct em28xx_dvb *dvb; 599 struct em28xx_dvb *dvb;
600
601 /* I2C keyboard data */
602 struct i2c_board_info info;
603 struct IR_i2c_init_data init_data;
598}; 604};
599 605
600struct em28xx_ops { 606struct em28xx_ops {
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index e994dcac43ff..8897283b0bb4 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -47,6 +47,15 @@ config USB_GSPCA_FINEPIX
47 To compile this driver as a module, choose M here: the 47 To compile this driver as a module, choose M here: the
48 module will be called gspca_finepix. 48 module will be called gspca_finepix.
49 49
50config USB_GSPCA_JEILINJ
51 tristate "Jeilin JPEG USB V4L2 driver"
52 depends on VIDEO_V4L2 && USB_GSPCA
53 help
54 Say Y here if you want support for cameras based on this Jeilin chip.
55
56 To compile this driver as a module, choose M here: the
57 module will be called gspca_jeilinj.
58
50config USB_GSPCA_MARS 59config USB_GSPCA_MARS
51 tristate "Mars USB Camera Driver" 60 tristate "Mars USB Camera Driver"
52 depends on VIDEO_V4L2 && USB_GSPCA 61 depends on VIDEO_V4L2 && USB_GSPCA
@@ -103,9 +112,9 @@ config USB_GSPCA_PAC7311
103 module will be called gspca_pac7311. 112 module will be called gspca_pac7311.
104 113
105config USB_GSPCA_SN9C20X 114config USB_GSPCA_SN9C20X
106 tristate "SN9C20X USB Camera Driver" 115 tristate "SN9C20X USB Camera Driver"
107 depends on VIDEO_V4L2 && USB_GSPCA 116 depends on VIDEO_V4L2 && USB_GSPCA
108 help 117 help
109 Say Y here if you want support for cameras based on the 118 Say Y here if you want support for cameras based on the
110 sn9c20x chips (SN9C201 and SN9C202). 119 sn9c20x chips (SN9C201 and SN9C202).
111 120
@@ -113,10 +122,10 @@ config USB_GSPCA_SN9C20X
113 module will be called gspca_sn9c20x. 122 module will be called gspca_sn9c20x.
114 123
115config USB_GSPCA_SN9C20X_EVDEV 124config USB_GSPCA_SN9C20X_EVDEV
116 bool "Enable evdev support" 125 bool "Enable evdev support"
117 depends on USB_GSPCA_SN9C20X && INPUT 126 depends on USB_GSPCA_SN9C20X && INPUT
118 ---help--- 127 ---help---
119 Say Y here in order to enable evdev support for sn9c20x webcam button. 128 Say Y here in order to enable evdev support for sn9c20x webcam button.
120 129
121config USB_GSPCA_SONIXB 130config USB_GSPCA_SONIXB
122 tristate "SONIX Bayer USB Camera Driver" 131 tristate "SONIX Bayer USB Camera Driver"
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index f6d3b86e9ad5..035616b5e867 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_USB_GSPCA) += gspca_main.o
2obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o 2obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o
3obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o 3obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o
4obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o 4obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o
5obj-$(CONFIG_USB_GSPCA_JEILINJ) += gspca_jeilinj.o
5obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o 6obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o
6obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o 7obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o
7obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o 8obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
@@ -30,6 +31,7 @@ gspca_main-objs := gspca.o
30gspca_conex-objs := conex.o 31gspca_conex-objs := conex.o
31gspca_etoms-objs := etoms.o 32gspca_etoms-objs := etoms.o
32gspca_finepix-objs := finepix.o 33gspca_finepix-objs := finepix.o
34gspca_jeilinj-objs := jeilinj.o
33gspca_mars-objs := mars.o 35gspca_mars-objs := mars.o
34gspca_mr97310a-objs := mr97310a.o 36gspca_mr97310a-objs := mr97310a.o
35gspca_ov519-objs := ov519.o 37gspca_ov519-objs := ov519.o
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index 8d48ea1742c2..eca003566ae3 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -820,7 +820,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
820 820
821 cam = &gspca_dev->cam; 821 cam = &gspca_dev->cam;
822 cam->cam_mode = vga_mode; 822 cam->cam_mode = vga_mode;
823 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; 823 cam->nmodes = ARRAY_SIZE(vga_mode);
824 824
825 sd->brightness = BRIGHTNESS_DEF; 825 sd->brightness = BRIGHTNESS_DEF;
826 sd->contrast = CONTRAST_DEF; 826 sd->contrast = CONTRAST_DEF;
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index 2c20d06a03e8..c1461e63647f 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -635,10 +635,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
635 sd->sensor = id->driver_info; 635 sd->sensor = id->driver_info;
636 if (sd->sensor == SENSOR_PAS106) { 636 if (sd->sensor == SENSOR_PAS106) {
637 cam->cam_mode = sif_mode; 637 cam->cam_mode = sif_mode;
638 cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; 638 cam->nmodes = ARRAY_SIZE(sif_mode);
639 } else { 639 } else {
640 cam->cam_mode = vga_mode; 640 cam->cam_mode = vga_mode;
641 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; 641 cam->nmodes = ARRAY_SIZE(vga_mode);
642 gspca_dev->ctrl_dis = (1 << COLOR_IDX); 642 gspca_dev->ctrl_dis = (1 << COLOR_IDX);
643 } 643 }
644 sd->brightness = BRIGHTNESS_DEF; 644 sd->brightness = BRIGHTNESS_DEF;
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index b8561dfb6c8c..cf6540da1e42 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -47,7 +47,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
47MODULE_DESCRIPTION("GSPCA USB Camera Driver"); 47MODULE_DESCRIPTION("GSPCA USB Camera Driver");
48MODULE_LICENSE("GPL"); 48MODULE_LICENSE("GPL");
49 49
50#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 6, 0) 50#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 7, 0)
51 51
52#ifdef GSPCA_DEBUG 52#ifdef GSPCA_DEBUG
53int gspca_debug = D_ERR | D_PROBE; 53int gspca_debug = D_ERR | D_PROBE;
@@ -486,6 +486,7 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
486 } 486 }
487 PDEBUG(D_STREAM, "use alt %d ep 0x%02x", 487 PDEBUG(D_STREAM, "use alt %d ep 0x%02x",
488 i, ep->desc.bEndpointAddress); 488 i, ep->desc.bEndpointAddress);
489 gspca_dev->alt = i; /* memorize the current alt setting */
489 if (gspca_dev->nbalt > 1) { 490 if (gspca_dev->nbalt > 1) {
490 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); 491 ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);
491 if (ret < 0) { 492 if (ret < 0) {
@@ -493,7 +494,6 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
493 return NULL; 494 return NULL;
494 } 495 }
495 } 496 }
496 gspca_dev->alt = i; /* memorize the current alt setting */
497 return ep; 497 return ep;
498} 498}
499 499
@@ -512,7 +512,10 @@ static int create_urbs(struct gspca_dev *gspca_dev,
512 if (!gspca_dev->cam.bulk) { /* isoc */ 512 if (!gspca_dev->cam.bulk) { /* isoc */
513 513
514 /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ 514 /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */
515 psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); 515 if (gspca_dev->pkt_size == 0)
516 psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
517 else
518 psize = gspca_dev->pkt_size;
516 npkt = gspca_dev->cam.npkt; 519 npkt = gspca_dev->cam.npkt;
517 if (npkt == 0) 520 if (npkt == 0)
518 npkt = 32; /* default value */ 521 npkt = 32; /* default value */
@@ -597,13 +600,18 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
597 /* set the higher alternate setting and 600 /* set the higher alternate setting and
598 * loop until urb submit succeeds */ 601 * loop until urb submit succeeds */
599 gspca_dev->alt = gspca_dev->nbalt; 602 gspca_dev->alt = gspca_dev->nbalt;
603 if (gspca_dev->sd_desc->isoc_init) {
604 ret = gspca_dev->sd_desc->isoc_init(gspca_dev);
605 if (ret < 0)
606 goto out;
607 }
608 ep = get_ep(gspca_dev);
609 if (ep == NULL) {
610 ret = -EIO;
611 goto out;
612 }
600 for (;;) { 613 for (;;) {
601 PDEBUG(D_STREAM, "init transfer alt %d", gspca_dev->alt); 614 PDEBUG(D_STREAM, "init transfer alt %d", gspca_dev->alt);
602 ep = get_ep(gspca_dev);
603 if (ep == NULL) {
604 ret = -EIO;
605 goto out;
606 }
607 ret = create_urbs(gspca_dev, ep); 615 ret = create_urbs(gspca_dev, ep);
608 if (ret < 0) 616 if (ret < 0)
609 goto out; 617 goto out;
@@ -628,21 +636,32 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
628 /* submit the URBs */ 636 /* submit the URBs */
629 for (n = 0; n < gspca_dev->nurbs; n++) { 637 for (n = 0; n < gspca_dev->nurbs; n++) {
630 ret = usb_submit_urb(gspca_dev->urb[n], GFP_KERNEL); 638 ret = usb_submit_urb(gspca_dev->urb[n], GFP_KERNEL);
631 if (ret < 0) { 639 if (ret < 0)
632 PDEBUG(D_ERR|D_STREAM, 640 break;
633 "usb_submit_urb [%d] err %d", n, ret);
634 gspca_dev->streaming = 0;
635 destroy_urbs(gspca_dev);
636 if (ret == -ENOSPC) {
637 msleep(20); /* wait for kill
638 * complete */
639 break; /* try the previous alt */
640 }
641 goto out;
642 }
643 } 641 }
644 if (ret >= 0) 642 if (ret >= 0)
645 break; 643 break;
644 PDEBUG(D_ERR|D_STREAM,
645 "usb_submit_urb alt %d err %d", gspca_dev->alt, ret);
646 gspca_dev->streaming = 0;
647 destroy_urbs(gspca_dev);
648 if (ret != -ENOSPC)
649 goto out;
650
651 /* the bandwidth is not wide enough
652 * negociate or try a lower alternate setting */
653 msleep(20); /* wait for kill complete */
654 if (gspca_dev->sd_desc->isoc_nego) {
655 ret = gspca_dev->sd_desc->isoc_nego(gspca_dev);
656 if (ret < 0)
657 goto out;
658 } else {
659 ep = get_ep(gspca_dev);
660 if (ep == NULL) {
661 ret = -EIO;
662 goto out;
663 }
664 }
646 } 665 }
647out: 666out:
648 mutex_unlock(&gspca_dev->usb_lock); 667 mutex_unlock(&gspca_dev->usb_lock);
@@ -1473,12 +1492,6 @@ static int vidioc_s_parm(struct file *filp, void *priv,
1473 return 0; 1492 return 0;
1474} 1493}
1475 1494
1476static int vidioc_s_std(struct file *filp, void *priv,
1477 v4l2_std_id *parm)
1478{
1479 return 0;
1480}
1481
1482#ifdef CONFIG_VIDEO_V4L1_COMPAT 1495#ifdef CONFIG_VIDEO_V4L1_COMPAT
1483static int vidiocgmbuf(struct file *file, void *priv, 1496static int vidiocgmbuf(struct file *file, void *priv,
1484 struct video_mbuf *mbuf) 1497 struct video_mbuf *mbuf)
@@ -1949,7 +1962,6 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = {
1949 .vidioc_s_jpegcomp = vidioc_s_jpegcomp, 1962 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1950 .vidioc_g_parm = vidioc_g_parm, 1963 .vidioc_g_parm = vidioc_g_parm,
1951 .vidioc_s_parm = vidioc_s_parm, 1964 .vidioc_s_parm = vidioc_s_parm,
1952 .vidioc_s_std = vidioc_s_std,
1953 .vidioc_enum_framesizes = vidioc_enum_framesizes, 1965 .vidioc_enum_framesizes = vidioc_enum_framesizes,
1954#ifdef CONFIG_VIDEO_ADV_DEBUG 1966#ifdef CONFIG_VIDEO_ADV_DEBUG
1955 .vidioc_g_register = vidioc_g_register, 1967 .vidioc_g_register = vidioc_g_register,
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 46c4effdfcd5..70b1fd830876 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -98,9 +98,11 @@ struct sd_desc {
98/* mandatory operations */ 98/* mandatory operations */
99 cam_cf_op config; /* called on probe */ 99 cam_cf_op config; /* called on probe */
100 cam_op init; /* called on probe and resume */ 100 cam_op init; /* called on probe and resume */
101 cam_op start; /* called on stream on */ 101 cam_op start; /* called on stream on after URBs creation */
102 cam_pkt_op pkt_scan; 102 cam_pkt_op pkt_scan;
103/* optional operations */ 103/* optional operations */
104 cam_op isoc_init; /* called on stream on before getting the EP */
105 cam_op isoc_nego; /* called when URB submit failed with NOSPC */
104 cam_v_op stopN; /* called on stream off - main alt */ 106 cam_v_op stopN; /* called on stream off - main alt */
105 cam_v_op stop0; /* called on stream off & disconnect - alt 0 */ 107 cam_v_op stop0; /* called on stream off & disconnect - alt 0 */
106 cam_v_op dq_callback; /* called when a frame has been dequeued */ 108 cam_v_op dq_callback; /* called when a frame has been dequeued */
@@ -178,6 +180,7 @@ struct gspca_dev {
178 __u8 iface; /* USB interface number */ 180 __u8 iface; /* USB interface number */
179 __u8 alt; /* USB alternate setting */ 181 __u8 alt; /* USB alternate setting */
180 __u8 nbalt; /* number of USB alternate settings */ 182 __u8 nbalt; /* number of USB alternate settings */
183 u16 pkt_size; /* ISOC packet size */
181}; 184};
182 185
183int gspca_dev_probe(struct usb_interface *intf, 186int gspca_dev_probe(struct usb_interface *intf,
diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c
new file mode 100644
index 000000000000..dbfa3ed6e8ef
--- /dev/null
+++ b/drivers/media/video/gspca/jeilinj.c
@@ -0,0 +1,388 @@
1/*
2 * Jeilinj subdriver
3 *
4 * Supports some Jeilin dual-mode cameras which use bulk transport and
5 * download raw JPEG data.
6 *
7 * Copyright (C) 2009 Theodore Kilgore
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 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#define MODULE_NAME "jeilinj"
25
26#include <linux/workqueue.h>
27#include "gspca.h"
28#include "jpeg.h"
29
30MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>");
31MODULE_DESCRIPTION("GSPCA/JEILINJ USB Camera Driver");
32MODULE_LICENSE("GPL");
33
34/* Default timeouts, in ms */
35#define JEILINJ_CMD_TIMEOUT 500
36#define JEILINJ_DATA_TIMEOUT 1000
37
38/* Maximum transfer size to use. */
39#define JEILINJ_MAX_TRANSFER 0x200
40
41#define FRAME_HEADER_LEN 0x10
42
43/* Structure to hold all of our device specific stuff */
44struct sd {
45 struct gspca_dev gspca_dev; /* !! must be the first item */
46 const struct v4l2_pix_format *cap_mode;
47 /* Driver stuff */
48 struct work_struct work_struct;
49 struct workqueue_struct *work_thread;
50 u8 quality; /* image quality */
51 u8 jpegqual; /* webcam quality */
52 u8 *jpeg_hdr;
53};
54
55 struct jlj_command {
56 unsigned char instruction[2];
57 unsigned char ack_wanted;
58 };
59
60/* AFAICT these cameras will only do 320x240. */
61static struct v4l2_pix_format jlj_mode[] = {
62 { 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
63 .bytesperline = 320,
64 .sizeimage = 320 * 240,
65 .colorspace = V4L2_COLORSPACE_JPEG,
66 .priv = 0}
67};
68
69/*
70 * cam uses endpoint 0x03 to send commands, 0x84 for read commands,
71 * and 0x82 for bulk transfer.
72 */
73
74/* All commands are two bytes only */
75static int jlj_write2(struct gspca_dev *gspca_dev, unsigned char *command)
76{
77 int retval;
78
79 memcpy(gspca_dev->usb_buf, command, 2);
80 retval = usb_bulk_msg(gspca_dev->dev,
81 usb_sndbulkpipe(gspca_dev->dev, 3),
82 gspca_dev->usb_buf, 2, NULL, 500);
83 if (retval < 0)
84 PDEBUG(D_ERR, "command write [%02x] error %d",
85 gspca_dev->usb_buf[0], retval);
86 return retval;
87}
88
89/* Responses are one byte only */
90static int jlj_read1(struct gspca_dev *gspca_dev, unsigned char response)
91{
92 int retval;
93
94 retval = usb_bulk_msg(gspca_dev->dev,
95 usb_rcvbulkpipe(gspca_dev->dev, 0x84),
96 gspca_dev->usb_buf, 1, NULL, 500);
97 response = gspca_dev->usb_buf[0];
98 if (retval < 0)
99 PDEBUG(D_ERR, "read command [%02x] error %d",
100 gspca_dev->usb_buf[0], retval);
101 return retval;
102}
103
104static int jlj_start(struct gspca_dev *gspca_dev)
105{
106 int i;
107 int retval = -1;
108 u8 response = 0xff;
109 struct jlj_command start_commands[] = {
110 {{0x71, 0x81}, 0},
111 {{0x70, 0x05}, 0},
112 {{0x95, 0x70}, 1},
113 {{0x71, 0x81}, 0},
114 {{0x70, 0x04}, 0},
115 {{0x95, 0x70}, 1},
116 {{0x71, 0x00}, 0},
117 {{0x70, 0x08}, 0},
118 {{0x95, 0x70}, 1},
119 {{0x94, 0x02}, 0},
120 {{0xde, 0x24}, 0},
121 {{0x94, 0x02}, 0},
122 {{0xdd, 0xf0}, 0},
123 {{0x94, 0x02}, 0},
124 {{0xe3, 0x2c}, 0},
125 {{0x94, 0x02}, 0},
126 {{0xe4, 0x00}, 0},
127 {{0x94, 0x02}, 0},
128 {{0xe5, 0x00}, 0},
129 {{0x94, 0x02}, 0},
130 {{0xe6, 0x2c}, 0},
131 {{0x94, 0x03}, 0},
132 {{0xaa, 0x00}, 0},
133 {{0x71, 0x1e}, 0},
134 {{0x70, 0x06}, 0},
135 {{0x71, 0x80}, 0},
136 {{0x70, 0x07}, 0}
137 };
138 for (i = 0; i < ARRAY_SIZE(start_commands); i++) {
139 retval = jlj_write2(gspca_dev, start_commands[i].instruction);
140 if (retval < 0)
141 return retval;
142 if (start_commands[i].ack_wanted)
143 retval = jlj_read1(gspca_dev, response);
144 if (retval < 0)
145 return retval;
146 }
147 PDEBUG(D_ERR, "jlj_start retval is %d", retval);
148 return retval;
149}
150
151static int jlj_stop(struct gspca_dev *gspca_dev)
152{
153 int i;
154 int retval;
155 struct jlj_command stop_commands[] = {
156 {{0x71, 0x00}, 0},
157 {{0x70, 0x09}, 0},
158 {{0x71, 0x80}, 0},
159 {{0x70, 0x05}, 0}
160 };
161 for (i = 0; i < ARRAY_SIZE(stop_commands); i++) {
162 retval = jlj_write2(gspca_dev, stop_commands[i].instruction);
163 if (retval < 0)
164 return retval;
165 }
166 return retval;
167}
168
169/* This function is called as a workqueue function and runs whenever the camera
170 * is streaming data. Because it is a workqueue function it is allowed to sleep
171 * so we can use synchronous USB calls. To avoid possible collisions with other
172 * threads attempting to use the camera's USB interface the gspca usb_lock is
173 * used when performing the one USB control operation inside the workqueue,
174 * which tells the camera to close the stream. In practice the only thing
175 * which needs to be protected against is the usb_set_interface call that
176 * gspca makes during stream_off. Otherwise the camera doesn't provide any
177 * controls that the user could try to change.
178 */
179
180static void jlj_dostream(struct work_struct *work)
181{
182 struct sd *dev = container_of(work, struct sd, work_struct);
183 struct gspca_dev *gspca_dev = &dev->gspca_dev;
184 struct gspca_frame *frame;
185 int blocks_left; /* 0x200-sized blocks remaining in current frame. */
186 int size_in_blocks;
187 int act_len;
188 int discarding = 0; /* true if we failed to get space for frame. */
189 int packet_type;
190 int ret;
191 u8 *buffer;
192
193 buffer = kmalloc(JEILINJ_MAX_TRANSFER, GFP_KERNEL | GFP_DMA);
194 if (!buffer) {
195 PDEBUG(D_ERR, "Couldn't allocate USB buffer");
196 goto quit_stream;
197 }
198 while (gspca_dev->present && gspca_dev->streaming) {
199 if (!gspca_dev->present)
200 goto quit_stream;
201 /* Start a new frame, and add the JPEG header, first thing */
202 frame = gspca_get_i_frame(gspca_dev);
203 if (frame && !discarding)
204 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
205 dev->jpeg_hdr, JPEG_HDR_SZ);
206 else
207 discarding = 1;
208 /*
209 * Now request data block 0. Line 0 reports the size
210 * to download, in blocks of size 0x200, and also tells the
211 * "actual" data size, in bytes, which seems best to ignore.
212 */
213 ret = usb_bulk_msg(gspca_dev->dev,
214 usb_rcvbulkpipe(gspca_dev->dev, 0x82),
215 buffer, JEILINJ_MAX_TRANSFER, &act_len,
216 JEILINJ_DATA_TIMEOUT);
217 PDEBUG(D_STREAM,
218 "Got %d bytes out of %d for Block 0",
219 act_len, JEILINJ_MAX_TRANSFER);
220 if (ret < 0 || act_len < FRAME_HEADER_LEN)
221 goto quit_stream;
222 size_in_blocks = buffer[0x0a];
223 blocks_left = buffer[0x0a] - 1;
224 PDEBUG(D_STREAM, "blocks_left = 0x%x", blocks_left);
225 packet_type = INTER_PACKET;
226 if (frame && !discarding)
227 /* Toss line 0 of data block 0, keep the rest. */
228 gspca_frame_add(gspca_dev, packet_type,
229 frame, buffer + FRAME_HEADER_LEN,
230 JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN);
231 else
232 discarding = 1;
233 while (blocks_left > 0) {
234 if (!gspca_dev->present)
235 goto quit_stream;
236 ret = usb_bulk_msg(gspca_dev->dev,
237 usb_rcvbulkpipe(gspca_dev->dev, 0x82),
238 buffer, JEILINJ_MAX_TRANSFER, &act_len,
239 JEILINJ_DATA_TIMEOUT);
240 if (ret < 0 || act_len < JEILINJ_MAX_TRANSFER)
241 goto quit_stream;
242 PDEBUG(D_STREAM,
243 "%d blocks remaining for frame", blocks_left);
244 blocks_left -= 1;
245 if (blocks_left == 0)
246 packet_type = LAST_PACKET;
247 else
248 packet_type = INTER_PACKET;
249 if (frame && !discarding)
250 gspca_frame_add(gspca_dev, packet_type,
251 frame, buffer,
252 JEILINJ_MAX_TRANSFER);
253 else
254 discarding = 1;
255 }
256 }
257quit_stream:
258 mutex_lock(&gspca_dev->usb_lock);
259 if (gspca_dev->present)
260 jlj_stop(gspca_dev);
261 mutex_unlock(&gspca_dev->usb_lock);
262 kfree(buffer);
263}
264
265/* This function is called at probe time just before sd_init */
266static int sd_config(struct gspca_dev *gspca_dev,
267 const struct usb_device_id *id)
268{
269 struct cam *cam = &gspca_dev->cam;
270 struct sd *dev = (struct sd *) gspca_dev;
271
272 dev->quality = 85;
273 dev->jpegqual = 85;
274 PDEBUG(D_PROBE,
275 "JEILINJ camera detected"
276 " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
277 cam->cam_mode = jlj_mode;
278 cam->nmodes = 1;
279 cam->bulk = 1;
280 /* We don't use the buffer gspca allocates so make it small. */
281 cam->bulk_size = 32;
282 INIT_WORK(&dev->work_struct, jlj_dostream);
283 return 0;
284}
285
286/* called on streamoff with alt==0 and on disconnect */
287/* the usb_lock is held at entry - restore on exit */
288static void sd_stop0(struct gspca_dev *gspca_dev)
289{
290 struct sd *dev = (struct sd *) gspca_dev;
291
292 /* wait for the work queue to terminate */
293 mutex_unlock(&gspca_dev->usb_lock);
294 /* This waits for jlj_dostream to finish */
295 destroy_workqueue(dev->work_thread);
296 dev->work_thread = NULL;
297 mutex_lock(&gspca_dev->usb_lock);
298 kfree(dev->jpeg_hdr);
299}
300
301/* this function is called at probe and resume time */
302static int sd_init(struct gspca_dev *gspca_dev)
303{
304 return 0;
305}
306
307/* Set up for getting frames. */
308static int sd_start(struct gspca_dev *gspca_dev)
309{
310 struct sd *dev = (struct sd *) gspca_dev;
311 int ret;
312
313 /* create the JPEG header */
314 dev->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
315 jpeg_define(dev->jpeg_hdr, gspca_dev->height, gspca_dev->width,
316 0x21); /* JPEG 422 */
317 jpeg_set_qual(dev->jpeg_hdr, dev->quality);
318 PDEBUG(D_STREAM, "Start streaming at 320x240");
319 ret = jlj_start(gspca_dev);
320 if (ret < 0) {
321 PDEBUG(D_ERR, "Start streaming command failed");
322 return ret;
323 }
324 /* Start the workqueue function to do the streaming */
325 dev->work_thread = create_singlethread_workqueue(MODULE_NAME);
326 queue_work(dev->work_thread, &dev->work_struct);
327
328 return 0;
329}
330
331/* Table of supported USB devices */
332static const __devinitdata struct usb_device_id device_table[] = {
333 {USB_DEVICE(0x0979, 0x0280)},
334 {}
335};
336
337MODULE_DEVICE_TABLE(usb, device_table);
338
339/* sub-driver description */
340static const struct sd_desc sd_desc = {
341 .name = MODULE_NAME,
342 .config = sd_config,
343 .init = sd_init,
344 .start = sd_start,
345 .stop0 = sd_stop0,
346};
347
348/* -- device connect -- */
349static int sd_probe(struct usb_interface *intf,
350 const struct usb_device_id *id)
351{
352 return gspca_dev_probe(intf, id,
353 &sd_desc,
354 sizeof(struct sd),
355 THIS_MODULE);
356}
357
358static struct usb_driver sd_driver = {
359 .name = MODULE_NAME,
360 .id_table = device_table,
361 .probe = sd_probe,
362 .disconnect = gspca_disconnect,
363#ifdef CONFIG_PM
364 .suspend = gspca_suspend,
365 .resume = gspca_resume,
366#endif
367};
368
369/* -- module insert / remove -- */
370static int __init sd_mod_init(void)
371{
372 int ret;
373
374 ret = usb_register(&sd_driver);
375 if (ret < 0)
376 return ret;
377 PDEBUG(D_PROBE, "registered");
378 return 0;
379}
380
381static void __exit sd_mod_exit(void)
382{
383 usb_deregister(&sd_driver);
384 PDEBUG(D_PROBE, "deregistered");
385}
386
387module_init(sd_mod_init);
388module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index 7127321ace8c..6b89f33a4ce0 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -178,8 +178,10 @@ sensor_found:
178 178
179 sens_priv->settings = 179 sens_priv->settings =
180 kmalloc(sizeof(s32)*ARRAY_SIZE(s5k83a_ctrls), GFP_KERNEL); 180 kmalloc(sizeof(s32)*ARRAY_SIZE(s5k83a_ctrls), GFP_KERNEL);
181 if (!sens_priv->settings) 181 if (!sens_priv->settings) {
182 kfree(sens_priv);
182 return -ENOMEM; 183 return -ENOMEM;
184 }
183 185
184 sd->gspca_dev.cam.cam_mode = s5k83a_modes; 186 sd->gspca_dev.cam.cam_mode = s5k83a_modes;
185 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes); 187 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes);
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
index 30132513400c..140c8f320e47 100644
--- a/drivers/media/video/gspca/mr97310a.c
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -3,6 +3,21 @@
3 * 3 *
4 * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com> 4 * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com>
5 * 5 *
6 * Support for the MR97310A cameras in addition to the Aiptek Pencam VGA+
7 * and for the routines for detecting and classifying these various cameras,
8 *
9 * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
10 *
11 * Acknowledgements:
12 *
13 * The MR97311A support in gspca/mars.c has been helpful in understanding some
14 * of the registers in these cameras.
15 *
16 * Hans de Goede <hdgoede@redhat.com> and
17 * Thomas Kaiser <thomas@kaiser-linux.li>
18 * have assisted with their experience. Each of them has also helped by
19 * testing a previously unsupported camera.
20 *
6 * This program is free software; you can redistribute it and/or modify 21 * 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 22 * 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 23 * the Free Software Foundation; either version 2 of the License, or
@@ -22,18 +37,108 @@
22 37
23#include "gspca.h" 38#include "gspca.h"
24 39
25MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>"); 40#define CAM_TYPE_CIF 0
41#define CAM_TYPE_VGA 1
42
43#define MR97310A_BRIGHTNESS_MIN -254
44#define MR97310A_BRIGHTNESS_MAX 255
45#define MR97310A_BRIGHTNESS_DEFAULT 0
46
47#define MR97310A_EXPOSURE_MIN 300
48#define MR97310A_EXPOSURE_MAX 4095
49#define MR97310A_EXPOSURE_DEFAULT 1000
50
51#define MR97310A_GAIN_MIN 0
52#define MR97310A_GAIN_MAX 31
53#define MR97310A_GAIN_DEFAULT 25
54
55MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>,"
56 "Theodore Kilgore <kilgota@auburn.edu>");
26MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver"); 57MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
27MODULE_LICENSE("GPL"); 58MODULE_LICENSE("GPL");
28 59
60/* global parameters */
61int force_sensor_type = -1;
62module_param(force_sensor_type, int, 0644);
63MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)");
64
29/* specific webcam descriptor */ 65/* specific webcam descriptor */
30struct sd { 66struct sd {
31 struct gspca_dev gspca_dev; /* !! must be the first item */ 67 struct gspca_dev gspca_dev; /* !! must be the first item */
32 u8 sof_read; 68 u8 sof_read;
69 u8 cam_type; /* 0 is CIF and 1 is VGA */
70 u8 sensor_type; /* We use 0 and 1 here, too. */
71 u8 do_lcd_stop;
72
73 int brightness;
74 u16 exposure;
75 u8 gain;
76};
77
78struct sensor_w_data {
79 u8 reg;
80 u8 flags;
81 u8 data[16];
82 int len;
33}; 83};
34 84
85static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
86static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
87static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
88static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
89static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
90static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
91static void setbrightness(struct gspca_dev *gspca_dev);
92static void setexposure(struct gspca_dev *gspca_dev);
93static void setgain(struct gspca_dev *gspca_dev);
94
35/* V4L2 controls supported by the driver */ 95/* V4L2 controls supported by the driver */
36static struct ctrl sd_ctrls[] = { 96static struct ctrl sd_ctrls[] = {
97 {
98#define BRIGHTNESS_IDX 0
99 {
100 .id = V4L2_CID_BRIGHTNESS,
101 .type = V4L2_CTRL_TYPE_INTEGER,
102 .name = "Brightness",
103 .minimum = MR97310A_BRIGHTNESS_MIN,
104 .maximum = MR97310A_BRIGHTNESS_MAX,
105 .step = 1,
106 .default_value = MR97310A_BRIGHTNESS_DEFAULT,
107 .flags = 0,
108 },
109 .set = sd_setbrightness,
110 .get = sd_getbrightness,
111 },
112 {
113#define EXPOSURE_IDX 1
114 {
115 .id = V4L2_CID_EXPOSURE,
116 .type = V4L2_CTRL_TYPE_INTEGER,
117 .name = "Exposure",
118 .minimum = MR97310A_EXPOSURE_MIN,
119 .maximum = MR97310A_EXPOSURE_MAX,
120 .step = 1,
121 .default_value = MR97310A_EXPOSURE_DEFAULT,
122 .flags = 0,
123 },
124 .set = sd_setexposure,
125 .get = sd_getexposure,
126 },
127 {
128#define GAIN_IDX 2
129 {
130 .id = V4L2_CID_GAIN,
131 .type = V4L2_CTRL_TYPE_INTEGER,
132 .name = "Gain",
133 .minimum = MR97310A_GAIN_MIN,
134 .maximum = MR97310A_GAIN_MAX,
135 .step = 1,
136 .default_value = MR97310A_GAIN_DEFAULT,
137 .flags = 0,
138 },
139 .set = sd_setgain,
140 .get = sd_getgain,
141 },
37}; 142};
38 143
39static const struct v4l2_pix_format vga_mode[] = { 144static const struct v4l2_pix_format vga_mode[] = {
@@ -65,7 +170,7 @@ static const struct v4l2_pix_format vga_mode[] = {
65}; 170};
66 171
67/* the bytes to write are in gspca_dev->usb_buf */ 172/* the bytes to write are in gspca_dev->usb_buf */
68static int reg_w(struct gspca_dev *gspca_dev, int len) 173static int mr_write(struct gspca_dev *gspca_dev, int len)
69{ 174{
70 int rc; 175 int rc;
71 176
@@ -78,15 +183,249 @@ static int reg_w(struct gspca_dev *gspca_dev, int len)
78 return rc; 183 return rc;
79} 184}
80 185
186/* the bytes are read into gspca_dev->usb_buf */
187static int mr_read(struct gspca_dev *gspca_dev, int len)
188{
189 int rc;
190
191 rc = usb_bulk_msg(gspca_dev->dev,
192 usb_rcvbulkpipe(gspca_dev->dev, 3),
193 gspca_dev->usb_buf, len, NULL, 500);
194 if (rc < 0)
195 PDEBUG(D_ERR, "reg read [%02x] error %d",
196 gspca_dev->usb_buf[0], rc);
197 return rc;
198}
199
200static int sensor_write_reg(struct gspca_dev *gspca_dev, u8 reg, u8 flags,
201 const u8 *data, int len)
202{
203 gspca_dev->usb_buf[0] = 0x1f;
204 gspca_dev->usb_buf[1] = flags;
205 gspca_dev->usb_buf[2] = reg;
206 memcpy(gspca_dev->usb_buf + 3, data, len);
207
208 return mr_write(gspca_dev, len + 3);
209}
210
211static int sensor_write_regs(struct gspca_dev *gspca_dev,
212 const struct sensor_w_data *data, int len)
213{
214 int i, rc;
215
216 for (i = 0; i < len; i++) {
217 rc = sensor_write_reg(gspca_dev, data[i].reg, data[i].flags,
218 data[i].data, data[i].len);
219 if (rc < 0)
220 return rc;
221 }
222
223 return 0;
224}
225
226static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data)
227{
228 struct sd *sd = (struct sd *) gspca_dev;
229 u8 buf, confirm_reg;
230 int rc;
231
232 buf = data;
233 rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1);
234 if (rc < 0)
235 return rc;
236
237 buf = 0x01;
238 confirm_reg = sd->sensor_type ? 0x13 : 0x11;
239 rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1);
240 if (rc < 0)
241 return rc;
242
243 return 0;
244}
245
246static int cam_get_response16(struct gspca_dev *gspca_dev)
247{
248 __u8 *data = gspca_dev->usb_buf;
249 int err_code;
250
251 data[0] = 0x21;
252 err_code = mr_write(gspca_dev, 1);
253 if (err_code < 0)
254 return err_code;
255
256 err_code = mr_read(gspca_dev, 16);
257 return err_code;
258}
259
260static int zero_the_pointer(struct gspca_dev *gspca_dev)
261{
262 __u8 *data = gspca_dev->usb_buf;
263 int err_code;
264 u8 status = 0;
265 int tries = 0;
266
267 err_code = cam_get_response16(gspca_dev);
268 if (err_code < 0)
269 return err_code;
270
271 err_code = mr_write(gspca_dev, 1);
272 data[0] = 0x19;
273 data[1] = 0x51;
274 err_code = mr_write(gspca_dev, 2);
275 if (err_code < 0)
276 return err_code;
277
278 err_code = cam_get_response16(gspca_dev);
279 if (err_code < 0)
280 return err_code;
281
282 data[0] = 0x19;
283 data[1] = 0xba;
284 err_code = mr_write(gspca_dev, 2);
285 if (err_code < 0)
286 return err_code;
287
288 err_code = cam_get_response16(gspca_dev);
289 if (err_code < 0)
290 return err_code;
291
292 data[0] = 0x19;
293 data[1] = 0x00;
294 err_code = mr_write(gspca_dev, 2);
295 if (err_code < 0)
296 return err_code;
297
298 err_code = cam_get_response16(gspca_dev);
299 if (err_code < 0)
300 return err_code;
301
302 data[0] = 0x19;
303 data[1] = 0x00;
304 err_code = mr_write(gspca_dev, 2);
305 if (err_code < 0)
306 return err_code;
307
308 while (status != 0x0a && tries < 256) {
309 err_code = cam_get_response16(gspca_dev);
310 status = data[0];
311 tries++;
312 if (err_code < 0)
313 return err_code;
314 }
315 if (status != 0x0a)
316 PDEBUG(D_ERR, "status is %02x", status);
317
318 tries = 0;
319 while (tries < 4) {
320 data[0] = 0x19;
321 data[1] = 0x00;
322 err_code = mr_write(gspca_dev, 2);
323 if (err_code < 0)
324 return err_code;
325
326 err_code = cam_get_response16(gspca_dev);
327 status = data[0];
328 tries++;
329 if (err_code < 0)
330 return err_code;
331 }
332
333 data[0] = 0x19;
334 err_code = mr_write(gspca_dev, 1);
335 if (err_code < 0)
336 return err_code;
337
338 err_code = mr_read(gspca_dev, 16);
339 if (err_code < 0)
340 return err_code;
341
342 return 0;
343}
344
345static u8 get_sensor_id(struct gspca_dev *gspca_dev)
346{
347 int err_code;
348
349 gspca_dev->usb_buf[0] = 0x1e;
350 err_code = mr_write(gspca_dev, 1);
351 if (err_code < 0)
352 return err_code;
353
354 err_code = mr_read(gspca_dev, 16);
355 if (err_code < 0)
356 return err_code;
357
358 PDEBUG(D_PROBE, "Byte zero reported is %01x", gspca_dev->usb_buf[0]);
359
360 return gspca_dev->usb_buf[0];
361}
362
81/* this function is called at probe time */ 363/* this function is called at probe time */
82static int sd_config(struct gspca_dev *gspca_dev, 364static int sd_config(struct gspca_dev *gspca_dev,
83 const struct usb_device_id *id) 365 const struct usb_device_id *id)
84{ 366{
367 struct sd *sd = (struct sd *) gspca_dev;
85 struct cam *cam; 368 struct cam *cam;
369 __u8 *data = gspca_dev->usb_buf;
370 int err_code;
86 371
87 cam = &gspca_dev->cam; 372 cam = &gspca_dev->cam;
88 cam->cam_mode = vga_mode; 373 cam->cam_mode = vga_mode;
89 cam->nmodes = ARRAY_SIZE(vga_mode); 374 cam->nmodes = ARRAY_SIZE(vga_mode);
375
376 if (id->idProduct == 0x010e) {
377 sd->cam_type = CAM_TYPE_CIF;
378 cam->nmodes--;
379
380 data[0] = 0x01;
381 data[1] = 0x01;
382 err_code = mr_write(gspca_dev, 2);
383 if (err_code < 0)
384 return err_code;
385
386 msleep(200);
387 data[0] = get_sensor_id(gspca_dev);
388 /*
389 * Known CIF cameras. If you have another to report, please do
390 *
391 * Name byte just read sd->sensor_type
392 * reported by
393 * Sakar Spy-shot 0x28 T. Kilgore 0
394 * Innovage 0xf5 (unstable) T. Kilgore 0
395 * Vivitar Mini 0x53 H. De Goede 0
396 * Vivitar Mini 0x04 / 0x24 E. Rodriguez 0
397 * Vivitar Mini 0x08 T. Kilgore 1
398 * Elta-Media 8212dc 0x23 T. Kaiser 1
399 * Philips dig. keych. 0x37 T. Kilgore 1
400 */
401 if ((data[0] & 0x78) == 8 ||
402 ((data[0] & 0x2) == 0x2 && data[0] != 0x53))
403 sd->sensor_type = 1;
404 else
405 sd->sensor_type = 0;
406
407 PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d",
408 sd->sensor_type);
409
410 if (force_sensor_type != -1) {
411 sd->sensor_type = !! force_sensor_type;
412 PDEBUG(D_PROBE, "Forcing sensor type to: %d",
413 sd->sensor_type);
414 }
415
416 if (sd->sensor_type == 0)
417 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX);
418 } else {
419 sd->cam_type = CAM_TYPE_VGA;
420 PDEBUG(D_PROBE, "MR97310A VGA camera detected");
421 gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) |
422 (1 << EXPOSURE_IDX) | (1 << GAIN_IDX);
423 }
424
425 sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
426 sd->exposure = MR97310A_EXPOSURE_DEFAULT;
427 sd->gain = MR97310A_GAIN_DEFAULT;
428
90 return 0; 429 return 0;
91} 430}
92 431
@@ -96,183 +435,462 @@ static int sd_init(struct gspca_dev *gspca_dev)
96 return 0; 435 return 0;
97} 436}
98 437
99static int sd_start(struct gspca_dev *gspca_dev) 438static int start_cif_cam(struct gspca_dev *gspca_dev)
100{ 439{
101 struct sd *sd = (struct sd *) gspca_dev; 440 struct sd *sd = (struct sd *) gspca_dev;
102 __u8 *data = gspca_dev->usb_buf; 441 __u8 *data = gspca_dev->usb_buf;
103 int err_code; 442 int err_code;
104 443 const __u8 startup_string[] = {
105 sd->sof_read = 0; 444 0x00,
106 445 0x0d,
107 /* Note: register descriptions guessed from MR97113A driver */ 446 0x01,
108 447 0x00, /* Hsize/8 for 352 or 320 */
448 0x00, /* Vsize/4 for 288 or 240 */
449 0x13, /* or 0xbb, depends on sensor */
450 0x00, /* Hstart, depends on res. */
451 0x00, /* reserved ? */
452 0x00, /* Vstart, depends on res. and sensor */
453 0x50, /* 0x54 to get 176 or 160 */
454 0xc0
455 };
456
457 /* Note: Some of the above descriptions guessed from MR97113A driver */
109 data[0] = 0x01; 458 data[0] = 0x01;
110 data[1] = 0x01; 459 data[1] = 0x01;
111 err_code = reg_w(gspca_dev, 2); 460 err_code = mr_write(gspca_dev, 2);
112 if (err_code < 0) 461 if (err_code < 0)
113 return err_code; 462 return err_code;
114 463
115 data[0] = 0x00; 464 memcpy(data, startup_string, 11);
116 data[1] = 0x0d; 465 if (sd->sensor_type)
117 data[2] = 0x01; 466 data[5] = 0xbb;
118 data[5] = 0x2b;
119 data[7] = 0x00;
120 data[9] = 0x50; /* reg 8, no scale down */
121 data[10] = 0xc0;
122 467
123 switch (gspca_dev->width) { 468 switch (gspca_dev->width) {
124 case 160: 469 case 160:
125 data[9] |= 0x0c; /* reg 8, 4:1 scale down */ 470 data[9] |= 0x04; /* reg 8, 2:1 scale down from 320 */
126 /* fall thru */ 471 /* fall thru */
127 case 320: 472 case 320:
128 data[9] |= 0x04; /* reg 8, 2:1 scale down */
129 /* fall thru */
130 case 640:
131 default: 473 default:
132 data[3] = 0x50; /* reg 2, H size */ 474 data[3] = 0x28; /* reg 2, H size/8 */
133 data[4] = 0x78; /* reg 3, V size */ 475 data[4] = 0x3c; /* reg 3, V size/4 */
134 data[6] = 0x04; /* reg 5, H start */ 476 data[6] = 0x14; /* reg 5, H start */
135 data[8] = 0x03; /* reg 7, V start */ 477 data[8] = 0x1a + sd->sensor_type; /* reg 7, V start */
136 break; 478 break;
137
138 case 176: 479 case 176:
139 data[9] |= 0x04; /* reg 8, 2:1 scale down */ 480 data[9] |= 0x04; /* reg 8, 2:1 scale down from 352 */
140 /* fall thru */ 481 /* fall thru */
141 case 352: 482 case 352:
142 data[3] = 0x2c; /* reg 2, H size */ 483 data[3] = 0x2c; /* reg 2, H size/8 */
143 data[4] = 0x48; /* reg 3, V size */ 484 data[4] = 0x48; /* reg 3, V size/4 */
144 data[6] = 0x94; /* reg 5, H start */ 485 data[6] = 0x06; /* reg 5, H start */
145 data[8] = 0x63; /* reg 7, V start */ 486 data[8] = 0x06 + sd->sensor_type; /* reg 7, V start */
146 break; 487 break;
147 } 488 }
148 489 err_code = mr_write(gspca_dev, 11);
149 err_code = reg_w(gspca_dev, 11);
150 if (err_code < 0) 490 if (err_code < 0)
151 return err_code; 491 return err_code;
152 492
153 data[0] = 0x0a; 493 if (!sd->sensor_type) {
154 data[1] = 0x80; 494 const struct sensor_w_data cif_sensor0_init_data[] = {
155 err_code = reg_w(gspca_dev, 2); 495 {0x02, 0x00, {0x03, 0x5a, 0xb5, 0x01,
496 0x0f, 0x14, 0x0f, 0x10}, 8},
497 {0x0c, 0x00, {0x04, 0x01, 0x01, 0x00, 0x1f}, 5},
498 {0x12, 0x00, {0x07}, 1},
499 {0x1f, 0x00, {0x06}, 1},
500 {0x27, 0x00, {0x04}, 1},
501 {0x29, 0x00, {0x0c}, 1},
502 {0x40, 0x00, {0x40, 0x00, 0x04}, 3},
503 {0x50, 0x00, {0x60}, 1},
504 {0x60, 0x00, {0x06}, 1},
505 {0x6b, 0x00, {0x85, 0x85, 0xc8, 0xc8, 0xc8, 0xc8}, 6},
506 {0x72, 0x00, {0x1e, 0x56}, 2},
507 {0x75, 0x00, {0x58, 0x40, 0xa2, 0x02, 0x31, 0x02,
508 0x31, 0x80, 0x00}, 9},
509 {0x11, 0x00, {0x01}, 1},
510 {0, 0, {0}, 0}
511 };
512 err_code = sensor_write_regs(gspca_dev, cif_sensor0_init_data,
513 ARRAY_SIZE(cif_sensor0_init_data));
514 } else { /* sd->sensor_type = 1 */
515 const struct sensor_w_data cif_sensor1_init_data[] = {
516 /* Reg 3,4, 7,8 get set by the controls */
517 {0x02, 0x00, {0x10}, 1},
518 {0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */
519 {0x06, 0x01, {0x00}, 1},
520 {0x09, 0x02, {0x0e}, 1},
521 {0x0a, 0x02, {0x05}, 1},
522 {0x0b, 0x02, {0x05}, 1},
523 {0x0c, 0x02, {0x0f}, 1},
524 {0x0d, 0x02, {0x07}, 1},
525 {0x0e, 0x02, {0x0c}, 1},
526 {0x0f, 0x00, {0x00}, 1},
527 {0x10, 0x00, {0x06}, 1},
528 {0x11, 0x00, {0x07}, 1},
529 {0x12, 0x00, {0x00}, 1},
530 {0x13, 0x00, {0x01}, 1},
531 {0, 0, {0}, 0}
532 };
533 err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
534 ARRAY_SIZE(cif_sensor1_init_data));
535 }
156 if (err_code < 0) 536 if (err_code < 0)
157 return err_code; 537 return err_code;
158 538
159 data[0] = 0x14; 539 setbrightness(gspca_dev);
160 data[1] = 0x0a; 540 setexposure(gspca_dev);
161 err_code = reg_w(gspca_dev, 2); 541 setgain(gspca_dev);
162 if (err_code < 0)
163 return err_code;
164 542
165 data[0] = 0x1b; 543 msleep(200);
166 data[1] = 0x00;
167 err_code = reg_w(gspca_dev, 2);
168 if (err_code < 0)
169 return err_code;
170 544
171 data[0] = 0x15; 545 data[0] = 0x00;
172 data[1] = 0x16; 546 data[1] = 0x4d; /* ISOC transfering enable... */
173 err_code = reg_w(gspca_dev, 2); 547 err_code = mr_write(gspca_dev, 2);
174 if (err_code < 0) 548 if (err_code < 0)
175 return err_code; 549 return err_code;
176 550
177 data[0] = 0x16; 551 return 0;
178 data[1] = 0x10; 552}
179 err_code = reg_w(gspca_dev, 2);
180 if (err_code < 0)
181 return err_code;
182 553
183 data[0] = 0x17; 554static int start_vga_cam(struct gspca_dev *gspca_dev)
184 data[1] = 0x3a; 555{
185 err_code = reg_w(gspca_dev, 2); 556 struct sd *sd = (struct sd *) gspca_dev;
186 if (err_code < 0) 557 __u8 *data = gspca_dev->usb_buf;
187 return err_code; 558 int err_code;
559 const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b,
560 0x00, 0x00, 0x00, 0x50, 0xc0};
188 561
189 data[0] = 0x18; 562 /* What some of these mean is explained in start_cif_cam(), above */
190 data[1] = 0x68; 563 sd->sof_read = 0;
191 err_code = reg_w(gspca_dev, 2);
192 if (err_code < 0)
193 return err_code;
194 564
195 data[0] = 0x1f; 565 /*
196 data[1] = 0x00; 566 * We have to know which camera we have, because the register writes
197 data[2] = 0x02; 567 * depend upon the camera. This test, run before we actually enter
198 data[3] = 0x06; 568 * the initialization routine, distinguishes most of the cameras, If
199 data[4] = 0x59; 569 * needed, another routine is done later, too.
200 data[5] = 0x0c; 570 */
201 data[6] = 0x16; 571 memset(data, 0, 16);
202 data[7] = 0x00; 572 data[0] = 0x20;
203 data[8] = 0x07; 573 err_code = mr_write(gspca_dev, 1);
204 data[9] = 0x00;
205 data[10] = 0x01;
206 err_code = reg_w(gspca_dev, 11);
207 if (err_code < 0) 574 if (err_code < 0)
208 return err_code; 575 return err_code;
209 576
210 data[0] = 0x1f; 577 err_code = mr_read(gspca_dev, 16);
211 data[1] = 0x04;
212 data[2] = 0x11;
213 data[3] = 0x01;
214 err_code = reg_w(gspca_dev, 4);
215 if (err_code < 0) 578 if (err_code < 0)
216 return err_code; 579 return err_code;
217 580
218 data[0] = 0x1f; 581 PDEBUG(D_PROBE, "Byte reported is %02x", data[0]);
219 data[1] = 0x00; 582
220 data[2] = 0x0a; 583 msleep(200);
221 data[3] = 0x00; 584 /*
222 data[4] = 0x01; 585 * Known VGA cameras. If you have another to report, please do
223 data[5] = 0x00; 586 *
224 data[6] = 0x00; 587 * Name byte just read sd->sensor_type
225 data[7] = 0x01; 588 * sd->do_lcd_stop
226 data[8] = 0x00; 589 * Aiptek Pencam VGA+ 0x31 0 1
227 data[9] = 0x0a; 590 * ION digital 0x31 0 1
228 err_code = reg_w(gspca_dev, 10); 591 * Argus DC-1620 0x30 1 0
229 if (err_code < 0) 592 * Argus QuickClix 0x30 1 1 (not caught here)
230 return err_code; 593 */
594 sd->sensor_type = data[0] & 1;
595 sd->do_lcd_stop = (~data[0]) & 1;
596
597
231 598
232 data[0] = 0x1f; 599 /* Streaming setup begins here. */
233 data[1] = 0x04; 600
234 data[2] = 0x11; 601
235 data[3] = 0x01; 602 data[0] = 0x01;
236 err_code = reg_w(gspca_dev, 4); 603 data[1] = 0x01;
604 err_code = mr_write(gspca_dev, 2);
237 if (err_code < 0) 605 if (err_code < 0)
238 return err_code; 606 return err_code;
239 607
240 data[0] = 0x1f; 608 /*
241 data[1] = 0x00; 609 * A second test can now resolve any remaining ambiguity in the
242 data[2] = 0x12; 610 * identification of the camera type,
243 data[3] = 0x00; 611 */
244 data[4] = 0x63; 612 if (!sd->sensor_type) {
245 data[5] = 0x00; 613 data[0] = get_sensor_id(gspca_dev);
246 data[6] = 0x70; 614 if (data[0] == 0x7f) {
247 data[7] = 0x00; 615 sd->sensor_type = 1;
248 data[8] = 0x00; 616 PDEBUG(D_PROBE, "sensor_type corrected to 1");
249 err_code = reg_w(gspca_dev, 9); 617 }
618 msleep(200);
619 }
620
621 if (force_sensor_type != -1) {
622 sd->sensor_type = !! force_sensor_type;
623 PDEBUG(D_PROBE, "Forcing sensor type to: %d",
624 sd->sensor_type);
625 }
626
627 /*
628 * Known VGA cameras.
629 * This test is only run if the previous test returned 0x30, but
630 * here is the information for all others, too, just for reference.
631 *
632 * Name byte just read sd->sensor_type
633 *
634 * Aiptek Pencam VGA+ 0xfb (this test not run) 1
635 * ION digital 0xbd (this test not run) 1
636 * Argus DC-1620 0xe5 (no change) 0
637 * Argus QuickClix 0x7f (reclassified) 1
638 */
639 memcpy(data, startup_string, 11);
640 if (!sd->sensor_type) {
641 data[5] = 0x00;
642 data[10] = 0x91;
643 }
644
645 switch (gspca_dev->width) {
646 case 160:
647 data[9] |= 0x0c; /* reg 8, 4:1 scale down */
648 /* fall thru */
649 case 320:
650 data[9] |= 0x04; /* reg 8, 2:1 scale down */
651 /* fall thru */
652 case 640:
653 default:
654 data[3] = 0x50; /* reg 2, H size/8 */
655 data[4] = 0x78; /* reg 3, V size/4 */
656 data[6] = 0x04; /* reg 5, H start */
657 data[8] = 0x03; /* reg 7, V start */
658 if (sd->do_lcd_stop)
659 data[8] = 0x04; /* Bayer tile shifted */
660 break;
661
662 case 176:
663 data[9] |= 0x04; /* reg 8, 2:1 scale down */
664 /* fall thru */
665 case 352:
666 data[3] = 0x2c; /* reg 2, H size */
667 data[4] = 0x48; /* reg 3, V size */
668 data[6] = 0x94; /* reg 5, H start */
669 data[8] = 0x63; /* reg 7, V start */
670 if (sd->do_lcd_stop)
671 data[8] = 0x64; /* Bayer tile shifted */
672 break;
673 }
674
675 err_code = mr_write(gspca_dev, 11);
250 if (err_code < 0) 676 if (err_code < 0)
251 return err_code; 677 return err_code;
252 678
253 data[0] = 0x1f; 679 if (!sd->sensor_type) {
254 data[1] = 0x04; 680 /* The only known sensor_type 0 cam is the Argus DC-1620 */
255 data[2] = 0x11; 681 const struct sensor_w_data vga_sensor0_init_data[] = {
256 data[3] = 0x01; 682 {0x01, 0x00, {0x0c, 0x00, 0x04}, 3},
257 err_code = reg_w(gspca_dev, 4); 683 {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4},
684 {0x20, 0x00, {0x00, 0x80, 0x00, 0x08}, 4},
685 {0x25, 0x00, {0x03, 0xa9, 0x80}, 3},
686 {0x30, 0x00, {0x30, 0x18, 0x10, 0x18}, 4},
687 {0, 0, {0}, 0}
688 };
689 err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
690 ARRAY_SIZE(vga_sensor0_init_data));
691 } else { /* sd->sensor_type = 1 */
692 const struct sensor_w_data vga_sensor1_init_data[] = {
693 {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
694 0x07, 0x00, 0x01}, 8},
695 {0x11, 0x04, {0x01}, 1},
696 /*{0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01, */
697 {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01,
698 0x00, 0x0a}, 7},
699 {0x11, 0x04, {0x01}, 1},
700 {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6},
701 {0x11, 0x04, {0x01}, 1},
702 {0, 0, {0}, 0}
703 };
704 err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
705 ARRAY_SIZE(vga_sensor1_init_data));
706 }
258 if (err_code < 0) 707 if (err_code < 0)
259 return err_code; 708 return err_code;
260 709
710 msleep(200);
261 data[0] = 0x00; 711 data[0] = 0x00;
262 data[1] = 0x4d; /* ISOC transfering enable... */ 712 data[1] = 0x4d; /* ISOC transfering enable... */
263 err_code = reg_w(gspca_dev, 2); 713 err_code = mr_write(gspca_dev, 2);
714
715 return err_code;
716}
717
718static int sd_start(struct gspca_dev *gspca_dev)
719{
720 struct sd *sd = (struct sd *) gspca_dev;
721 int err_code;
722 struct cam *cam;
723
724 cam = &gspca_dev->cam;
725 sd->sof_read = 0;
726 /*
727 * Some of the supported cameras require the memory pointer to be
728 * set to 0, or else they will not stream.
729 */
730 zero_the_pointer(gspca_dev);
731 msleep(200);
732 if (sd->cam_type == CAM_TYPE_CIF) {
733 err_code = start_cif_cam(gspca_dev);
734 } else {
735 err_code = start_vga_cam(gspca_dev);
736 }
264 return err_code; 737 return err_code;
265} 738}
266 739
267static void sd_stopN(struct gspca_dev *gspca_dev) 740static void sd_stopN(struct gspca_dev *gspca_dev)
268{ 741{
742 struct sd *sd = (struct sd *) gspca_dev;
269 int result; 743 int result;
270 744
271 gspca_dev->usb_buf[0] = 1; 745 gspca_dev->usb_buf[0] = 1;
272 gspca_dev->usb_buf[1] = 0; 746 gspca_dev->usb_buf[1] = 0;
273 result = reg_w(gspca_dev, 2); 747 result = mr_write(gspca_dev, 2);
274 if (result < 0) 748 if (result < 0)
275 PDEBUG(D_ERR, "Camera Stop failed"); 749 PDEBUG(D_ERR, "Camera Stop failed");
750
751 /* Not all the cams need this, but even if not, probably a good idea */
752 zero_the_pointer(gspca_dev);
753 if (sd->do_lcd_stop) {
754 gspca_dev->usb_buf[0] = 0x19;
755 gspca_dev->usb_buf[1] = 0x54;
756 result = mr_write(gspca_dev, 2);
757 if (result < 0)
758 PDEBUG(D_ERR, "Camera Stop failed");
759 }
760}
761
762static void setbrightness(struct gspca_dev *gspca_dev)
763{
764 struct sd *sd = (struct sd *) gspca_dev;
765 u8 val;
766
767 if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX))
768 return;
769
770 /* Note register 7 is also seen as 0x8x or 0xCx in dumps */
771 if (sd->brightness > 0) {
772 sensor_write1(gspca_dev, 7, 0x00);
773 val = sd->brightness;
774 } else {
775 sensor_write1(gspca_dev, 7, 0x01);
776 val = 257 - sd->brightness;
777 }
778 sensor_write1(gspca_dev, 8, val);
779}
780
781static void setexposure(struct gspca_dev *gspca_dev)
782{
783 struct sd *sd = (struct sd *) gspca_dev;
784 u8 val;
785
786 if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
787 return;
788
789 if (sd->sensor_type) {
790 val = sd->exposure >> 4;
791 sensor_write1(gspca_dev, 3, val);
792 val = sd->exposure & 0xf;
793 sensor_write1(gspca_dev, 4, val);
794 } else {
795 u8 clockdiv;
796 int exposure;
797
798 /* We have both a clock divider and an exposure register.
799 We first calculate the clock divider, as that determines
800 the maximum exposure and then we calculayte the exposure
801 register setting (which goes from 0 - 511).
802
803 Note our 0 - 4095 exposure is mapped to 0 - 511
804 milliseconds exposure time */
805 clockdiv = (60 * sd->exposure + 7999) / 8000;
806
807 /* Limit framerate to not exceed usb bandwidth */
808 if (clockdiv < 3 && gspca_dev->width >= 320)
809 clockdiv = 3;
810 else if (clockdiv < 2)
811 clockdiv = 2;
812
813 /* Frame exposure time in ms = 1000 * clockdiv / 60 ->
814 exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */
815 exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv);
816 if (exposure > 511)
817 exposure = 511;
818
819 /* exposure register value is reversed! */
820 exposure = 511 - exposure;
821
822 sensor_write1(gspca_dev, 0x02, clockdiv);
823 sensor_write1(gspca_dev, 0x0e, exposure & 0xff);
824 sensor_write1(gspca_dev, 0x0f, exposure >> 8);
825 }
826}
827
828static void setgain(struct gspca_dev *gspca_dev)
829{
830 struct sd *sd = (struct sd *) gspca_dev;
831
832 if (gspca_dev->ctrl_dis & (1 << GAIN_IDX))
833 return;
834
835 if (sd->sensor_type) {
836 sensor_write1(gspca_dev, 0x0e, sd->gain);
837 } else {
838 sensor_write1(gspca_dev, 0x10, sd->gain);
839 }
840}
841
842static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
843{
844 struct sd *sd = (struct sd *) gspca_dev;
845
846 sd->brightness = val;
847 if (gspca_dev->streaming)
848 setbrightness(gspca_dev);
849 return 0;
850}
851
852static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
853{
854 struct sd *sd = (struct sd *) gspca_dev;
855
856 *val = sd->brightness;
857 return 0;
858}
859
860static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
861{
862 struct sd *sd = (struct sd *) gspca_dev;
863
864 sd->exposure = val;
865 if (gspca_dev->streaming)
866 setexposure(gspca_dev);
867 return 0;
868}
869
870static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
871{
872 struct sd *sd = (struct sd *) gspca_dev;
873
874 *val = sd->exposure;
875 return 0;
876}
877
878static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
879{
880 struct sd *sd = (struct sd *) gspca_dev;
881
882 sd->gain = val;
883 if (gspca_dev->streaming)
884 setgain(gspca_dev);
885 return 0;
886}
887
888static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
889{
890 struct sd *sd = (struct sd *) gspca_dev;
891
892 *val = sd->gain;
893 return 0;
276} 894}
277 895
278/* Include pac common sof detection functions */ 896/* Include pac common sof detection functions */
@@ -320,8 +938,9 @@ static const struct sd_desc sd_desc = {
320 938
321/* -- module initialisation -- */ 939/* -- module initialisation -- */
322static const __devinitdata struct usb_device_id device_table[] = { 940static const __devinitdata struct usb_device_id device_table[] = {
323 {USB_DEVICE(0x08ca, 0x0111)}, 941 {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */
324 {USB_DEVICE(0x093a, 0x010f)}, 942 {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */
943 {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */
325 {} 944 {}
326}; 945};
327MODULE_DEVICE_TABLE(usb, device_table); 946MODULE_DEVICE_TABLE(usb, device_table);
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index 95a97ab684cd..96659433d248 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -35,25 +35,17 @@ MODULE_LICENSE("GPL");
35 35
36#define PAC207_BRIGHTNESS_MIN 0 36#define PAC207_BRIGHTNESS_MIN 0
37#define PAC207_BRIGHTNESS_MAX 255 37#define PAC207_BRIGHTNESS_MAX 255
38#define PAC207_BRIGHTNESS_DEFAULT 4 /* power on default: 4 */ 38#define PAC207_BRIGHTNESS_DEFAULT 46
39 39
40/* An exposure value of 4 also works (3 does not) but then we need to lower 40#define PAC207_EXPOSURE_MIN 3
41 the compression balance setting when in 352x288 mode, otherwise the usb
42 bandwidth is not enough and packets get dropped resulting in corrupt
43 frames. The problem with this is that when the compression balance gets
44 lowered below 0x80, the pac207 starts using a different compression
45 algorithm for some lines, these lines get prefixed with a 0x2dd2 prefix
46 and currently we do not know how to decompress these lines, so for now
47 we use a minimum exposure value of 5 */
48#define PAC207_EXPOSURE_MIN 5
49#define PAC207_EXPOSURE_MAX 26 41#define PAC207_EXPOSURE_MAX 26
50#define PAC207_EXPOSURE_DEFAULT 5 /* power on default: 3 ?? */ 42#define PAC207_EXPOSURE_DEFAULT 5 /* power on default: 3 */
51#define PAC207_EXPOSURE_KNEE 11 /* 4 = 30 fps, 11 = 8, 15 = 6 */ 43#define PAC207_EXPOSURE_KNEE 8 /* 4 = 30 fps, 11 = 8, 15 = 6 */
52 44
53#define PAC207_GAIN_MIN 0 45#define PAC207_GAIN_MIN 0
54#define PAC207_GAIN_MAX 31 46#define PAC207_GAIN_MAX 31
55#define PAC207_GAIN_DEFAULT 9 /* power on default: 9 */ 47#define PAC207_GAIN_DEFAULT 9 /* power on default: 9 */
56#define PAC207_GAIN_KNEE 20 48#define PAC207_GAIN_KNEE 31
57 49
58#define PAC207_AUTOGAIN_DEADZONE 30 50#define PAC207_AUTOGAIN_DEADZONE 30
59 51
@@ -166,16 +158,12 @@ static const struct v4l2_pix_format sif_mode[] = {
166}; 158};
167 159
168static const __u8 pac207_sensor_init[][8] = { 160static const __u8 pac207_sensor_init[][8] = {
169 {0x10, 0x12, 0x0d, 0x12, 0x0c, 0x01, 0x29, 0xf0}, 161 {0x10, 0x12, 0x0d, 0x12, 0x0c, 0x01, 0x29, 0x84},
170 {0x00, 0x64, 0x64, 0x64, 0x04, 0x10, 0xf0, 0x30}, 162 {0x49, 0x64, 0x64, 0x64, 0x04, 0x10, 0xf0, 0x30},
171 {0x00, 0x00, 0x00, 0x70, 0xa0, 0xf8, 0x00, 0x00}, 163 {0x00, 0x00, 0x00, 0x70, 0xa0, 0xf8, 0x00, 0x00},
172 {0x00, 0x00, 0x32, 0x00, 0x96, 0x00, 0xa2, 0x02},
173 {0x32, 0x00, 0x96, 0x00, 0xA2, 0x02, 0xaf, 0x00}, 164 {0x32, 0x00, 0x96, 0x00, 0xA2, 0x02, 0xaf, 0x00},
174}; 165};
175 166
176 /* 48 reg_72 Rate Control end BalSize_4a =0x36 */
177static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 };
178
179static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index, 167static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index,
180 const u8 *buffer, u16 length) 168 const u8 *buffer, u16 length)
181{ 169{
@@ -274,7 +262,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
274 * Bit_1=LED, 262 * Bit_1=LED,
275 * Bit_2=Compression test mode enable */ 263 * Bit_2=Compression test mode enable */
276 pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */ 264 pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
277 pac207_write_reg(gspca_dev, 0x11, 0x30); /* Analog Bias */
278 265
279 return 0; 266 return 0;
280} 267}
@@ -289,15 +276,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
289 pac207_write_regs(gspca_dev, 0x0002, pac207_sensor_init[0], 8); 276 pac207_write_regs(gspca_dev, 0x0002, pac207_sensor_init[0], 8);
290 pac207_write_regs(gspca_dev, 0x000a, pac207_sensor_init[1], 8); 277 pac207_write_regs(gspca_dev, 0x000a, pac207_sensor_init[1], 8);
291 pac207_write_regs(gspca_dev, 0x0012, pac207_sensor_init[2], 8); 278 pac207_write_regs(gspca_dev, 0x0012, pac207_sensor_init[2], 8);
292 pac207_write_regs(gspca_dev, 0x0040, pac207_sensor_init[3], 8); 279 pac207_write_regs(gspca_dev, 0x0042, pac207_sensor_init[3], 8);
293 pac207_write_regs(gspca_dev, 0x0042, pac207_sensor_init[4], 8);
294 pac207_write_regs(gspca_dev, 0x0048, PacReg72, 4);
295 280
296 /* Compression Balance */ 281 /* Compression Balance */
297 if (gspca_dev->width == 176) 282 if (gspca_dev->width == 176)
298 pac207_write_reg(gspca_dev, 0x4a, 0xff); 283 pac207_write_reg(gspca_dev, 0x4a, 0xff);
299 else 284 else
300 pac207_write_reg(gspca_dev, 0x4a, 0x88); 285 pac207_write_reg(gspca_dev, 0x4a, 0x30);
301 pac207_write_reg(gspca_dev, 0x4b, 0x00); /* Sram test value */ 286 pac207_write_reg(gspca_dev, 0x4b, 0x00); /* Sram test value */
302 pac207_write_reg(gspca_dev, 0x08, sd->brightness); 287 pac207_write_reg(gspca_dev, 0x08, sd->brightness);
303 288
@@ -346,7 +331,7 @@ static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
346 if (sd->autogain_ignore_frames > 0) 331 if (sd->autogain_ignore_frames > 0)
347 sd->autogain_ignore_frames--; 332 sd->autogain_ignore_frames--;
348 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, 333 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
349 100 + sd->brightness / 2, PAC207_AUTOGAIN_DEADZONE, 334 100, PAC207_AUTOGAIN_DEADZONE,
350 PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE)) 335 PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE))
351 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES; 336 sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
352} 337}
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index e1e3a3a50484..052714484e83 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -1057,6 +1057,7 @@ static struct sd_desc sd_desc = {
1057 1057
1058/* -- module initialisation -- */ 1058/* -- module initialisation -- */
1059static __devinitdata struct usb_device_id device_table[] = { 1059static __devinitdata struct usb_device_id device_table[] = {
1060 {USB_DEVICE(0x06f8, 0x3009), .driver_info = SENSOR_PAC7302},
1060 {USB_DEVICE(0x093a, 0x2600), .driver_info = SENSOR_PAC7311}, 1061 {USB_DEVICE(0x093a, 0x2600), .driver_info = SENSOR_PAC7311},
1061 {USB_DEVICE(0x093a, 0x2601), .driver_info = SENSOR_PAC7311}, 1062 {USB_DEVICE(0x093a, 0x2601), .driver_info = SENSOR_PAC7311},
1062 {USB_DEVICE(0x093a, 0x2603), .driver_info = SENSOR_PAC7311}, 1063 {USB_DEVICE(0x093a, 0x2603), .driver_info = SENSOR_PAC7311},
@@ -1068,6 +1069,7 @@ static __devinitdata struct usb_device_id device_table[] = {
1068 {USB_DEVICE(0x093a, 0x2622), .driver_info = SENSOR_PAC7302}, 1069 {USB_DEVICE(0x093a, 0x2622), .driver_info = SENSOR_PAC7302},
1069 {USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302}, 1070 {USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302},
1070 {USB_DEVICE(0x093a, 0x2626), .driver_info = SENSOR_PAC7302}, 1071 {USB_DEVICE(0x093a, 0x2626), .driver_info = SENSOR_PAC7302},
1072 {USB_DEVICE(0x093a, 0x2629), .driver_info = SENSOR_PAC7302},
1071 {USB_DEVICE(0x093a, 0x262a), .driver_info = SENSOR_PAC7302}, 1073 {USB_DEVICE(0x093a, 0x262a), .driver_info = SENSOR_PAC7302},
1072 {USB_DEVICE(0x093a, 0x262c), .driver_info = SENSOR_PAC7302}, 1074 {USB_DEVICE(0x093a, 0x262c), .driver_info = SENSOR_PAC7302},
1073 {} 1075 {}
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
index fcfbbd329b4c..cdad3db33367 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -94,6 +94,16 @@ struct sd {
94#endif 94#endif
95}; 95};
96 96
97struct i2c_reg_u8 {
98 u8 reg;
99 u8 val;
100};
101
102struct i2c_reg_u16 {
103 u8 reg;
104 u16 val;
105};
106
97static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val); 107static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val);
98static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val); 108static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val);
99static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val); 109static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val);
@@ -403,7 +413,7 @@ static const struct v4l2_pix_format sxga_mode[] = {
403 .priv = 3 | MODE_RAW | MODE_SXGA}, 413 .priv = 3 | MODE_RAW | MODE_SXGA},
404}; 414};
405 415
406static const int hsv_red_x[] = { 416static const s16 hsv_red_x[] = {
407 41, 44, 46, 48, 50, 52, 54, 56, 417 41, 44, 46, 48, 50, 52, 54, 56,
408 58, 60, 62, 64, 66, 68, 70, 72, 418 58, 60, 62, 64, 66, 68, 70, 72,
409 74, 76, 78, 80, 81, 83, 85, 87, 419 74, 76, 78, 80, 81, 83, 85, 87,
@@ -451,7 +461,7 @@ static const int hsv_red_x[] = {
451 24, 26, 28, 30, 33, 35, 37, 39, 41 461 24, 26, 28, 30, 33, 35, 37, 39, 41
452}; 462};
453 463
454static const int hsv_red_y[] = { 464static const s16 hsv_red_y[] = {
455 82, 80, 78, 76, 74, 73, 71, 69, 465 82, 80, 78, 76, 74, 73, 71, 69,
456 67, 65, 63, 61, 58, 56, 54, 52, 466 67, 65, 63, 61, 58, 56, 54, 52,
457 50, 48, 46, 44, 41, 39, 37, 35, 467 50, 48, 46, 44, 41, 39, 37, 35,
@@ -499,7 +509,7 @@ static const int hsv_red_y[] = {
499 96, 94, 92, 91, 89, 87, 85, 84, 82 509 96, 94, 92, 91, 89, 87, 85, 84, 82
500}; 510};
501 511
502static const int hsv_green_x[] = { 512static const s16 hsv_green_x[] = {
503 -124, -124, -125, -125, -125, -125, -125, -125, 513 -124, -124, -125, -125, -125, -125, -125, -125,
504 -125, -126, -126, -125, -125, -125, -125, -125, 514 -125, -126, -126, -125, -125, -125, -125, -125,
505 -125, -124, -124, -124, -123, -123, -122, -122, 515 -125, -124, -124, -124, -123, -123, -122, -122,
@@ -547,7 +557,7 @@ static const int hsv_green_x[] = {
547 -120, -120, -121, -122, -122, -123, -123, -124, -124 557 -120, -120, -121, -122, -122, -123, -123, -124, -124
548}; 558};
549 559
550static const int hsv_green_y[] = { 560static const s16 hsv_green_y[] = {
551 -100, -99, -98, -97, -95, -94, -93, -91, 561 -100, -99, -98, -97, -95, -94, -93, -91,
552 -90, -89, -87, -86, -84, -83, -81, -80, 562 -90, -89, -87, -86, -84, -83, -81, -80,
553 -78, -76, -75, -73, -71, -70, -68, -66, 563 -78, -76, -75, -73, -71, -70, -68, -66,
@@ -595,7 +605,7 @@ static const int hsv_green_y[] = {
595 -109, -108, -107, -106, -105, -104, -103, -102, -100 605 -109, -108, -107, -106, -105, -104, -103, -102, -100
596}; 606};
597 607
598static const int hsv_blue_x[] = { 608static const s16 hsv_blue_x[] = {
599 112, 113, 114, 114, 115, 116, 117, 117, 609 112, 113, 114, 114, 115, 116, 117, 117,
600 118, 118, 119, 119, 120, 120, 120, 121, 610 118, 118, 119, 119, 120, 120, 120, 121,
601 121, 121, 122, 122, 122, 122, 122, 122, 611 121, 121, 122, 122, 122, 122, 122, 122,
@@ -643,7 +653,7 @@ static const int hsv_blue_x[] = {
643 104, 105, 106, 107, 108, 109, 110, 111, 112 653 104, 105, 106, 107, 108, 109, 110, 111, 112
644}; 654};
645 655
646static const int hsv_blue_y[] = { 656static const s16 hsv_blue_y[] = {
647 -11, -13, -15, -17, -19, -21, -23, -25, 657 -11, -13, -15, -17, -19, -21, -23, -25,
648 -27, -29, -31, -33, -35, -37, -39, -41, 658 -27, -29, -31, -33, -35, -37, -39, -41,
649 -43, -45, -46, -48, -50, -52, -54, -55, 659 -43, -45, -46, -48, -50, -52, -54, -55,
@@ -792,21 +802,21 @@ static u8 hv7131r_gain[] = {
792 0x78 /* 8x */ 802 0x78 /* 8x */
793}; 803};
794 804
795static u8 soi968_init[][2] = { 805static struct i2c_reg_u8 soi968_init[] = {
796 {0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f}, 806 {0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f},
797 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00}, 807 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
798 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c}, 808 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
799 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff}, 809 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
800 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20}, 810 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
801 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e}, 811 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
802 {0x13, 0x8a}, {0x12, 0x40}, {0x17, 0x13}, 812 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
803 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79}, 813 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
804 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40}, 814 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
805 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32}, 815 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
806 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80}, 816 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
807}; 817};
808 818
809static u8 ov7660_init[][2] = { 819static struct i2c_reg_u8 ov7660_init[] = {
810 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3}, 820 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
811 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40}, 821 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
812 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a}, 822 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
@@ -815,7 +825,7 @@ static u8 ov7660_init[][2] = {
815 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50}, 825 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
816}; 826};
817 827
818static u8 ov7670_init[][2] = { 828static struct i2c_reg_u8 ov7670_init[] = {
819 {0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01}, 829 {0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
820 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00}, 830 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
821 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0}, 831 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
@@ -872,7 +882,7 @@ static u8 ov7670_init[][2] = {
872 {0x93, 0x00}, 882 {0x93, 0x00},
873}; 883};
874 884
875static u8 ov9650_init[][2] = { 885static struct i2c_reg_u8 ov9650_init[] = {
876 {0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78}, 886 {0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78},
877 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03}, 887 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
878 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00}, 888 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
@@ -902,7 +912,7 @@ static u8 ov9650_init[][2] = {
902 {0xaa, 0x92}, {0xab, 0x0a}, 912 {0xaa, 0x92}, {0xab, 0x0a},
903}; 913};
904 914
905static u8 ov9655_init[][2] = { 915static struct i2c_reg_u8 ov9655_init[] = {
906 {0x12, 0x80}, {0x12, 0x01}, {0x0d, 0x00}, {0x0e, 0x61}, 916 {0x12, 0x80}, {0x12, 0x01}, {0x0d, 0x00}, {0x0e, 0x61},
907 {0x11, 0x80}, {0x13, 0xba}, {0x14, 0x2e}, {0x16, 0x24}, 917 {0x11, 0x80}, {0x13, 0xba}, {0x14, 0x2e}, {0x16, 0x24},
908 {0x1e, 0x04}, {0x1e, 0x04}, {0x1e, 0x04}, {0x27, 0x08}, 918 {0x1e, 0x04}, {0x1e, 0x04}, {0x1e, 0x04}, {0x27, 0x08},
@@ -939,7 +949,7 @@ static u8 ov9655_init[][2] = {
939 {0x00, 0x03}, {0x00, 0x0a}, {0x00, 0x10}, {0x00, 0x13}, 949 {0x00, 0x03}, {0x00, 0x0a}, {0x00, 0x10}, {0x00, 0x13},
940}; 950};
941 951
942static u16 mt9v112_init[][2] = { 952static struct i2c_reg_u16 mt9v112_init[] = {
943 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020}, 953 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
944 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b}, 954 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
945 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001}, 955 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
@@ -958,7 +968,7 @@ static u16 mt9v112_init[][2] = {
958 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae}, 968 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
959}; 969};
960 970
961static u16 mt9v111_init[][2] = { 971static struct i2c_reg_u16 mt9v111_init[] = {
962 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000}, 972 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
963 {0x01, 0x0001}, {0x02, 0x0016}, {0x03, 0x01e1}, 973 {0x01, 0x0001}, {0x02, 0x0016}, {0x03, 0x01e1},
964 {0x04, 0x0281}, {0x05, 0x0004}, {0x07, 0x3002}, 974 {0x04, 0x0281}, {0x05, 0x0004}, {0x07, 0x3002},
@@ -985,7 +995,7 @@ static u16 mt9v111_init[][2] = {
985 {0x0e, 0x0008}, {0x06, 0x002d}, {0x05, 0x0004}, 995 {0x0e, 0x0008}, {0x06, 0x002d}, {0x05, 0x0004},
986}; 996};
987 997
988static u16 mt9v011_init[][2] = { 998static struct i2c_reg_u16 mt9v011_init[] = {
989 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000}, 999 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
990 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1}, 1000 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
991 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006}, 1001 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
@@ -1012,7 +1022,7 @@ static u16 mt9v011_init[][2] = {
1012 {0x06, 0x0029}, {0x05, 0x0009}, 1022 {0x06, 0x0029}, {0x05, 0x0009},
1013}; 1023};
1014 1024
1015static u16 mt9m001_init[][2] = { 1025static struct i2c_reg_u16 mt9m001_init[] = {
1016 {0x0d, 0x0001}, {0x0d, 0x0000}, {0x01, 0x000e}, 1026 {0x0d, 0x0001}, {0x0d, 0x0000}, {0x01, 0x000e},
1017 {0x02, 0x0014}, {0x03, 0x03c1}, {0x04, 0x0501}, 1027 {0x02, 0x0014}, {0x03, 0x03c1}, {0x04, 0x0501},
1018 {0x05, 0x0083}, {0x06, 0x0006}, {0x0d, 0x0002}, 1028 {0x05, 0x0083}, {0x06, 0x0006}, {0x0d, 0x0002},
@@ -1025,14 +1035,14 @@ static u16 mt9m001_init[][2] = {
1025 {0x2e, 0x0029}, {0x07, 0x0002}, 1035 {0x2e, 0x0029}, {0x07, 0x0002},
1026}; 1036};
1027 1037
1028static u16 mt9m111_init[][2] = { 1038static struct i2c_reg_u16 mt9m111_init[] = {
1029 {0xf0, 0x0000}, {0x0d, 0x0008}, {0x0d, 0x0009}, 1039 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1030 {0x0d, 0x0008}, {0xf0, 0x0001}, {0x3a, 0x4300}, 1040 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1031 {0x9b, 0x4300}, {0xa1, 0x0280}, {0xa4, 0x0200}, 1041 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1032 {0x06, 0x308e}, {0xf0, 0x0000}, 1042 {0xf0, 0x0000},
1033}; 1043};
1034 1044
1035static u8 hv7131r_init[][2] = { 1045static struct i2c_reg_u8 hv7131r_init[] = {
1036 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08}, 1046 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1037 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0}, 1047 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
1038 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08}, 1048 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
@@ -1043,7 +1053,7 @@ static u8 hv7131r_init[][2] = {
1043 {0x23, 0x09}, {0x01, 0x08}, 1053 {0x23, 0x09}, {0x01, 0x08},
1044}; 1054};
1045 1055
1046int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length) 1056static int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
1047{ 1057{
1048 struct usb_device *dev = gspca_dev->dev; 1058 struct usb_device *dev = gspca_dev->dev;
1049 int result; 1059 int result;
@@ -1062,7 +1072,8 @@ int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
1062 return 0; 1072 return 0;
1063} 1073}
1064 1074
1065int reg_w(struct gspca_dev *gspca_dev, u16 reg, const u8 *buffer, int length) 1075static int reg_w(struct gspca_dev *gspca_dev, u16 reg,
1076 const u8 *buffer, int length)
1066{ 1077{
1067 struct usb_device *dev = gspca_dev->dev; 1078 struct usb_device *dev = gspca_dev->dev;
1068 int result; 1079 int result;
@@ -1082,13 +1093,13 @@ int reg_w(struct gspca_dev *gspca_dev, u16 reg, const u8 *buffer, int length)
1082 return 0; 1093 return 0;
1083} 1094}
1084 1095
1085int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value) 1096static int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
1086{ 1097{
1087 u8 data[1] = {value}; 1098 u8 data[1] = {value};
1088 return reg_w(gspca_dev, reg, data, 1); 1099 return reg_w(gspca_dev, reg, data, 1);
1089} 1100}
1090 1101
1091int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer) 1102static int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
1092{ 1103{
1093 int i; 1104 int i;
1094 reg_w(gspca_dev, 0x10c0, buffer, 8); 1105 reg_w(gspca_dev, 0x10c0, buffer, 8);
@@ -1096,15 +1107,15 @@ int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
1096 reg_r(gspca_dev, 0x10c0, 1); 1107 reg_r(gspca_dev, 0x10c0, 1);
1097 if (gspca_dev->usb_buf[0] & 0x04) { 1108 if (gspca_dev->usb_buf[0] & 0x04) {
1098 if (gspca_dev->usb_buf[0] & 0x08) 1109 if (gspca_dev->usb_buf[0] & 0x08)
1099 return -1; 1110 return -EIO;
1100 return 0; 1111 return 0;
1101 } 1112 }
1102 msleep(1); 1113 msleep(1);
1103 } 1114 }
1104 return -1; 1115 return -EIO;
1105} 1116}
1106 1117
1107int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) 1118static int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1108{ 1119{
1109 struct sd *sd = (struct sd *) gspca_dev; 1120 struct sd *sd = (struct sd *) gspca_dev;
1110 1121
@@ -1126,7 +1137,7 @@ int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1126 return i2c_w(gspca_dev, row); 1137 return i2c_w(gspca_dev, row);
1127} 1138}
1128 1139
1129int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val) 1140static int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1130{ 1141{
1131 struct sd *sd = (struct sd *) gspca_dev; 1142 struct sd *sd = (struct sd *) gspca_dev;
1132 u8 row[8]; 1143 u8 row[8];
@@ -1152,7 +1163,7 @@ int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1152 struct sd *sd = (struct sd *) gspca_dev; 1163 struct sd *sd = (struct sd *) gspca_dev;
1153 u8 row[8]; 1164 u8 row[8];
1154 1165
1155 row[0] = 0x81 | 0x10; 1166 row[0] = 0x81 | (1 << 4);
1156 row[1] = sd->i2c_addr; 1167 row[1] = sd->i2c_addr;
1157 row[2] = reg; 1168 row[2] = reg;
1158 row[3] = 0; 1169 row[3] = 0;
@@ -1160,14 +1171,15 @@ int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1160 row[5] = 0; 1171 row[5] = 0;
1161 row[6] = 0; 1172 row[6] = 0;
1162 row[7] = 0x10; 1173 row[7] = 0x10;
1163 reg_w(gspca_dev, 0x10c0, row, 8); 1174 if (i2c_w(gspca_dev, row) < 0)
1164 msleep(1); 1175 return -EIO;
1165 row[0] = 0x81 | (2 << 4) | 0x02; 1176 row[0] = 0x81 | (1 << 4) | 0x02;
1166 row[2] = 0; 1177 row[2] = 0;
1167 reg_w(gspca_dev, 0x10c0, row, 8); 1178 if (i2c_w(gspca_dev, row) < 0)
1168 msleep(1); 1179 return -EIO;
1169 reg_r(gspca_dev, 0x10c2, 5); 1180 if (reg_r(gspca_dev, 0x10c2, 5) < 0)
1170 *val = gspca_dev->usb_buf[3]; 1181 return -EIO;
1182 *val = gspca_dev->usb_buf[4];
1171 return 0; 1183 return 0;
1172} 1184}
1173 1185
@@ -1176,7 +1188,7 @@ int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1176 struct sd *sd = (struct sd *) gspca_dev; 1188 struct sd *sd = (struct sd *) gspca_dev;
1177 u8 row[8]; 1189 u8 row[8];
1178 1190
1179 row[0] = 0x81 | 0x10; 1191 row[0] = 0x81 | (1 << 4);
1180 row[1] = sd->i2c_addr; 1192 row[1] = sd->i2c_addr;
1181 row[2] = reg; 1193 row[2] = reg;
1182 row[3] = 0; 1194 row[3] = 0;
@@ -1184,14 +1196,15 @@ int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1184 row[5] = 0; 1196 row[5] = 0;
1185 row[6] = 0; 1197 row[6] = 0;
1186 row[7] = 0x10; 1198 row[7] = 0x10;
1187 reg_w(gspca_dev, 0x10c0, row, 8); 1199 if (i2c_w(gspca_dev, row) < 0)
1188 msleep(1); 1200 return -EIO;
1189 row[0] = 0x81 | (3 << 4) | 0x02; 1201 row[0] = 0x81 | (2 << 4) | 0x02;
1190 row[2] = 0; 1202 row[2] = 0;
1191 reg_w(gspca_dev, 0x10c0, row, 8); 1203 if (i2c_w(gspca_dev, row) < 0)
1192 msleep(1); 1204 return -EIO;
1193 reg_r(gspca_dev, 0x10c2, 5); 1205 if (reg_r(gspca_dev, 0x10c2, 5) < 0)
1194 *val = (gspca_dev->usb_buf[2] << 8) | gspca_dev->usb_buf[3]; 1206 return -EIO;
1207 *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1195 return 0; 1208 return 0;
1196} 1209}
1197 1210
@@ -1201,8 +1214,8 @@ static int ov9650_init_sensor(struct gspca_dev *gspca_dev)
1201 struct sd *sd = (struct sd *) gspca_dev; 1214 struct sd *sd = (struct sd *) gspca_dev;
1202 1215
1203 for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) { 1216 for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) {
1204 if (i2c_w1(gspca_dev, ov9650_init[i][0], 1217 if (i2c_w1(gspca_dev, ov9650_init[i].reg,
1205 ov9650_init[i][1]) < 0) { 1218 ov9650_init[i].val) < 0) {
1206 err("OV9650 sensor initialization failed"); 1219 err("OV9650 sensor initialization failed");
1207 return -ENODEV; 1220 return -ENODEV;
1208 } 1221 }
@@ -1218,8 +1231,8 @@ static int ov9655_init_sensor(struct gspca_dev *gspca_dev)
1218 struct sd *sd = (struct sd *) gspca_dev; 1231 struct sd *sd = (struct sd *) gspca_dev;
1219 1232
1220 for (i = 0; i < ARRAY_SIZE(ov9655_init); i++) { 1233 for (i = 0; i < ARRAY_SIZE(ov9655_init); i++) {
1221 if (i2c_w1(gspca_dev, ov9655_init[i][0], 1234 if (i2c_w1(gspca_dev, ov9655_init[i].reg,
1222 ov9655_init[i][1]) < 0) { 1235 ov9655_init[i].val) < 0) {
1223 err("OV9655 sensor initialization failed"); 1236 err("OV9655 sensor initialization failed");
1224 return -ENODEV; 1237 return -ENODEV;
1225 } 1238 }
@@ -1237,14 +1250,14 @@ static int soi968_init_sensor(struct gspca_dev *gspca_dev)
1237 struct sd *sd = (struct sd *) gspca_dev; 1250 struct sd *sd = (struct sd *) gspca_dev;
1238 1251
1239 for (i = 0; i < ARRAY_SIZE(soi968_init); i++) { 1252 for (i = 0; i < ARRAY_SIZE(soi968_init); i++) {
1240 if (i2c_w1(gspca_dev, soi968_init[i][0], 1253 if (i2c_w1(gspca_dev, soi968_init[i].reg,
1241 soi968_init[i][1]) < 0) { 1254 soi968_init[i].val) < 0) {
1242 err("SOI968 sensor initialization failed"); 1255 err("SOI968 sensor initialization failed");
1243 return -ENODEV; 1256 return -ENODEV;
1244 } 1257 }
1245 } 1258 }
1246 /* disable hflip and vflip */ 1259 /* disable hflip and vflip */
1247 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); 1260 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << EXPOSURE_IDX);
1248 sd->hstart = 60; 1261 sd->hstart = 60;
1249 sd->vstart = 11; 1262 sd->vstart = 11;
1250 return 0; 1263 return 0;
@@ -1256,8 +1269,8 @@ static int ov7660_init_sensor(struct gspca_dev *gspca_dev)
1256 struct sd *sd = (struct sd *) gspca_dev; 1269 struct sd *sd = (struct sd *) gspca_dev;
1257 1270
1258 for (i = 0; i < ARRAY_SIZE(ov7660_init); i++) { 1271 for (i = 0; i < ARRAY_SIZE(ov7660_init); i++) {
1259 if (i2c_w1(gspca_dev, ov7660_init[i][0], 1272 if (i2c_w1(gspca_dev, ov7660_init[i].reg,
1260 ov7660_init[i][1]) < 0) { 1273 ov7660_init[i].val) < 0) {
1261 err("OV7660 sensor initialization failed"); 1274 err("OV7660 sensor initialization failed");
1262 return -ENODEV; 1275 return -ENODEV;
1263 } 1276 }
@@ -1275,8 +1288,8 @@ static int ov7670_init_sensor(struct gspca_dev *gspca_dev)
1275 struct sd *sd = (struct sd *) gspca_dev; 1288 struct sd *sd = (struct sd *) gspca_dev;
1276 1289
1277 for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) { 1290 for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) {
1278 if (i2c_w1(gspca_dev, ov7670_init[i][0], 1291 if (i2c_w1(gspca_dev, ov7670_init[i].reg,
1279 ov7670_init[i][1]) < 0) { 1292 ov7670_init[i].val) < 0) {
1280 err("OV7670 sensor initialization failed"); 1293 err("OV7670 sensor initialization failed");
1281 return -ENODEV; 1294 return -ENODEV;
1282 } 1295 }
@@ -1299,8 +1312,8 @@ static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
1299 ret = i2c_r2(gspca_dev, 0xff, &value); 1312 ret = i2c_r2(gspca_dev, 0xff, &value);
1300 if ((ret == 0) && (value == 0x8243)) { 1313 if ((ret == 0) && (value == 0x8243)) {
1301 for (i = 0; i < ARRAY_SIZE(mt9v011_init); i++) { 1314 for (i = 0; i < ARRAY_SIZE(mt9v011_init); i++) {
1302 if (i2c_w2(gspca_dev, mt9v011_init[i][0], 1315 if (i2c_w2(gspca_dev, mt9v011_init[i].reg,
1303 mt9v011_init[i][1]) < 0) { 1316 mt9v011_init[i].val) < 0) {
1304 err("MT9V011 sensor initialization failed"); 1317 err("MT9V011 sensor initialization failed");
1305 return -ENODEV; 1318 return -ENODEV;
1306 } 1319 }
@@ -1317,8 +1330,8 @@ static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
1317 ret = i2c_r2(gspca_dev, 0xff, &value); 1330 ret = i2c_r2(gspca_dev, 0xff, &value);
1318 if ((ret == 0) && (value == 0x823a)) { 1331 if ((ret == 0) && (value == 0x823a)) {
1319 for (i = 0; i < ARRAY_SIZE(mt9v111_init); i++) { 1332 for (i = 0; i < ARRAY_SIZE(mt9v111_init); i++) {
1320 if (i2c_w2(gspca_dev, mt9v111_init[i][0], 1333 if (i2c_w2(gspca_dev, mt9v111_init[i].reg,
1321 mt9v111_init[i][1]) < 0) { 1334 mt9v111_init[i].val) < 0) {
1322 err("MT9V111 sensor initialization failed"); 1335 err("MT9V111 sensor initialization failed");
1323 return -ENODEV; 1336 return -ENODEV;
1324 } 1337 }
@@ -1339,8 +1352,8 @@ static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
1339 ret = i2c_r2(gspca_dev, 0x00, &value); 1352 ret = i2c_r2(gspca_dev, 0x00, &value);
1340 if ((ret == 0) && (value == 0x1229)) { 1353 if ((ret == 0) && (value == 0x1229)) {
1341 for (i = 0; i < ARRAY_SIZE(mt9v112_init); i++) { 1354 for (i = 0; i < ARRAY_SIZE(mt9v112_init); i++) {
1342 if (i2c_w2(gspca_dev, mt9v112_init[i][0], 1355 if (i2c_w2(gspca_dev, mt9v112_init[i].reg,
1343 mt9v112_init[i][1]) < 0) { 1356 mt9v112_init[i].val) < 0) {
1344 err("MT9V112 sensor initialization failed"); 1357 err("MT9V112 sensor initialization failed");
1345 return -ENODEV; 1358 return -ENODEV;
1346 } 1359 }
@@ -1360,12 +1373,13 @@ static int mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1360 struct sd *sd = (struct sd *) gspca_dev; 1373 struct sd *sd = (struct sd *) gspca_dev;
1361 int i; 1374 int i;
1362 for (i = 0; i < ARRAY_SIZE(mt9m111_init); i++) { 1375 for (i = 0; i < ARRAY_SIZE(mt9m111_init); i++) {
1363 if (i2c_w2(gspca_dev, mt9m111_init[i][0], 1376 if (i2c_w2(gspca_dev, mt9m111_init[i].reg,
1364 mt9m111_init[i][1]) < 0) { 1377 mt9m111_init[i].val) < 0) {
1365 err("MT9M111 sensor initialization failed"); 1378 err("MT9M111 sensor initialization failed");
1366 return -ENODEV; 1379 return -ENODEV;
1367 } 1380 }
1368 } 1381 }
1382 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX);
1369 sd->hstart = 0; 1383 sd->hstart = 0;
1370 sd->vstart = 2; 1384 sd->vstart = 2;
1371 return 0; 1385 return 0;
@@ -1376,8 +1390,8 @@ static int mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1376 struct sd *sd = (struct sd *) gspca_dev; 1390 struct sd *sd = (struct sd *) gspca_dev;
1377 int i; 1391 int i;
1378 for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) { 1392 for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) {
1379 if (i2c_w2(gspca_dev, mt9m001_init[i][0], 1393 if (i2c_w2(gspca_dev, mt9m001_init[i].reg,
1380 mt9m001_init[i][1]) < 0) { 1394 mt9m001_init[i].val) < 0) {
1381 err("MT9M001 sensor initialization failed"); 1395 err("MT9M001 sensor initialization failed");
1382 return -ENODEV; 1396 return -ENODEV;
1383 } 1397 }
@@ -1395,8 +1409,8 @@ static int hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1395 struct sd *sd = (struct sd *) gspca_dev; 1409 struct sd *sd = (struct sd *) gspca_dev;
1396 1410
1397 for (i = 0; i < ARRAY_SIZE(hv7131r_init); i++) { 1411 for (i = 0; i < ARRAY_SIZE(hv7131r_init); i++) {
1398 if (i2c_w1(gspca_dev, hv7131r_init[i][0], 1412 if (i2c_w1(gspca_dev, hv7131r_init[i].reg,
1399 hv7131r_init[i][1]) < 0) { 1413 hv7131r_init[i].val) < 0) {
1400 err("HV7131R Sensor initialization failed"); 1414 err("HV7131R Sensor initialization failed");
1401 return -ENODEV; 1415 return -ENODEV;
1402 } 1416 }
@@ -1620,7 +1634,6 @@ static int set_exposure(struct gspca_dev *gspca_dev)
1620 switch (sd->sensor) { 1634 switch (sd->sensor) {
1621 case SENSOR_OV7660: 1635 case SENSOR_OV7660:
1622 case SENSOR_OV7670: 1636 case SENSOR_OV7670:
1623 case SENSOR_SOI968:
1624 case SENSOR_OV9655: 1637 case SENSOR_OV9655:
1625 case SENSOR_OV9650: 1638 case SENSOR_OV9650:
1626 exp[0] |= (3 << 4); 1639 exp[0] |= (3 << 4);
@@ -1629,7 +1642,6 @@ static int set_exposure(struct gspca_dev *gspca_dev)
1629 exp[4] = sd->exposure >> 8; 1642 exp[4] = sd->exposure >> 8;
1630 break; 1643 break;
1631 case SENSOR_MT9M001: 1644 case SENSOR_MT9M001:
1632 case SENSOR_MT9M111:
1633 case SENSOR_MT9V112: 1645 case SENSOR_MT9V112:
1634 case SENSOR_MT9V111: 1646 case SENSOR_MT9V111:
1635 case SENSOR_MT9V011: 1647 case SENSOR_MT9V011:
@@ -1645,6 +1657,8 @@ static int set_exposure(struct gspca_dev *gspca_dev)
1645 exp[4] = ((sd->exposure * 0xffffff) / 0xffff) >> 8; 1657 exp[4] = ((sd->exposure * 0xffffff) / 0xffff) >> 8;
1646 exp[5] = ((sd->exposure * 0xffffff) / 0xffff) & 0xff; 1658 exp[5] = ((sd->exposure * 0xffffff) / 0xffff) & 0xff;
1647 break; 1659 break;
1660 default:
1661 return 0;
1648 } 1662 }
1649 i2c_w(gspca_dev, exp); 1663 i2c_w(gspca_dev, exp);
1650 return 0; 1664 return 0;
@@ -1671,7 +1685,6 @@ static int set_gain(struct gspca_dev *gspca_dev)
1671 gain[4] = micron1_gain[sd->gain] & 0xff; 1685 gain[4] = micron1_gain[sd->gain] & 0xff;
1672 break; 1686 break;
1673 case SENSOR_MT9V112: 1687 case SENSOR_MT9V112:
1674 case SENSOR_MT9M111:
1675 gain[0] |= (3 << 4); 1688 gain[0] |= (3 << 4);
1676 gain[2] = 0x2f; 1689 gain[2] = 0x2f;
1677 gain[3] = micron1_gain[sd->gain] >> 8; 1690 gain[3] = micron1_gain[sd->gain] >> 8;
@@ -1688,6 +1701,8 @@ static int set_gain(struct gspca_dev *gspca_dev)
1688 gain[2] = 0x30; 1701 gain[2] = 0x30;
1689 gain[3] = hv7131r_gain[sd->gain]; 1702 gain[3] = hv7131r_gain[sd->gain];
1690 break; 1703 break;
1704 default:
1705 return 0;
1691 } 1706 }
1692 i2c_w(gspca_dev, gain); 1707 i2c_w(gspca_dev, gain);
1693 return 0; 1708 return 0;
@@ -1990,7 +2005,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
1990 sd->i2c_addr = id->driver_info & 0xff; 2005 sd->i2c_addr = id->driver_info & 0xff;
1991 2006
1992 switch (sd->sensor) { 2007 switch (sd->sensor) {
2008 case SENSOR_MT9M111:
1993 case SENSOR_OV9650: 2009 case SENSOR_OV9650:
2010 case SENSOR_SOI968:
1994 cam->cam_mode = sxga_mode; 2011 cam->cam_mode = sxga_mode;
1995 cam->nmodes = ARRAY_SIZE(sxga_mode); 2012 cam->nmodes = ARRAY_SIZE(sxga_mode);
1996 break; 2013 break;
@@ -2106,6 +2123,25 @@ static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
2106 struct sd *sd = (struct sd *) gspca_dev; 2123 struct sd *sd = (struct sd *) gspca_dev;
2107 u8 value; 2124 u8 value;
2108 switch (sd->sensor) { 2125 switch (sd->sensor) {
2126 case SENSOR_SOI968:
2127 if (mode & MODE_SXGA) {
2128 i2c_w1(gspca_dev, 0x17, 0x1d);
2129 i2c_w1(gspca_dev, 0x18, 0xbd);
2130 i2c_w1(gspca_dev, 0x19, 0x01);
2131 i2c_w1(gspca_dev, 0x1a, 0x81);
2132 i2c_w1(gspca_dev, 0x12, 0x00);
2133 sd->hstart = 140;
2134 sd->vstart = 19;
2135 } else {
2136 i2c_w1(gspca_dev, 0x17, 0x13);
2137 i2c_w1(gspca_dev, 0x18, 0x63);
2138 i2c_w1(gspca_dev, 0x19, 0x01);
2139 i2c_w1(gspca_dev, 0x1a, 0x79);
2140 i2c_w1(gspca_dev, 0x12, 0x40);
2141 sd->hstart = 60;
2142 sd->vstart = 11;
2143 }
2144 break;
2109 case SENSOR_OV9650: 2145 case SENSOR_OV9650:
2110 if (mode & MODE_SXGA) { 2146 if (mode & MODE_SXGA) {
2111 i2c_w1(gspca_dev, 0x17, 0x1b); 2147 i2c_w1(gspca_dev, 0x17, 0x1b);
@@ -2123,6 +2159,17 @@ static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
2123 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40); 2159 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
2124 } 2160 }
2125 break; 2161 break;
2162 case SENSOR_MT9M111:
2163 if (mode & MODE_SXGA) {
2164 i2c_w2(gspca_dev, 0xf0, 0x0002);
2165 i2c_w2(gspca_dev, 0xc8, 0x970b);
2166 i2c_w2(gspca_dev, 0xf0, 0x0000);
2167 } else {
2168 i2c_w2(gspca_dev, 0xf0, 0x0002);
2169 i2c_w2(gspca_dev, 0xc8, 0x8000);
2170 i2c_w2(gspca_dev, 0xf0, 0x0000);
2171 }
2172 break;
2126 } 2173 }
2127} 2174}
2128 2175
@@ -2211,15 +2258,10 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
2211 kfree(sd->jpeg_hdr); 2258 kfree(sd->jpeg_hdr);
2212} 2259}
2213 2260
2214static void do_autoexposure(struct gspca_dev *gspca_dev) 2261static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2215{ 2262{
2216 struct sd *sd = (struct sd *) gspca_dev; 2263 struct sd *sd = (struct sd *) gspca_dev;
2217 int avg_lum, new_exp; 2264 s16 new_exp;
2218
2219 if (!sd->auto_exposure)
2220 return;
2221
2222 avg_lum = atomic_read(&sd->avg_lum);
2223 2265
2224 /* 2266 /*
2225 * some hardcoded values are present 2267 * some hardcoded values are present
@@ -2266,6 +2308,39 @@ static void do_autoexposure(struct gspca_dev *gspca_dev)
2266 } 2308 }
2267} 2309}
2268 2310
2311static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2312{
2313 struct sd *sd = (struct sd *) gspca_dev;
2314
2315 if (avg_lum < MIN_AVG_LUM) {
2316 if (sd->gain + 1 <= 28) {
2317 sd->gain++;
2318 set_gain(gspca_dev);
2319 }
2320 }
2321 if (avg_lum > MAX_AVG_LUM) {
2322 if (sd->gain - 1 >= 0) {
2323 sd->gain--;
2324 set_gain(gspca_dev);
2325 }
2326 }
2327}
2328
2329static void sd_dqcallback(struct gspca_dev *gspca_dev)
2330{
2331 struct sd *sd = (struct sd *) gspca_dev;
2332 int avg_lum;
2333
2334 if (!sd->auto_exposure)
2335 return;
2336
2337 avg_lum = atomic_read(&sd->avg_lum);
2338 if (sd->sensor == SENSOR_SOI968)
2339 do_autogain(gspca_dev, avg_lum);
2340 else
2341 do_autoexposure(gspca_dev, avg_lum);
2342}
2343
2269static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2344static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2270 struct gspca_frame *frame, /* target */ 2345 struct gspca_frame *frame, /* target */
2271 u8 *data, /* isoc packet */ 2346 u8 *data, /* isoc packet */
@@ -2333,7 +2408,7 @@ static const struct sd_desc sd_desc = {
2333 .stopN = sd_stopN, 2408 .stopN = sd_stopN,
2334 .stop0 = sd_stop0, 2409 .stop0 = sd_stop0,
2335 .pkt_scan = sd_pkt_scan, 2410 .pkt_scan = sd_pkt_scan,
2336 .dq_callback = do_autoexposure, 2411 .dq_callback = sd_dqcallback,
2337#ifdef CONFIG_VIDEO_ADV_DEBUG 2412#ifdef CONFIG_VIDEO_ADV_DEBUG
2338 .set_register = sd_dbg_s_register, 2413 .set_register = sd_dbg_s_register,
2339 .get_register = sd_dbg_g_register, 2414 .get_register = sd_dbg_g_register,
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index d6332ab80669..33f4d0a1f6fd 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -727,7 +727,7 @@ static const u8 ov7660_sensor_init[][8] = {
727 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, 727 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
728 /* Outformat = rawRGB */ 728 /* Outformat = rawRGB */
729 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */ 729 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
730 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10}, 730 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
731 /* GAIN BLUE RED VREF */ 731 /* GAIN BLUE RED VREF */
732 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10}, 732 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
733 /* COM 1 BAVE GEAVE AECHH */ 733 /* COM 1 BAVE GEAVE AECHH */
@@ -783,7 +783,7 @@ static const u8 ov7660_sensor_init[][8] = {
783 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ 783 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
784 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ 784 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
785 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */ 785 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
786 {0xb1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10}, 786 {0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
787/****** (some exchanges in the win trace) ******/ 787/****** (some exchanges in the win trace) ******/
788 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */ 788 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
789 /* bits[3..0]reserved */ 789 /* bits[3..0]reserved */
@@ -1145,17 +1145,12 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
1145 reg_w1(gspca_dev, 0x01, 0x42); 1145 reg_w1(gspca_dev, 0x01, 0x42);
1146 break; 1146 break;
1147 case SENSOR_OV7660: 1147 case SENSOR_OV7660:
1148 reg_w1(gspca_dev, 0x01, 0x61);
1149 reg_w1(gspca_dev, 0x17, 0x20);
1150 reg_w1(gspca_dev, 0x01, 0x60);
1151 reg_w1(gspca_dev, 0x01, 0x40);
1152 break;
1153 case SENSOR_SP80708: 1148 case SENSOR_SP80708:
1154 reg_w1(gspca_dev, 0x01, 0x63); 1149 reg_w1(gspca_dev, 0x01, 0x63);
1155 reg_w1(gspca_dev, 0x17, 0x20); 1150 reg_w1(gspca_dev, 0x17, 0x20);
1156 reg_w1(gspca_dev, 0x01, 0x62); 1151 reg_w1(gspca_dev, 0x01, 0x62);
1157 reg_w1(gspca_dev, 0x01, 0x42); 1152 reg_w1(gspca_dev, 0x01, 0x42);
1158 mdelay(100); 1153 msleep(100);
1159 reg_w1(gspca_dev, 0x02, 0x62); 1154 reg_w1(gspca_dev, 0x02, 0x62);
1160 break; 1155 break;
1161/* case SENSOR_HV7131R: */ 1156/* case SENSOR_HV7131R: */
@@ -1624,6 +1619,8 @@ static void setvflip(struct sd *sd)
1624 1619
1625static void setinfrared(struct sd *sd) 1620static void setinfrared(struct sd *sd)
1626{ 1621{
1622 if (sd->gspca_dev.ctrl_dis & (1 << INFRARED_IDX))
1623 return;
1627/*fixme: different sequence for StarCam Clip and StarCam 370i */ 1624/*fixme: different sequence for StarCam Clip and StarCam 370i */
1628/* Clip */ 1625/* Clip */
1629 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */ 1626 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
@@ -1637,16 +1634,19 @@ static void setfreq(struct gspca_dev *gspca_dev)
1637 if (gspca_dev->ctrl_dis & (1 << FREQ_IDX)) 1634 if (gspca_dev->ctrl_dis & (1 << FREQ_IDX))
1638 return; 1635 return;
1639 if (sd->sensor == SENSOR_OV7660) { 1636 if (sd->sensor == SENSOR_OV7660) {
1637 u8 com8;
1638
1639 com8 = 0xdf; /* auto gain/wb/expo */
1640 switch (sd->freq) { 1640 switch (sd->freq) {
1641 case 0: /* Banding filter disabled */ 1641 case 0: /* Banding filter disabled */
1642 i2c_w1(gspca_dev, 0x13, 0xdf); 1642 i2c_w1(gspca_dev, 0x13, com8 | 0x20);
1643 break; 1643 break;
1644 case 1: /* 50 hz */ 1644 case 1: /* 50 hz */
1645 i2c_w1(gspca_dev, 0x13, 0xff); 1645 i2c_w1(gspca_dev, 0x13, com8);
1646 i2c_w1(gspca_dev, 0x3b, 0x0a); 1646 i2c_w1(gspca_dev, 0x3b, 0x0a);
1647 break; 1647 break;
1648 case 2: /* 60 hz */ 1648 case 2: /* 60 hz */
1649 i2c_w1(gspca_dev, 0x13, 0xff); 1649 i2c_w1(gspca_dev, 0x13, com8);
1650 i2c_w1(gspca_dev, 0x3b, 0x02); 1650 i2c_w1(gspca_dev, 0x3b, 0x02);
1651 break; 1651 break;
1652 } 1652 }
@@ -1796,12 +1796,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
1796 reg_w1(gspca_dev, 0x99, 0x60); 1796 reg_w1(gspca_dev, 0x99, 0x60);
1797 break; 1797 break;
1798 case SENSOR_OV7660: 1798 case SENSOR_OV7660:
1799 reg_w1(gspca_dev, 0x9a, 0x05);
1800 if (sd->bridge == BRIDGE_SN9C105)
1801 reg_w1(gspca_dev, 0x99, 0xff);
1802 else
1803 reg_w1(gspca_dev, 0x99, 0x5b);
1804 break;
1805 case SENSOR_SP80708: 1799 case SENSOR_SP80708:
1806 reg_w1(gspca_dev, 0x9a, 0x05); 1800 reg_w1(gspca_dev, 0x9a, 0x05);
1807 reg_w1(gspca_dev, 0x99, 0x59); 1801 reg_w1(gspca_dev, 0x99, 0x59);
@@ -2325,18 +2319,19 @@ static const __devinitdata struct usb_device_id device_table[] = {
2325 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)}, 2319 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
2326/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */ 2320/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
2327 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)}, 2321 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
2328/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */ 2322/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6802, 0x??)}, */
2329/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */ 2323/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
2330 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)}, 2324 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
2331/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */ 2325/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
2332/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */ 2326/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
2333 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)}, 2327 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
2334 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
2335#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 2328#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2329 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
2336 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)}, 2330 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
2337#endif 2331#endif
2338 {USB_DEVICE(0x0c45, 0x6100), BSI(SN9C120, MI0360, 0x5d)}, /*sn9c128*/ 2332 {USB_DEVICE(0x0c45, 0x6100), BSI(SN9C120, MI0360, 0x5d)}, /*sn9c128*/
2339/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */ 2333/* {USB_DEVICE(0x0c45, 0x6102), BSI(SN9C120, PO2030N, ??)}, */
2334/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6802, 0x21)}, */
2340 {USB_DEVICE(0x0c45, 0x610a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c128*/ 2335 {USB_DEVICE(0x0c45, 0x610a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c128*/
2341 {USB_DEVICE(0x0c45, 0x610b), BSI(SN9C120, OV7660, 0x21)}, /*sn9c128*/ 2336 {USB_DEVICE(0x0c45, 0x610b), BSI(SN9C120, OV7660, 0x21)}, /*sn9c128*/
2342 {USB_DEVICE(0x0c45, 0x610c), BSI(SN9C120, HV7131R, 0x11)}, /*sn9c128*/ 2337 {USB_DEVICE(0x0c45, 0x610c), BSI(SN9C120, HV7131R, 0x11)}, /*sn9c128*/
@@ -2352,6 +2347,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
2352#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 2347#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2353 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)}, 2348 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
2354#endif 2349#endif
2350/* {USB_DEVICE(0x0c45, 0x6132), BSI(SN9C120, OV7670, 0x21)}, */
2355 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)}, 2351 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
2356 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)}, 2352 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
2357#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE 2353#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
@@ -2359,7 +2355,9 @@ static const __devinitdata struct usb_device_id device_table[] = {
2359#endif 2355#endif
2360 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)}, 2356 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
2361 {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x21)}, 2357 {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x21)},
2362 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)}, 2358/* {USB_DEVICE(0x0c45, 0x6142), BSI(SN9C120, PO2030N, ??)}, *sn9c120b*/
2359 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)}, /*sn9c120b*/
2360 {USB_DEVICE(0x0c45, 0x6148), BSI(SN9C120, OM6802, 0x21)}, /*sn9c120b*/
2363 {} 2361 {}
2364}; 2362};
2365MODULE_DEVICE_TABLE(usb, device_table); 2363MODULE_DEVICE_TABLE(usb, device_table);
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
index d48b27c648ca..b74a34218da0 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/video/gspca/spca501.c
@@ -1923,7 +1923,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
1923 1923
1924 cam = &gspca_dev->cam; 1924 cam = &gspca_dev->cam;
1925 cam->cam_mode = vga_mode; 1925 cam->cam_mode = vga_mode;
1926 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; 1926 cam->nmodes = ARRAY_SIZE(vga_mode);
1927 sd->subtype = id->driver_info; 1927 sd->subtype = id->driver_info;
1928 sd->brightness = sd_ctrls[MY_BRIGHTNESS].qctrl.default_value; 1928 sd->brightness = sd_ctrls[MY_BRIGHTNESS].qctrl.default_value;
1929 sd->contrast = sd_ctrls[MY_CONTRAST].qctrl.default_value; 1929 sd->contrast = sd_ctrls[MY_CONTRAST].qctrl.default_value;
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index 3a0c893f942d..a199298a6419 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -286,7 +286,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
286 286
287 cam = &gspca_dev->cam; 287 cam = &gspca_dev->cam;
288 cam->cam_mode = vga_mode; 288 cam->cam_mode = vga_mode;
289 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; 289 cam->nmodes = ARRAY_SIZE(vga_mode);
290 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; 290 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
291 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; 291 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
292 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; 292 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index 2ed2669bac3e..9696c4caf5c9 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -1304,19 +1304,70 @@ static int reg_read(struct gspca_dev *gspca_dev,
1304 return gspca_dev->usb_buf[0]; 1304 return gspca_dev->usb_buf[0];
1305} 1305}
1306 1306
1307/* send 1 or 2 bytes to the sensor via the Synchronous Serial Interface */
1308static int ssi_w(struct gspca_dev *gspca_dev,
1309 u16 reg, u16 val)
1310{
1311 struct usb_device *dev = gspca_dev->dev;
1312 int ret, retry;
1313
1314 ret = reg_write(dev, 0x8802, reg >> 8);
1315 if (ret < 0)
1316 goto out;
1317 ret = reg_write(dev, 0x8801, reg & 0x00ff);
1318 if (ret < 0)
1319 goto out;
1320 if ((reg & 0xff00) == 0x1000) { /* if 2 bytes */
1321 ret = reg_write(dev, 0x8805, val & 0x00ff);
1322 if (ret < 0)
1323 goto out;
1324 val >>= 8;
1325 }
1326 ret = reg_write(dev, 0x8800, val);
1327 if (ret < 0)
1328 goto out;
1329
1330 /* poll until not busy */
1331 retry = 10;
1332 for (;;) {
1333 ret = reg_read(gspca_dev, 0x8803);
1334 if (ret < 0)
1335 break;
1336 if (gspca_dev->usb_buf[0] == 0)
1337 break;
1338 if (--retry <= 0) {
1339 PDEBUG(D_ERR, "ssi_w busy %02x",
1340 gspca_dev->usb_buf[0]);
1341 ret = -1;
1342 break;
1343 }
1344 msleep(8);
1345 }
1346
1347out:
1348 return ret;
1349}
1350
1307static int write_vector(struct gspca_dev *gspca_dev, 1351static int write_vector(struct gspca_dev *gspca_dev,
1308 const u16 (*data)[2]) 1352 const u16 (*data)[2])
1309{ 1353{
1310 struct usb_device *dev = gspca_dev->dev; 1354 struct usb_device *dev = gspca_dev->dev;
1311 int ret; 1355 int ret = 0;
1312 1356
1313 while ((*data)[1] != 0) { 1357 while ((*data)[1] != 0) {
1314 ret = reg_write(dev, (*data)[1], (*data)[0]); 1358 if ((*data)[1] & 0x8000) {
1359 if ((*data)[1] == 0xdd00) /* delay */
1360 msleep((*data)[0]);
1361 else
1362 ret = reg_write(dev, (*data)[1], (*data)[0]);
1363 } else {
1364 ret = ssi_w(gspca_dev, (*data)[1], (*data)[0]);
1365 }
1315 if (ret < 0) 1366 if (ret < 0)
1316 return ret; 1367 break;
1317 data++; 1368 data++;
1318 } 1369 }
1319 return 0; 1370 return ret;
1320} 1371}
1321 1372
1322/* this function is called at probe time */ 1373/* this function is called at probe time */
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index 0da8e0de0456..7af511b5e9c2 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -130,8 +130,8 @@ int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len)
130 STV06XX_URB_MSG_TIMEOUT); 130 STV06XX_URB_MSG_TIMEOUT);
131 if (err < 0) 131 if (err < 0)
132 return err; 132 return err;
133 } 133 }
134 return stv06xx_write_sensor_finish(sd); 134 return stv06xx_write_sensor_finish(sd);
135} 135}
136 136
137int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len) 137int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len)
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index 5127bbf9dd26..aa8f995ce04e 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -32,26 +32,27 @@ MODULE_LICENSE("GPL");
32struct sd { 32struct sd {
33 struct gspca_dev gspca_dev; /* !! must be the first item */ 33 struct gspca_dev gspca_dev; /* !! must be the first item */
34 34
35 unsigned char brightness; 35 s8 brightness;
36 unsigned char contrast; 36 u8 contrast;
37 unsigned char colors; 37 u8 colors;
38 unsigned char autogain; 38 u8 autogain;
39 u8 quality; 39 u8 quality;
40#define QUALITY_MIN 70 40#define QUALITY_MIN 70
41#define QUALITY_MAX 95 41#define QUALITY_MAX 95
42#define QUALITY_DEF 85 42#define QUALITY_DEF 85
43 43
44 char bridge; 44 u8 bridge;
45#define BRIDGE_SPCA504 0 45#define BRIDGE_SPCA504 0
46#define BRIDGE_SPCA504B 1 46#define BRIDGE_SPCA504B 1
47#define BRIDGE_SPCA504C 2 47#define BRIDGE_SPCA504C 2
48#define BRIDGE_SPCA533 3 48#define BRIDGE_SPCA533 3
49#define BRIDGE_SPCA536 4 49#define BRIDGE_SPCA536 4
50 char subtype; 50 u8 subtype;
51#define AiptekMiniPenCam13 1 51#define AiptekMiniPenCam13 1
52#define LogitechClickSmart420 2 52#define LogitechClickSmart420 2
53#define LogitechClickSmart820 3 53#define LogitechClickSmart820 3
54#define MegapixV4 4 54#define MegapixV4 4
55#define MegaImageVI 5
55 56
56 u8 *jpeg_hdr; 57 u8 *jpeg_hdr;
57}; 58};
@@ -67,21 +68,20 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
67static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 68static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
68 69
69static struct ctrl sd_ctrls[] = { 70static struct ctrl sd_ctrls[] = {
70#define SD_BRIGHTNESS 0
71 { 71 {
72 { 72 {
73 .id = V4L2_CID_BRIGHTNESS, 73 .id = V4L2_CID_BRIGHTNESS,
74 .type = V4L2_CTRL_TYPE_INTEGER, 74 .type = V4L2_CTRL_TYPE_INTEGER,
75 .name = "Brightness", 75 .name = "Brightness",
76 .minimum = 0, 76 .minimum = -128,
77 .maximum = 0xff, 77 .maximum = 127,
78 .step = 1, 78 .step = 1,
79 .default_value = 0, 79#define BRIGHTNESS_DEF 0
80 .default_value = BRIGHTNESS_DEF,
80 }, 81 },
81 .set = sd_setbrightness, 82 .set = sd_setbrightness,
82 .get = sd_getbrightness, 83 .get = sd_getbrightness,
83 }, 84 },
84#define SD_CONTRAST 1
85 { 85 {
86 { 86 {
87 .id = V4L2_CID_CONTRAST, 87 .id = V4L2_CID_CONTRAST,
@@ -90,12 +90,12 @@ static struct ctrl sd_ctrls[] = {
90 .minimum = 0, 90 .minimum = 0,
91 .maximum = 0xff, 91 .maximum = 0xff,
92 .step = 1, 92 .step = 1,
93 .default_value = 0x20, 93#define CONTRAST_DEF 0x20
94 .default_value = CONTRAST_DEF,
94 }, 95 },
95 .set = sd_setcontrast, 96 .set = sd_setcontrast,
96 .get = sd_getcontrast, 97 .get = sd_getcontrast,
97 }, 98 },
98#define SD_COLOR 2
99 { 99 {
100 { 100 {
101 .id = V4L2_CID_SATURATION, 101 .id = V4L2_CID_SATURATION,
@@ -104,12 +104,12 @@ static struct ctrl sd_ctrls[] = {
104 .minimum = 0, 104 .minimum = 0,
105 .maximum = 0xff, 105 .maximum = 0xff,
106 .step = 1, 106 .step = 1,
107 .default_value = 0x1a, 107#define COLOR_DEF 0x1a
108 .default_value = COLOR_DEF,
108 }, 109 },
109 .set = sd_setcolors, 110 .set = sd_setcolors,
110 .get = sd_getcolors, 111 .get = sd_getcolors,
111 }, 112 },
112#define SD_AUTOGAIN 3
113 { 113 {
114 { 114 {
115 .id = V4L2_CID_AUTOGAIN, 115 .id = V4L2_CID_AUTOGAIN,
@@ -118,7 +118,8 @@ static struct ctrl sd_ctrls[] = {
118 .minimum = 0, 118 .minimum = 0,
119 .maximum = 1, 119 .maximum = 1,
120 .step = 1, 120 .step = 1,
121 .default_value = 1, 121#define AUTOGAIN_DEF 1
122 .default_value = AUTOGAIN_DEF,
122 }, 123 },
123 .set = sd_setautogain, 124 .set = sd_setautogain,
124 .get = sd_getautogain, 125 .get = sd_getautogain,
@@ -180,14 +181,20 @@ static const struct v4l2_pix_format vga_mode2[] = {
180#define SPCA504_PCCAM600_OFFSET_MODE 5 181#define SPCA504_PCCAM600_OFFSET_MODE 5
181#define SPCA504_PCCAM600_OFFSET_DATA 14 182#define SPCA504_PCCAM600_OFFSET_DATA 14
182 /* Frame packet header offsets for the spca533 */ 183 /* Frame packet header offsets for the spca533 */
183#define SPCA533_OFFSET_DATA 16 184#define SPCA533_OFFSET_DATA 16
184#define SPCA533_OFFSET_FRAMSEQ 15 185#define SPCA533_OFFSET_FRAMSEQ 15
185/* Frame packet header offsets for the spca536 */ 186/* Frame packet header offsets for the spca536 */
186#define SPCA536_OFFSET_DATA 4 187#define SPCA536_OFFSET_DATA 4
187#define SPCA536_OFFSET_FRAMSEQ 1 188#define SPCA536_OFFSET_FRAMSEQ 1
189
190struct cmd {
191 u8 req;
192 u16 val;
193 u16 idx;
194};
188 195
189/* Initialisation data for the Creative PC-CAM 600 */ 196/* Initialisation data for the Creative PC-CAM 600 */
190static const __u16 spca504_pccam600_init_data[][3] = { 197static const struct cmd spca504_pccam600_init_data[] = {
191/* {0xa0, 0x0000, 0x0503}, * capture mode */ 198/* {0xa0, 0x0000, 0x0503}, * capture mode */
192 {0x00, 0x0000, 0x2000}, 199 {0x00, 0x0000, 0x2000},
193 {0x00, 0x0013, 0x2301}, 200 {0x00, 0x0013, 0x2301},
@@ -211,22 +218,20 @@ static const __u16 spca504_pccam600_init_data[][3] = {
211 {0x00, 0x0003, 0x2000}, 218 {0x00, 0x0003, 0x2000},
212 {0x00, 0x0013, 0x2301}, 219 {0x00, 0x0013, 0x2301},
213 {0x00, 0x0003, 0x2000}, 220 {0x00, 0x0003, 0x2000},
214 {}
215}; 221};
216 222
217/* Creative PC-CAM 600 specific open data, sent before using the 223/* Creative PC-CAM 600 specific open data, sent before using the
218 * generic initialisation data from spca504_open_data. 224 * generic initialisation data from spca504_open_data.
219 */ 225 */
220static const __u16 spca504_pccam600_open_data[][3] = { 226static const struct cmd spca504_pccam600_open_data[] = {
221 {0x00, 0x0001, 0x2501}, 227 {0x00, 0x0001, 0x2501},
222 {0x20, 0x0500, 0x0001}, /* snapshot mode */ 228 {0x20, 0x0500, 0x0001}, /* snapshot mode */
223 {0x00, 0x0003, 0x2880}, 229 {0x00, 0x0003, 0x2880},
224 {0x00, 0x0001, 0x2881}, 230 {0x00, 0x0001, 0x2881},
225 {}
226}; 231};
227 232
228/* Initialisation data for the logitech clicksmart 420 */ 233/* Initialisation data for the logitech clicksmart 420 */
229static const __u16 spca504A_clicksmart420_init_data[][3] = { 234static const struct cmd spca504A_clicksmart420_init_data[] = {
230/* {0xa0, 0x0000, 0x0503}, * capture mode */ 235/* {0xa0, 0x0000, 0x0503}, * capture mode */
231 {0x00, 0x0000, 0x2000}, 236 {0x00, 0x0000, 0x2000},
232 {0x00, 0x0013, 0x2301}, 237 {0x00, 0x0013, 0x2301},
@@ -243,7 +248,7 @@ static const __u16 spca504A_clicksmart420_init_data[][3] = {
243 {0xb0, 0x0001, 0x0000}, 248 {0xb0, 0x0001, 0x0000},
244 249
245 250
246 {0x0a1, 0x0080, 0x0001}, 251 {0xa1, 0x0080, 0x0001},
247 {0x30, 0x0049, 0x0000}, 252 {0x30, 0x0049, 0x0000},
248 {0x30, 0x0060, 0x0005}, 253 {0x30, 0x0060, 0x0005},
249 {0x0c, 0x0004, 0x0000}, 254 {0x0c, 0x0004, 0x0000},
@@ -253,11 +258,10 @@ static const __u16 spca504A_clicksmart420_init_data[][3] = {
253 {0x00, 0x0003, 0x2000}, 258 {0x00, 0x0003, 0x2000},
254 {0x00, 0x0000, 0x2000}, 259 {0x00, 0x0000, 0x2000},
255 260
256 {}
257}; 261};
258 262
259/* clicksmart 420 open data ? */ 263/* clicksmart 420 open data ? */
260static const __u16 spca504A_clicksmart420_open_data[][3] = { 264static const struct cmd spca504A_clicksmart420_open_data[] = {
261 {0x00, 0x0001, 0x2501}, 265 {0x00, 0x0001, 0x2501},
262 {0x20, 0x0502, 0x0000}, 266 {0x20, 0x0502, 0x0000},
263 {0x06, 0x0000, 0x0000}, 267 {0x06, 0x0000, 0x0000},
@@ -401,10 +405,9 @@ static const __u16 spca504A_clicksmart420_open_data[][3] = {
401 {0x00, 0x0028, 0x287f}, 405 {0x00, 0x0028, 0x287f},
402 406
403 {0xa0, 0x0000, 0x0503}, 407 {0xa0, 0x0000, 0x0503},
404 {}
405}; 408};
406 409
407static const __u8 qtable_creative_pccam[2][64] = { 410static const u8 qtable_creative_pccam[2][64] = {
408 { /* Q-table Y-components */ 411 { /* Q-table Y-components */
409 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12, 412 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
410 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11, 413 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
@@ -429,7 +432,7 @@ static const __u8 qtable_creative_pccam[2][64] = {
429 * except for one byte. Possibly a typo? 432 * except for one byte. Possibly a typo?
430 * NWG: 18/05/2003. 433 * NWG: 18/05/2003.
431 */ 434 */
432static const __u8 qtable_spca504_default[2][64] = { 435static const u8 qtable_spca504_default[2][64] = {
433 { /* Q-table Y-components */ 436 { /* Q-table Y-components */
434 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12, 437 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
435 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11, 438 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
@@ -453,9 +456,9 @@ static const __u8 qtable_spca504_default[2][64] = {
453 456
454/* read <len> bytes to gspca_dev->usb_buf */ 457/* read <len> bytes to gspca_dev->usb_buf */
455static void reg_r(struct gspca_dev *gspca_dev, 458static void reg_r(struct gspca_dev *gspca_dev,
456 __u16 req, 459 u8 req,
457 __u16 index, 460 u16 index,
458 __u16 len) 461 u16 len)
459{ 462{
460#ifdef GSPCA_DEBUG 463#ifdef GSPCA_DEBUG
461 if (len > USB_BUF_SZ) { 464 if (len > USB_BUF_SZ) {
@@ -473,31 +476,26 @@ static void reg_r(struct gspca_dev *gspca_dev,
473 500); 476 500);
474} 477}
475 478
476/* write <len> bytes from gspca_dev->usb_buf */ 479/* write one byte */
477static void reg_w(struct gspca_dev *gspca_dev, 480static void reg_w_1(struct gspca_dev *gspca_dev,
478 __u16 req, 481 u8 req,
479 __u16 value, 482 u16 value,
480 __u16 index, 483 u16 index,
481 __u16 len) 484 u16 byte)
482{ 485{
483#ifdef GSPCA_DEBUG 486 gspca_dev->usb_buf[0] = byte;
484 if (len > USB_BUF_SZ) {
485 err("reg_w: buffer overflow");
486 return;
487 }
488#endif
489 usb_control_msg(gspca_dev->dev, 487 usb_control_msg(gspca_dev->dev,
490 usb_sndctrlpipe(gspca_dev->dev, 0), 488 usb_sndctrlpipe(gspca_dev->dev, 0),
491 req, 489 req,
492 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 490 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
493 value, index, 491 value, index,
494 len ? gspca_dev->usb_buf : NULL, len, 492 gspca_dev->usb_buf, 1,
495 500); 493 500);
496} 494}
497 495
498/* write req / index / value */ 496/* write req / index / value */
499static int reg_w_riv(struct usb_device *dev, 497static int reg_w_riv(struct usb_device *dev,
500 __u16 req, __u16 index, __u16 value) 498 u8 req, u16 index, u16 value)
501{ 499{
502 int ret; 500 int ret;
503 501
@@ -515,7 +513,7 @@ static int reg_w_riv(struct usb_device *dev,
515 513
516/* read 1 byte */ 514/* read 1 byte */
517static int reg_r_1(struct gspca_dev *gspca_dev, 515static int reg_r_1(struct gspca_dev *gspca_dev,
518 __u16 value) /* wValue */ 516 u16 value) /* wValue */
519{ 517{
520 int ret; 518 int ret;
521 519
@@ -536,9 +534,9 @@ static int reg_r_1(struct gspca_dev *gspca_dev,
536 534
537/* read 1 or 2 bytes - returns < 0 if error */ 535/* read 1 or 2 bytes - returns < 0 if error */
538static int reg_r_12(struct gspca_dev *gspca_dev, 536static int reg_r_12(struct gspca_dev *gspca_dev,
539 __u16 req, /* bRequest */ 537 u8 req, /* bRequest */
540 __u16 index, /* wIndex */ 538 u16 index, /* wIndex */
541 __u16 length) /* wLength (1 or 2 only) */ 539 u16 length) /* wLength (1 or 2 only) */
542{ 540{
543 int ret; 541 int ret;
544 542
@@ -559,43 +557,40 @@ static int reg_r_12(struct gspca_dev *gspca_dev,
559} 557}
560 558
561static int write_vector(struct gspca_dev *gspca_dev, 559static int write_vector(struct gspca_dev *gspca_dev,
562 const __u16 data[][3]) 560 const struct cmd *data, int ncmds)
563{ 561{
564 struct usb_device *dev = gspca_dev->dev; 562 struct usb_device *dev = gspca_dev->dev;
565 int ret, i = 0; 563 int ret;
566 564
567 while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { 565 while (--ncmds >= 0) {
568 ret = reg_w_riv(dev, data[i][0], data[i][2], data[i][1]); 566 ret = reg_w_riv(dev, data->req, data->idx, data->val);
569 if (ret < 0) { 567 if (ret < 0) {
570 PDEBUG(D_ERR, 568 PDEBUG(D_ERR,
571 "Register write failed for 0x%x,0x%x,0x%x", 569 "Register write failed for 0x%02x, 0x%04x, 0x%04x",
572 data[i][0], data[i][1], data[i][2]); 570 data->req, data->val, data->idx);
573 return ret; 571 return ret;
574 } 572 }
575 i++; 573 data++;
576 } 574 }
577 return 0; 575 return 0;
578} 576}
579 577
580static int spca50x_setup_qtable(struct gspca_dev *gspca_dev, 578static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
581 unsigned int request, 579 const u8 qtable[2][64])
582 unsigned int ybase,
583 unsigned int cbase,
584 const __u8 qtable[2][64])
585{ 580{
586 struct usb_device *dev = gspca_dev->dev; 581 struct usb_device *dev = gspca_dev->dev;
587 int i, err; 582 int i, err;
588 583
589 /* loop over y components */ 584 /* loop over y components */
590 for (i = 0; i < 64; i++) { 585 for (i = 0; i < 64; i++) {
591 err = reg_w_riv(dev, request, ybase + i, qtable[0][i]); 586 err = reg_w_riv(dev, 0x00, 0x2800 + i, qtable[0][i]);
592 if (err < 0) 587 if (err < 0)
593 return err; 588 return err;
594 } 589 }
595 590
596 /* loop over c components */ 591 /* loop over c components */
597 for (i = 0; i < 64; i++) { 592 for (i = 0; i < 64; i++) {
598 err = reg_w_riv(dev, request, cbase + i, qtable[1][i]); 593 err = reg_w_riv(dev, 0x00, 0x2840 + i, qtable[1][i]);
599 if (err < 0) 594 if (err < 0)
600 return err; 595 return err;
601 } 596 }
@@ -603,34 +598,34 @@ static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
603} 598}
604 599
605static void spca504_acknowledged_command(struct gspca_dev *gspca_dev, 600static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
606 __u16 req, __u16 idx, __u16 val) 601 u8 req, u16 idx, u16 val)
607{ 602{
608 struct usb_device *dev = gspca_dev->dev; 603 struct usb_device *dev = gspca_dev->dev;
609 __u8 notdone; 604 int notdone;
610 605
611 reg_w_riv(dev, req, idx, val); 606 reg_w_riv(dev, req, idx, val);
612 notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1); 607 notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
613 reg_w_riv(dev, req, idx, val); 608 reg_w_riv(dev, req, idx, val);
614 609
615 PDEBUG(D_FRAM, "before wait 0x%x", notdone); 610 PDEBUG(D_FRAM, "before wait 0x%04x", notdone);
616 611
617 msleep(200); 612 msleep(200);
618 notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1); 613 notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
619 PDEBUG(D_FRAM, "after wait 0x%x", notdone); 614 PDEBUG(D_FRAM, "after wait 0x%04x", notdone);
620} 615}
621 616
622static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev, 617static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
623 __u16 req, 618 u8 req,
624 __u16 idx, __u16 val, __u8 stat, __u8 count) 619 u16 idx, u16 val, u8 stat, u8 count)
625{ 620{
626 struct usb_device *dev = gspca_dev->dev; 621 struct usb_device *dev = gspca_dev->dev;
627 __u8 status; 622 int status;
628 __u8 endcode; 623 u8 endcode;
629 624
630 reg_w_riv(dev, req, idx, val); 625 reg_w_riv(dev, req, idx, val);
631 status = reg_r_12(gspca_dev, 0x01, 0x0001, 1); 626 status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
632 endcode = stat; 627 endcode = stat;
633 PDEBUG(D_FRAM, "Status 0x%x Need 0x%x", status, stat); 628 PDEBUG(D_FRAM, "Status 0x%x Need 0x%04x", status, stat);
634 if (!count) 629 if (!count)
635 return; 630 return;
636 count = 200; 631 count = 200;
@@ -640,7 +635,7 @@ static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
640/* reg_w_riv(dev, req, idx, val); */ 635/* reg_w_riv(dev, req, idx, val); */
641 status = reg_r_12(gspca_dev, 0x01, 0x0001, 1); 636 status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
642 if (status == endcode) { 637 if (status == endcode) {
643 PDEBUG(D_FRAM, "status 0x%x after wait 0x%x", 638 PDEBUG(D_FRAM, "status 0x%04x after wait %d",
644 status, 200 - count); 639 status, 200 - count);
645 break; 640 break;
646 } 641 }
@@ -667,8 +662,7 @@ static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
667 while (--count > 0) { 662 while (--count > 0) {
668 reg_r(gspca_dev, 0x21, 1, 1); 663 reg_r(gspca_dev, 0x21, 1, 1);
669 if (gspca_dev->usb_buf[0] != 0) { 664 if (gspca_dev->usb_buf[0] != 0) {
670 gspca_dev->usb_buf[0] = 0; 665 reg_w_1(gspca_dev, 0x21, 0, 1, 0);
671 reg_w(gspca_dev, 0x21, 0, 1, 1);
672 reg_r(gspca_dev, 0x21, 1, 1); 666 reg_r(gspca_dev, 0x21, 1, 1);
673 spca504B_PollingDataReady(gspca_dev); 667 spca504B_PollingDataReady(gspca_dev);
674 break; 668 break;
@@ -679,7 +673,7 @@ static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
679 673
680static void spca50x_GetFirmware(struct gspca_dev *gspca_dev) 674static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
681{ 675{
682 __u8 *data; 676 u8 *data;
683 677
684 data = gspca_dev->usb_buf; 678 data = gspca_dev->usb_buf;
685 reg_r(gspca_dev, 0x20, 0, 5); 679 reg_r(gspca_dev, 0x20, 0, 5);
@@ -693,41 +687,34 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
693{ 687{
694 struct sd *sd = (struct sd *) gspca_dev; 688 struct sd *sd = (struct sd *) gspca_dev;
695 struct usb_device *dev = gspca_dev->dev; 689 struct usb_device *dev = gspca_dev->dev;
696 __u8 Size; 690 u8 Size;
697 __u8 Type;
698 int rc; 691 int rc;
699 692
700 Size = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 693 Size = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
701 Type = 0;
702 switch (sd->bridge) { 694 switch (sd->bridge) {
703 case BRIDGE_SPCA533: 695 case BRIDGE_SPCA533:
704 reg_w(gspca_dev, 0x31, 0, 0, 0); 696 reg_w_riv(dev, 0x31, 0, 0);
705 spca504B_WaitCmdStatus(gspca_dev); 697 spca504B_WaitCmdStatus(gspca_dev);
706 rc = spca504B_PollingDataReady(gspca_dev); 698 rc = spca504B_PollingDataReady(gspca_dev);
707 spca50x_GetFirmware(gspca_dev); 699 spca50x_GetFirmware(gspca_dev);
708 gspca_dev->usb_buf[0] = 2; /* type */ 700 reg_w_1(gspca_dev, 0x24, 0, 8, 2); /* type */
709 reg_w(gspca_dev, 0x24, 0, 8, 1);
710 reg_r(gspca_dev, 0x24, 8, 1); 701 reg_r(gspca_dev, 0x24, 8, 1);
711 702
712 gspca_dev->usb_buf[0] = Size; 703 reg_w_1(gspca_dev, 0x25, 0, 4, Size);
713 reg_w(gspca_dev, 0x25, 0, 4, 1);
714 reg_r(gspca_dev, 0x25, 4, 1); /* size */ 704 reg_r(gspca_dev, 0x25, 4, 1); /* size */
715 rc = spca504B_PollingDataReady(gspca_dev); 705 rc = spca504B_PollingDataReady(gspca_dev);
716 706
717 /* Init the cam width height with some values get on init ? */ 707 /* Init the cam width height with some values get on init ? */
718 reg_w(gspca_dev, 0x31, 0, 4, 0); 708 reg_w_riv(dev, 0x31, 0, 0x04);
719 spca504B_WaitCmdStatus(gspca_dev); 709 spca504B_WaitCmdStatus(gspca_dev);
720 rc = spca504B_PollingDataReady(gspca_dev); 710 rc = spca504B_PollingDataReady(gspca_dev);
721 break; 711 break;
722 default: 712 default:
723/* case BRIDGE_SPCA504B: */ 713/* case BRIDGE_SPCA504B: */
724/* case BRIDGE_SPCA536: */ 714/* case BRIDGE_SPCA536: */
725 gspca_dev->usb_buf[0] = Size; 715 reg_w_1(gspca_dev, 0x25, 0, 4, Size);
726 reg_w(gspca_dev, 0x25, 0, 4, 1);
727 reg_r(gspca_dev, 0x25, 4, 1); /* size */ 716 reg_r(gspca_dev, 0x25, 4, 1); /* size */
728 Type = 6; 717 reg_w_1(gspca_dev, 0x27, 0, 0, 6);
729 gspca_dev->usb_buf[0] = Type;
730 reg_w(gspca_dev, 0x27, 0, 0, 1);
731 reg_r(gspca_dev, 0x27, 0, 1); /* type */ 718 reg_r(gspca_dev, 0x27, 0, 1); /* type */
732 rc = spca504B_PollingDataReady(gspca_dev); 719 rc = spca504B_PollingDataReady(gspca_dev);
733 break; 720 break;
@@ -767,17 +754,51 @@ static void spca504_wait_status(struct gspca_dev *gspca_dev)
767 754
768static void spca504B_setQtable(struct gspca_dev *gspca_dev) 755static void spca504B_setQtable(struct gspca_dev *gspca_dev)
769{ 756{
770 gspca_dev->usb_buf[0] = 3; 757 reg_w_1(gspca_dev, 0x26, 0, 0, 3);
771 reg_w(gspca_dev, 0x26, 0, 0, 1);
772 reg_r(gspca_dev, 0x26, 0, 1); 758 reg_r(gspca_dev, 0x26, 0, 1);
773 spca504B_PollingDataReady(gspca_dev); 759 spca504B_PollingDataReady(gspca_dev);
774} 760}
775 761
776static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev) 762static void setbrightness(struct gspca_dev *gspca_dev)
763{
764 struct sd *sd = (struct sd *) gspca_dev;
765 struct usb_device *dev = gspca_dev->dev;
766 u16 reg;
767
768 reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7;
769 reg_w_riv(dev, 0x00, reg, sd->brightness);
770}
771
772static void setcontrast(struct gspca_dev *gspca_dev)
773{
774 struct sd *sd = (struct sd *) gspca_dev;
775 struct usb_device *dev = gspca_dev->dev;
776 u16 reg;
777
778 reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8;
779 reg_w_riv(dev, 0x00, reg, sd->contrast);
780}
781
782static void setcolors(struct gspca_dev *gspca_dev)
783{
784 struct sd *sd = (struct sd *) gspca_dev;
785 struct usb_device *dev = gspca_dev->dev;
786 u16 reg;
787
788 reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae;
789 reg_w_riv(dev, 0x00, reg, sd->colors);
790}
791
792static void init_ctl_reg(struct gspca_dev *gspca_dev)
777{ 793{
778 struct sd *sd = (struct sd *) gspca_dev; 794 struct sd *sd = (struct sd *) gspca_dev;
795 struct usb_device *dev = gspca_dev->dev;
779 int pollreg = 1; 796 int pollreg = 1;
780 797
798 setbrightness(gspca_dev);
799 setcontrast(gspca_dev);
800 setcolors(gspca_dev);
801
781 switch (sd->bridge) { 802 switch (sd->bridge) {
782 case BRIDGE_SPCA504: 803 case BRIDGE_SPCA504:
783 case BRIDGE_SPCA504C: 804 case BRIDGE_SPCA504C:
@@ -786,20 +807,14 @@ static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev)
786 default: 807 default:
787/* case BRIDGE_SPCA533: */ 808/* case BRIDGE_SPCA533: */
788/* case BRIDGE_SPCA504B: */ 809/* case BRIDGE_SPCA504B: */
789 reg_w(gspca_dev, 0, 0, 0x21a7, 0); /* brightness */ 810 reg_w_riv(dev, 0, 0x00, 0x21ad); /* hue */
790 reg_w(gspca_dev, 0, 0x20, 0x21a8, 0); /* contrast */ 811 reg_w_riv(dev, 0, 0x01, 0x21ac); /* sat/hue */
791 reg_w(gspca_dev, 0, 0, 0x21ad, 0); /* hue */ 812 reg_w_riv(dev, 0, 0x00, 0x21a3); /* gamma */
792 reg_w(gspca_dev, 0, 1, 0x21ac, 0); /* sat/hue */
793 reg_w(gspca_dev, 0, 0x20, 0x21ae, 0); /* saturation */
794 reg_w(gspca_dev, 0, 0, 0x21a3, 0); /* gamma */
795 break; 813 break;
796 case BRIDGE_SPCA536: 814 case BRIDGE_SPCA536:
797 reg_w(gspca_dev, 0, 0, 0x20f0, 0); 815 reg_w_riv(dev, 0, 0x40, 0x20f5);
798 reg_w(gspca_dev, 0, 0x21, 0x20f1, 0); 816 reg_w_riv(dev, 0, 0x01, 0x20f4);
799 reg_w(gspca_dev, 0, 0x40, 0x20f5, 0); 817 reg_w_riv(dev, 0, 0x00, 0x2089);
800 reg_w(gspca_dev, 0, 1, 0x20f4, 0);
801 reg_w(gspca_dev, 0, 0x40, 0x20f6, 0);
802 reg_w(gspca_dev, 0, 0, 0x2089, 0);
803 break; 818 break;
804 } 819 }
805 if (pollreg) 820 if (pollreg)
@@ -840,20 +855,24 @@ static int sd_config(struct gspca_dev *gspca_dev,
840/* case BRIDGE_SPCA504: */ 855/* case BRIDGE_SPCA504: */
841/* case BRIDGE_SPCA536: */ 856/* case BRIDGE_SPCA536: */
842 cam->cam_mode = vga_mode; 857 cam->cam_mode = vga_mode;
843 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; 858 cam->nmodes =ARRAY_SIZE(vga_mode);
844 break; 859 break;
845 case BRIDGE_SPCA533: 860 case BRIDGE_SPCA533:
846 cam->cam_mode = custom_mode; 861 cam->cam_mode = custom_mode;
847 cam->nmodes = sizeof custom_mode / sizeof custom_mode[0]; 862 if (sd->subtype == MegaImageVI) /* 320x240 only */
863 cam->nmodes = ARRAY_SIZE(custom_mode) - 1;
864 else
865 cam->nmodes = ARRAY_SIZE(custom_mode);
848 break; 866 break;
849 case BRIDGE_SPCA504C: 867 case BRIDGE_SPCA504C:
850 cam->cam_mode = vga_mode2; 868 cam->cam_mode = vga_mode2;
851 cam->nmodes = sizeof vga_mode2 / sizeof vga_mode2[0]; 869 cam->nmodes = ARRAY_SIZE(vga_mode2);
852 break; 870 break;
853 } 871 }
854 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; 872 sd->brightness = BRIGHTNESS_DEF;
855 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; 873 sd->contrast = CONTRAST_DEF;
856 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; 874 sd->colors = COLOR_DEF;
875 sd->autogain = AUTOGAIN_DEF;
857 sd->quality = QUALITY_DEF; 876 sd->quality = QUALITY_DEF;
858 return 0; 877 return 0;
859} 878}
@@ -863,32 +882,29 @@ static int sd_init(struct gspca_dev *gspca_dev)
863{ 882{
864 struct sd *sd = (struct sd *) gspca_dev; 883 struct sd *sd = (struct sd *) gspca_dev;
865 struct usb_device *dev = gspca_dev->dev; 884 struct usb_device *dev = gspca_dev->dev;
866 int rc; 885 int i, err_code;
867 __u8 i; 886 u8 info[6];
868 __u8 info[6];
869 int err_code;
870 887
871 switch (sd->bridge) { 888 switch (sd->bridge) {
872 case BRIDGE_SPCA504B: 889 case BRIDGE_SPCA504B:
873 reg_w(gspca_dev, 0x1d, 0, 0, 0); 890 reg_w_riv(dev, 0x1d, 0x00, 0);
874 reg_w(gspca_dev, 0, 1, 0x2306, 0); 891 reg_w_riv(dev, 0, 0x01, 0x2306);
875 reg_w(gspca_dev, 0, 0, 0x0d04, 0); 892 reg_w_riv(dev, 0, 0x00, 0x0d04);
876 reg_w(gspca_dev, 0, 0, 0x2000, 0); 893 reg_w_riv(dev, 0, 0x00, 0x2000);
877 reg_w(gspca_dev, 0, 0x13, 0x2301, 0); 894 reg_w_riv(dev, 0, 0x13, 0x2301);
878 reg_w(gspca_dev, 0, 0, 0x2306, 0); 895 reg_w_riv(dev, 0, 0x00, 0x2306);
879 /* fall thru */ 896 /* fall thru */
880 case BRIDGE_SPCA533: 897 case BRIDGE_SPCA533:
881 rc = spca504B_PollingDataReady(gspca_dev); 898 spca504B_PollingDataReady(gspca_dev);
882 spca50x_GetFirmware(gspca_dev); 899 spca50x_GetFirmware(gspca_dev);
883 break; 900 break;
884 case BRIDGE_SPCA536: 901 case BRIDGE_SPCA536:
885 spca50x_GetFirmware(gspca_dev); 902 spca50x_GetFirmware(gspca_dev);
886 reg_r(gspca_dev, 0x00, 0x5002, 1); 903 reg_r(gspca_dev, 0x00, 0x5002, 1);
887 gspca_dev->usb_buf[0] = 0; 904 reg_w_1(gspca_dev, 0x24, 0, 0, 0);
888 reg_w(gspca_dev, 0x24, 0, 0, 1);
889 reg_r(gspca_dev, 0x24, 0, 1); 905 reg_r(gspca_dev, 0x24, 0, 1);
890 rc = spca504B_PollingDataReady(gspca_dev); 906 spca504B_PollingDataReady(gspca_dev);
891 reg_w(gspca_dev, 0x34, 0, 0, 0); 907 reg_w_riv(dev, 0x34, 0, 0);
892 spca504B_WaitCmdStatus(gspca_dev); 908 spca504B_WaitCmdStatus(gspca_dev);
893 break; 909 break;
894 case BRIDGE_SPCA504C: /* pccam600 */ 910 case BRIDGE_SPCA504C: /* pccam600 */
@@ -898,12 +914,13 @@ static int sd_init(struct gspca_dev *gspca_dev)
898 spca504_wait_status(gspca_dev); 914 spca504_wait_status(gspca_dev);
899 if (sd->subtype == LogitechClickSmart420) 915 if (sd->subtype == LogitechClickSmart420)
900 write_vector(gspca_dev, 916 write_vector(gspca_dev,
901 spca504A_clicksmart420_open_data); 917 spca504A_clicksmart420_open_data,
918 ARRAY_SIZE(spca504A_clicksmart420_open_data));
902 else 919 else
903 write_vector(gspca_dev, spca504_pccam600_open_data); 920 write_vector(gspca_dev, spca504_pccam600_open_data,
921 ARRAY_SIZE(spca504_pccam600_open_data));
904 err_code = spca50x_setup_qtable(gspca_dev, 922 err_code = spca50x_setup_qtable(gspca_dev,
905 0x00, 0x2800, 923 qtable_creative_pccam);
906 0x2840, qtable_creative_pccam);
907 if (err_code < 0) { 924 if (err_code < 0) {
908 PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed"); 925 PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed");
909 return err_code; 926 return err_code;
@@ -941,8 +958,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
941 6, 0, 0x86, 1); */ 958 6, 0, 0x86, 1); */
942/* spca504A_acknowledged_command (gspca_dev, 0x24, 959/* spca504A_acknowledged_command (gspca_dev, 0x24,
943 0, 0, 0x9D, 1); */ 960 0, 0, 0x9D, 1); */
944 reg_w_riv(dev, 0x0, 0x270c, 0x05); /* L92 sno1t.txt */ 961 reg_w_riv(dev, 0x00, 0x270c, 0x05); /* L92 sno1t.txt */
945 reg_w_riv(dev, 0x0, 0x2310, 0x05); 962 reg_w_riv(dev, 0x00, 0x2310, 0x05);
946 spca504A_acknowledged_command(gspca_dev, 0x01, 963 spca504A_acknowledged_command(gspca_dev, 0x01,
947 0x0f, 0, 0xff, 0); 964 0x0f, 0, 0xff, 0);
948 } 965 }
@@ -950,8 +967,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
950 reg_w_riv(dev, 0, 0x2000, 0); 967 reg_w_riv(dev, 0, 0x2000, 0);
951 reg_w_riv(dev, 0, 0x2883, 1); 968 reg_w_riv(dev, 0, 0x2883, 1);
952 err_code = spca50x_setup_qtable(gspca_dev, 969 err_code = spca50x_setup_qtable(gspca_dev,
953 0x00, 0x2800,
954 0x2840,
955 qtable_spca504_default); 970 qtable_spca504_default);
956 if (err_code < 0) { 971 if (err_code < 0) {
957 PDEBUG(D_ERR, "spca50x_setup_qtable failed"); 972 PDEBUG(D_ERR, "spca50x_setup_qtable failed");
@@ -966,10 +981,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
966{ 981{
967 struct sd *sd = (struct sd *) gspca_dev; 982 struct sd *sd = (struct sd *) gspca_dev;
968 struct usb_device *dev = gspca_dev->dev; 983 struct usb_device *dev = gspca_dev->dev;
969 int rc;
970 int enable; 984 int enable;
971 __u8 i; 985 int i;
972 __u8 info[6]; 986 u8 info[6];
973 987
974 /* create the JPEG header */ 988 /* create the JPEG header */
975 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); 989 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
@@ -987,16 +1001,20 @@ static int sd_start(struct gspca_dev *gspca_dev)
987/* case BRIDGE_SPCA504B: */ 1001/* case BRIDGE_SPCA504B: */
988/* case BRIDGE_SPCA533: */ 1002/* case BRIDGE_SPCA533: */
989/* case BRIDGE_SPCA536: */ 1003/* case BRIDGE_SPCA536: */
990 if (sd->subtype == MegapixV4 || 1004 switch (sd->subtype) {
991 sd->subtype == LogitechClickSmart820) { 1005 case MegapixV4:
992 reg_w(gspca_dev, 0xf0, 0, 0, 0); 1006 case LogitechClickSmart820:
1007 case MegaImageVI:
1008 reg_w_riv(dev, 0xf0, 0, 0);
993 spca504B_WaitCmdStatus(gspca_dev); 1009 spca504B_WaitCmdStatus(gspca_dev);
994 reg_r(gspca_dev, 0xf0, 4, 0); 1010 reg_r(gspca_dev, 0xf0, 4, 0);
995 spca504B_WaitCmdStatus(gspca_dev); 1011 spca504B_WaitCmdStatus(gspca_dev);
996 } else { 1012 break;
997 reg_w(gspca_dev, 0x31, 0, 4, 0); 1013 default:
1014 reg_w_riv(dev, 0x31, 0, 0x04);
998 spca504B_WaitCmdStatus(gspca_dev); 1015 spca504B_WaitCmdStatus(gspca_dev);
999 rc = spca504B_PollingDataReady(gspca_dev); 1016 spca504B_PollingDataReady(gspca_dev);
1017 break;
1000 } 1018 }
1001 break; 1019 break;
1002 case BRIDGE_SPCA504: 1020 case BRIDGE_SPCA504:
@@ -1030,15 +1048,17 @@ static int sd_start(struct gspca_dev *gspca_dev)
1030 spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); 1048 spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
1031 } 1049 }
1032 spca504B_SetSizeType(gspca_dev); 1050 spca504B_SetSizeType(gspca_dev);
1033 reg_w_riv(dev, 0x0, 0x270c, 0x05); /* L92 sno1t.txt */ 1051 reg_w_riv(dev, 0x00, 0x270c, 0x05); /* L92 sno1t.txt */
1034 reg_w_riv(dev, 0x0, 0x2310, 0x05); 1052 reg_w_riv(dev, 0x00, 0x2310, 0x05);
1035 break; 1053 break;
1036 case BRIDGE_SPCA504C: 1054 case BRIDGE_SPCA504C:
1037 if (sd->subtype == LogitechClickSmart420) { 1055 if (sd->subtype == LogitechClickSmart420) {
1038 write_vector(gspca_dev, 1056 write_vector(gspca_dev,
1039 spca504A_clicksmart420_init_data); 1057 spca504A_clicksmart420_init_data,
1058 ARRAY_SIZE(spca504A_clicksmart420_init_data));
1040 } else { 1059 } else {
1041 write_vector(gspca_dev, spca504_pccam600_init_data); 1060 write_vector(gspca_dev, spca504_pccam600_init_data,
1061 ARRAY_SIZE(spca504_pccam600_init_data));
1042 } 1062 }
1043 enable = (sd->autogain ? 0x04 : 0x01); 1063 enable = (sd->autogain ? 0x04 : 0x01);
1044 reg_w_riv(dev, 0x0c, 0x0000, enable); /* auto exposure */ 1064 reg_w_riv(dev, 0x0c, 0x0000, enable); /* auto exposure */
@@ -1050,7 +1070,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
1050 spca504B_SetSizeType(gspca_dev); 1070 spca504B_SetSizeType(gspca_dev);
1051 break; 1071 break;
1052 } 1072 }
1053 sp5xx_initContBrigHueRegisters(gspca_dev); 1073 init_ctl_reg(gspca_dev);
1054 return 0; 1074 return 0;
1055} 1075}
1056 1076
@@ -1064,7 +1084,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1064/* case BRIDGE_SPCA533: */ 1084/* case BRIDGE_SPCA533: */
1065/* case BRIDGE_SPCA536: */ 1085/* case BRIDGE_SPCA536: */
1066/* case BRIDGE_SPCA504B: */ 1086/* case BRIDGE_SPCA504B: */
1067 reg_w(gspca_dev, 0x31, 0, 0, 0); 1087 reg_w_riv(dev, 0x31, 0, 0);
1068 spca504B_WaitCmdStatus(gspca_dev); 1088 spca504B_WaitCmdStatus(gspca_dev);
1069 spca504B_PollingDataReady(gspca_dev); 1089 spca504B_PollingDataReady(gspca_dev);
1070 break; 1090 break;
@@ -1082,7 +1102,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1082 0x0f, 0x00, 0xff, 1); 1102 0x0f, 0x00, 0xff, 1);
1083 } else { 1103 } else {
1084 spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); 1104 spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
1085 reg_w_riv(dev, 0x01, 0x000f, 0x00); 1105 reg_w_riv(dev, 0x01, 0x000f, 0x0000);
1086 } 1106 }
1087 break; 1107 break;
1088 } 1108 }
@@ -1097,12 +1117,12 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
1097 1117
1098static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1118static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1099 struct gspca_frame *frame, /* target */ 1119 struct gspca_frame *frame, /* target */
1100 __u8 *data, /* isoc packet */ 1120 u8 *data, /* isoc packet */
1101 int len) /* iso packet length */ 1121 int len) /* iso packet length */
1102{ 1122{
1103 struct sd *sd = (struct sd *) gspca_dev; 1123 struct sd *sd = (struct sd *) gspca_dev;
1104 int i, sof = 0; 1124 int i, sof = 0;
1105 static unsigned char ffd9[] = {0xff, 0xd9}; 1125 static u8 ffd9[] = {0xff, 0xd9};
1106 1126
1107/* frames are jpeg 4.1.1 without 0xff escape */ 1127/* frames are jpeg 4.1.1 without 0xff escape */
1108 switch (sd->bridge) { 1128 switch (sd->bridge) {
@@ -1190,63 +1210,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1190 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 1210 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1191} 1211}
1192 1212
1193static void setbrightness(struct gspca_dev *gspca_dev)
1194{
1195 struct sd *sd = (struct sd *) gspca_dev;
1196 struct usb_device *dev = gspca_dev->dev;
1197
1198 switch (sd->bridge) {
1199 default:
1200/* case BRIDGE_SPCA533: */
1201/* case BRIDGE_SPCA504B: */
1202/* case BRIDGE_SPCA504: */
1203/* case BRIDGE_SPCA504C: */
1204 reg_w_riv(dev, 0x0, 0x21a7, sd->brightness);
1205 break;
1206 case BRIDGE_SPCA536:
1207 reg_w_riv(dev, 0x0, 0x20f0, sd->brightness);
1208 break;
1209 }
1210}
1211
1212static void setcontrast(struct gspca_dev *gspca_dev)
1213{
1214 struct sd *sd = (struct sd *) gspca_dev;
1215 struct usb_device *dev = gspca_dev->dev;
1216
1217 switch (sd->bridge) {
1218 default:
1219/* case BRIDGE_SPCA533: */
1220/* case BRIDGE_SPCA504B: */
1221/* case BRIDGE_SPCA504: */
1222/* case BRIDGE_SPCA504C: */
1223 reg_w_riv(dev, 0x0, 0x21a8, sd->contrast);
1224 break;
1225 case BRIDGE_SPCA536:
1226 reg_w_riv(dev, 0x0, 0x20f1, sd->contrast);
1227 break;
1228 }
1229}
1230
1231static void setcolors(struct gspca_dev *gspca_dev)
1232{
1233 struct sd *sd = (struct sd *) gspca_dev;
1234 struct usb_device *dev = gspca_dev->dev;
1235
1236 switch (sd->bridge) {
1237 default:
1238/* case BRIDGE_SPCA533: */
1239/* case BRIDGE_SPCA504B: */
1240/* case BRIDGE_SPCA504: */
1241/* case BRIDGE_SPCA504C: */
1242 reg_w_riv(dev, 0x0, 0x21ae, sd->colors);
1243 break;
1244 case BRIDGE_SPCA536:
1245 reg_w_riv(dev, 0x0, 0x20f6, sd->colors);
1246 break;
1247 }
1248}
1249
1250static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1213static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1251{ 1214{
1252 struct sd *sd = (struct sd *) gspca_dev; 1215 struct sd *sd = (struct sd *) gspca_dev;
@@ -1384,6 +1347,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
1384 {USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)}, 1347 {USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)},
1385 {USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)}, 1348 {USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)},
1386 {USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)}, 1349 {USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)},
1350 {USB_DEVICE(0x052b, 0x1803), BS(SPCA533, MegaImageVI)},
1387 {USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)}, 1351 {USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)},
1388 {USB_DEVICE(0x0546, 0x3191), BS(SPCA504B, 0)}, 1352 {USB_DEVICE(0x0546, 0x3191), BS(SPCA504B, 0)},
1389 {USB_DEVICE(0x0546, 0x3273), BS(SPCA504B, 0)}, 1353 {USB_DEVICE(0x0546, 0x3273), BS(SPCA504B, 0)},
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index 404214b8cd2b..1d321c30d22f 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -264,6 +264,10 @@ static const struct v4l2_pix_format vga_mode_t16[] = {
264 264
265/* sensor specific data */ 265/* sensor specific data */
266struct additional_sensor_data { 266struct additional_sensor_data {
267 const u8 n3[6];
268 const u8 *n4, n4sz;
269 const u8 reg80, reg8e;
270 const u8 nset8[6];
267 const u8 data1[10]; 271 const u8 data1[10];
268 const u8 data2[9]; 272 const u8 data2[9];
269 const u8 data3[9]; 273 const u8 data3[9];
@@ -272,14 +276,55 @@ struct additional_sensor_data {
272 const u8 stream[4]; 276 const u8 stream[4];
273}; 277};
274 278
279static const u8 n4_om6802[] = {
280 0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
281 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
282 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
283 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
284 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
285 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
286 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
287 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
288 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46
289};
290static const u8 n4_other[] = {
291 0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69,
292 0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68,
293 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8,
294 0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8,
295 0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56,
296 0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5,
297 0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0,
298 0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00
299};
300static const u8 n4_tas5130a[] = {
301 0x80, 0x3c, 0x81, 0x68, 0x83, 0xa0, 0x84, 0x20,
302 0x8a, 0x68, 0x8b, 0x58, 0x8c, 0x88, 0x8e, 0xb4,
303 0x8f, 0x24, 0xa1, 0xb1, 0xa2, 0x30, 0xa5, 0x10,
304 0xa6, 0x4a, 0xae, 0x03, 0xb1, 0x44, 0xb2, 0x08,
305 0xb7, 0x06, 0xb9, 0xe7, 0xbb, 0xc4, 0xbc, 0x4a,
306 0xbe, 0x36, 0xbf, 0xff, 0xc2, 0x88, 0xc5, 0xc8,
307 0xc6, 0xda
308};
309
275static const struct additional_sensor_data sensor_data[] = { 310static const struct additional_sensor_data sensor_data[] = {
276 { /* OM6802 */ 311 { /* 0: OM6802 */
312 .n3 =
313 {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04},
314 .n4 = n4_om6802,
315 .n4sz = sizeof n4_om6802,
316 .reg80 = 0x3c,
317 .reg8e = 0x33,
318 .nset8 = {0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00},
277 .data1 = 319 .data1 =
278 {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06, 320 {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
279 0xb3, 0xfc}, 321 0xb3, 0xfc},
280 .data2 = 322 .data2 =
281 {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff, 323 {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
282 0xff}, 324 0xff},
325 .data3 =
326 {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
327 0xff},
283 .data4 = /*Freq (50/60Hz). Splitted for test purpose */ 328 .data4 = /*Freq (50/60Hz). Splitted for test purpose */
284 {0x66, 0xca, 0xa8, 0xf0}, 329 {0x66, 0xca, 0xa8, 0xf0},
285 .data5 = /* this could be removed later */ 330 .data5 = /* this could be removed later */
@@ -287,13 +332,23 @@ static const struct additional_sensor_data sensor_data[] = {
287 .stream = 332 .stream =
288 {0x0b, 0x04, 0x0a, 0x78}, 333 {0x0b, 0x04, 0x0a, 0x78},
289 }, 334 },
290 { /* OTHER */ 335 { /* 1: OTHER */
336 .n3 =
337 {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00},
338 .n4 = n4_other,
339 .n4sz = sizeof n4_other,
340 .reg80 = 0xac,
341 .reg8e = 0xb8,
342 .nset8 = {0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00},
291 .data1 = 343 .data1 =
292 {0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a, 344 {0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a,
293 0xe8, 0xfc}, 345 0xe8, 0xfc},
294 .data2 = 346 .data2 =
295 {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96, 347 {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
296 0xd9}, 348 0xd9},
349 .data3 =
350 {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
351 0xd9},
297 .data4 = 352 .data4 =
298 {0x66, 0x00, 0xa8, 0xa8}, 353 {0x66, 0x00, 0xa8, 0xa8},
299 .data5 = 354 .data5 =
@@ -301,13 +356,23 @@ static const struct additional_sensor_data sensor_data[] = {
301 .stream = 356 .stream =
302 {0x0b, 0x04, 0x0a, 0x00}, 357 {0x0b, 0x04, 0x0a, 0x00},
303 }, 358 },
304 { /* TAS5130A */ 359 { /* 2: TAS5130A */
360 .n3 =
361 {0x61, 0xc2, 0x65, 0x0d, 0x60, 0x08},
362 .n4 = n4_tas5130a,
363 .n4sz = sizeof n4_tas5130a,
364 .reg80 = 0x3c,
365 .reg8e = 0xb4,
366 .nset8 = {0xa8, 0xf0, 0xc6, 0xda, 0xc0, 0x00},
305 .data1 = 367 .data1 =
306 {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27, 368 {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
307 0xc8, 0xfc}, 369 0xc8, 0xfc},
308 .data2 = 370 .data2 =
309 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8, 371 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
310 0xe0}, 372 0xe0},
373 .data3 =
374 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
375 0xe0},
311 .data4 = /* Freq (50/60Hz). Splitted for test purpose */ 376 .data4 = /* Freq (50/60Hz). Splitted for test purpose */
312 {0x66, 0x00, 0xa8, 0xe8}, 377 {0x66, 0x00, 0xa8, 0xe8},
313 .data5 = 378 .data5 =
@@ -364,7 +429,7 @@ static const u8 gamma_table[GAMMA_MAX][17] = {
364 {0x00, 0x18, 0x2b, 0x44, 0x60, 0x70, 0x80, 0x8e, /* 10 */ 429 {0x00, 0x18, 0x2b, 0x44, 0x60, 0x70, 0x80, 0x8e, /* 10 */
365 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xd8, 0xe2, 0xf0, 430 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xd8, 0xe2, 0xf0,
366 0xff}, 431 0xff},
367 {0x00, 0x1a, 0x34, 0x52, 0x66, 0x7e, 0x8D, 0x9B, /* 11 */ 432 {0x00, 0x1a, 0x34, 0x52, 0x66, 0x7e, 0x8d, 0x9b, /* 11 */
368 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5, 433 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
369 0xff}, 434 0xff},
370 {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8, /* 12 */ 435 {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8, /* 12 */
@@ -385,8 +450,6 @@ static const u8 tas5130a_sensor_init[][8] = {
385 {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09}, 450 {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
386 {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09}, 451 {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
387 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}, 452 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
388 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
389 {},
390}; 453};
391 454
392static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07}; 455static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
@@ -633,10 +696,10 @@ static int sd_init(struct gspca_dev *gspca_dev)
633 * but wont hurt anyway, and can help someone with similar webcam 696 * but wont hurt anyway, and can help someone with similar webcam
634 * to see the initial parameters.*/ 697 * to see the initial parameters.*/
635 struct sd *sd = (struct sd *) gspca_dev; 698 struct sd *sd = (struct sd *) gspca_dev;
699 const struct additional_sensor_data *sensor;
636 int i; 700 int i;
637 u16 sensor_id; 701 u16 sensor_id;
638 u8 test_byte = 0; 702 u8 test_byte = 0;
639 u16 reg80, reg8e;
640 703
641 static const u8 read_indexs[] = 704 static const u8 read_indexs[] =
642 { 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5, 705 { 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
@@ -645,37 +708,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
645 {0x08, 0x03, 0x09, 0x03, 0x12, 0x04}; 708 {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
646 static const u8 n2[] = 709 static const u8 n2[] =
647 {0x08, 0x00}; 710 {0x08, 0x00};
648 static const u8 n3[6] =
649 {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
650 static const u8 n3_other[6] =
651 {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00};
652 static const u8 n4[] =
653 {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
654 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
655 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
656 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
657 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
658 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
659 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
660 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
661 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
662 static const u8 n4_other[] =
663 {0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69,
664 0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68,
665 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8,
666 0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8,
667 0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56,
668 0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5,
669 0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0,
670 0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00};
671 static const u8 nset8[6] =
672 { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
673 static const u8 nset8_other[6] =
674 { 0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00 };
675 static const u8 nset9[4] =
676 { 0x0b, 0x04, 0x0a, 0x78 };
677 static const u8 nset9_other[4] =
678 { 0x0b, 0x04, 0x0a, 0x00 };
679 711
680 sensor_id = (reg_r(gspca_dev, 0x06) << 8) 712 sensor_id = (reg_r(gspca_dev, 0x06) << 8)
681 | reg_r(gspca_dev, 0x07); 713 | reg_r(gspca_dev, 0x07);
@@ -709,8 +741,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
709 } 741 }
710 if (i < 0) { 742 if (i < 0) {
711 err("Bad sensor reset %02x", test_byte); 743 err("Bad sensor reset %02x", test_byte);
712/* return -EIO; */ 744 return -EIO;
713/*fixme: test - continue */
714 } 745 }
715 reg_w_buf(gspca_dev, n2, sizeof n2); 746 reg_w_buf(gspca_dev, n2, sizeof n2);
716 } 747 }
@@ -723,31 +754,17 @@ static int sd_init(struct gspca_dev *gspca_dev)
723 i++; 754 i++;
724 } 755 }
725 756
726 if (sd->sensor != SENSOR_OTHER) { 757 sensor = &sensor_data[sd->sensor];
727 reg_w_buf(gspca_dev, n3, sizeof n3); 758 reg_w_buf(gspca_dev, sensor->n3, sizeof sensor->n3);
728 reg_w_buf(gspca_dev, n4, sizeof n4); 759 reg_w_buf(gspca_dev, sensor->n4, sensor->n4sz);
729 reg_r(gspca_dev, 0x0080);
730 reg_w(gspca_dev, 0x2c80);
731 reg80 = 0x3880;
732 reg8e = 0x338e;
733 } else {
734 reg_w_buf(gspca_dev, n3_other, sizeof n3_other);
735 reg_w_buf(gspca_dev, n4_other, sizeof n4_other);
736 sd->gamma = 5;
737 reg80 = 0xac80;
738 reg8e = 0xb88e;
739 }
740 760
741 reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1, 761 reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
742 sizeof sensor_data[sd->sensor].data1); 762 reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
743 reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2, 763 reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
744 sizeof sensor_data[sd->sensor].data2);
745 reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2,
746 sizeof sensor_data[sd->sensor].data2);
747 764
748 reg_w(gspca_dev, reg80); 765 reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
749 reg_w(gspca_dev, reg80); 766 reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
750 reg_w(gspca_dev, reg8e); 767 reg_w(gspca_dev, (sensor->reg8e << 8) + 0x8e);
751 768
752 setbrightness(gspca_dev); 769 setbrightness(gspca_dev);
753 setcontrast(gspca_dev); 770 setcontrast(gspca_dev);
@@ -760,25 +777,14 @@ static int sd_init(struct gspca_dev *gspca_dev)
760 reg_w(gspca_dev, 0x2088); 777 reg_w(gspca_dev, 0x2088);
761 reg_w(gspca_dev, 0x2089); 778 reg_w(gspca_dev, 0x2089);
762 779
763 reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4, 780 reg_w_buf(gspca_dev, sensor->data4, sizeof sensor->data4);
764 sizeof sensor_data[sd->sensor].data4); 781 reg_w_buf(gspca_dev, sensor->data5, sizeof sensor->data5);
765 reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5, 782 reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8);
766 sizeof sensor_data[sd->sensor].data5); 783 reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
767 if (sd->sensor != SENSOR_OTHER) {
768 reg_w_buf(gspca_dev, nset8, sizeof nset8);
769 reg_w_buf(gspca_dev, nset9, sizeof nset9);
770 reg_w(gspca_dev, 0x2880);
771 } else {
772 reg_w_buf(gspca_dev, nset8_other, sizeof nset8_other);
773 reg_w_buf(gspca_dev, nset9_other, sizeof nset9_other);
774 }
775 784
776 reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1, 785 reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
777 sizeof sensor_data[sd->sensor].data1); 786 reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
778 reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2, 787 reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
779 sizeof sensor_data[sd->sensor].data2);
780 reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2,
781 sizeof sensor_data[sd->sensor].data2);
782 788
783 return 0; 789 return 0;
784} 790}
@@ -828,7 +834,6 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
828 * i added some module parameters for test with some users */ 834 * i added some module parameters for test with some users */
829static void poll_sensor(struct gspca_dev *gspca_dev) 835static void poll_sensor(struct gspca_dev *gspca_dev)
830{ 836{
831 struct sd *sd = (struct sd *) gspca_dev;
832 static const u8 poll1[] = 837 static const u8 poll1[] =
833 {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82, 838 {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
834 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34, 839 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
@@ -844,24 +849,23 @@ static void poll_sensor(struct gspca_dev *gspca_dev)
844 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c, 849 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
845 0xc2, 0x80, 0xc3, 0x10}; 850 0xc2, 0x80, 0xc3, 0x10};
846 851
847 if (sd->sensor == SENSOR_OM6802) { 852 PDEBUG(D_STREAM, "[Sensor requires polling]");
848 PDEBUG(D_STREAM, "[Sensor requires polling]"); 853 reg_w_buf(gspca_dev, poll1, sizeof poll1);
849 reg_w_buf(gspca_dev, poll1, sizeof poll1); 854 reg_w_buf(gspca_dev, poll2, sizeof poll2);
850 reg_w_buf(gspca_dev, poll2, sizeof poll2); 855 reg_w_buf(gspca_dev, poll3, sizeof poll3);
851 reg_w_buf(gspca_dev, poll3, sizeof poll3); 856 reg_w_buf(gspca_dev, poll4, sizeof poll4);
852 reg_w_buf(gspca_dev, poll4, sizeof poll4);
853 }
854} 857}
855 858
856static int sd_start(struct gspca_dev *gspca_dev) 859static int sd_start(struct gspca_dev *gspca_dev)
857{ 860{
858 struct sd *sd = (struct sd *) gspca_dev; 861 struct sd *sd = (struct sd *) gspca_dev;
862 const struct additional_sensor_data *sensor;
859 int i, mode; 863 int i, mode;
860 u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 }; 864 u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
861 static const u8 t3[] = 865 static const u8 t3[] =
862 { 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 }; 866 { 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 };
863 867
864 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv; 868 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
865 switch (mode) { 869 switch (mode) {
866 case 0: /* 640x480 (0x00) */ 870 case 0: /* 640x480 (0x00) */
867 break; 871 break;
@@ -889,34 +893,33 @@ static int sd_start(struct gspca_dev *gspca_dev)
889 default: 893 default:
890/* case SENSOR_TAS5130A: */ 894/* case SENSOR_TAS5130A: */
891 i = 0; 895 i = 0;
892 while (tas5130a_sensor_init[i][0] != 0) { 896 for (;;) {
893 reg_w_buf(gspca_dev, tas5130a_sensor_init[i], 897 reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
894 sizeof tas5130a_sensor_init[0]); 898 sizeof tas5130a_sensor_init[0]);
899 if (i >= ARRAY_SIZE(tas5130a_sensor_init) - 1)
900 break;
895 i++; 901 i++;
896 } 902 }
897 reg_w(gspca_dev, 0x3c80); 903 reg_w(gspca_dev, 0x3c80);
898 /* just in case and to keep sync with logs (for mine) */ 904 /* just in case and to keep sync with logs (for mine) */
899 reg_w_buf(gspca_dev, tas5130a_sensor_init[3], 905 reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
900 sizeof tas5130a_sensor_init[0]); 906 sizeof tas5130a_sensor_init[0]);
901 reg_w(gspca_dev, 0x3c80); 907 reg_w(gspca_dev, 0x3c80);
902 break; 908 break;
903 } 909 }
904 reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4, 910 sensor = &sensor_data[sd->sensor];
905 sizeof sensor_data[sd->sensor].data4); 911 reg_w_buf(gspca_dev, sensor->data4, sizeof sensor->data4);
906 reg_r(gspca_dev, 0x0012); 912 reg_r(gspca_dev, 0x0012);
907 reg_w_buf(gspca_dev, t2, sizeof t2); 913 reg_w_buf(gspca_dev, t2, sizeof t2);
908 reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3); 914 reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3);
909 reg_w(gspca_dev, 0x0013); 915 reg_w(gspca_dev, 0x0013);
910 msleep(15); 916 msleep(15);
911 reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream, 917 reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
912 sizeof sensor_data[sd->sensor].stream); 918 reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
913 poll_sensor(gspca_dev); 919
920 if (sd->sensor == SENSOR_OM6802)
921 poll_sensor(gspca_dev);
914 922
915 /* restart on each start, just in case, sometimes regs goes wrong
916 * when using controls from app */
917 setbrightness(gspca_dev);
918 setcontrast(gspca_dev);
919 setcolors(gspca_dev);
920 return 0; 923 return 0;
921} 924}
922 925
@@ -926,10 +929,9 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
926 929
927 reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream, 930 reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
928 sizeof sensor_data[sd->sensor].stream); 931 sizeof sensor_data[sd->sensor].stream);
929 msleep(20);
930 reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream, 932 reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
931 sizeof sensor_data[sd->sensor].stream); 933 sizeof sensor_data[sd->sensor].stream);
932 if (sd->sensor != SENSOR_OTHER) { 934 if (sd->sensor == SENSOR_OM6802) {
933 msleep(20); 935 msleep(20);
934 reg_w(gspca_dev, 0x0309); 936 reg_w(gspca_dev, 0x0309);
935 } 937 }
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index 9f243d7e3110..4b44dde9f8b8 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -426,7 +426,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
426 gspca_frame_add(gspca_dev, packet_type0, 426 gspca_frame_add(gspca_dev, packet_type0,
427 frame, data + 2, gspca_dev->width); 427 frame, data + 2, gspca_dev->width);
428 gspca_frame_add(gspca_dev, packet_type1, 428 gspca_frame_add(gspca_dev, packet_type1,
429 frame, data + gspca_dev->width + 6, gspca_dev->width); 429 frame, data + gspca_dev->width + 5, gspca_dev->width);
430} 430}
431 431
432static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 432static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 26dd155efcc3..619250e70718 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -32,14 +32,14 @@ MODULE_LICENSE("GPL");
32struct sd { 32struct sd {
33 struct gspca_dev gspca_dev; /* !! must be the first item */ 33 struct gspca_dev gspca_dev; /* !! must be the first item */
34 34
35 __u8 hflip; 35 u8 hflip;
36 __u8 vflip; 36 u8 vflip;
37 __u8 lightfreq; 37 u8 lightfreq;
38 __u8 sharpness; 38 u8 sharpness;
39 39
40 u8 image_offset; 40 u8 image_offset;
41 41
42 char bridge; 42 u8 bridge;
43#define BRIDGE_VC0321 0 43#define BRIDGE_VC0321 0
44#define BRIDGE_VC0323 1 44#define BRIDGE_VC0323 1
45 u8 sensor; 45 u8 sensor;
@@ -52,6 +52,10 @@ struct sd {
52#define SENSOR_OV7670 6 52#define SENSOR_OV7670 6
53#define SENSOR_PO1200 7 53#define SENSOR_PO1200 7
54#define SENSOR_PO3130NC 8 54#define SENSOR_PO3130NC 8
55 u8 flags;
56#define FL_SAMSUNG 0x01 /* SamsungQ1 (2 sensors) */
57#define FL_HFLIP 0x02 /* mirrored by default */
58#define FL_VFLIP 0x04 /* vertical flipped by default */
55}; 59};
56 60
57/* V4L2 controls supported by the driver */ 61/* V4L2 controls supported by the driver */
@@ -65,7 +69,7 @@ static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
65static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); 69static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
66 70
67static struct ctrl sd_ctrls[] = { 71static struct ctrl sd_ctrls[] = {
68/* next 2 controls work with ov7660 and ov7670 only */ 72/* next 2 controls work with some sensors only */
69#define HFLIP_IDX 0 73#define HFLIP_IDX 0
70 { 74 {
71 { 75 {
@@ -152,9 +156,9 @@ static const struct v4l2_pix_format vc0323_mode[] = {
152 .sizeimage = 640 * 480 * 3 / 8 + 590, 156 .sizeimage = 640 * 480 * 3 / 8 + 590,
153 .colorspace = V4L2_COLORSPACE_JPEG, 157 .colorspace = V4L2_COLORSPACE_JPEG,
154 .priv = 0}, 158 .priv = 0},
155 {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, /* mi13x0_soc only */ 159 {1280, 960, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, /* mi1310_soc only */
156 .bytesperline = 1280, 160 .bytesperline = 1280,
157 .sizeimage = 1280 * 1024 * 1 / 4 + 590, 161 .sizeimage = 1280 * 960 * 3 / 8 + 590,
158 .colorspace = V4L2_COLORSPACE_JPEG, 162 .colorspace = V4L2_COLORSPACE_JPEG,
159 .priv = 2}, 163 .priv = 2},
160}; 164};
@@ -188,11 +192,11 @@ static const struct v4l2_pix_format svga_mode[] = {
188#define OV7660_MVFP_MIRROR 0x20 192#define OV7660_MVFP_MIRROR 0x20
189#define OV7660_MVFP_VFLIP 0x10 193#define OV7660_MVFP_VFLIP 0x10
190 194
191static const __u8 mi0360_matrix[9] = { 195static const u8 mi0360_matrix[9] = {
192 0x50, 0xf8, 0xf8, 0xf5, 0x50, 0xfb, 0xff, 0xf1, 0x50 196 0x50, 0xf8, 0xf8, 0xf5, 0x50, 0xfb, 0xff, 0xf1, 0x50
193}; 197};
194 198
195static const __u8 mi0360_initVGA_JPG[][4] = { 199static const u8 mi0360_initVGA_JPG[][4] = {
196 {0xb0, 0x03, 0x19, 0xcc}, 200 {0xb0, 0x03, 0x19, 0xcc},
197 {0xb0, 0x04, 0x02, 0xcc}, 201 {0xb0, 0x04, 0x02, 0xcc},
198 {0xb3, 0x00, 0x24, 0xcc}, 202 {0xb3, 0x00, 0x24, 0xcc},
@@ -301,7 +305,7 @@ static const __u8 mi0360_initVGA_JPG[][4] = {
301 {0xb3, 0x5c, 0x01, 0xcc}, 305 {0xb3, 0x5c, 0x01, 0xcc},
302 {} 306 {}
303}; 307};
304static const __u8 mi0360_initQVGA_JPG[][4] = { 308static const u8 mi0360_initQVGA_JPG[][4] = {
305 {0xb0, 0x03, 0x19, 0xcc}, 309 {0xb0, 0x03, 0x19, 0xcc},
306 {0xb0, 0x04, 0x02, 0xcc}, 310 {0xb0, 0x04, 0x02, 0xcc},
307 {0xb3, 0x00, 0x24, 0xcc}, 311 {0xb3, 0x00, 0x24, 0xcc},
@@ -421,211 +425,95 @@ static const __u8 mi0360_initQVGA_JPG[][4] = {
421 {} 425 {}
422}; 426};
423 427
424static const __u8 mi1310_socinitVGA_JPG[][4] = { 428static const u8 mi1310_socinitVGA_JPG[][4] = {
425 {0xb0, 0x03, 0x19, 0xcc}, 429 {0xb0, 0x03, 0x19, 0xcc},
426 {0xb0, 0x04, 0x02, 0xcc}, 430 {0xb0, 0x04, 0x02, 0xcc},
427 {0xb3, 0x00, 0x24, 0xcc}, 431 {0xb3, 0x00, 0x64, 0xcc},
428 {0xb3, 0x00, 0x25, 0xcc}, 432 {0xb3, 0x00, 0x65, 0xcc},
429 {0xb3, 0x05, 0x01, 0xcc}, 433 {0xb3, 0x05, 0x00, 0xcc},
430 {0xb3, 0x06, 0x03, 0xcc}, 434 {0xb3, 0x06, 0x00, 0xcc},
431 {0xb3, 0x5c, 0x01, 0xcc},
432 {0xb3, 0x08, 0x01, 0xcc}, 435 {0xb3, 0x08, 0x01, 0xcc},
433 {0xb3, 0x09, 0x0c, 0xcc}, 436 {0xb3, 0x09, 0x0c, 0xcc},
434 {0xb3, 0x34, 0x02, 0xcc}, 437 {0xb3, 0x34, 0x02, 0xcc},
435 {0xb3, 0x35, 0xdd, 0xcc}, 438 {0xb3, 0x35, 0xdd, 0xcc},
439 {0xb3, 0x02, 0x00, 0xcc},
436 {0xb3, 0x03, 0x0a, 0xcc}, 440 {0xb3, 0x03, 0x0a, 0xcc},
437 {0xb3, 0x04, 0x0d, 0xcc}, 441 {0xb3, 0x04, 0x05, 0xcc},
438 {0xb3, 0x20, 0x00, 0xcc}, 442 {0xb3, 0x20, 0x00, 0xcc},
439 {0xb3, 0x21, 0x00, 0xcc}, 443 {0xb3, 0x21, 0x00, 0xcc},
440 {0xb3, 0x22, 0x01, 0xcc}, 444 {0xb3, 0x22, 0x03, 0xcc},
441 {0xb3, 0x23, 0xe0, 0xcc}, 445 {0xb3, 0x23, 0xc0, 0xcc},
442 {0xb3, 0x14, 0x00, 0xcc}, 446 {0xb3, 0x14, 0x00, 0xcc},
443 {0xb3, 0x15, 0x00, 0xcc}, 447 {0xb3, 0x15, 0x00, 0xcc},
444 {0xb3, 0x16, 0x02, 0xcc}, 448 {0xb3, 0x16, 0x04, 0xcc},
445 {0xb3, 0x17, 0x7f, 0xcc}, 449 {0xb3, 0x17, 0xff, 0xcc},
446 {0xb8, 0x01, 0x7d, 0xcc}, 450 {0xb3, 0x00, 0x65, 0xcc},
447 {0xb8, 0x81, 0x09, 0xcc}, 451 {0xb8, 0x00, 0x00, 0xcc},
448 {0xb8, 0x27, 0x20, 0xcc}, 452 {0xbc, 0x00, 0xd0, 0xcc},
449 {0xb8, 0x26, 0x80, 0xcc}, 453 {0xbc, 0x01, 0x01, 0xcc},
450 {0xb3, 0x00, 0x25, 0xcc}, 454 {0xf0, 0x00, 0x02, 0xbb},
451 {0xb8, 0x00, 0x13, 0xcc}, 455 {0xc8, 0x9f, 0x0b, 0xbb},
452 {0xbc, 0x00, 0x71, 0xcc}, 456 {0x5b, 0x00, 0x01, 0xbb},
453 {0xb8, 0x81, 0x01, 0xcc}, 457 {0x2f, 0xde, 0x20, 0xbb},
454 {0xb8, 0x2c, 0x5a, 0xcc},
455 {0xb8, 0x2d, 0xff, 0xcc},
456 {0xb8, 0x2e, 0xee, 0xcc},
457 {0xb8, 0x2f, 0xfb, 0xcc},
458 {0xb8, 0x30, 0x52, 0xcc},
459 {0xb8, 0x31, 0xf8, 0xcc},
460 {0xb8, 0x32, 0xf1, 0xcc},
461 {0xb8, 0x33, 0xff, 0xcc},
462 {0xb8, 0x34, 0x54, 0xcc},
463 {0xb8, 0x35, 0x00, 0xcc},
464 {0xb8, 0x36, 0x00, 0xcc},
465 {0xb8, 0x37, 0x00, 0xcc},
466 {0xf0, 0x00, 0x00, 0xbb}, 458 {0xf0, 0x00, 0x00, 0xbb},
467 {0x00, 0x01, 0x00, 0xdd}, 459 {0x20, 0x03, 0x02, 0xbb}, /* h/v flip */
468 {0x0d, 0x00, 0x09, 0xbb},
469 {0x0d, 0x00, 0x08, 0xbb},
470 {0xf0, 0x00, 0x01, 0xbb}, 460 {0xf0, 0x00, 0x01, 0xbb},
471 {0x00, 0x01, 0x00, 0xdd}, 461 {0x05, 0x00, 0x07, 0xbb},
472 {0x06, 0x00, 0x14, 0xbb}, 462 {0x34, 0x00, 0x00, 0xbb},
473 {0x3a, 0x10, 0x00, 0xbb}, 463 {0x35, 0xff, 0x00, 0xbb},
474 {0x00, 0x00, 0x10, 0xdd}, 464 {0xdc, 0x07, 0x02, 0xbb},
475 {0x9b, 0x10, 0x00, 0xbb}, 465 {0xdd, 0x3c, 0x18, 0xbb},
476 {0x00, 0x00, 0x10, 0xdd}, 466 {0xde, 0x92, 0x6d, 0xbb},
467 {0xdf, 0xcd, 0xb1, 0xbb},
468 {0xe0, 0xff, 0xe7, 0xbb},
469 {0x06, 0xf0, 0x0d, 0xbb},
470 {0x06, 0x70, 0x0e, 0xbb},
471 {0x4c, 0x00, 0x01, 0xbb},
472 {0x4d, 0x00, 0x01, 0xbb},
473 {0xf0, 0x00, 0x02, 0xbb},
474 {0x2e, 0x0c, 0x55, 0xbb},
475 {0x21, 0xb6, 0x6e, 0xbb},
476 {0x36, 0x30, 0x10, 0xbb},
477 {0x37, 0x00, 0xc1, 0xbb},
477 {0xf0, 0x00, 0x00, 0xbb}, 478 {0xf0, 0x00, 0x00, 0xbb},
478 {0x00, 0x01, 0x00, 0xdd}, 479 {0x07, 0x00, 0x84, 0xbb},
479 {0x2b, 0x00, 0x28, 0xbb}, 480 {0x08, 0x02, 0x4a, 0xbb},
480 {0x2c, 0x00, 0x30, 0xbb}, 481 {0x05, 0x01, 0x10, 0xbb},
481 {0x2d, 0x00, 0x30, 0xbb}, 482 {0x06, 0x00, 0x39, 0xbb},
482 {0x2e, 0x00, 0x28, 0xbb}, 483 {0xf0, 0x00, 0x02, 0xbb},
483 {0x41, 0x00, 0xd7, 0xbb}, 484 {0x58, 0x02, 0x67, 0xbb},
484 {0x09, 0x02, 0x3a, 0xbb}, 485 {0x57, 0x02, 0x00, 0xbb},
485 {0x0c, 0x00, 0x00, 0xbb}, 486 {0x5a, 0x02, 0x67, 0xbb},
486 {0x20, 0x00, 0x00, 0xbb}, 487 {0x59, 0x02, 0x00, 0xbb},
487 {0x05, 0x00, 0x8c, 0xbb}, 488 {0x5c, 0x12, 0x0d, 0xbb},
488 {0x06, 0x00, 0x32, 0xbb}, 489 {0x5d, 0x16, 0x11, 0xbb},
489 {0x07, 0x00, 0xc6, 0xbb}, 490 {0x39, 0x06, 0x18, 0xbb},
490 {0x08, 0x00, 0x19, 0xbb}, 491 {0x3a, 0x06, 0x18, 0xbb},
491 {0x24, 0x80, 0x6f, 0xbb}, 492 {0x3b, 0x06, 0x18, 0xbb},
492 {0xc8, 0x00, 0x0f, 0xbb}, 493 {0x3c, 0x06, 0x18, 0xbb},
493 {0x20, 0x00, 0x0f, 0xbb}, 494 {0x64, 0x7b, 0x5b, 0xbb},
495 {0xf0, 0x00, 0x02, 0xbb},
496 {0x36, 0x30, 0x10, 0xbb},
497 {0x37, 0x00, 0xc0, 0xbb},
498 {0xbc, 0x0e, 0x00, 0xcc},
499 {0xbc, 0x0f, 0x05, 0xcc},
500 {0xbc, 0x10, 0xc0, 0xcc},
501 {0xbc, 0x11, 0x03, 0xcc},
494 {0xb6, 0x00, 0x00, 0xcc}, 502 {0xb6, 0x00, 0x00, 0xcc},
495 {0xb6, 0x03, 0x02, 0xcc}, 503 {0xb6, 0x03, 0x02, 0xcc},
496 {0xb6, 0x02, 0x80, 0xcc}, 504 {0xb6, 0x02, 0x80, 0xcc},
497 {0xb6, 0x05, 0x01, 0xcc}, 505 {0xb6, 0x05, 0x01, 0xcc},
498 {0xb6, 0x04, 0xe0, 0xcc}, 506 {0xb6, 0x04, 0xe0, 0xcc},
499 {0xb6, 0x12, 0x78, 0xcc}, 507 {0xb6, 0x12, 0xf8, 0xcc},
508 {0xb6, 0x13, 0x25, 0xcc},
500 {0xb6, 0x18, 0x02, 0xcc}, 509 {0xb6, 0x18, 0x02, 0xcc},
501 {0xb6, 0x17, 0x58, 0xcc}, 510 {0xb6, 0x17, 0x58, 0xcc},
502 {0xb6, 0x16, 0x00, 0xcc}, 511 {0xb6, 0x16, 0x00, 0xcc},
503 {0xb6, 0x22, 0x12, 0xcc}, 512 {0xb6, 0x22, 0x12, 0xcc},
504 {0xb6, 0x23, 0x0b, 0xcc}, 513 {0xb6, 0x23, 0x0b, 0xcc},
505 {0xb3, 0x02, 0x02, 0xcc},
506 {0xbf, 0xc0, 0x39, 0xcc},
507 {0xbf, 0xc1, 0x04, 0xcc},
508 {0xbf, 0xcc, 0x10, 0xcc},
509 {0xb9, 0x12, 0x00, 0xcc},
510 {0xb9, 0x13, 0x0a, 0xcc},
511 {0xb9, 0x14, 0x0a, 0xcc},
512 {0xb9, 0x15, 0x0a, 0xcc},
513 {0xb9, 0x16, 0x0a, 0xcc},
514 {0xb9, 0x18, 0x00, 0xcc},
515 {0xb9, 0x19, 0x0f, 0xcc},
516 {0xb9, 0x1a, 0x0f, 0xcc},
517 {0xb9, 0x1b, 0x0f, 0xcc},
518 {0xb9, 0x1c, 0x0f, 0xcc},
519 {0xb8, 0x8e, 0x00, 0xcc},
520 {0xb8, 0x8f, 0xff, 0xcc},
521 {0xb3, 0x01, 0x41, 0xcc},
522 {0x03, 0x03, 0xc0, 0xbb},
523 {0x06, 0x00, 0x10, 0xbb},
524 {0xb6, 0x12, 0xf8, 0xcc},
525 {0xb8, 0x0c, 0x20, 0xcc},
526 {0xb8, 0x0d, 0x70, 0xcc},
527 {0xb6, 0x13, 0x13, 0xcc},
528 {0x2f, 0x00, 0xC0, 0xbb},
529 {0xb8, 0xa0, 0x12, 0xcc},
530 {},
531};
532static const __u8 mi1310_socinitQVGA_JPG[][4] = {
533 {0xb0, 0x03, 0x19, 0xcc},
534 {0xb0, 0x04, 0x02, 0xcc},
535 {0xb3, 0x00, 0x24, 0xcc},
536 {0xb3, 0x00, 0x25, 0xcc},
537 {0xb3, 0x05, 0x01, 0xcc},
538 {0xb3, 0x06, 0x03, 0xcc},
539 {0xb3, 0x5c, 0x01, 0xcc},
540 {0xb3, 0x08, 0x01, 0xcc},
541 {0xb3, 0x09, 0x0c, 0xcc},
542 {0xb3, 0x34, 0x02, 0xcc},
543 {0xb3, 0x35, 0xdd, 0xcc},
544 {0xb3, 0x03, 0x0a, 0xcc},
545 {0xb3, 0x04, 0x0d, 0xcc},
546 {0xb3, 0x20, 0x00, 0xcc},
547 {0xb3, 0x21, 0x00, 0xcc},
548 {0xb3, 0x22, 0x01, 0xcc},
549 {0xb3, 0x23, 0xe0, 0xcc},
550 {0xb3, 0x14, 0x00, 0xcc},
551 {0xb3, 0x15, 0x00, 0xcc},
552 {0xb3, 0x16, 0x02, 0xcc},
553 {0xb3, 0x17, 0x7f, 0xcc},
554 {0xb8, 0x01, 0x7d, 0xcc},
555 {0xb8, 0x81, 0x09, 0xcc},
556 {0xb8, 0x27, 0x20, 0xcc},
557 {0xb8, 0x26, 0x80, 0xcc},
558 {0xb3, 0x00, 0x25, 0xcc},
559 {0xb8, 0x00, 0x13, 0xcc},
560 {0xbc, 0x00, 0xd1, 0xcc},
561 {0xb8, 0x81, 0x01, 0xcc},
562 {0xb8, 0x2c, 0x5a, 0xcc},
563 {0xb8, 0x2d, 0xff, 0xcc},
564 {0xb8, 0x2e, 0xee, 0xcc},
565 {0xb8, 0x2f, 0xfb, 0xcc},
566 {0xb8, 0x30, 0x52, 0xcc},
567 {0xb8, 0x31, 0xf8, 0xcc},
568 {0xb8, 0x32, 0xf1, 0xcc},
569 {0xb8, 0x33, 0xff, 0xcc},
570 {0xb8, 0x34, 0x54, 0xcc},
571 {0xb8, 0x35, 0x00, 0xcc},
572 {0xb8, 0x36, 0x00, 0xcc},
573 {0xb8, 0x37, 0x00, 0xcc},
574 {0xf0, 0x00, 0x00, 0xbb},
575 {0x00, 0x01, 0x00, 0xdd},
576 {0x0d, 0x00, 0x09, 0xbb},
577 {0x0d, 0x00, 0x08, 0xbb},
578 {0xf0, 0x00, 0x01, 0xbb},
579 {0x00, 0x01, 0x00, 0xdd},
580 {0x06, 0x00, 0x14, 0xbb},
581 {0x3a, 0x10, 0x00, 0xbb},
582 {0x00, 0x00, 0x10, 0xdd},
583 {0x9b, 0x10, 0x00, 0xbb},
584 {0x00, 0x00, 0x10, 0xdd},
585 {0xf0, 0x00, 0x00, 0xbb},
586 {0x00, 0x01, 0x00, 0xdd},
587 {0x2b, 0x00, 0x28, 0xbb},
588 {0x2c, 0x00, 0x30, 0xbb},
589 {0x2d, 0x00, 0x30, 0xbb},
590 {0x2e, 0x00, 0x28, 0xbb},
591 {0x41, 0x00, 0xd7, 0xbb},
592 {0x09, 0x02, 0x3a, 0xbb},
593 {0x0c, 0x00, 0x00, 0xbb},
594 {0x20, 0x00, 0x00, 0xbb},
595 {0x05, 0x00, 0x8c, 0xbb},
596 {0x06, 0x00, 0x32, 0xbb},
597 {0x07, 0x00, 0xc6, 0xbb},
598 {0x08, 0x00, 0x19, 0xbb},
599 {0x24, 0x80, 0x6f, 0xbb},
600 {0xc8, 0x00, 0x0f, 0xbb},
601 {0x20, 0x00, 0x0f, 0xbb},
602 {0xb6, 0x00, 0x00, 0xcc},
603 {0xb6, 0x03, 0x01, 0xcc},
604 {0xb6, 0x02, 0x40, 0xcc},
605 {0xb6, 0x05, 0x00, 0xcc},
606 {0xb6, 0x04, 0xf0, 0xcc},
607 {0xb6, 0x12, 0x78, 0xcc},
608 {0xb6, 0x18, 0x00, 0xcc},
609 {0xb6, 0x17, 0x96, 0xcc},
610 {0xb6, 0x16, 0x00, 0xcc},
611 {0xb6, 0x22, 0x12, 0xcc},
612 {0xb6, 0x23, 0x0b, 0xcc},
613 {0xb3, 0x02, 0x02, 0xcc},
614 {0xbf, 0xc0, 0x39, 0xcc}, 514 {0xbf, 0xc0, 0x39, 0xcc},
615 {0xbf, 0xc1, 0x04, 0xcc}, 515 {0xbf, 0xc1, 0x04, 0xcc},
616 {0xbf, 0xcc, 0x10, 0xcc}, 516 {0xbf, 0xcc, 0x00, 0xcc},
617 {0xb9, 0x12, 0x00, 0xcc},
618 {0xb9, 0x13, 0x0a, 0xcc},
619 {0xb9, 0x14, 0x0a, 0xcc},
620 {0xb9, 0x15, 0x0a, 0xcc},
621 {0xb9, 0x16, 0x0a, 0xcc},
622 {0xb9, 0x18, 0x00, 0xcc},
623 {0xb9, 0x19, 0x0f, 0xcc},
624 {0xb9, 0x1a, 0x0f, 0xcc},
625 {0xb9, 0x1b, 0x0f, 0xcc},
626 {0xb9, 0x1c, 0x0f, 0xcc},
627 {0xb8, 0x8e, 0x00, 0xcc},
628 {0xb8, 0x8f, 0xff, 0xcc},
629 {0xbc, 0x02, 0x18, 0xcc}, 517 {0xbc, 0x02, 0x18, 0xcc},
630 {0xbc, 0x03, 0x50, 0xcc}, 518 {0xbc, 0x03, 0x50, 0xcc},
631 {0xbc, 0x04, 0x18, 0xcc}, 519 {0xbc, 0x04, 0x18, 0xcc},
@@ -636,133 +524,335 @@ static const __u8 mi1310_socinitQVGA_JPG[][4] = {
636 {0xbc, 0x0a, 0x10, 0xcc}, 524 {0xbc, 0x0a, 0x10, 0xcc},
637 {0xbc, 0x0b, 0x00, 0xcc}, 525 {0xbc, 0x0b, 0x00, 0xcc},
638 {0xbc, 0x0c, 0x00, 0xcc}, 526 {0xbc, 0x0c, 0x00, 0xcc},
527 {0xb3, 0x5c, 0x01, 0xcc},
528 {0xf0, 0x00, 0x01, 0xbb},
529 {0x80, 0x00, 0x03, 0xbb},
530 {0x81, 0xc7, 0x14, 0xbb},
531 {0x82, 0xeb, 0xe8, 0xbb},
532 {0x83, 0xfe, 0xf4, 0xbb},
533 {0x84, 0xcd, 0x10, 0xbb},
534 {0x85, 0xf3, 0xee, 0xbb},
535 {0x86, 0xff, 0xf1, 0xbb},
536 {0x87, 0xcd, 0x10, 0xbb},
537 {0x88, 0xf3, 0xee, 0xbb},
538 {0x89, 0x01, 0xf1, 0xbb},
539 {0x8a, 0xe5, 0x17, 0xbb},
540 {0x8b, 0xe8, 0xe2, 0xbb},
541 {0x8c, 0xf7, 0xed, 0xbb},
542 {0x8d, 0x00, 0xff, 0xbb},
543 {0x8e, 0xec, 0x10, 0xbb},
544 {0x8f, 0xf0, 0xed, 0xbb},
545 {0x90, 0xf9, 0xf2, 0xbb},
546 {0x91, 0x00, 0x00, 0xbb},
547 {0x92, 0xe9, 0x0d, 0xbb},
548 {0x93, 0xf4, 0xf2, 0xbb},
549 {0x94, 0xfb, 0xf5, 0xbb},
550 {0x95, 0x00, 0xff, 0xbb},
551 {0xb6, 0x0f, 0x08, 0xbb},
552 {0xb7, 0x3d, 0x16, 0xbb},
553 {0xb8, 0x0c, 0x04, 0xbb},
554 {0xb9, 0x1c, 0x07, 0xbb},
555 {0xba, 0x0a, 0x03, 0xbb},
556 {0xbb, 0x1b, 0x09, 0xbb},
557 {0xbc, 0x17, 0x0d, 0xbb},
558 {0xbd, 0x23, 0x1d, 0xbb},
559 {0xbe, 0x00, 0x28, 0xbb},
560 {0xbf, 0x11, 0x09, 0xbb},
561 {0xc0, 0x16, 0x15, 0xbb},
562 {0xc1, 0x00, 0x1b, 0xbb},
563 {0xc2, 0x0e, 0x07, 0xbb},
564 {0xc3, 0x14, 0x10, 0xbb},
565 {0xc4, 0x00, 0x17, 0xbb},
566 {0x06, 0x74, 0x8e, 0xbb},
567 {0xf0, 0x00, 0x01, 0xbb},
568 {0x06, 0xf4, 0x8e, 0xbb},
569 {0x00, 0x00, 0x50, 0xdd},
570 {0x06, 0x74, 0x8e, 0xbb},
571 {0xf0, 0x00, 0x02, 0xbb},
572 {0x24, 0x50, 0x20, 0xbb},
573 {0xf0, 0x00, 0x02, 0xbb},
574 {0x34, 0x0c, 0x50, 0xbb},
639 {0xb3, 0x01, 0x41, 0xcc}, 575 {0xb3, 0x01, 0x41, 0xcc},
576 {0xf0, 0x00, 0x00, 0xbb},
577 {0x03, 0x03, 0xc0, 0xbb},
578 {},
579};
580static const u8 mi1310_socinitQVGA_JPG[][4] = {
581 {0xb0, 0x03, 0x19, 0xcc}, {0xb0, 0x04, 0x02, 0xcc},
582 {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc},
583 {0xb3, 0x05, 0x00, 0xcc}, {0xb3, 0x06, 0x00, 0xcc},
584 {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc},
585 {0xb3, 0x34, 0x02, 0xcc}, {0xb3, 0x35, 0xdd, 0xcc},
586 {0xb3, 0x02, 0x00, 0xcc}, {0xb3, 0x03, 0x0a, 0xcc},
587 {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc},
588 {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x03, 0xcc},
589 {0xb3, 0x23, 0xc0, 0xcc}, {0xb3, 0x14, 0x00, 0xcc},
590 {0xb3, 0x15, 0x00, 0xcc}, {0xb3, 0x16, 0x04, 0xcc},
591 {0xb3, 0x17, 0xff, 0xcc}, {0xb3, 0x00, 0x65, 0xcc},
592 {0xb8, 0x00, 0x00, 0xcc}, {0xbc, 0x00, 0xf0, 0xcc},
593 {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x02, 0xbb},
594 {0xc8, 0x9f, 0x0b, 0xbb}, {0x5b, 0x00, 0x01, 0xbb},
595 {0x2f, 0xde, 0x20, 0xbb}, {0xf0, 0x00, 0x00, 0xbb},
596 {0x20, 0x03, 0x02, 0xbb}, /* h/v flip */
597 {0xf0, 0x00, 0x01, 0xbb},
598 {0x05, 0x00, 0x07, 0xbb}, {0x34, 0x00, 0x00, 0xbb},
599 {0x35, 0xff, 0x00, 0xbb}, {0xdc, 0x07, 0x02, 0xbb},
600 {0xdd, 0x3c, 0x18, 0xbb}, {0xde, 0x92, 0x6d, 0xbb},
601 {0xdf, 0xcd, 0xb1, 0xbb}, {0xe0, 0xff, 0xe7, 0xbb},
602 {0x06, 0xf0, 0x0d, 0xbb}, {0x06, 0x70, 0x0e, 0xbb},
603 {0x4c, 0x00, 0x01, 0xbb}, {0x4d, 0x00, 0x01, 0xbb},
604 {0xf0, 0x00, 0x02, 0xbb}, {0x2e, 0x0c, 0x55, 0xbb},
605 {0x21, 0xb6, 0x6e, 0xbb}, {0x36, 0x30, 0x10, 0xbb},
606 {0x37, 0x00, 0xc1, 0xbb}, {0xf0, 0x00, 0x00, 0xbb},
607 {0x07, 0x00, 0x84, 0xbb}, {0x08, 0x02, 0x4a, 0xbb},
608 {0x05, 0x01, 0x10, 0xbb}, {0x06, 0x00, 0x39, 0xbb},
609 {0xf0, 0x00, 0x02, 0xbb}, {0x58, 0x02, 0x67, 0xbb},
610 {0x57, 0x02, 0x00, 0xbb}, {0x5a, 0x02, 0x67, 0xbb},
611 {0x59, 0x02, 0x00, 0xbb}, {0x5c, 0x12, 0x0d, 0xbb},
612 {0x5d, 0x16, 0x11, 0xbb}, {0x39, 0x06, 0x18, 0xbb},
613 {0x3a, 0x06, 0x18, 0xbb}, {0x3b, 0x06, 0x18, 0xbb},
614 {0x3c, 0x06, 0x18, 0xbb}, {0x64, 0x7b, 0x5b, 0xbb},
615 {0xf0, 0x00, 0x02, 0xbb}, {0x36, 0x30, 0x10, 0xbb},
616 {0x37, 0x00, 0xc0, 0xbb}, {0xbc, 0x0e, 0x00, 0xcc},
617 {0xbc, 0x0f, 0x05, 0xcc}, {0xbc, 0x10, 0xc0, 0xcc},
618 {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc},
619 {0xb6, 0x03, 0x01, 0xcc}, {0xb6, 0x02, 0x40, 0xcc},
620 {0xb6, 0x05, 0x00, 0xcc}, {0xb6, 0x04, 0xf0, 0xcc},
621 {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x25, 0xcc},
622 {0xb6, 0x18, 0x00, 0xcc}, {0xb6, 0x17, 0x96, 0xcc},
623 {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc},
624 {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc},
625 {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc},
626 {0xb3, 0x5c, 0x01, 0xcc}, {0xf0, 0x00, 0x01, 0xbb},
627 {0x80, 0x00, 0x03, 0xbb}, {0x81, 0xc7, 0x14, 0xbb},
628 {0x82, 0xeb, 0xe8, 0xbb}, {0x83, 0xfe, 0xf4, 0xbb},
629 {0x84, 0xcd, 0x10, 0xbb}, {0x85, 0xf3, 0xee, 0xbb},
630 {0x86, 0xff, 0xf1, 0xbb}, {0x87, 0xcd, 0x10, 0xbb},
631 {0x88, 0xf3, 0xee, 0xbb}, {0x89, 0x01, 0xf1, 0xbb},
632 {0x8a, 0xe5, 0x17, 0xbb}, {0x8b, 0xe8, 0xe2, 0xbb},
633 {0x8c, 0xf7, 0xed, 0xbb}, {0x8d, 0x00, 0xff, 0xbb},
634 {0x8e, 0xec, 0x10, 0xbb}, {0x8f, 0xf0, 0xed, 0xbb},
635 {0x90, 0xf9, 0xf2, 0xbb}, {0x91, 0x00, 0x00, 0xbb},
636 {0x92, 0xe9, 0x0d, 0xbb}, {0x93, 0xf4, 0xf2, 0xbb},
637 {0x94, 0xfb, 0xf5, 0xbb}, {0x95, 0x00, 0xff, 0xbb},
638 {0xb6, 0x0f, 0x08, 0xbb}, {0xb7, 0x3d, 0x16, 0xbb},
639 {0xb8, 0x0c, 0x04, 0xbb}, {0xb9, 0x1c, 0x07, 0xbb},
640 {0xba, 0x0a, 0x03, 0xbb}, {0xbb, 0x1b, 0x09, 0xbb},
641 {0xbc, 0x17, 0x0d, 0xbb}, {0xbd, 0x23, 0x1d, 0xbb},
642 {0xbe, 0x00, 0x28, 0xbb}, {0xbf, 0x11, 0x09, 0xbb},
643 {0xc0, 0x16, 0x15, 0xbb}, {0xc1, 0x00, 0x1b, 0xbb},
644 {0xc2, 0x0e, 0x07, 0xbb}, {0xc3, 0x14, 0x10, 0xbb},
645 {0xc4, 0x00, 0x17, 0xbb}, {0x06, 0x74, 0x8e, 0xbb},
646 {0xf0, 0x00, 0x01, 0xbb}, {0x06, 0xf4, 0x8e, 0xbb},
647 {0x00, 0x00, 0x50, 0xdd}, {0x06, 0x74, 0x8e, 0xbb},
648 {0xf0, 0x00, 0x02, 0xbb}, {0x24, 0x50, 0x20, 0xbb},
649 {0xf0, 0x00, 0x02, 0xbb}, {0x34, 0x0c, 0x50, 0xbb},
650 {0xb3, 0x01, 0x41, 0xcc}, {0xf0, 0x00, 0x00, 0xbb},
640 {0x03, 0x03, 0xc0, 0xbb}, 651 {0x03, 0x03, 0xc0, 0xbb},
641 {0x06, 0x00, 0x10, 0xbb},
642 {0xb6, 0x12, 0xf8, 0xcc},
643 {0xb8, 0x0c, 0x20, 0xcc},
644 {0xb8, 0x0d, 0x70, 0xcc},
645 {0xb6, 0x13, 0x13, 0xcc},
646 {0x2f, 0x00, 0xC0, 0xbb},
647 {0xb8, 0xa0, 0x12, 0xcc},
648 {}, 652 {},
649}; 653};
650static const u8 mi1310_soc_InitSXGA_JPG[][4] = { 654static const u8 mi1310_soc_InitSXGA_JPG[][4] = {
651 {0xb0, 0x03, 0x19, 0xcc}, 655 {0xb0, 0x03, 0x19, 0xcc},
652 {0xb0, 0x04, 0x02, 0xcc}, 656 {0xb0, 0x04, 0x02, 0xcc},
653 {0xb3, 0x00, 0x24, 0xcc}, 657 {0xb3, 0x00, 0x64, 0xcc},
654 {0xb3, 0x00, 0x25, 0xcc}, 658 {0xb3, 0x00, 0x65, 0xcc},
655 {0xb3, 0x05, 0x00, 0xcc}, 659 {0xb3, 0x05, 0x00, 0xcc},
656 {0xb3, 0x06, 0x01, 0xcc}, 660 {0xb3, 0x06, 0x00, 0xcc},
657 {0xb3, 0x5c, 0x01, 0xcc},
658 {0xb3, 0x08, 0x01, 0xcc}, 661 {0xb3, 0x08, 0x01, 0xcc},
659 {0xb3, 0x09, 0x0c, 0xcc}, 662 {0xb3, 0x09, 0x0c, 0xcc},
660 {0xb3, 0x34, 0x02, 0xcc}, 663 {0xb3, 0x34, 0x02, 0xcc},
661 {0xb3, 0x35, 0xdd, 0xcc}, 664 {0xb3, 0x35, 0xdd, 0xcc},
665 {0xb3, 0x02, 0x00, 0xcc},
662 {0xb3, 0x03, 0x0a, 0xcc}, 666 {0xb3, 0x03, 0x0a, 0xcc},
663 {0xb3, 0x04, 0x0d, 0xcc}, 667 {0xb3, 0x04, 0x0d, 0xcc},
664 {0xb3, 0x20, 0x00, 0xcc}, 668 {0xb3, 0x20, 0x00, 0xcc},
665 {0xb3, 0x21, 0x00, 0xcc}, 669 {0xb3, 0x21, 0x00, 0xcc},
666 {0xb3, 0x22, 0x04, 0xcc}, 670 {0xb3, 0x22, 0x03, 0xcc},
667 {0xb3, 0x23, 0x00, 0xcc}, 671 {0xb3, 0x23, 0xc0, 0xcc},
668 {0xb3, 0x14, 0x00, 0xcc}, 672 {0xb3, 0x14, 0x00, 0xcc},
669 {0xb3, 0x15, 0x00, 0xcc}, 673 {0xb3, 0x15, 0x00, 0xcc},
670 {0xb3, 0x16, 0x04, 0xcc}, 674 {0xb3, 0x16, 0x04, 0xcc},
671 {0xb3, 0x17, 0xff, 0xcc}, 675 {0xb3, 0x17, 0xff, 0xcc},
672 {0xb8, 0x01, 0x7d, 0xcc}, 676 {0xb3, 0x00, 0x65, 0xcc},
673 {0xb8, 0x81, 0x09, 0xcc}, 677 {0xb8, 0x00, 0x00, 0xcc},
674 {0xb8, 0x27, 0x20, 0xcc}, 678 {0xbc, 0x00, 0x70, 0xcc},
675 {0xb8, 0x26, 0x80, 0xcc}, 679 {0xbc, 0x01, 0x01, 0xcc},
676 {0xb8, 0x06, 0x00, 0xcc}, 680 {0xf0, 0x00, 0x02, 0xbb},
677 {0xb8, 0x07, 0x05, 0xcc}, 681 {0xc8, 0x9f, 0x0b, 0xbb},
678 {0xb8, 0x08, 0x00, 0xcc}, 682 {0x5b, 0x00, 0x01, 0xbb},
679 {0xb8, 0x09, 0x04, 0xcc},
680 {0xb3, 0x00, 0x25, 0xcc},
681 {0xb8, 0x00, 0x11, 0xcc},
682 {0xbc, 0x00, 0x71, 0xcc},
683 {0xb8, 0x81, 0x01, 0xcc},
684 {0xb8, 0x2c, 0x5a, 0xcc},
685 {0xb8, 0x2d, 0xff, 0xcc},
686 {0xb8, 0x2e, 0xee, 0xcc},
687 {0xb8, 0x2f, 0xfb, 0xcc},
688 {0xb8, 0x30, 0x52, 0xcc},
689 {0xb8, 0x31, 0xf8, 0xcc},
690 {0xb8, 0x32, 0xf1, 0xcc},
691 {0xb8, 0x33, 0xff, 0xcc},
692 {0xb8, 0x34, 0x54, 0xcc},
693 {0xf0, 0x00, 0x00, 0xbb}, 683 {0xf0, 0x00, 0x00, 0xbb},
694 {0x00, 0x01, 0x00, 0xdd}, 684 {0x20, 0x03, 0x02, 0xbb}, /* h/v flip */
695 {0x0d, 0x00, 0x09, 0xbb},
696 {0x0d, 0x00, 0x08, 0xbb},
697 {0xf0, 0x00, 0x01, 0xbb}, 685 {0xf0, 0x00, 0x01, 0xbb},
698 {0x00, 0x01, 0x00, 0xdd}, 686 {0x05, 0x00, 0x07, 0xbb},
699 {0x06, 0x00, 0x14, 0xbb}, 687 {0x34, 0x00, 0x00, 0xbb},
700 {0x3a, 0x10, 0x00, 0xbb}, 688 {0x35, 0xff, 0x00, 0xbb},
701 {0x00, 0x00, 0x10, 0xdd}, 689 {0xdc, 0x07, 0x02, 0xbb},
702 {0x9b, 0x10, 0x00, 0xbb}, 690 {0xdd, 0x3c, 0x18, 0xbb},
703 {0x00, 0x00, 0x10, 0xdd}, 691 {0xde, 0x92, 0x6d, 0xbb},
692 {0xdf, 0xcd, 0xb1, 0xbb},
693 {0xe0, 0xff, 0xe7, 0xbb},
694 {0x06, 0xf0, 0x0d, 0xbb},
695 {0x06, 0x70, 0x0e, 0xbb},
696 {0x4c, 0x00, 0x01, 0xbb},
697 {0x4d, 0x00, 0x01, 0xbb},
698 {0xf0, 0x00, 0x02, 0xbb},
699 {0x2e, 0x0c, 0x60, 0xbb},
700 {0x21, 0xb6, 0x6e, 0xbb},
701 {0x37, 0x01, 0x40, 0xbb},
704 {0xf0, 0x00, 0x00, 0xbb}, 702 {0xf0, 0x00, 0x00, 0xbb},
705 {0x00, 0x01, 0x00, 0xdd}, 703 {0x07, 0x00, 0x84, 0xbb},
706 {0x2b, 0x00, 0x28, 0xbb}, 704 {0x08, 0x02, 0x4a, 0xbb},
707 {0x2c, 0x00, 0x30, 0xbb}, 705 {0x05, 0x01, 0x10, 0xbb},
708 {0x2d, 0x00, 0x30, 0xbb}, 706 {0x06, 0x00, 0x39, 0xbb},
709 {0x2e, 0x00, 0x28, 0xbb}, 707 {0xf0, 0x00, 0x02, 0xbb},
710 {0x41, 0x00, 0xd7, 0xbb}, 708 {0x58, 0x02, 0x67, 0xbb},
711 {0x09, 0x02, 0x3a, 0xbb}, 709 {0x57, 0x02, 0x00, 0xbb},
712 {0x0c, 0x00, 0x00, 0xbb}, 710 {0x5a, 0x02, 0x67, 0xbb},
713 {0x20, 0x00, 0x00, 0xbb}, 711 {0x59, 0x02, 0x00, 0xbb},
714 {0x05, 0x00, 0x8c, 0xbb}, 712 {0x5c, 0x12, 0x0d, 0xbb},
715 {0x06, 0x00, 0x32, 0xbb}, 713 {0x5d, 0x16, 0x11, 0xbb},
716 {0x07, 0x00, 0xc6, 0xbb}, 714 {0x39, 0x06, 0x18, 0xbb},
717 {0x08, 0x00, 0x19, 0xbb}, 715 {0x3a, 0x06, 0x18, 0xbb},
718 {0x24, 0x80, 0x6f, 0xbb}, 716 {0x3b, 0x06, 0x18, 0xbb},
719 {0xc8, 0x00, 0x0f, 0xbb}, 717 {0x3c, 0x06, 0x18, 0xbb},
720 {0x20, 0x00, 0x03, 0xbb}, 718 {0x64, 0x7b, 0x5b, 0xbb},
721 {0xb6, 0x00, 0x00, 0xcc}, 719 {0xb6, 0x00, 0x00, 0xcc},
722 {0xb6, 0x03, 0x05, 0xcc}, 720 {0xb6, 0x03, 0x05, 0xcc},
723 {0xb6, 0x02, 0x00, 0xcc}, 721 {0xb6, 0x02, 0x00, 0xcc},
724 {0xb6, 0x05, 0x04, 0xcc}, 722 {0xb6, 0x05, 0x03, 0xcc},
725 {0xb6, 0x04, 0x00, 0xcc}, 723 {0xb6, 0x04, 0xc0, 0xcc},
726 {0xb6, 0x12, 0xf8, 0xcc}, 724 {0xb6, 0x12, 0xf8, 0xcc},
727 {0xb6, 0x18, 0x0a, 0xcc}, 725 {0xb6, 0x13, 0x29, 0xcc},
728 {0xb6, 0x17, 0x00, 0xcc}, 726 {0xb6, 0x18, 0x09, 0xcc},
727 {0xb6, 0x17, 0x60, 0xcc},
729 {0xb6, 0x16, 0x00, 0xcc}, 728 {0xb6, 0x16, 0x00, 0xcc},
730 {0xb6, 0x22, 0x12, 0xcc}, 729 {0xb6, 0x22, 0x12, 0xcc},
731 {0xb6, 0x23, 0x0b, 0xcc}, 730 {0xb6, 0x23, 0x0b, 0xcc},
732 {0xb3, 0x02, 0x02, 0xcc},
733 {0xbf, 0xc0, 0x39, 0xcc}, 731 {0xbf, 0xc0, 0x39, 0xcc},
734 {0xbf, 0xc1, 0x04, 0xcc}, 732 {0xbf, 0xc1, 0x04, 0xcc},
735 {0xbf, 0xcc, 0x10, 0xcc}, 733 {0xbf, 0xcc, 0x00, 0xcc},
736 {0xb9, 0x12, 0x00, 0xcc},
737 {0xb9, 0x13, 0x14, 0xcc},
738 {0xb9, 0x14, 0x14, 0xcc},
739 {0xb9, 0x15, 0x14, 0xcc},
740 {0xb9, 0x16, 0x14, 0xcc},
741 {0xb9, 0x18, 0x00, 0xcc},
742 {0xb9, 0x19, 0x1e, 0xcc},
743 {0xb9, 0x1a, 0x1e, 0xcc},
744 {0xb9, 0x1b, 0x1e, 0xcc},
745 {0xb9, 0x1c, 0x1e, 0xcc},
746 {0xb3, 0x01, 0x41, 0xcc}, 734 {0xb3, 0x01, 0x41, 0xcc},
747 {0xb8, 0x8e, 0x00, 0xcc}, 735 {0x00, 0x00, 0x80, 0xdd},
748 {0xb8, 0x8f, 0xff, 0xcc}, 736 {0xf0, 0x00, 0x02, 0xbb},
749 {0xb6, 0x12, 0xf8, 0xcc}, 737 {0x00, 0x00, 0x10, 0xdd},
750 {0xb8, 0x0c, 0x20, 0xcc}, 738 {0x22, 0xa0, 0x78, 0xbb},
751 {0xb8, 0x0d, 0x70, 0xcc}, 739 {0x23, 0xa0, 0x78, 0xbb},
752 {0xb6, 0x13, 0x13, 0xcc}, 740 {0x24, 0x7f, 0x00, 0xbb},
753 {0x2f, 0x00, 0xC0, 0xbb}, 741 {0x28, 0xea, 0x02, 0xbb},
754 {0xb8, 0xa0, 0x12, 0xcc}, 742 {0x29, 0x86, 0x7a, 0xbb},
743 {0x5e, 0x52, 0x4c, 0xbb},
744 {0x5f, 0x20, 0x24, 0xbb},
745 {0x60, 0x00, 0x02, 0xbb},
746 {0x02, 0x00, 0xee, 0xbb},
747 {0x03, 0x39, 0x23, 0xbb},
748 {0x04, 0x07, 0x24, 0xbb},
749 {0x09, 0x00, 0xc0, 0xbb},
750 {0x0a, 0x00, 0x79, 0xbb},
751 {0x0b, 0x00, 0x04, 0xbb},
752 {0x0c, 0x00, 0x5c, 0xbb},
753 {0x0d, 0x00, 0xd9, 0xbb},
754 {0x0e, 0x00, 0x53, 0xbb},
755 {0x0f, 0x00, 0x21, 0xbb},
756 {0x10, 0x00, 0xa4, 0xbb},
757 {0x11, 0x00, 0xe5, 0xbb},
758 {0x15, 0x00, 0x00, 0xbb},
759 {0x16, 0x00, 0x00, 0xbb},
760 {0x17, 0x00, 0x00, 0xbb},
761 {0x18, 0x00, 0x00, 0xbb},
762 {0x19, 0x00, 0x00, 0xbb},
763 {0x1a, 0x00, 0x00, 0xbb},
764 {0x1b, 0x00, 0x00, 0xbb},
765 {0x1c, 0x00, 0x00, 0xbb},
766 {0x1d, 0x00, 0x00, 0xbb},
767 {0x1e, 0x00, 0x00, 0xbb},
768 {0xf0, 0x00, 0x01, 0xbb},
769 {0x00, 0x00, 0x20, 0xdd},
770 {0x06, 0xf0, 0x8e, 0xbb},
771 {0x00, 0x00, 0x80, 0xdd},
772 {0x06, 0x70, 0x8e, 0xbb},
773 {0xf0, 0x00, 0x02, 0xbb},
774 {0x00, 0x00, 0x20, 0xdd},
775 {0x5e, 0x6a, 0x53, 0xbb},
776 {0x5f, 0x40, 0x2c, 0xbb},
777 {0xf0, 0x00, 0x01, 0xbb},
778 {0x00, 0x00, 0x20, 0xdd},
779 {0x58, 0x00, 0x00, 0xbb},
780 {0x53, 0x09, 0x03, 0xbb},
781 {0x54, 0x31, 0x18, 0xbb},
782 {0x55, 0x8b, 0x5f, 0xbb},
783 {0x56, 0xc0, 0xa9, 0xbb},
784 {0x57, 0xe0, 0xd2, 0xbb},
785 {0xe1, 0x00, 0x00, 0xbb},
786 {0xdc, 0x09, 0x03, 0xbb},
787 {0xdd, 0x31, 0x18, 0xbb},
788 {0xde, 0x8b, 0x5f, 0xbb},
789 {0xdf, 0xc0, 0xa9, 0xbb},
790 {0xe0, 0xe0, 0xd2, 0xbb},
791 {0xb3, 0x5c, 0x01, 0xcc},
792 {0xf0, 0x00, 0x01, 0xbb},
793 {0x06, 0xf0, 0x8e, 0xbb},
794 {0xf0, 0x00, 0x02, 0xbb},
795 {0x2f, 0xde, 0x20, 0xbb},
796 {0xf0, 0x00, 0x02, 0xbb},
797 {0x24, 0x50, 0x20, 0xbb},
798 {0xbc, 0x0e, 0x00, 0xcc},
799 {0xbc, 0x0f, 0x05, 0xcc},
800 {0xbc, 0x10, 0xc0, 0xcc},
801 {0xf0, 0x00, 0x02, 0xbb},
802 {0x34, 0x0c, 0x50, 0xbb},
803 {0xbc, 0x11, 0x03, 0xcc},
804 {0xf0, 0x00, 0x01, 0xbb},
805 {0x80, 0x00, 0x03, 0xbb},
806 {0x81, 0xc7, 0x14, 0xbb},
807 {0x82, 0xeb, 0xe8, 0xbb},
808 {0x83, 0xfe, 0xf4, 0xbb},
809 {0x84, 0xcd, 0x10, 0xbb},
810 {0x85, 0xf3, 0xee, 0xbb},
811 {0x86, 0xff, 0xf1, 0xbb},
812 {0x87, 0xcd, 0x10, 0xbb},
813 {0x88, 0xf3, 0xee, 0xbb},
814 {0x89, 0x01, 0xf1, 0xbb},
815 {0x8a, 0xe5, 0x17, 0xbb},
816 {0x8b, 0xe8, 0xe2, 0xbb},
817 {0x8c, 0xf7, 0xed, 0xbb},
818 {0x8d, 0x00, 0xff, 0xbb},
819 {0x8e, 0xec, 0x10, 0xbb},
820 {0x8f, 0xf0, 0xed, 0xbb},
821 {0x90, 0xf9, 0xf2, 0xbb},
822 {0x91, 0x00, 0x00, 0xbb},
823 {0x92, 0xe9, 0x0d, 0xbb},
824 {0x93, 0xf4, 0xf2, 0xbb},
825 {0x94, 0xfb, 0xf5, 0xbb},
826 {0x95, 0x00, 0xff, 0xbb},
827 {0xb6, 0x0f, 0x08, 0xbb},
828 {0xb7, 0x3d, 0x16, 0xbb},
829 {0xb8, 0x0c, 0x04, 0xbb},
830 {0xb9, 0x1c, 0x07, 0xbb},
831 {0xba, 0x0a, 0x03, 0xbb},
832 {0xbb, 0x1b, 0x09, 0xbb},
833 {0xbc, 0x17, 0x0d, 0xbb},
834 {0xbd, 0x23, 0x1d, 0xbb},
835 {0xbe, 0x00, 0x28, 0xbb},
836 {0xbf, 0x11, 0x09, 0xbb},
837 {0xc0, 0x16, 0x15, 0xbb},
838 {0xc1, 0x00, 0x1b, 0xbb},
839 {0xc2, 0x0e, 0x07, 0xbb},
840 {0xc3, 0x14, 0x10, 0xbb},
841 {0xc4, 0x00, 0x17, 0xbb},
842 {0x06, 0x74, 0x8e, 0xbb},
843 {0xf0, 0x00, 0x00, 0xbb},
844 {0x03, 0x03, 0xc0, 0xbb},
755 {} 845 {}
756}; 846};
757 847
758static const __u8 mi1320_gamma[17] = { 848static const u8 mi1320_gamma[17] = {
759 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, 849 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
760 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff 850 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
761}; 851};
762static const __u8 mi1320_matrix[9] = { 852static const u8 mi1320_matrix[9] = {
763 0x54, 0xda, 0x06, 0xf1, 0x50, 0xf4, 0xf7, 0xea, 0x52 853 0x54, 0xda, 0x06, 0xf1, 0x50, 0xf4, 0xf7, 0xea, 0x52
764}; 854};
765static const __u8 mi1320_initVGA_data[][4] = { 855static const u8 mi1320_initVGA_data[][4] = {
766 {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, 856 {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
767 {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, 857 {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
768 {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, 858 {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
@@ -841,7 +931,7 @@ static const __u8 mi1320_initVGA_data[][4] = {
841 {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x41, 0xcc}, 931 {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x41, 0xcc},
842 {} 932 {}
843}; 933};
844static const __u8 mi1320_initQVGA_data[][4] = { 934static const u8 mi1320_initQVGA_data[][4] = {
845 {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, 935 {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
846 {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, 936 {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
847 {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, 937 {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
@@ -948,7 +1038,7 @@ static const u8 mi1320_soc_InitVGA[][4] = {
948 {0x07, 0x00, 0xe0, 0xbb}, 1038 {0x07, 0x00, 0xe0, 0xbb},
949 {0x08, 0x00, 0x0b, 0xbb}, 1039 {0x08, 0x00, 0x0b, 0xbb},
950 {0x21, 0x00, 0x0c, 0xbb}, 1040 {0x21, 0x00, 0x0c, 0xbb},
951 {0x20, 0x01, 0x03, 0xbb}, 1041 {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
952 {0xbf, 0xc0, 0x26, 0xcc}, 1042 {0xbf, 0xc0, 0x26, 0xcc},
953 {0xbf, 0xc1, 0x02, 0xcc}, 1043 {0xbf, 0xc1, 0x02, 0xcc},
954 {0xbf, 0xcc, 0x04, 0xcc}, 1044 {0xbf, 0xcc, 0x04, 0xcc},
@@ -958,7 +1048,7 @@ static const u8 mi1320_soc_InitVGA[][4] = {
958 {0x06, 0x00, 0x11, 0xbb}, 1048 {0x06, 0x00, 0x11, 0xbb},
959 {0x07, 0x01, 0x42, 0xbb}, 1049 {0x07, 0x01, 0x42, 0xbb},
960 {0x08, 0x00, 0x11, 0xbb}, 1050 {0x08, 0x00, 0x11, 0xbb},
961 {0x20, 0x01, 0x03, 0xbb}, 1051 {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
962 {0x21, 0x80, 0x00, 0xbb}, 1052 {0x21, 0x80, 0x00, 0xbb},
963 {0x22, 0x0d, 0x0f, 0xbb}, 1053 {0x22, 0x0d, 0x0f, 0xbb},
964 {0x24, 0x80, 0x00, 0xbb}, 1054 {0x24, 0x80, 0x00, 0xbb},
@@ -1051,7 +1141,7 @@ static const u8 mi1320_soc_InitQVGA[][4] = {
1051 {0x07, 0x00, 0xe0, 0xbb}, 1141 {0x07, 0x00, 0xe0, 0xbb},
1052 {0x08, 0x00, 0x0b, 0xbb}, 1142 {0x08, 0x00, 0x0b, 0xbb},
1053 {0x21, 0x00, 0x0c, 0xbb}, 1143 {0x21, 0x00, 0x0c, 0xbb},
1054 {0x20, 0x01, 0x03, 0xbb}, 1144 {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
1055 {0xbf, 0xc0, 0x26, 0xcc}, 1145 {0xbf, 0xc0, 0x26, 0xcc},
1056 {0xbf, 0xc1, 0x02, 0xcc}, 1146 {0xbf, 0xc1, 0x02, 0xcc},
1057 {0xbf, 0xcc, 0x04, 0xcc}, 1147 {0xbf, 0xcc, 0x04, 0xcc},
@@ -1071,7 +1161,7 @@ static const u8 mi1320_soc_InitQVGA[][4] = {
1071 {0x06, 0x00, 0x11, 0xbb}, 1161 {0x06, 0x00, 0x11, 0xbb},
1072 {0x07, 0x01, 0x42, 0xbb}, 1162 {0x07, 0x01, 0x42, 0xbb},
1073 {0x08, 0x00, 0x11, 0xbb}, 1163 {0x08, 0x00, 0x11, 0xbb},
1074 {0x20, 0x01, 0x03, 0xbb}, 1164 {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
1075 {0x21, 0x80, 0x00, 0xbb}, 1165 {0x21, 0x80, 0x00, 0xbb},
1076 {0x22, 0x0d, 0x0f, 0xbb}, 1166 {0x22, 0x0d, 0x0f, 0xbb},
1077 {0x24, 0x80, 0x00, 0xbb}, 1167 {0x24, 0x80, 0x00, 0xbb},
@@ -1161,7 +1251,7 @@ static const u8 mi1320_soc_InitSXGA[][4] = {
1161 {0x00, 0x00, 0x20, 0xdd}, 1251 {0x00, 0x00, 0x20, 0xdd},
1162 {0xf0, 0x00, 0x00, 0xbb}, 1252 {0xf0, 0x00, 0x00, 0xbb},
1163 {0x00, 0x00, 0x30, 0xdd}, 1253 {0x00, 0x00, 0x30, 0xdd},
1164 {0x20, 0x01, 0x03, 0xbb}, 1254 {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
1165 {0x00, 0x00, 0x20, 0xdd}, 1255 {0x00, 0x00, 0x20, 0xdd},
1166 {0xbf, 0xc0, 0x26, 0xcc}, 1256 {0xbf, 0xc0, 0x26, 0xcc},
1167 {0xbf, 0xc1, 0x02, 0xcc}, 1257 {0xbf, 0xc1, 0x02, 0xcc},
@@ -1172,7 +1262,7 @@ static const u8 mi1320_soc_InitSXGA[][4] = {
1172 {0x06, 0x00, 0x11, 0xbb}, 1262 {0x06, 0x00, 0x11, 0xbb},
1173 {0x07, 0x01, 0x42, 0xbb}, 1263 {0x07, 0x01, 0x42, 0xbb},
1174 {0x08, 0x00, 0x11, 0xbb}, 1264 {0x08, 0x00, 0x11, 0xbb},
1175 {0x20, 0x01, 0x03, 0xbb}, 1265 {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
1176 {0x21, 0x80, 0x00, 0xbb}, 1266 {0x21, 0x80, 0x00, 0xbb},
1177 {0x22, 0x0d, 0x0f, 0xbb}, 1267 {0x22, 0x0d, 0x0f, 0xbb},
1178 {0x24, 0x80, 0x00, 0xbb}, 1268 {0x24, 0x80, 0x00, 0xbb},
@@ -1230,7 +1320,7 @@ static const u8 mi1320_soc_InitSXGA[][4] = {
1230 {0x06, 0x00, 0x11, 0xbb}, 1320 {0x06, 0x00, 0x11, 0xbb},
1231 {0x07, 0x00, 0x85, 0xbb}, 1321 {0x07, 0x00, 0x85, 0xbb},
1232 {0x08, 0x00, 0x27, 0xbb}, 1322 {0x08, 0x00, 0x27, 0xbb},
1233 {0x20, 0x01, 0x03, 0xbb}, 1323 {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
1234 {0x21, 0x80, 0x00, 0xbb}, 1324 {0x21, 0x80, 0x00, 0xbb},
1235 {0x22, 0x0d, 0x0f, 0xbb}, 1325 {0x22, 0x0d, 0x0f, 0xbb},
1236 {0x24, 0x80, 0x00, 0xbb}, 1326 {0x24, 0x80, 0x00, 0xbb},
@@ -1249,15 +1339,15 @@ static const u8 mi1320_soc_InitSXGA[][4] = {
1249 {0x64, 0x5e, 0x1c, 0xbb}, 1339 {0x64, 0x5e, 0x1c, 0xbb},
1250 {} 1340 {}
1251}; 1341};
1252static const __u8 po3130_gamma[17] = { 1342static const u8 po3130_gamma[17] = {
1253 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, 1343 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
1254 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff 1344 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
1255}; 1345};
1256static const __u8 po3130_matrix[9] = { 1346static const u8 po3130_matrix[9] = {
1257 0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63 1347 0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63
1258}; 1348};
1259 1349
1260static const __u8 po3130_initVGA_data[][4] = { 1350static const u8 po3130_initVGA_data[][4] = {
1261 {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, 1351 {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc},
1262 {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, 1352 {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc},
1263 {0xb3, 0x00, 0x04, 0xcc}, {0xb3, 0x00, 0x24, 0xcc}, 1353 {0xb3, 0x00, 0x04, 0xcc}, {0xb3, 0x00, 0x24, 0xcc},
@@ -1340,7 +1430,7 @@ static const __u8 po3130_initVGA_data[][4] = {
1340 {0xb3, 0x5c, 0x00, 0xcc}, {0xb3, 0x01, 0x41, 0xcc}, 1430 {0xb3, 0x5c, 0x00, 0xcc}, {0xb3, 0x01, 0x41, 0xcc},
1341 {} 1431 {}
1342}; 1432};
1343static const __u8 po3130_rundata[][4] = { 1433static const u8 po3130_rundata[][4] = {
1344 {0x00, 0x47, 0x45, 0xaa}, {0x00, 0x48, 0x9b, 0xaa}, 1434 {0x00, 0x47, 0x45, 0xaa}, {0x00, 0x48, 0x9b, 0xaa},
1345 {0x00, 0x49, 0x3a, 0xaa}, {0x00, 0x4a, 0x01, 0xaa}, 1435 {0x00, 0x49, 0x3a, 0xaa}, {0x00, 0x4a, 0x01, 0xaa},
1346 {0x00, 0x44, 0x40, 0xaa}, 1436 {0x00, 0x44, 0x40, 0xaa},
@@ -1355,7 +1445,7 @@ static const __u8 po3130_rundata[][4] = {
1355 {} 1445 {}
1356}; 1446};
1357 1447
1358static const __u8 po3130_initQVGA_data[][4] = { 1448static const u8 po3130_initQVGA_data[][4] = {
1359 {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, 1449 {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc},
1360 {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x09, 0xcc}, 1450 {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x09, 0xcc},
1361 {0xb3, 0x00, 0x04, 0xcc}, {0xb3, 0x00, 0x24, 0xcc}, 1451 {0xb3, 0x00, 0x04, 0xcc}, {0xb3, 0x00, 0x24, 0xcc},
@@ -1441,121 +1531,207 @@ static const __u8 po3130_initQVGA_data[][4] = {
1441 {} 1531 {}
1442}; 1532};
1443 1533
1444static const __u8 hv7131r_gamma[17] = { 1534static const u8 hv7131r_gamma[17] = {
1445/* 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, 1535 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
1446 * 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff */ 1536 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
1447 0x04, 0x1a, 0x36, 0x55, 0x6f, 0x87, 0x9d, 0xb0, 0xc1,
1448 0xcf, 0xda, 0xe4, 0xec, 0xf3, 0xf8, 0xfd, 0xff
1449}; 1537};
1450static const __u8 hv7131r_matrix[9] = { 1538static const u8 hv7131r_matrix[9] = {
1451 0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63 1539 0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63
1452}; 1540};
1453static const __u8 hv7131r_initVGA_data[][4] = { 1541static const u8 hv7131r_initVGA_data[][4] = {
1454 {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, 1542 {0xb3, 0x01, 0x01, 0xcc},
1455 {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, 1543 {0xb0, 0x03, 0x19, 0xcc},
1544 {0xb0, 0x04, 0x02, 0xcc},
1545 {0x00, 0x00, 0x20, 0xdd},
1456 {0xb3, 0x00, 0x24, 0xcc}, 1546 {0xb3, 0x00, 0x24, 0xcc},
1457 {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, 1547 {0xb3, 0x00, 0x25, 0xcc},
1458 {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, 1548 {0xb3, 0x08, 0x01, 0xcc},
1459 {0xb3, 0x06, 0x01, 0xcc}, 1549 {0xb3, 0x09, 0x0c, 0xcc},
1460 {0xb3, 0x01, 0x45, 0xcc}, {0xb3, 0x03, 0x0b, 0xcc}, 1550 {0xb3, 0x05, 0x01, 0xcc},
1461 {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, 1551 {0xb3, 0x06, 0x03, 0xcc},
1552 {0xb3, 0x01, 0x45, 0xcc},
1553 {0xb3, 0x03, 0x0b, 0xcc},
1554 {0xb3, 0x04, 0x05, 0xcc},
1555 {0xb3, 0x20, 0x00, 0xcc},
1462 {0xb3, 0x21, 0x00, 0xcc}, 1556 {0xb3, 0x21, 0x00, 0xcc},
1463 {0xb3, 0x22, 0x01, 0xcc}, {0xb3, 0x23, 0xe0, 0xcc}, 1557 {0xb3, 0x22, 0x01, 0xcc},
1464 {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, 1558 {0xb3, 0x23, 0xe0, 0xcc},
1559 {0xb3, 0x14, 0x00, 0xcc},
1560 {0xb3, 0x15, 0x02, 0xcc},
1465 {0xb3, 0x16, 0x02, 0xcc}, 1561 {0xb3, 0x16, 0x02, 0xcc},
1466 {0xb3, 0x17, 0x7f, 0xcc}, {0xb3, 0x34, 0x01, 0xcc}, 1562 {0xb3, 0x17, 0x7f, 0xcc},
1467 {0xb3, 0x35, 0x91, 0xcc}, {0xb3, 0x00, 0x27, 0xcc}, 1563 {0xb3, 0x34, 0x01, 0xcc},
1564 {0xb3, 0x35, 0x91, 0xcc},
1565 {0xb3, 0x00, 0x27, 0xcc},
1468 {0xbc, 0x00, 0x73, 0xcc}, 1566 {0xbc, 0x00, 0x73, 0xcc},
1469 {0xb8, 0x00, 0x23, 0xcc}, {0x00, 0x01, 0x0c, 0xaa}, 1567 {0xb8, 0x00, 0x23, 0xcc},
1470 {0x00, 0x14, 0x01, 0xaa}, {0x00, 0x15, 0xe6, 0xaa}, 1568 {0xb8, 0x2c, 0x50, 0xcc},
1471 {0x00, 0x16, 0x02, 0xaa}, 1569 {0xb8, 0x2d, 0xf8, 0xcc},
1472 {0x00, 0x17, 0x86, 0xaa}, {0x00, 0x23, 0x00, 0xaa}, 1570 {0xb8, 0x2e, 0xf8, 0xcc},
1473 {0x00, 0x25, 0x09, 0xaa}, {0x00, 0x26, 0x27, 0xaa}, 1571 {0xb8, 0x2f, 0xf8, 0xcc},
1474 {0x00, 0x27, 0xc0, 0xaa},
1475 {0xb8, 0x2c, 0x60, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc},
1476 {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc},
1477 {0xb8, 0x30, 0x50, 0xcc}, 1572 {0xb8, 0x30, 0x50, 0xcc},
1478 {0xb8, 0x31, 0xf8, 0xcc}, {0xb8, 0x32, 0xf8, 0xcc}, 1573 {0xb8, 0x31, 0xf8, 0xcc},
1479 {0xb8, 0x33, 0xf8, 0xcc}, {0xb8, 0x34, 0x65, 0xcc}, 1574 {0xb8, 0x32, 0xf8, 0xcc},
1575 {0xb8, 0x33, 0xf8, 0xcc},
1576 {0xb8, 0x34, 0x58, 0xcc},
1480 {0xb8, 0x35, 0x00, 0xcc}, 1577 {0xb8, 0x35, 0x00, 0xcc},
1481 {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc}, 1578 {0xb8, 0x36, 0x00, 0xcc},
1482 {0xb8, 0x27, 0x20, 0xcc}, {0xb8, 0x01, 0x7d, 0xcc}, 1579 {0xb8, 0x37, 0x00, 0xcc},
1580 {0xb8, 0x27, 0x20, 0xcc},
1581 {0xb8, 0x01, 0x7d, 0xcc},
1483 {0xb8, 0x81, 0x09, 0xcc}, 1582 {0xb8, 0x81, 0x09, 0xcc},
1484 {0xb3, 0x01, 0x41, 0xcc}, {0xb8, 0xfe, 0x00, 0xcc}, 1583 {0xb3, 0x01, 0x41, 0xcc},
1485 {0xb8, 0xff, 0x28, 0xcc}, {0xb9, 0x00, 0x28, 0xcc}, 1584 {0xb8, 0x8e, 0x00, 0xcc},
1486 {0xb9, 0x01, 0x28, 0xcc}, 1585 {0xb8, 0x8f, 0xff, 0xcc},
1487 {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc}, 1586 {0x00, 0x01, 0x0c, 0xaa},
1488 {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc}, 1587 {0x00, 0x14, 0x01, 0xaa},
1489 {0xb9, 0x06, 0x3c, 0xcc}, 1588 {0x00, 0x15, 0xe6, 0xaa},
1490 {0xb9, 0x07, 0x3c, 0xcc}, {0xb9, 0x08, 0x3c, 0xcc}, 1589 {0x00, 0x16, 0x02, 0xaa},
1491 {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, 1590 {0x00, 0x17, 0x86, 0xaa},
1591 {0x00, 0x23, 0x00, 0xaa},
1592 {0x00, 0x25, 0x03, 0xaa},
1593 {0x00, 0x26, 0xa9, 0xaa},
1594 {0x00, 0x27, 0x80, 0xaa},
1492 {0x00, 0x30, 0x18, 0xaa}, 1595 {0x00, 0x30, 0x18, 0xaa},
1596 {0xb6, 0x00, 0x00, 0xcc},
1597 {0xb6, 0x03, 0x02, 0xcc},
1598 {0xb6, 0x02, 0x80, 0xcc},
1599 {0xb6, 0x05, 0x01, 0xcc},
1600 {0xb6, 0x04, 0xe0, 0xcc},
1601 {0xb6, 0x12, 0x78, 0xcc},
1602 {0xb6, 0x18, 0x02, 0xcc},
1603 {0xb6, 0x17, 0x58, 0xcc},
1604 {0xb6, 0x16, 0x00, 0xcc},
1605 {0xb6, 0x22, 0x12, 0xcc},
1606 {0xb6, 0x23, 0x0b, 0xcc},
1607 {0xb3, 0x02, 0x02, 0xcc},
1608 {0xbf, 0xc0, 0x39, 0xcc},
1609 {0xbf, 0xc1, 0x04, 0xcc},
1610 {0xbf, 0xcc, 0x10, 0xcc},
1611 {0xb6, 0x12, 0xf8, 0xcc},
1612 {0xb6, 0x13, 0x13, 0xcc},
1613 {0xb9, 0x12, 0x00, 0xcc},
1614 {0xb9, 0x13, 0x0a, 0xcc},
1615 {0xb9, 0x14, 0x0a, 0xcc},
1616 {0xb9, 0x15, 0x0a, 0xcc},
1617 {0xb9, 0x16, 0x0a, 0xcc},
1618 {0xb8, 0x0c, 0x20, 0xcc},
1619 {0xb8, 0x0d, 0x70, 0xcc},
1620 {0xb9, 0x18, 0x00, 0xcc},
1621 {0xb9, 0x19, 0x0f, 0xcc},
1622 {0xb9, 0x1a, 0x0f, 0xcc},
1623 {0xb9, 0x1b, 0x0f, 0xcc},
1624 {0xb9, 0x1c, 0x0f, 0xcc},
1625 {0xb3, 0x5c, 0x01, 0xcc},
1493 {} 1626 {}
1494}; 1627};
1495 1628
1496static const __u8 hv7131r_initQVGA_data[][4] = { 1629static const u8 hv7131r_initQVGA_data[][4] = {
1497 {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, 1630 {0xb3, 0x01, 0x01, 0xcc},
1498 {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, 1631 {0xb0, 0x03, 0x19, 0xcc},
1632 {0xb0, 0x04, 0x02, 0xcc},
1633 {0x00, 0x00, 0x20, 0xdd},
1499 {0xb3, 0x00, 0x24, 0xcc}, 1634 {0xb3, 0x00, 0x24, 0xcc},
1500 {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, 1635 {0xb3, 0x00, 0x25, 0xcc},
1501 {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, 1636 {0xb3, 0x08, 0x01, 0xcc},
1502 {0xb3, 0x06, 0x01, 0xcc}, 1637 {0xb3, 0x09, 0x0c, 0xcc},
1503 {0xb3, 0x03, 0x0b, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, 1638 {0xb3, 0x05, 0x01, 0xcc},
1504 {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc}, 1639 {0xb3, 0x06, 0x03, 0xcc},
1640 {0xb3, 0x01, 0x45, 0xcc},
1641 {0xb3, 0x03, 0x0b, 0xcc},
1642 {0xb3, 0x04, 0x05, 0xcc},
1643 {0xb3, 0x20, 0x00, 0xcc},
1644 {0xb3, 0x21, 0x00, 0xcc},
1505 {0xb3, 0x22, 0x01, 0xcc}, 1645 {0xb3, 0x22, 0x01, 0xcc},
1506 {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x14, 0x00, 0xcc}, 1646 {0xb3, 0x23, 0xe0, 0xcc},
1507 {0xb3, 0x15, 0x00, 0xcc}, {0xb3, 0x16, 0x02, 0xcc}, 1647 {0xb3, 0x14, 0x00, 0xcc},
1648 {0xb3, 0x15, 0x02, 0xcc},
1649 {0xb3, 0x16, 0x02, 0xcc},
1508 {0xb3, 0x17, 0x7f, 0xcc}, 1650 {0xb3, 0x17, 0x7f, 0xcc},
1509 {0xb3, 0x34, 0x01, 0xcc}, {0xb3, 0x35, 0x91, 0xcc}, 1651 {0xb3, 0x34, 0x01, 0xcc},
1510 {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0xd1, 0xcc}, 1652 {0xb3, 0x35, 0x91, 0xcc},
1511 {0xb8, 0x00, 0x21, 0xcc}, 1653 {0xb3, 0x00, 0x27, 0xcc},
1512 {0x00, 0x01, 0x0c, 0xaa}, {0x00, 0x14, 0x01, 0xaa}, 1654 {0xbc, 0x00, 0xd3, 0xcc},
1513 {0x00, 0x15, 0xe6, 0xaa}, {0x00, 0x16, 0x02, 0xaa}, 1655 {0xb8, 0x00, 0x23, 0xcc},
1514 {0x00, 0x17, 0x86, 0xaa}, 1656 {0xb8, 0x2c, 0x50, 0xcc},
1515 {0x00, 0x23, 0x00, 0xaa}, {0x00, 0x25, 0x01, 0xaa}, 1657 {0xb8, 0x2d, 0xf8, 0xcc},
1516 {0x00, 0x26, 0xd4, 0xaa}, {0x00, 0x27, 0xc0, 0xaa}, 1658 {0xb8, 0x2e, 0xf8, 0xcc},
1517 {0xbc, 0x02, 0x08, 0xcc}, 1659 {0xb8, 0x2f, 0xf8, 0xcc},
1518 {0xbc, 0x03, 0x70, 0xcc}, {0xbc, 0x04, 0x08, 0xcc},
1519 {0xbc, 0x05, 0x00, 0xcc}, {0xbc, 0x06, 0x00, 0xcc},
1520 {0xbc, 0x08, 0x3c, 0xcc},
1521 {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x04, 0xcc},
1522 {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc},
1523 {0xb8, 0xfe, 0x02, 0xcc},
1524 {0xb8, 0xff, 0x07, 0xcc}, {0xb9, 0x00, 0x14, 0xcc},
1525 {0xb9, 0x01, 0x14, 0xcc}, {0xb9, 0x02, 0x14, 0xcc},
1526 {0xb9, 0x03, 0x00, 0xcc},
1527 {0xb9, 0x04, 0x02, 0xcc}, {0xb9, 0x05, 0x05, 0xcc},
1528 {0xb9, 0x06, 0x0f, 0xcc}, {0xb9, 0x07, 0x0f, 0xcc},
1529 {0xb9, 0x08, 0x0f, 0xcc},
1530 {0xb8, 0x2c, 0x60, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc},
1531 {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc},
1532 {0xb8, 0x30, 0x50, 0xcc}, 1660 {0xb8, 0x30, 0x50, 0xcc},
1533 {0xb8, 0x31, 0xf8, 0xcc}, {0xb8, 0x32, 0xf8, 0xcc}, 1661 {0xb8, 0x31, 0xf8, 0xcc},
1662 {0xb8, 0x32, 0xf8, 0xcc},
1534 {0xb8, 0x33, 0xf8, 0xcc}, 1663 {0xb8, 0x33, 0xf8, 0xcc},
1535 {0xb8, 0x34, 0x65, 0xcc}, {0xb8, 0x35, 0x00, 0xcc}, 1664 {0xb8, 0x34, 0x58, 0xcc},
1536 {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc}, 1665 {0xb8, 0x35, 0x00, 0xcc},
1666 {0xb8, 0x36, 0x00, 0xcc},
1667 {0xb8, 0x37, 0x00, 0xcc},
1537 {0xb8, 0x27, 0x20, 0xcc}, 1668 {0xb8, 0x27, 0x20, 0xcc},
1538 {0xb8, 0x01, 0x7d, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, 1669 {0xb8, 0x01, 0x7d, 0xcc},
1539 {0xb3, 0x01, 0x41, 0xcc}, {0xb8, 0xfe, 0x00, 0xcc}, 1670 {0xb8, 0x81, 0x09, 0xcc},
1540 {0xb8, 0xff, 0x28, 0xcc}, 1671 {0xb3, 0x01, 0x41, 0xcc},
1541 {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc},
1542 {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc},
1543 {0xb9, 0x04, 0x00, 0xcc},
1544 {0xb9, 0x05, 0x3c, 0xcc}, {0xb9, 0x06, 0x3c, 0xcc},
1545 {0xb9, 0x07, 0x3c, 0xcc}, {0xb9, 0x08, 0x3c, 0xcc},
1546 {0xb8, 0x8e, 0x00, 0xcc}, 1672 {0xb8, 0x8e, 0x00, 0xcc},
1547 {0xb8, 0x8f, 0xff, 0xcc}, {0x00, 0x30, 0x18, 0xaa}, 1673 {0xb8, 0x8f, 0xff, 0xcc},
1674 {0x00, 0x01, 0x0c, 0xaa},
1675 {0x00, 0x14, 0x01, 0xaa},
1676 {0x00, 0x15, 0xe6, 0xaa},
1677 {0x00, 0x16, 0x02, 0xaa},
1678 {0x00, 0x17, 0x86, 0xaa},
1679 {0x00, 0x23, 0x00, 0xaa},
1680 {0x00, 0x25, 0x03, 0xaa},
1681 {0x00, 0x26, 0xa9, 0xaa},
1682 {0x00, 0x27, 0x80, 0xaa},
1683 {0x00, 0x30, 0x18, 0xaa},
1684 {0xb6, 0x00, 0x00, 0xcc},
1685 {0xb6, 0x03, 0x01, 0xcc},
1686 {0xb6, 0x02, 0x40, 0xcc},
1687 {0xb6, 0x05, 0x00, 0xcc},
1688 {0xb6, 0x04, 0xf0, 0xcc},
1689 {0xb6, 0x12, 0x78, 0xcc},
1690 {0xb6, 0x18, 0x00, 0xcc},
1691 {0xb6, 0x17, 0x96, 0xcc},
1692 {0xb6, 0x16, 0x00, 0xcc},
1693 {0xb6, 0x22, 0x12, 0xcc},
1694 {0xb6, 0x23, 0x0b, 0xcc},
1695 {0xb3, 0x02, 0x02, 0xcc},
1696 {0xbf, 0xc0, 0x39, 0xcc},
1697 {0xbf, 0xc1, 0x04, 0xcc},
1698 {0xbf, 0xcc, 0x10, 0xcc},
1699 {0xbc, 0x02, 0x18, 0xcc},
1700 {0xbc, 0x03, 0x50, 0xcc},
1701 {0xbc, 0x04, 0x18, 0xcc},
1702 {0xbc, 0x05, 0x00, 0xcc},
1703 {0xbc, 0x06, 0x00, 0xcc},
1704 {0xbc, 0x08, 0x30, 0xcc},
1705 {0xbc, 0x09, 0x40, 0xcc},
1706 {0xbc, 0x0a, 0x10, 0xcc},
1707 {0xbc, 0x0b, 0x00, 0xcc},
1708 {0xbc, 0x0c, 0x00, 0xcc},
1709 {0xb9, 0x12, 0x00, 0xcc},
1710 {0xb9, 0x13, 0x0a, 0xcc},
1711 {0xb9, 0x14, 0x0a, 0xcc},
1712 {0xb9, 0x15, 0x0a, 0xcc},
1713 {0xb9, 0x16, 0x0a, 0xcc},
1714 {0xb9, 0x18, 0x00, 0xcc},
1715 {0xb9, 0x19, 0x0f, 0xcc},
1716 {0xb8, 0x0c, 0x20, 0xcc},
1717 {0xb8, 0x0d, 0x70, 0xcc},
1718 {0xb9, 0x1a, 0x0f, 0xcc},
1719 {0xb9, 0x1b, 0x0f, 0xcc},
1720 {0xb9, 0x1c, 0x0f, 0xcc},
1721 {0xb6, 0x12, 0xf8, 0xcc},
1722 {0xb6, 0x13, 0x13, 0xcc},
1723 {0xb3, 0x5c, 0x01, 0xcc},
1548 {} 1724 {}
1549}; 1725};
1550 1726
1551static const __u8 ov7660_gamma[17] = { 1727static const u8 ov7660_gamma[17] = {
1552 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, 1728 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
1553 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff 1729 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
1554}; 1730};
1555static const __u8 ov7660_matrix[9] = { 1731static const u8 ov7660_matrix[9] = {
1556 0x5a, 0xf0, 0xf6, 0xf3, 0x57, 0xf6, 0xf3, 0xef, 0x62 1732 0x5a, 0xf0, 0xf6, 0xf3, 0x57, 0xf6, 0xf3, 0xef, 0x62
1557}; 1733};
1558static const __u8 ov7660_initVGA_data[][4] = { 1734static const u8 ov7660_initVGA_data[][4] = {
1559 {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, 1735 {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc},
1560 {0x00, 0x00, 0x50, 0xdd}, 1736 {0x00, 0x00, 0x50, 0xdd},
1561 {0xb0, 0x03, 0x01, 0xcc}, 1737 {0xb0, 0x03, 0x01, 0xcc},
@@ -1613,7 +1789,7 @@ static const __u8 ov7660_initVGA_data[][4] = {
1613 {0x00, 0x29, 0x3c, 0xaa}, {0xb3, 0x01, 0x45, 0xcc}, 1789 {0x00, 0x29, 0x3c, 0xaa}, {0xb3, 0x01, 0x45, 0xcc},
1614 {} 1790 {}
1615}; 1791};
1616static const __u8 ov7660_initQVGA_data[][4] = { 1792static const u8 ov7660_initQVGA_data[][4] = {
1617 {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, 1793 {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc},
1618 {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, 1794 {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc},
1619 {0xb3, 0x00, 0x21, 0xcc}, {0xb3, 0x00, 0x26, 0xcc}, 1795 {0xb3, 0x00, 0x21, 0xcc}, {0xb3, 0x00, 0x26, 0xcc},
@@ -1682,26 +1858,26 @@ static const __u8 ov7660_initQVGA_data[][4] = {
1682 {} 1858 {}
1683}; 1859};
1684 1860
1685static const __u8 ov7660_50HZ[][4] = { 1861static const u8 ov7660_50HZ[][4] = {
1686 {0x00, 0x3b, 0x08, 0xaa}, 1862 {0x00, 0x3b, 0x08, 0xaa},
1687 {0x00, 0x9d, 0x40, 0xaa}, 1863 {0x00, 0x9d, 0x40, 0xaa},
1688 {0x00, 0x13, 0xa7, 0xaa}, 1864 {0x00, 0x13, 0xa7, 0xaa},
1689 {} 1865 {}
1690}; 1866};
1691 1867
1692static const __u8 ov7660_60HZ[][4] = { 1868static const u8 ov7660_60HZ[][4] = {
1693 {0x00, 0x3b, 0x00, 0xaa}, 1869 {0x00, 0x3b, 0x00, 0xaa},
1694 {0x00, 0x9e, 0x40, 0xaa}, 1870 {0x00, 0x9e, 0x40, 0xaa},
1695 {0x00, 0x13, 0xa7, 0xaa}, 1871 {0x00, 0x13, 0xa7, 0xaa},
1696 {} 1872 {}
1697}; 1873};
1698 1874
1699static const __u8 ov7660_NoFliker[][4] = { 1875static const u8 ov7660_NoFliker[][4] = {
1700 {0x00, 0x13, 0x87, 0xaa}, 1876 {0x00, 0x13, 0x87, 0xaa},
1701 {} 1877 {}
1702}; 1878};
1703 1879
1704static const __u8 ov7670_initVGA_JPG[][4] = { 1880static const u8 ov7670_initVGA_JPG[][4] = {
1705 {0xb3, 0x01, 0x05, 0xcc}, 1881 {0xb3, 0x01, 0x05, 0xcc},
1706 {0x00, 0x00, 0x30, 0xdd}, {0xb0, 0x03, 0x19, 0xcc}, 1882 {0x00, 0x00, 0x30, 0xdd}, {0xb0, 0x03, 0x19, 0xcc},
1707 {0x00, 0x00, 0x10, 0xdd}, 1883 {0x00, 0x00, 0x10, 0xdd},
@@ -1831,7 +2007,7 @@ static const __u8 ov7670_initVGA_JPG[][4] = {
1831 {}, 2007 {},
1832}; 2008};
1833 2009
1834static const __u8 ov7670_initQVGA_JPG[][4] = { 2010static const u8 ov7670_initQVGA_JPG[][4] = {
1835 {0xb3, 0x01, 0x05, 0xcc}, {0x00, 0x00, 0x30, 0xdd}, 2011 {0xb3, 0x01, 0x05, 0xcc}, {0x00, 0x00, 0x30, 0xdd},
1836 {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x10, 0xdd}, 2012 {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x10, 0xdd},
1837 {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x10, 0xdd}, 2013 {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x10, 0xdd},
@@ -1966,14 +2142,14 @@ static const __u8 ov7670_initQVGA_JPG[][4] = {
1966}; 2142};
1967 2143
1968/* PO1200 - values from usbvm326.inf and ms-win trace */ 2144/* PO1200 - values from usbvm326.inf and ms-win trace */
1969static const __u8 po1200_gamma[17] = { 2145static const u8 po1200_gamma[17] = {
1970 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, 2146 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
1971 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff 2147 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
1972}; 2148};
1973static const __u8 po1200_matrix[9] = { 2149static const u8 po1200_matrix[9] = {
1974 0x60, 0xf9, 0xe5, 0xe7, 0x50, 0x05, 0xf3, 0xe6, 0x5e 2150 0x60, 0xf9, 0xe5, 0xe7, 0x50, 0x05, 0xf3, 0xe6, 0x5e
1975}; 2151};
1976static const __u8 po1200_initVGA_data[][4] = { 2152static const u8 po1200_initVGA_data[][4] = {
1977 {0xb0, 0x03, 0x19, 0xcc}, /* reset? */ 2153 {0xb0, 0x03, 0x19, 0xcc}, /* reset? */
1978 {0xb0, 0x03, 0x19, 0xcc}, 2154 {0xb0, 0x03, 0x19, 0xcc},
1979/* {0x00, 0x00, 0x33, 0xdd}, */ 2155/* {0x00, 0x00, 0x33, 0xdd}, */
@@ -2276,9 +2452,9 @@ static const struct sensor_info sensor_info_data[] = {
2276 2452
2277/* read 'len' bytes in gspca_dev->usb_buf */ 2453/* read 'len' bytes in gspca_dev->usb_buf */
2278static void reg_r(struct gspca_dev *gspca_dev, 2454static void reg_r(struct gspca_dev *gspca_dev,
2279 __u16 req, 2455 u16 req,
2280 __u16 index, 2456 u16 index,
2281 __u16 len) 2457 u16 len)
2282{ 2458{
2283 usb_control_msg(gspca_dev->dev, 2459 usb_control_msg(gspca_dev->dev,
2284 usb_rcvctrlpipe(gspca_dev->dev, 0), 2460 usb_rcvctrlpipe(gspca_dev->dev, 0),
@@ -2290,9 +2466,9 @@ static void reg_r(struct gspca_dev *gspca_dev,
2290} 2466}
2291 2467
2292static void reg_w(struct usb_device *dev, 2468static void reg_w(struct usb_device *dev,
2293 __u16 req, 2469 u16 req,
2294 __u16 value, 2470 u16 value,
2295 __u16 index) 2471 u16 index)
2296{ 2472{
2297 usb_control_msg(dev, 2473 usb_control_msg(dev,
2298 usb_sndctrlpipe(dev, 0), 2474 usb_sndctrlpipe(dev, 0),
@@ -2342,11 +2518,18 @@ static u16 read_sensor_register(struct gspca_dev *gspca_dev,
2342 2518
2343static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) 2519static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
2344{ 2520{
2521 struct sd *sd = (struct sd *) gspca_dev;
2345 struct usb_device *dev = gspca_dev->dev; 2522 struct usb_device *dev = gspca_dev->dev;
2346 int i; 2523 int i;
2347 u16 value; 2524 u16 value;
2348 const struct sensor_info *ptsensor_info; 2525 const struct sensor_info *ptsensor_info;
2349 2526
2527/*fixme: should also check the other sensor (back mi1320_soc, front mc501cb)*/
2528 if (sd->flags & FL_SAMSUNG) {
2529 reg_w(dev, 0xa0, 0x01, 0xb301);
2530 reg_w(dev, 0x89, 0xf0ff, 0xffff); /* select the back sensor */
2531 }
2532
2350 reg_r(gspca_dev, 0xa1, 0xbfcf, 1); 2533 reg_r(gspca_dev, 0xa1, 0xbfcf, 1);
2351 PDEBUG(D_PROBE, "check sensor header %02x", gspca_dev->usb_buf[0]); 2534 PDEBUG(D_PROBE, "check sensor header %02x", gspca_dev->usb_buf[0]);
2352 for (i = 0; i < ARRAY_SIZE(sensor_info_data); i++) { 2535 for (i = 0; i < ARRAY_SIZE(sensor_info_data); i++) {
@@ -2406,17 +2589,17 @@ static void i2c_write(struct gspca_dev *gspca_dev,
2406} 2589}
2407 2590
2408static void put_tab_to_reg(struct gspca_dev *gspca_dev, 2591static void put_tab_to_reg(struct gspca_dev *gspca_dev,
2409 const __u8 *tab, __u8 tabsize, __u16 addr) 2592 const u8 *tab, u8 tabsize, u16 addr)
2410{ 2593{
2411 int j; 2594 int j;
2412 __u16 ad = addr; 2595 u16 ad = addr;
2413 2596
2414 for (j = 0; j < tabsize; j++) 2597 for (j = 0; j < tabsize; j++)
2415 reg_w(gspca_dev->dev, 0xa0, tab[j], ad++); 2598 reg_w(gspca_dev->dev, 0xa0, tab[j], ad++);
2416} 2599}
2417 2600
2418static void usb_exchange(struct gspca_dev *gspca_dev, 2601static void usb_exchange(struct gspca_dev *gspca_dev,
2419 const __u8 data[][4]) 2602 const u8 data[][4])
2420{ 2603{
2421 struct usb_device *dev = gspca_dev->dev; 2604 struct usb_device *dev = gspca_dev->dev;
2422 int i = 0; 2605 int i = 0;
@@ -2466,7 +2649,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
2466 }; 2649 };
2467 2650
2468 cam = &gspca_dev->cam; 2651 cam = &gspca_dev->cam;
2469 sd->bridge = id->driver_info; 2652 sd->bridge = id->driver_info >> 8;
2653 sd->flags = id->driver_info & 0xff;
2470 sensor = vc032x_probe_sensor(gspca_dev); 2654 sensor = vc032x_probe_sensor(gspca_dev);
2471 switch (sensor) { 2655 switch (sensor) {
2472 case -1: 2656 case -1:
@@ -2519,8 +2703,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
2519 case SENSOR_MI1320_SOC: 2703 case SENSOR_MI1320_SOC:
2520 cam->cam_mode = bi_mode; 2704 cam->cam_mode = bi_mode;
2521 cam->nmodes = ARRAY_SIZE(bi_mode); 2705 cam->nmodes = ARRAY_SIZE(bi_mode);
2522 cam->input_flags = V4L2_IN_ST_VFLIP |
2523 V4L2_IN_ST_HFLIP;
2524 break; 2706 break;
2525 default: 2707 default:
2526 cam->cam_mode = vc0323_mode; 2708 cam->cam_mode = vc0323_mode;
@@ -2532,14 +2714,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
2532 2714
2533 sd->hflip = HFLIP_DEF; 2715 sd->hflip = HFLIP_DEF;
2534 sd->vflip = VFLIP_DEF; 2716 sd->vflip = VFLIP_DEF;
2535 if (sd->sensor == SENSOR_OV7670) { 2717 if (sd->sensor == SENSOR_OV7670)
2536 sd->hflip = 1; 2718 sd->flags |= FL_HFLIP | FL_VFLIP;
2537 sd->vflip = 1;
2538 }
2539 sd->lightfreq = FREQ_DEF; 2719 sd->lightfreq = FREQ_DEF;
2540 if (sd->sensor != SENSOR_OV7670) 2720 if (sd->sensor != SENSOR_OV7670)
2541 gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX); 2721 gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX);
2542 switch (sd->sensor) { 2722 switch (sd->sensor) {
2723 case SENSOR_MI1310_SOC:
2724 case SENSOR_MI1320_SOC:
2543 case SENSOR_OV7660: 2725 case SENSOR_OV7660:
2544 case SENSOR_OV7670: 2726 case SENSOR_OV7670:
2545 case SENSOR_PO1200: 2727 case SENSOR_PO1200:
@@ -2568,39 +2750,50 @@ static int sd_init(struct gspca_dev *gspca_dev)
2568 return 0; 2750 return 0;
2569} 2751}
2570 2752
2571/* for OV7660 and OV7670 only */ 2753/* some sensors only */
2572static void sethvflip(struct gspca_dev *gspca_dev) 2754static void sethvflip(struct gspca_dev *gspca_dev)
2573{ 2755{
2574 struct sd *sd = (struct sd *) gspca_dev; 2756 struct sd *sd = (struct sd *) gspca_dev;
2575 __u8 data; 2757 u8 data[2], hflip, vflip;
2576 2758
2759 hflip = sd->hflip;
2760 if (sd->flags & FL_HFLIP)
2761 hflip = !hflip;
2762 vflip = sd->vflip;
2763 if (sd->flags & FL_VFLIP)
2764 vflip = !vflip;
2577 switch (sd->sensor) { 2765 switch (sd->sensor) {
2578 case SENSOR_OV7660: 2766 case SENSOR_MI1310_SOC:
2579 data = 1; 2767 case SENSOR_MI1320_SOC:
2768 data[0] = data[1] = 0; /* select page 0 */
2769 i2c_write(gspca_dev, 0xf0, data, 2);
2770 data[0] = sd->sensor == SENSOR_MI1310_SOC ? 0x03 : 0x01;
2771 data[1] = 0x02 * hflip
2772 | 0x01 * vflip;
2773 i2c_write(gspca_dev, 0x20, data, 2);
2580 break; 2774 break;
2775 case SENSOR_OV7660:
2581 case SENSOR_OV7670: 2776 case SENSOR_OV7670:
2582 data = 7; 2777 data[0] = sd->sensor == SENSOR_OV7660 ? 0x01 : 0x07;
2778 data[0] |= OV7660_MVFP_MIRROR * hflip
2779 | OV7660_MVFP_VFLIP * vflip;
2780 i2c_write(gspca_dev, OV7660_REG_MVFP, data, 1);
2583 break; 2781 break;
2584 case SENSOR_PO1200: 2782 case SENSOR_PO1200:
2585 data = 0; 2783 data[0] = 0;
2586 i2c_write(gspca_dev, 0x03, &data, 1); 2784 i2c_write(gspca_dev, 0x03, data, 1);
2587 data = 0x80 * sd->hflip 2785 data[0] = 0x80 * hflip
2588 | 0x40 * sd->vflip 2786 | 0x40 * vflip
2589 | 0x06; 2787 | 0x06;
2590 i2c_write(gspca_dev, 0x1e, &data, 1); 2788 i2c_write(gspca_dev, 0x1e, data, 1);
2591 return; 2789 break;
2592 default:
2593 return;
2594 } 2790 }
2595 data |= OV7660_MVFP_MIRROR * sd->hflip
2596 | OV7660_MVFP_VFLIP * sd->vflip;
2597 i2c_write(gspca_dev, OV7660_REG_MVFP, &data, 1);
2598} 2791}
2599 2792
2600static void setlightfreq(struct gspca_dev *gspca_dev) 2793static void setlightfreq(struct gspca_dev *gspca_dev)
2601{ 2794{
2602 struct sd *sd = (struct sd *) gspca_dev; 2795 struct sd *sd = (struct sd *) gspca_dev;
2603 static const __u8 (*ov7660_freq_tb[3])[4] = 2796 static const u8 (*ov7660_freq_tb[3])[4] =
2604 {ov7660_NoFliker, ov7660_50HZ, ov7660_60HZ}; 2797 {ov7660_NoFliker, ov7660_50HZ, ov7660_60HZ};
2605 2798
2606 if (sd->sensor != SENSOR_OV7660) 2799 if (sd->sensor != SENSOR_OV7660)
@@ -2612,7 +2805,7 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
2612static void setsharpness(struct gspca_dev *gspca_dev) 2805static void setsharpness(struct gspca_dev *gspca_dev)
2613{ 2806{
2614 struct sd *sd = (struct sd *) gspca_dev; 2807 struct sd *sd = (struct sd *) gspca_dev;
2615 __u8 data; 2808 u8 data;
2616 2809
2617 if (sd->sensor != SENSOR_PO1200) 2810 if (sd->sensor != SENSOR_PO1200)
2618 return; 2811 return;
@@ -2625,9 +2818,9 @@ static void setsharpness(struct gspca_dev *gspca_dev)
2625static int sd_start(struct gspca_dev *gspca_dev) 2818static int sd_start(struct gspca_dev *gspca_dev)
2626{ 2819{
2627 struct sd *sd = (struct sd *) gspca_dev; 2820 struct sd *sd = (struct sd *) gspca_dev;
2628 const __u8 (*init)[4]; 2821 const u8 (*init)[4];
2629 const __u8 *GammaT = NULL; 2822 const u8 *GammaT = NULL;
2630 const __u8 *MatrixT = NULL; 2823 const u8 *MatrixT = NULL;
2631 int mode; 2824 int mode;
2632 static const u8 (*mi1320_soc_init[])[4] = { 2825 static const u8 (*mi1320_soc_init[])[4] = {
2633 mi1320_soc_InitSXGA, 2826 mi1320_soc_InitSXGA,
@@ -2635,6 +2828,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
2635 mi1320_soc_InitQVGA, 2828 mi1320_soc_InitQVGA,
2636 }; 2829 };
2637 2830
2831/*fixme: back sensor only*/
2832 if (sd->flags & FL_SAMSUNG) {
2833 reg_w(gspca_dev->dev, 0x89, 0xf0ff, 0xffff);
2834 reg_w(gspca_dev->dev, 0xa9, 0x8348, 0x000e);
2835 reg_w(gspca_dev->dev, 0xa9, 0x0000, 0x001a);
2836 }
2837
2638 /* Assume start use the good resolution from gspca_dev->mode */ 2838 /* Assume start use the good resolution from gspca_dev->mode */
2639 if (sd->bridge == BRIDGE_VC0321) { 2839 if (sd->bridge == BRIDGE_VC0321) {
2640 reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfec); 2840 reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfec);
@@ -2737,16 +2937,22 @@ static int sd_start(struct gspca_dev *gspca_dev)
2737 put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c); 2937 put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c);
2738 2938
2739 /* set the led on 0x0892 0x0896 */ 2939 /* set the led on 0x0892 0x0896 */
2740 if (sd->sensor != SENSOR_PO1200) { 2940 switch (sd->sensor) {
2741 reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff); 2941 case SENSOR_PO1200:
2742 msleep(100); 2942 case SENSOR_HV7131R:
2743 sethvflip(gspca_dev);
2744 setlightfreq(gspca_dev);
2745 } else {
2746 setsharpness(gspca_dev);
2747 sethvflip(gspca_dev);
2748 reg_w(gspca_dev->dev, 0x89, 0x0400, 0x1415); 2943 reg_w(gspca_dev->dev, 0x89, 0x0400, 0x1415);
2944 break;
2945 case SENSOR_MI1310_SOC:
2946 reg_w(gspca_dev->dev, 0x89, 0x058c, 0x0000);
2947 break;
2948 default:
2949 reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
2950 break;
2749 } 2951 }
2952 msleep(100);
2953 setsharpness(gspca_dev);
2954 sethvflip(gspca_dev);
2955 setlightfreq(gspca_dev);
2750 } 2956 }
2751 return 0; 2957 return 0;
2752} 2958}
@@ -2754,8 +2960,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
2754static void sd_stopN(struct gspca_dev *gspca_dev) 2960static void sd_stopN(struct gspca_dev *gspca_dev)
2755{ 2961{
2756 struct usb_device *dev = gspca_dev->dev; 2962 struct usb_device *dev = gspca_dev->dev;
2963 struct sd *sd = (struct sd *) gspca_dev;
2757 2964
2758 reg_w(dev, 0x89, 0xffff, 0xffff); 2965 if (sd->sensor == SENSOR_MI1310_SOC)
2966 reg_w(dev, 0x89, 0x058c, 0x00ff);
2967 else
2968 reg_w(dev, 0x89, 0xffff, 0xffff);
2759 reg_w(dev, 0xa0, 0x01, 0xb301); 2969 reg_w(dev, 0xa0, 0x01, 0xb301);
2760 reg_w(dev, 0xa0, 0x09, 0xb003); 2970 reg_w(dev, 0xa0, 0x09, 0xb003);
2761} 2971}
@@ -2764,15 +2974,20 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
2764static void sd_stop0(struct gspca_dev *gspca_dev) 2974static void sd_stop0(struct gspca_dev *gspca_dev)
2765{ 2975{
2766 struct usb_device *dev = gspca_dev->dev; 2976 struct usb_device *dev = gspca_dev->dev;
2977 struct sd *sd = (struct sd *) gspca_dev;
2767 2978
2768 if (!gspca_dev->present) 2979 if (!gspca_dev->present)
2769 return; 2980 return;
2770 reg_w(dev, 0x89, 0xffff, 0xffff); 2981/*fixme: is this useful?*/
2982 if (sd->sensor == SENSOR_MI1310_SOC)
2983 reg_w(dev, 0x89, 0x058c, 0x00ff);
2984 else
2985 reg_w(dev, 0x89, 0xffff, 0xffff);
2771} 2986}
2772 2987
2773static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2988static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2774 struct gspca_frame *frame, /* target */ 2989 struct gspca_frame *frame, /* target */
2775 __u8 *data, /* isoc packet */ 2990 u8 *data, /* isoc packet */
2776 int len) /* iso pkt length */ 2991 int len) /* iso pkt length */
2777{ 2992{
2778 struct sd *sd = (struct sd *) gspca_dev; 2993 struct sd *sd = (struct sd *) gspca_dev;
@@ -2872,21 +3087,12 @@ static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
2872static int sd_querymenu(struct gspca_dev *gspca_dev, 3087static int sd_querymenu(struct gspca_dev *gspca_dev,
2873 struct v4l2_querymenu *menu) 3088 struct v4l2_querymenu *menu)
2874{ 3089{
3090 static const char *freq_nm[3] = {"NoFliker", "50 Hz", "60 Hz"};
3091
2875 switch (menu->id) { 3092 switch (menu->id) {
2876 case V4L2_CID_POWER_LINE_FREQUENCY: 3093 case V4L2_CID_POWER_LINE_FREQUENCY:
2877 switch (menu->index) { 3094 strcpy((char *) menu->name, freq_nm[menu->index]);
2878 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ 3095 return 0;
2879 strcpy((char *) menu->name, "NoFliker");
2880 return 0;
2881 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2882 strcpy((char *) menu->name, "50 Hz");
2883 return 0;
2884 default:
2885/* case 2: * V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2886 strcpy((char *) menu->name, "60 Hz");
2887 return 0;
2888 }
2889 break;
2890 } 3096 }
2891 return -EINVAL; 3097 return -EINVAL;
2892} 3098}
@@ -2906,19 +3112,23 @@ static const struct sd_desc sd_desc = {
2906}; 3112};
2907 3113
2908/* -- module initialisation -- */ 3114/* -- module initialisation -- */
3115#define BF(bridge, flags) \
3116 .driver_info = (BRIDGE_ ## bridge << 8) \
3117 | (flags)
2909static const __devinitdata struct usb_device_id device_table[] = { 3118static const __devinitdata struct usb_device_id device_table[] = {
2910 {USB_DEVICE(0x041e, 0x405b), .driver_info = BRIDGE_VC0323}, 3119 {USB_DEVICE(0x041e, 0x405b), BF(VC0323, FL_VFLIP)},
2911 {USB_DEVICE(0x046d, 0x0892), .driver_info = BRIDGE_VC0321}, 3120 {USB_DEVICE(0x046d, 0x0892), BF(VC0321, 0)},
2912 {USB_DEVICE(0x046d, 0x0896), .driver_info = BRIDGE_VC0321}, 3121 {USB_DEVICE(0x046d, 0x0896), BF(VC0321, 0)},
2913 {USB_DEVICE(0x046d, 0x0897), .driver_info = BRIDGE_VC0321}, 3122 {USB_DEVICE(0x046d, 0x0897), BF(VC0321, 0)},
2914 {USB_DEVICE(0x0ac8, 0x0321), .driver_info = BRIDGE_VC0321}, 3123 {USB_DEVICE(0x0ac8, 0x0321), BF(VC0321, 0)},
2915 {USB_DEVICE(0x0ac8, 0x0323), .driver_info = BRIDGE_VC0323}, 3124 {USB_DEVICE(0x0ac8, 0x0323), BF(VC0323, 0)},
2916 {USB_DEVICE(0x0ac8, 0x0328), .driver_info = BRIDGE_VC0321}, 3125 {USB_DEVICE(0x0ac8, 0x0328), BF(VC0321, 0)},
2917 {USB_DEVICE(0x0ac8, 0xc001), .driver_info = BRIDGE_VC0321}, 3126 {USB_DEVICE(0x0ac8, 0xc001), BF(VC0321, 0)},
2918 {USB_DEVICE(0x0ac8, 0xc002), .driver_info = BRIDGE_VC0321}, 3127 {USB_DEVICE(0x0ac8, 0xc002), BF(VC0321, 0)},
2919 {USB_DEVICE(0x15b8, 0x6001), .driver_info = BRIDGE_VC0323}, 3128 {USB_DEVICE(0x0ac8, 0xc301), BF(VC0323, FL_SAMSUNG)},
2920 {USB_DEVICE(0x15b8, 0x6002), .driver_info = BRIDGE_VC0323}, 3129 {USB_DEVICE(0x15b8, 0x6001), BF(VC0323, 0)},
2921 {USB_DEVICE(0x17ef, 0x4802), .driver_info = BRIDGE_VC0323}, 3130 {USB_DEVICE(0x15b8, 0x6002), BF(VC0323, 0)},
3131 {USB_DEVICE(0x17ef, 0x4802), BF(VC0323, 0)},
2922 {} 3132 {}
2923}; 3133};
2924MODULE_DEVICE_TABLE(usb, device_table); 3134MODULE_DEVICE_TABLE(usb, device_table);
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 3d2756f7874a..cdf3357b4c9f 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -7574,7 +7574,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
7574static const struct sd_desc sd_desc = { 7574static const struct sd_desc sd_desc = {
7575 .name = MODULE_NAME, 7575 .name = MODULE_NAME,
7576 .ctrls = sd_ctrls, 7576 .ctrls = sd_ctrls,
7577 .nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0], 7577 .nctrls = ARRAY_SIZE(sd_ctrls),
7578 .config = sd_config, 7578 .config = sd_config,
7579 .init = sd_init, 7579 .init = sd_init,
7580 .start = sd_start, 7580 .start = sd_start,
diff --git a/drivers/media/video/hdpvr/hdpvr-control.c b/drivers/media/video/hdpvr/hdpvr-control.c
index 06791749d1a0..5a6b78b8d25d 100644
--- a/drivers/media/video/hdpvr/hdpvr-control.c
+++ b/drivers/media/video/hdpvr/hdpvr-control.c
@@ -178,24 +178,24 @@ error:
178 178
179int hdpvr_set_options(struct hdpvr_device *dev) 179int hdpvr_set_options(struct hdpvr_device *dev)
180{ 180{
181 hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, dev->options.video_std); 181 hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, dev->options.video_std);
182 182
183 hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE, 183 hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE,
184 dev->options.video_input+1); 184 dev->options.video_input+1);
185 185
186 hdpvr_set_audio(dev, dev->options.audio_input+1, 186 hdpvr_set_audio(dev, dev->options.audio_input+1,
187 dev->options.audio_codec); 187 dev->options.audio_codec);
188 188
189 hdpvr_set_bitrate(dev); 189 hdpvr_set_bitrate(dev);
190 hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE, 190 hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
191 dev->options.bitrate_mode); 191 dev->options.bitrate_mode);
192 hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, dev->options.gop_mode); 192 hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, dev->options.gop_mode);
193 193
194 hdpvr_config_call(dev, CTRL_BRIGHTNESS, dev->options.brightness); 194 hdpvr_config_call(dev, CTRL_BRIGHTNESS, dev->options.brightness);
195 hdpvr_config_call(dev, CTRL_CONTRAST, dev->options.contrast); 195 hdpvr_config_call(dev, CTRL_CONTRAST, dev->options.contrast);
196 hdpvr_config_call(dev, CTRL_HUE, dev->options.hue); 196 hdpvr_config_call(dev, CTRL_HUE, dev->options.hue);
197 hdpvr_config_call(dev, CTRL_SATURATION, dev->options.saturation); 197 hdpvr_config_call(dev, CTRL_SATURATION, dev->options.saturation);
198 hdpvr_config_call(dev, CTRL_SHARPNESS, dev->options.sharpness); 198 hdpvr_config_call(dev, CTRL_SHARPNESS, dev->options.sharpness);
199 199
200 return 0; 200 return 0;
201} 201}
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
index 188bd5aea258..1c9bc94c905c 100644
--- a/drivers/media/video/hdpvr/hdpvr-core.c
+++ b/drivers/media/video/hdpvr/hdpvr-core.c
@@ -126,7 +126,7 @@ static int device_authorization(struct hdpvr_device *dev)
126 char *print_buf = kzalloc(5*buf_size+1, GFP_KERNEL); 126 char *print_buf = kzalloc(5*buf_size+1, GFP_KERNEL);
127 if (!print_buf) { 127 if (!print_buf) {
128 v4l2_err(&dev->v4l2_dev, "Out of memory\n"); 128 v4l2_err(&dev->v4l2_dev, "Out of memory\n");
129 goto error; 129 return retval;
130 } 130 }
131#endif 131#endif
132 132
@@ -140,7 +140,7 @@ static int device_authorization(struct hdpvr_device *dev)
140 if (ret != 46) { 140 if (ret != 46) {
141 v4l2_err(&dev->v4l2_dev, 141 v4l2_err(&dev->v4l2_dev,
142 "unexpected answer of status request, len %d\n", ret); 142 "unexpected answer of status request, len %d\n", ret);
143 goto error; 143 goto unlock;
144 } 144 }
145#ifdef HDPVR_DEBUG 145#ifdef HDPVR_DEBUG
146 else { 146 else {
@@ -163,7 +163,7 @@ static int device_authorization(struct hdpvr_device *dev)
163 v4l2_err(&dev->v4l2_dev, "unknown firmware version 0x%x\n", 163 v4l2_err(&dev->v4l2_dev, "unknown firmware version 0x%x\n",
164 dev->usbc_buf[1]); 164 dev->usbc_buf[1]);
165 ret = -EINVAL; 165 ret = -EINVAL;
166 goto error; 166 goto unlock;
167 } 167 }
168 168
169 response = dev->usbc_buf+38; 169 response = dev->usbc_buf+38;
@@ -188,10 +188,10 @@ static int device_authorization(struct hdpvr_device *dev)
188 10000); 188 10000);
189 v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, 189 v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
190 "magic request returned %d\n", ret); 190 "magic request returned %d\n", ret);
191 mutex_unlock(&dev->usbc_mutex);
192 191
193 retval = ret != 8; 192 retval = ret != 8;
194error: 193unlock:
194 mutex_unlock(&dev->usbc_mutex);
195 return retval; 195 return retval;
196} 196}
197 197
@@ -350,6 +350,7 @@ static int hdpvr_probe(struct usb_interface *interface,
350 350
351 mutex_lock(&dev->io_mutex); 351 mutex_lock(&dev->io_mutex);
352 if (hdpvr_alloc_buffers(dev, NUM_BUFFERS)) { 352 if (hdpvr_alloc_buffers(dev, NUM_BUFFERS)) {
353 mutex_unlock(&dev->io_mutex);
353 v4l2_err(&dev->v4l2_dev, 354 v4l2_err(&dev->v4l2_dev,
354 "allocating transfer buffers failed\n"); 355 "allocating transfer buffers failed\n");
355 goto error; 356 goto error;
@@ -381,7 +382,6 @@ static int hdpvr_probe(struct usb_interface *interface,
381 382
382error: 383error:
383 if (dev) { 384 if (dev) {
384 mutex_unlock(&dev->io_mutex);
385 /* this frees allocated memory */ 385 /* this frees allocated memory */
386 hdpvr_delete(dev); 386 hdpvr_delete(dev);
387 } 387 }
diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c
index c4b5d1515c10..296330a0e1e5 100644
--- a/drivers/media/video/hdpvr/hdpvr-i2c.c
+++ b/drivers/media/video/hdpvr/hdpvr-i2c.c
@@ -127,7 +127,6 @@ int hdpvr_register_i2c_adapter(struct hdpvr_device *dev)
127 sizeof(i2c_adap->name)); 127 sizeof(i2c_adap->name));
128 i2c_adap->algo = &hdpvr_algo; 128 i2c_adap->algo = &hdpvr_algo;
129 i2c_adap->class = I2C_CLASS_TV_ANALOG; 129 i2c_adap->class = I2C_CLASS_TV_ANALOG;
130 i2c_adap->id = I2C_HW_B_HDPVR;
131 i2c_adap->owner = THIS_MODULE; 130 i2c_adap->owner = THIS_MODULE;
132 i2c_adap->dev.parent = &dev->udev->dev; 131 i2c_adap->dev.parent = &dev->udev->dev;
133 132
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c
index d678765cbba2..2eb9dc2ebe59 100644
--- a/drivers/media/video/hdpvr/hdpvr-video.c
+++ b/drivers/media/video/hdpvr/hdpvr-video.c
@@ -375,6 +375,7 @@ static int hdpvr_open(struct file *file)
375 * in resumption */ 375 * in resumption */
376 mutex_lock(&dev->io_mutex); 376 mutex_lock(&dev->io_mutex);
377 dev->open_count++; 377 dev->open_count++;
378 mutex_unlock(&dev->io_mutex);
378 379
379 fh->dev = dev; 380 fh->dev = dev;
380 381
@@ -383,7 +384,6 @@ static int hdpvr_open(struct file *file)
383 384
384 retval = 0; 385 retval = 0;
385err: 386err:
386 mutex_unlock(&dev->io_mutex);
387 return retval; 387 return retval;
388} 388}
389 389
@@ -519,8 +519,10 @@ static unsigned int hdpvr_poll(struct file *filp, poll_table *wait)
519 519
520 mutex_lock(&dev->io_mutex); 520 mutex_lock(&dev->io_mutex);
521 521
522 if (video_is_unregistered(dev->video_dev)) 522 if (video_is_unregistered(dev->video_dev)) {
523 mutex_unlock(&dev->io_mutex);
523 return -EIO; 524 return -EIO;
525 }
524 526
525 if (dev->status == STATUS_IDLE) { 527 if (dev->status == STATUS_IDLE) {
526 if (hdpvr_start_streaming(dev)) { 528 if (hdpvr_start_streaming(dev)) {
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 86f2fefe1edf..247d3115a9b7 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -122,12 +122,12 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
122 return 1; 122 return 1;
123} 123}
124 124
125static inline int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) 125static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
126{ 126{
127 return get_key_haup_common (ir, ir_key, ir_raw, 3, 0); 127 return get_key_haup_common (ir, ir_key, ir_raw, 3, 0);
128} 128}
129 129
130static inline int get_key_haup_xvr(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) 130static int get_key_haup_xvr(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
131{ 131{
132 return get_key_haup_common (ir, ir_key, ir_raw, 6, 3); 132 return get_key_haup_common (ir, ir_key, ir_raw, 6, 3);
133} 133}
@@ -297,7 +297,7 @@ static void ir_work(struct work_struct *work)
297 297
298static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) 298static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
299{ 299{
300 IR_KEYTAB_TYPE *ir_codes = NULL; 300 struct ir_scancode_table *ir_codes = NULL;
301 const char *name = NULL; 301 const char *name = NULL;
302 int ir_type; 302 int ir_type;
303 struct IR_i2c *ir; 303 struct IR_i2c *ir;
@@ -322,13 +322,13 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
322 name = "Pixelview"; 322 name = "Pixelview";
323 ir->get_key = get_key_pixelview; 323 ir->get_key = get_key_pixelview;
324 ir_type = IR_TYPE_OTHER; 324 ir_type = IR_TYPE_OTHER;
325 ir_codes = ir_codes_empty; 325 ir_codes = &ir_codes_empty_table;
326 break; 326 break;
327 case 0x4b: 327 case 0x4b:
328 name = "PV951"; 328 name = "PV951";
329 ir->get_key = get_key_pv951; 329 ir->get_key = get_key_pv951;
330 ir_type = IR_TYPE_OTHER; 330 ir_type = IR_TYPE_OTHER;
331 ir_codes = ir_codes_pv951; 331 ir_codes = &ir_codes_pv951_table;
332 break; 332 break;
333 case 0x18: 333 case 0x18:
334 case 0x1a: 334 case 0x1a:
@@ -336,36 +336,38 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
336 ir->get_key = get_key_haup; 336 ir->get_key = get_key_haup;
337 ir_type = IR_TYPE_RC5; 337 ir_type = IR_TYPE_RC5;
338 if (hauppauge == 1) { 338 if (hauppauge == 1) {
339 ir_codes = ir_codes_hauppauge_new; 339 ir_codes = &ir_codes_hauppauge_new_table;
340 } else { 340 } else {
341 ir_codes = ir_codes_rc5_tv; 341 ir_codes = &ir_codes_rc5_tv_table;
342 } 342 }
343 break; 343 break;
344 case 0x30: 344 case 0x30:
345 name = "KNC One"; 345 name = "KNC One";
346 ir->get_key = get_key_knc1; 346 ir->get_key = get_key_knc1;
347 ir_type = IR_TYPE_OTHER; 347 ir_type = IR_TYPE_OTHER;
348 ir_codes = ir_codes_empty; 348 ir_codes = &ir_codes_empty_table;
349 break; 349 break;
350 case 0x6b: 350 case 0x6b:
351 name = "FusionHDTV"; 351 name = "FusionHDTV";
352 ir->get_key = get_key_fusionhdtv; 352 ir->get_key = get_key_fusionhdtv;
353 ir_type = IR_TYPE_RC5; 353 ir_type = IR_TYPE_RC5;
354 ir_codes = ir_codes_fusionhdtv_mce; 354 ir_codes = &ir_codes_fusionhdtv_mce_table;
355 break; 355 break;
356 case 0x7a: 356 case 0x7a:
357 case 0x47: 357 case 0x47:
358 case 0x71: 358 case 0x71:
359 case 0x2d: 359 case 0x2d:
360 if (adap->id == I2C_HW_B_CX2388x) { 360 if (adap->id == I2C_HW_B_CX2388x ||
361 adap->id == I2C_HW_B_CX2341X) {
361 /* Handled by cx88-input */ 362 /* Handled by cx88-input */
362 name = "CX2388x remote"; 363 name = adap->id == I2C_HW_B_CX2341X ? "CX2341x remote"
364 : "CX2388x remote";
363 ir_type = IR_TYPE_RC5; 365 ir_type = IR_TYPE_RC5;
364 ir->get_key = get_key_haup_xvr; 366 ir->get_key = get_key_haup_xvr;
365 if (hauppauge == 1) { 367 if (hauppauge == 1) {
366 ir_codes = ir_codes_hauppauge_new; 368 ir_codes = &ir_codes_hauppauge_new_table;
367 } else { 369 } else {
368 ir_codes = ir_codes_rc5_tv; 370 ir_codes = &ir_codes_rc5_tv_table;
369 } 371 }
370 } else { 372 } else {
371 /* Handled by saa7134-input */ 373 /* Handled by saa7134-input */
@@ -377,7 +379,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
377 name = "AVerMedia Cardbus remote"; 379 name = "AVerMedia Cardbus remote";
378 ir->get_key = get_key_avermedia_cardbus; 380 ir->get_key = get_key_avermedia_cardbus;
379 ir_type = IR_TYPE_OTHER; 381 ir_type = IR_TYPE_OTHER;
380 ir_codes = ir_codes_avermedia_cardbus; 382 ir_codes = &ir_codes_avermedia_cardbus_table;
381 break; 383 break;
382 default: 384 default:
383 dprintk(1, DEVNAME ": Unsupported i2c address 0x%02x\n", addr); 385 dprintk(1, DEVNAME ": Unsupported i2c address 0x%02x\n", addr);
@@ -392,7 +394,36 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
392 394
393 ir_codes = init_data->ir_codes; 395 ir_codes = init_data->ir_codes;
394 name = init_data->name; 396 name = init_data->name;
395 ir->get_key = init_data->get_key; 397 if (init_data->type)
398 ir_type = init_data->type;
399
400 switch (init_data->internal_get_key_func) {
401 case IR_KBD_GET_KEY_CUSTOM:
402 /* The bridge driver provided us its own function */
403 ir->get_key = init_data->get_key;
404 break;
405 case IR_KBD_GET_KEY_PIXELVIEW:
406 ir->get_key = get_key_pixelview;
407 break;
408 case IR_KBD_GET_KEY_PV951:
409 ir->get_key = get_key_pv951;
410 break;
411 case IR_KBD_GET_KEY_HAUP:
412 ir->get_key = get_key_haup;
413 break;
414 case IR_KBD_GET_KEY_KNC1:
415 ir->get_key = get_key_knc1;
416 break;
417 case IR_KBD_GET_KEY_FUSIONHDTV:
418 ir->get_key = get_key_fusionhdtv;
419 break;
420 case IR_KBD_GET_KEY_HAUP_XVR:
421 ir->get_key = get_key_haup_xvr;
422 break;
423 case IR_KBD_GET_KEY_AVERMEDIA_CARDBUS:
424 ir->get_key = get_key_avermedia_cardbus;
425 break;
426 }
396 } 427 }
397 428
398 /* Make sure we are all setup before going on */ 429 /* Make sure we are all setup before going on */
@@ -454,7 +485,8 @@ static int ir_remove(struct i2c_client *client)
454static const struct i2c_device_id ir_kbd_id[] = { 485static const struct i2c_device_id ir_kbd_id[] = {
455 /* Generic entry for any IR receiver */ 486 /* Generic entry for any IR receiver */
456 { "ir_video", 0 }, 487 { "ir_video", 0 },
457 /* IR device specific entries could be added here */ 488 /* IR device specific entries should be added here */
489 { "ir_rx_z8f0811_haup", 0 },
458 { } 490 { }
459}; 491};
460 492
diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c
index 2883c8780760..4873b6ca5801 100644
--- a/drivers/media/video/ivtv/ivtv-cards.c
+++ b/drivers/media/video/ivtv/ivtv-cards.c
@@ -977,26 +977,27 @@ static const struct ivtv_card ivtv_card_avertv_mce116 = {
977 977
978/* ------------------------------------------------------------------------- */ 978/* ------------------------------------------------------------------------- */
979 979
980/* AVerMedia PVR-150 Plus (M113) card */ 980/* AVerMedia PVR-150 Plus / AVerTV M113 cards with a Daewoo/Partsnic Tuner */
981 981
982static const struct ivtv_card_pci_info ivtv_pci_aver_pvr150[] = { 982static const struct ivtv_card_pci_info ivtv_pci_aver_pvr150[] = {
983 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc035 }, 983 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc034 }, /* NTSC */
984 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc035 }, /* NTSC FM */
984 { 0, 0, 0 } 985 { 0, 0, 0 }
985}; 986};
986 987
987static const struct ivtv_card ivtv_card_aver_pvr150 = { 988static const struct ivtv_card ivtv_card_aver_pvr150 = {
988 .type = IVTV_CARD_AVER_PVR150PLUS, 989 .type = IVTV_CARD_AVER_PVR150PLUS,
989 .name = "AVerMedia PVR-150 Plus", 990 .name = "AVerMedia PVR-150 Plus / AVerTV M113 Partsnic (Daewoo) Tuner",
990 .v4l2_capabilities = IVTV_CAP_ENCODER, 991 .v4l2_capabilities = IVTV_CAP_ENCODER,
991 .hw_video = IVTV_HW_CX25840, 992 .hw_video = IVTV_HW_CX25840,
992 .hw_audio = IVTV_HW_CX25840, 993 .hw_audio = IVTV_HW_CX25840,
993 .hw_audio_ctrl = IVTV_HW_CX25840, 994 .hw_audio_ctrl = IVTV_HW_CX25840,
994 .hw_muxer = IVTV_HW_GPIO, 995 .hw_muxer = IVTV_HW_GPIO,
995 .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER, 996 .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER |
997 IVTV_HW_WM8739 | IVTV_HW_GPIO,
996 .video_inputs = { 998 .video_inputs = {
997 { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 }, 999 { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
998 { IVTV_CARD_INPUT_SVIDEO1, 1, 1000 { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 },
999 CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
1000 { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 }, 1001 { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
1001 }, 1002 },
1002 .audio_inputs = { 1003 .audio_inputs = {
@@ -1004,18 +1005,66 @@ static const struct ivtv_card ivtv_card_aver_pvr150 = {
1004 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 }, 1005 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 },
1005 }, 1006 },
1006 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 }, 1007 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 },
1007 .gpio_init = { .direction = 0x0800, .initial_value = 0 }, 1008 /* The 74HC4052 Dual 4:1 multiplexer is controlled by 2 GPIO lines */
1008 .gpio_audio_input = { .mask = 0x0800, .tuner = 0, .linein = 0, .radio = 0x0800 }, 1009 .gpio_init = { .direction = 0xc000, .initial_value = 0 },
1010 .gpio_audio_input = { .mask = 0xc000,
1011 .tuner = 0x0000,
1012 .linein = 0x4000,
1013 .radio = 0x8000 },
1009 .tuners = { 1014 .tuners = {
1010 /* This card has a Partsnic PTI-5NF05 tuner */ 1015 /* Subsystem ID's 0xc03[45] have a Partsnic PTI-5NF05 tuner */
1011 { .std = V4L2_STD_MN, .tuner = TUNER_TCL_2002N }, 1016 { .std = V4L2_STD_MN, .tuner = TUNER_PARTSNIC_PTI_5NF05 },
1012 }, 1017 },
1013 .pci_list = ivtv_pci_aver_pvr150, 1018 .pci_list = ivtv_pci_aver_pvr150,
1019 /* Subsystem ID 0xc035 has a TEA5767(?) FM tuner, 0xc034 does not */
1014 .i2c = &ivtv_i2c_radio, 1020 .i2c = &ivtv_i2c_radio,
1015}; 1021};
1016 1022
1017/* ------------------------------------------------------------------------- */ 1023/* ------------------------------------------------------------------------- */
1018 1024
1025/* AVerMedia UltraTV 1500 MCE (newer non-cx88 version, M113 variant) card */
1026
1027static const struct ivtv_card_pci_info ivtv_pci_aver_ultra1500mce[] = {
1028 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc019 },
1029 { 0, 0, 0 }
1030};
1031
1032static const struct ivtv_card ivtv_card_aver_ultra1500mce = {
1033 .type = IVTV_CARD_AVER_ULTRA1500MCE,
1034 .name = "AVerMedia UltraTV 1500 MCE / AVerTV M113 Philips Tuner",
1035 .v4l2_capabilities = IVTV_CAP_ENCODER,
1036 .hw_video = IVTV_HW_CX25840,
1037 .hw_audio = IVTV_HW_CX25840,
1038 .hw_audio_ctrl = IVTV_HW_CX25840,
1039 .hw_muxer = IVTV_HW_GPIO,
1040 .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER |
1041 IVTV_HW_WM8739 | IVTV_HW_GPIO,
1042 .video_inputs = {
1043 { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
1044 { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 },
1045 { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
1046 },
1047 .audio_inputs = {
1048 { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5, 0 },
1049 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 },
1050 },
1051 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 },
1052 /* The 74HC4052 Dual 4:1 multiplexer is controlled by 2 GPIO lines */
1053 .gpio_init = { .direction = 0xc000, .initial_value = 0 },
1054 .gpio_audio_input = { .mask = 0xc000,
1055 .tuner = 0x0000,
1056 .linein = 0x4000,
1057 .radio = 0x8000 },
1058 .tuners = {
1059 /* The UltraTV 1500 MCE has a Philips FM1236 MK5 TV/FM tuner */
1060 { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FM1236_MK3 },
1061 },
1062 .pci_list = ivtv_pci_aver_ultra1500mce,
1063 .i2c = &ivtv_i2c_std,
1064};
1065
1066/* ------------------------------------------------------------------------- */
1067
1019/* AVerMedia EZMaker PCI Deluxe card */ 1068/* AVerMedia EZMaker PCI Deluxe card */
1020 1069
1021static const struct ivtv_card_pci_info ivtv_pci_aver_ezmaker[] = { 1070static const struct ivtv_card_pci_info ivtv_pci_aver_ezmaker[] = {
@@ -1180,6 +1229,7 @@ static const struct ivtv_card *ivtv_card_list[] = {
1180 &ivtv_card_aver_ezmaker, 1229 &ivtv_card_aver_ezmaker,
1181 &ivtv_card_aver_m104, 1230 &ivtv_card_aver_m104,
1182 &ivtv_card_buffalo, 1231 &ivtv_card_buffalo,
1232 &ivtv_card_aver_ultra1500mce,
1183 1233
1184 /* Variations of standard cards but with the same PCI IDs. 1234 /* Variations of standard cards but with the same PCI IDs.
1185 These cards must come last in this list. */ 1235 These cards must come last in this list. */
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h
index 0b8fe85fb697..e99a0a255578 100644
--- a/drivers/media/video/ivtv/ivtv-cards.h
+++ b/drivers/media/video/ivtv/ivtv-cards.h
@@ -50,7 +50,8 @@
50#define IVTV_CARD_AVER_EZMAKER 23 /* AVerMedia EZMaker PCI Deluxe */ 50#define IVTV_CARD_AVER_EZMAKER 23 /* AVerMedia EZMaker PCI Deluxe */
51#define IVTV_CARD_AVER_M104 24 /* AverMedia M104 miniPCI card */ 51#define IVTV_CARD_AVER_M104 24 /* AverMedia M104 miniPCI card */
52#define IVTV_CARD_BUFFALO_MV5L 25 /* Buffalo PC-MV5L/PCI card */ 52#define IVTV_CARD_BUFFALO_MV5L 25 /* Buffalo PC-MV5L/PCI card */
53#define IVTV_CARD_LAST 25 53#define IVTV_CARD_AVER_ULTRA1500MCE 26 /* AVerMedia UltraTV 1500 MCE */
54#define IVTV_CARD_LAST 26
54 55
55/* Variants of existing cards but with the same PCI IDs. The driver 56/* Variants of existing cards but with the same PCI IDs. The driver
56 detects these based on other device information. 57 detects these based on other device information.
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 558f8a837ff4..63ea0fb66063 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -186,6 +186,7 @@ MODULE_PARM_DESC(cardtype,
186 "\t\t\t24 = AverMedia EZMaker PCI Deluxe\n" 186 "\t\t\t24 = AverMedia EZMaker PCI Deluxe\n"
187 "\t\t\t25 = AverMedia M104 (not yet working)\n" 187 "\t\t\t25 = AverMedia M104 (not yet working)\n"
188 "\t\t\t26 = Buffalo PC-MV5L/PCI\n" 188 "\t\t\t26 = Buffalo PC-MV5L/PCI\n"
189 "\t\t\t27 = AVerMedia UltraTV 1500 MCE\n"
189 "\t\t\t 0 = Autodetect (default)\n" 190 "\t\t\t 0 = Autodetect (default)\n"
190 "\t\t\t-1 = Ignore this card\n\t\t"); 191 "\t\t\t-1 = Ignore this card\n\t\t");
191MODULE_PARM_DESC(pal, "Set PAL standard: BGH, DK, I, M, N, Nc, 60"); 192MODULE_PARM_DESC(pal, "Set PAL standard: BGH, DK, I, M, N, Nc, 60");
@@ -218,7 +219,7 @@ MODULE_PARM_DESC(ivtv_yuv_mode,
218 "\t\t\tDefault: 0 (interlaced)"); 219 "\t\t\tDefault: 0 (interlaced)");
219MODULE_PARM_DESC(ivtv_yuv_threshold, 220MODULE_PARM_DESC(ivtv_yuv_threshold,
220 "If ivtv_yuv_mode is 2 (auto) then playback content as\n\t\tprogressive if src height <= ivtv_yuvthreshold\n" 221 "If ivtv_yuv_mode is 2 (auto) then playback content as\n\t\tprogressive if src height <= ivtv_yuvthreshold\n"
221 "\t\t\tDefault: 480");; 222 "\t\t\tDefault: 480");
222MODULE_PARM_DESC(enc_mpg_buffers, 223MODULE_PARM_DESC(enc_mpg_buffers,
223 "Encoder MPG Buffers (in MB)\n" 224 "Encoder MPG Buffers (in MB)\n"
224 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_MPG_BUFFERS)); 225 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_MPG_BUFFERS));
diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c
index 85ac707228e7..aede061cae5d 100644
--- a/drivers/media/video/ivtv/ivtv-gpio.c
+++ b/drivers/media/video/ivtv/ivtv-gpio.c
@@ -236,18 +236,6 @@ static int subdev_s_radio(struct v4l2_subdev *sd)
236 return 0; 236 return 0;
237} 237}
238 238
239static int subdev_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
240{
241 struct ivtv *itv = sd_to_ivtv(sd);
242 u16 mask, data;
243
244 mask = itv->card->gpio_audio_input.mask;
245 data = itv->card->gpio_audio_input.tuner;
246 if (mask)
247 write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
248 return 0;
249}
250
251static int subdev_s_audio_routing(struct v4l2_subdev *sd, 239static int subdev_s_audio_routing(struct v4l2_subdev *sd,
252 u32 input, u32 output, u32 config) 240 u32 input, u32 output, u32 config)
253{ 241{
@@ -344,7 +332,6 @@ static const struct v4l2_subdev_core_ops subdev_core_ops = {
344 .g_ctrl = subdev_g_ctrl, 332 .g_ctrl = subdev_g_ctrl,
345 .s_ctrl = subdev_s_ctrl, 333 .s_ctrl = subdev_s_ctrl,
346 .queryctrl = subdev_queryctrl, 334 .queryctrl = subdev_queryctrl,
347 .s_std = subdev_s_std,
348}; 335};
349 336
350static const struct v4l2_subdev_tuner_ops subdev_tuner_ops = { 337static const struct v4l2_subdev_tuner_ops subdev_tuner_ops = {
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index e52aa322b134..8f15a31d3f66 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -509,7 +509,6 @@ static struct i2c_algorithm ivtv_algo = {
509/* template for our-bit banger */ 509/* template for our-bit banger */
510static struct i2c_adapter ivtv_i2c_adap_hw_template = { 510static struct i2c_adapter ivtv_i2c_adap_hw_template = {
511 .name = "ivtv i2c driver", 511 .name = "ivtv i2c driver",
512 .id = I2C_HW_B_CX2341X,
513 .algo = &ivtv_algo, 512 .algo = &ivtv_algo,
514 .algo_data = NULL, /* filled from template */ 513 .algo_data = NULL, /* filled from template */
515 .owner = THIS_MODULE, 514 .owner = THIS_MODULE,
@@ -560,7 +559,6 @@ static int ivtv_getsda_old(void *data)
560/* template for i2c-bit-algo */ 559/* template for i2c-bit-algo */
561static struct i2c_adapter ivtv_i2c_adap_template = { 560static struct i2c_adapter ivtv_i2c_adap_template = {
562 .name = "ivtv i2c driver", 561 .name = "ivtv i2c driver",
563 .id = I2C_HW_B_CX2341X,
564 .algo = NULL, /* set by i2c-algo-bit */ 562 .algo = NULL, /* set by i2c-algo-bit */
565 .algo_data = NULL, /* filled from template */ 563 .algo_data = NULL, /* filled from template */
566 .owner = THIS_MODULE, 564 .owner = THIS_MODULE,
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 1d66855a379a..d0765bed79c9 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -1915,8 +1915,7 @@ static void __devexit meye_remove(struct pci_dev *pcidev)
1915} 1915}
1916 1916
1917static struct pci_device_id meye_pci_tbl[] = { 1917static struct pci_device_id meye_pci_tbl[] = {
1918 { PCI_VENDOR_ID_KAWASAKI, PCI_DEVICE_ID_MCHIP_KL5A72002, 1918 { PCI_VDEVICE(KAWASAKI, PCI_DEVICE_ID_MCHIP_KL5A72002), 0 },
1919 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
1920 { } 1919 { }
1921}; 1920};
1922 1921
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/video/pvrusb2/pvrusb2-audio.c
index 416933ca607d..cc06d5e4adcc 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.c
@@ -65,9 +65,10 @@ void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
65 u32 input; 65 u32 input;
66 66
67 pvr2_trace(PVR2_TRACE_CHIPS, "subdev msp3400 v4l2 set_stereo"); 67 pvr2_trace(PVR2_TRACE_CHIPS, "subdev msp3400 v4l2 set_stereo");
68 sp = (sid < ARRAY_SIZE(routing_schemes)) ?
69 routing_schemes[sid] : NULL;
68 70
69 if ((sid < ARRAY_SIZE(routing_schemes)) && 71 if ((sp != NULL) &&
70 ((sp = routing_schemes[sid]) != NULL) &&
71 (hdw->input_val >= 0) && 72 (hdw->input_val >= 0) &&
72 (hdw->input_val < sp->cnt)) { 73 (hdw->input_val < sp->cnt)) {
73 input = sp->def[hdw->input_val]; 74 input = sp->def[hdw->input_val];
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 610bd848df24..a334b1a966a2 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -540,7 +540,6 @@ static struct i2c_algorithm pvr2_i2c_algo_template = {
540static struct i2c_adapter pvr2_i2c_adap_template = { 540static struct i2c_adapter pvr2_i2c_adap_template = {
541 .owner = THIS_MODULE, 541 .owner = THIS_MODULE,
542 .class = 0, 542 .class = 0,
543 .id = I2C_HW_B_BT848,
544}; 543};
545 544
546 545
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 8d17cf613306..f976df452a34 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -1057,7 +1057,8 @@ static int pwc_create_sysfs_files(struct video_device *vdev)
1057 goto err; 1057 goto err;
1058 if (pdev->features & FEATURE_MOTOR_PANTILT) { 1058 if (pdev->features & FEATURE_MOTOR_PANTILT) {
1059 rc = device_create_file(&vdev->dev, &dev_attr_pan_tilt); 1059 rc = device_create_file(&vdev->dev, &dev_attr_pan_tilt);
1060 if (rc) goto err_button; 1060 if (rc)
1061 goto err_button;
1061 } 1062 }
1062 1063
1063 return 0; 1064 return 0;
@@ -1072,6 +1073,7 @@ err:
1072static void pwc_remove_sysfs_files(struct video_device *vdev) 1073static void pwc_remove_sysfs_files(struct video_device *vdev)
1073{ 1074{
1074 struct pwc_device *pdev = video_get_drvdata(vdev); 1075 struct pwc_device *pdev = video_get_drvdata(vdev);
1076
1075 if (pdev->features & FEATURE_MOTOR_PANTILT) 1077 if (pdev->features & FEATURE_MOTOR_PANTILT)
1076 device_remove_file(&vdev->dev, &dev_attr_pan_tilt); 1078 device_remove_file(&vdev->dev, &dev_attr_pan_tilt);
1077 device_remove_file(&vdev->dev, &dev_attr_button); 1079 device_remove_file(&vdev->dev, &dev_attr_button);
@@ -1229,13 +1231,11 @@ static void pwc_cleanup(struct pwc_device *pdev)
1229 video_unregister_device(pdev->vdev); 1231 video_unregister_device(pdev->vdev);
1230 1232
1231#ifdef CONFIG_USB_PWC_INPUT_EVDEV 1233#ifdef CONFIG_USB_PWC_INPUT_EVDEV
1232 if (pdev->button_dev) { 1234 if (pdev->button_dev)
1233 input_unregister_device(pdev->button_dev); 1235 input_unregister_device(pdev->button_dev);
1234 input_free_device(pdev->button_dev);
1235 kfree(pdev->button_dev->phys);
1236 pdev->button_dev = NULL;
1237 }
1238#endif 1236#endif
1237
1238 kfree(pdev);
1239} 1239}
1240 1240
1241/* Note that all cleanup is done in the reverse order as in _open */ 1241/* Note that all cleanup is done in the reverse order as in _open */
@@ -1281,8 +1281,6 @@ static int pwc_video_close(struct file *file)
1281 PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen); 1281 PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen);
1282 } else { 1282 } else {
1283 pwc_cleanup(pdev); 1283 pwc_cleanup(pdev);
1284 /* Free memory (don't set pdev to 0 just yet) */
1285 kfree(pdev);
1286 /* search device_hint[] table if we occupy a slot, by any chance */ 1284 /* search device_hint[] table if we occupy a slot, by any chance */
1287 for (hint = 0; hint < MAX_DEV_HINTS; hint++) 1285 for (hint = 0; hint < MAX_DEV_HINTS; hint++)
1288 if (device_hint[hint].pdev == pdev) 1286 if (device_hint[hint].pdev == pdev)
@@ -1499,13 +1497,10 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1499 struct usb_device *udev = interface_to_usbdev(intf); 1497 struct usb_device *udev = interface_to_usbdev(intf);
1500 struct pwc_device *pdev = NULL; 1498 struct pwc_device *pdev = NULL;
1501 int vendor_id, product_id, type_id; 1499 int vendor_id, product_id, type_id;
1502 int i, hint, rc; 1500 int hint, rc;
1503 int features = 0; 1501 int features = 0;
1504 int video_nr = -1; /* default: use next available device */ 1502 int video_nr = -1; /* default: use next available device */
1505 char serial_number[30], *name; 1503 char serial_number[30], *name;
1506#ifdef CONFIG_USB_PWC_INPUT_EVDEV
1507 char *phys = NULL;
1508#endif
1509 1504
1510 vendor_id = le16_to_cpu(udev->descriptor.idVendor); 1505 vendor_id = le16_to_cpu(udev->descriptor.idVendor);
1511 product_id = le16_to_cpu(udev->descriptor.idProduct); 1506 product_id = le16_to_cpu(udev->descriptor.idProduct);
@@ -1757,8 +1752,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1757 pdev->vframes = default_fps; 1752 pdev->vframes = default_fps;
1758 strcpy(pdev->serial, serial_number); 1753 strcpy(pdev->serial, serial_number);
1759 pdev->features = features; 1754 pdev->features = features;
1760 if (vendor_id == 0x046D && product_id == 0x08B5) 1755 if (vendor_id == 0x046D && product_id == 0x08B5) {
1761 {
1762 /* Logitech QuickCam Orbit 1756 /* Logitech QuickCam Orbit
1763 The ranges have been determined experimentally; they may differ from cam to cam. 1757 The ranges have been determined experimentally; they may differ from cam to cam.
1764 Also, the exact ranges left-right and up-down are different for my cam 1758 Also, the exact ranges left-right and up-down are different for my cam
@@ -1780,8 +1774,8 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1780 pdev->vdev = video_device_alloc(); 1774 pdev->vdev = video_device_alloc();
1781 if (!pdev->vdev) { 1775 if (!pdev->vdev) {
1782 PWC_ERROR("Err, cannot allocate video_device struture. Failing probe."); 1776 PWC_ERROR("Err, cannot allocate video_device struture. Failing probe.");
1783 kfree(pdev); 1777 rc = -ENOMEM;
1784 return -ENOMEM; 1778 goto err_free_mem;
1785 } 1779 }
1786 memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template)); 1780 memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template));
1787 pdev->vdev->parent = &intf->dev; 1781 pdev->vdev->parent = &intf->dev;
@@ -1806,25 +1800,23 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1806 } 1800 }
1807 1801
1808 pdev->vdev->release = video_device_release; 1802 pdev->vdev->release = video_device_release;
1809 i = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr); 1803 rc = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr);
1810 if (i < 0) { 1804 if (rc < 0) {
1811 PWC_ERROR("Failed to register as video device (%d).\n", i); 1805 PWC_ERROR("Failed to register as video device (%d).\n", rc);
1812 rc = i; 1806 goto err_video_release;
1813 goto err;
1814 }
1815 else {
1816 PWC_INFO("Registered as /dev/video%d.\n", pdev->vdev->num);
1817 } 1807 }
1818 1808
1809 PWC_INFO("Registered as /dev/video%d.\n", pdev->vdev->num);
1810
1819 /* occupy slot */ 1811 /* occupy slot */
1820 if (hint < MAX_DEV_HINTS) 1812 if (hint < MAX_DEV_HINTS)
1821 device_hint[hint].pdev = pdev; 1813 device_hint[hint].pdev = pdev;
1822 1814
1823 PWC_DEBUG_PROBE("probe() function returning struct at 0x%p.\n", pdev); 1815 PWC_DEBUG_PROBE("probe() function returning struct at 0x%p.\n", pdev);
1824 usb_set_intfdata (intf, pdev); 1816 usb_set_intfdata(intf, pdev);
1825 rc = pwc_create_sysfs_files(pdev->vdev); 1817 rc = pwc_create_sysfs_files(pdev->vdev);
1826 if (rc) 1818 if (rc)
1827 goto err_unreg; 1819 goto err_video_unreg;
1828 1820
1829 /* Set the leds off */ 1821 /* Set the leds off */
1830 pwc_set_leds(pdev, 0, 0); 1822 pwc_set_leds(pdev, 0, 0);
@@ -1835,16 +1827,16 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1835 pdev->button_dev = input_allocate_device(); 1827 pdev->button_dev = input_allocate_device();
1836 if (!pdev->button_dev) { 1828 if (!pdev->button_dev) {
1837 PWC_ERROR("Err, insufficient memory for webcam snapshot button device."); 1829 PWC_ERROR("Err, insufficient memory for webcam snapshot button device.");
1838 return -ENOMEM; 1830 rc = -ENOMEM;
1831 pwc_remove_sysfs_files(pdev->vdev);
1832 goto err_video_unreg;
1839 } 1833 }
1840 1834
1835 usb_make_path(udev, pdev->button_phys, sizeof(pdev->button_phys));
1836 strlcat(pdev->button_phys, "/input0", sizeof(pdev->button_phys));
1837
1841 pdev->button_dev->name = "PWC snapshot button"; 1838 pdev->button_dev->name = "PWC snapshot button";
1842 phys = kasprintf(GFP_KERNEL,"usb-%s-%s", pdev->udev->bus->bus_name, pdev->udev->devpath); 1839 pdev->button_dev->phys = pdev->button_phys;
1843 if (!phys) {
1844 input_free_device(pdev->button_dev);
1845 return -ENOMEM;
1846 }
1847 pdev->button_dev->phys = phys;
1848 usb_to_input_id(pdev->udev, &pdev->button_dev->id); 1840 usb_to_input_id(pdev->udev, &pdev->button_dev->id);
1849 pdev->button_dev->dev.parent = &pdev->udev->dev; 1841 pdev->button_dev->dev.parent = &pdev->udev->dev;
1850 pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY); 1842 pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY);
@@ -1853,25 +1845,27 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1853 rc = input_register_device(pdev->button_dev); 1845 rc = input_register_device(pdev->button_dev);
1854 if (rc) { 1846 if (rc) {
1855 input_free_device(pdev->button_dev); 1847 input_free_device(pdev->button_dev);
1856 kfree(pdev->button_dev->phys);
1857 pdev->button_dev = NULL; 1848 pdev->button_dev = NULL;
1858 return rc; 1849 pwc_remove_sysfs_files(pdev->vdev);
1850 goto err_video_unreg;
1859 } 1851 }
1860#endif 1852#endif
1861 1853
1862 return 0; 1854 return 0;
1863 1855
1864err_unreg: 1856err_video_unreg:
1865 if (hint < MAX_DEV_HINTS) 1857 if (hint < MAX_DEV_HINTS)
1866 device_hint[hint].pdev = NULL; 1858 device_hint[hint].pdev = NULL;
1867 video_unregister_device(pdev->vdev); 1859 video_unregister_device(pdev->vdev);
1868err: 1860 pdev->vdev = NULL; /* So we don't try to release it below */
1869 video_device_release(pdev->vdev); /* Drip... drip... drip... */ 1861err_video_release:
1870 kfree(pdev); /* Oops, no memory leaks please */ 1862 video_device_release(pdev->vdev);
1863err_free_mem:
1864 kfree(pdev);
1871 return rc; 1865 return rc;
1872} 1866}
1873 1867
1874/* The user janked out the cable... */ 1868/* The user yanked out the cable... */
1875static void usb_pwc_disconnect(struct usb_interface *intf) 1869static void usb_pwc_disconnect(struct usb_interface *intf)
1876{ 1870{
1877 struct pwc_device *pdev; 1871 struct pwc_device *pdev;
@@ -1902,7 +1896,7 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
1902 /* Alert waiting processes */ 1896 /* Alert waiting processes */
1903 wake_up_interruptible(&pdev->frameq); 1897 wake_up_interruptible(&pdev->frameq);
1904 /* Wait until device is closed */ 1898 /* Wait until device is closed */
1905 if(pdev->vopen) { 1899 if (pdev->vopen) {
1906 mutex_lock(&pdev->modlock); 1900 mutex_lock(&pdev->modlock);
1907 pdev->unplugged = 1; 1901 pdev->unplugged = 1;
1908 mutex_unlock(&pdev->modlock); 1902 mutex_unlock(&pdev->modlock);
@@ -1911,8 +1905,6 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
1911 /* Device is closed, so we can safely unregister it */ 1905 /* Device is closed, so we can safely unregister it */
1912 PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n"); 1906 PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n");
1913 pwc_cleanup(pdev); 1907 pwc_cleanup(pdev);
1914 /* Free memory (don't set pdev to 0 just yet) */
1915 kfree(pdev);
1916 1908
1917disconnect_out: 1909disconnect_out:
1918 /* search device_hint[] table if we occupy a slot, by any chance */ 1910 /* search device_hint[] table if we occupy a slot, by any chance */
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index 2876ce084510..bdb4ced57496 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -1033,7 +1033,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1033 if (std->index != 0) 1033 if (std->index != 0)
1034 return -EINVAL; 1034 return -EINVAL;
1035 std->id = V4L2_STD_UNKNOWN; 1035 std->id = V4L2_STD_UNKNOWN;
1036 strncpy(std->name, "webcam", sizeof(std->name)); 1036 strlcpy(std->name, "webcam", sizeof(std->name));
1037 return 0; 1037 return 0;
1038 } 1038 }
1039 1039
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 0b658dee05a4..0902355dfa77 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -135,12 +135,6 @@
135#define DEVICE_USE_CODEC3(x) ((x)>=700) 135#define DEVICE_USE_CODEC3(x) ((x)>=700)
136#define DEVICE_USE_CODEC23(x) ((x)>=675) 136#define DEVICE_USE_CODEC23(x) ((x)>=675)
137 137
138
139#ifndef V4L2_PIX_FMT_PWC1
140#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P','W','C','1')
141#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P','W','C','2')
142#endif
143
144/* The following structures were based on cpia.h. Why reinvent the wheel? :-) */ 138/* The following structures were based on cpia.h. Why reinvent the wheel? :-) */
145struct pwc_iso_buf 139struct pwc_iso_buf
146{ 140{
@@ -259,6 +253,7 @@ struct pwc_device
259 int snapshot_button_status; /* set to 1 when the user push the button, reset to 0 when this value is read */ 253 int snapshot_button_status; /* set to 1 when the user push the button, reset to 0 when this value is read */
260#ifdef CONFIG_USB_PWC_INPUT_EVDEV 254#ifdef CONFIG_USB_PWC_INPUT_EVDEV
261 struct input_dev *button_dev; /* webcam snapshot button input */ 255 struct input_dev *button_dev; /* webcam snapshot button input */
256 char button_phys[64];
262#endif 257#endif
263 258
264 /*** Misc. data ***/ 259 /*** Misc. data ***/
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
index c25e81af5ce0..c3e96f070973 100644
--- a/drivers/media/video/saa6588.c
+++ b/drivers/media/video/saa6588.c
@@ -40,7 +40,7 @@
40/* insmod options */ 40/* insmod options */
41static unsigned int debug; 41static unsigned int debug;
42static unsigned int xtal; 42static unsigned int xtal;
43static unsigned int rbds; 43static unsigned int mmbs;
44static unsigned int plvl; 44static unsigned int plvl;
45static unsigned int bufblocks = 100; 45static unsigned int bufblocks = 100;
46 46
@@ -48,8 +48,8 @@ module_param(debug, int, 0644);
48MODULE_PARM_DESC(debug, "enable debug messages"); 48MODULE_PARM_DESC(debug, "enable debug messages");
49module_param(xtal, int, 0); 49module_param(xtal, int, 0);
50MODULE_PARM_DESC(xtal, "select oscillator frequency (0..3), default 0"); 50MODULE_PARM_DESC(xtal, "select oscillator frequency (0..3), default 0");
51module_param(rbds, int, 0); 51module_param(mmbs, int, 0);
52MODULE_PARM_DESC(rbds, "select mode, 0=RDS, 1=RBDS, default 0"); 52MODULE_PARM_DESC(mmbs, "enable MMBS mode: 0=off (default), 1=on");
53module_param(plvl, int, 0); 53module_param(plvl, int, 0);
54MODULE_PARM_DESC(plvl, "select pause level (0..3), default 0"); 54MODULE_PARM_DESC(plvl, "select pause level (0..3), default 0");
55module_param(bufblocks, int, 0); 55module_param(bufblocks, int, 0);
@@ -78,6 +78,7 @@ struct saa6588 {
78 unsigned char last_blocknum; 78 unsigned char last_blocknum;
79 wait_queue_head_t read_queue; 79 wait_queue_head_t read_queue;
80 int data_available_for_read; 80 int data_available_for_read;
81 u8 sync;
81}; 82};
82 83
83static inline struct saa6588 *to_saa6588(struct v4l2_subdev *sd) 84static inline struct saa6588 *to_saa6588(struct v4l2_subdev *sd)
@@ -261,13 +262,16 @@ static void saa6588_i2c_poll(struct saa6588 *s)
261 unsigned char tmp; 262 unsigned char tmp;
262 263
263 /* Although we only need 3 bytes, we have to read at least 6. 264 /* Although we only need 3 bytes, we have to read at least 6.
264 SAA6588 returns garbage otherwise */ 265 SAA6588 returns garbage otherwise. */
265 if (6 != i2c_master_recv(client, &tmpbuf[0], 6)) { 266 if (6 != i2c_master_recv(client, &tmpbuf[0], 6)) {
266 if (debug > 1) 267 if (debug > 1)
267 dprintk(PREFIX "read error!\n"); 268 dprintk(PREFIX "read error!\n");
268 return; 269 return;
269 } 270 }
270 271
272 s->sync = tmpbuf[0] & 0x10;
273 if (!s->sync)
274 return;
271 blocknum = tmpbuf[0] >> 5; 275 blocknum = tmpbuf[0] >> 5;
272 if (blocknum == s->last_blocknum) { 276 if (blocknum == s->last_blocknum) {
273 if (debug > 3) 277 if (debug > 3)
@@ -286,9 +290,8 @@ static void saa6588_i2c_poll(struct saa6588 *s)
286 occurred during reception of this block. 290 occurred during reception of this block.
287 Bit 6: Corrected bit. Indicates that an error was 291 Bit 6: Corrected bit. Indicates that an error was
288 corrected for this data block. 292 corrected for this data block.
289 Bits 5-3: Received Offset. Indicates the offset received 293 Bits 5-3: Same as bits 0-2.
290 by the sync system. 294 Bits 2-0: Block number.
291 Bits 2-0: Offset Name. Indicates the offset applied to this data.
292 295
293 SAA6588 byte order is Status-MSB-LSB, so we have to swap the 296 SAA6588 byte order is Status-MSB-LSB, so we have to swap the
294 first and the last of the 3 bytes block. 297 first and the last of the 3 bytes block.
@@ -298,12 +301,21 @@ static void saa6588_i2c_poll(struct saa6588 *s)
298 tmpbuf[2] = tmpbuf[0]; 301 tmpbuf[2] = tmpbuf[0];
299 tmpbuf[0] = tmp; 302 tmpbuf[0] = tmp;
300 303
304 /* Map 'Invalid block E' to 'Invalid Block' */
305 if (blocknum == 6)
306 blocknum = V4L2_RDS_BLOCK_INVALID;
307 /* And if are not in mmbs mode, then 'Block E' is also mapped
308 to 'Invalid Block'. As far as I can tell MMBS is discontinued,
309 and if there is ever a need to support E blocks, then please
310 contact the linux-media mailinglist. */
311 else if (!mmbs && blocknum == 5)
312 blocknum = V4L2_RDS_BLOCK_INVALID;
301 tmp = blocknum; 313 tmp = blocknum;
302 tmp |= blocknum << 3; /* Received offset == Offset Name (OK ?) */ 314 tmp |= blocknum << 3; /* Received offset == Offset Name (OK ?) */
303 if ((tmpbuf[2] & 0x03) == 0x03) 315 if ((tmpbuf[2] & 0x03) == 0x03)
304 tmp |= 0x80; /* uncorrectable error */ 316 tmp |= V4L2_RDS_BLOCK_ERROR; /* uncorrectable error */
305 else if ((tmpbuf[2] & 0x03) != 0x00) 317 else if ((tmpbuf[2] & 0x03) != 0x00)
306 tmp |= 0x40; /* corrected error */ 318 tmp |= V4L2_RDS_BLOCK_CORRECTED; /* corrected error */
307 tmpbuf[2] = tmp; /* Is this enough ? Should we also check other bits ? */ 319 tmpbuf[2] = tmp; /* Is this enough ? Should we also check other bits ? */
308 320
309 spin_lock_irqsave(&s->lock, flags); 321 spin_lock_irqsave(&s->lock, flags);
@@ -321,14 +333,14 @@ static void saa6588_work(struct work_struct *work)
321 schedule_delayed_work(&s->work, msecs_to_jiffies(20)); 333 schedule_delayed_work(&s->work, msecs_to_jiffies(20));
322} 334}
323 335
324static int saa6588_configure(struct saa6588 *s) 336static void saa6588_configure(struct saa6588 *s)
325{ 337{
326 struct i2c_client *client = v4l2_get_subdevdata(&s->sd); 338 struct i2c_client *client = v4l2_get_subdevdata(&s->sd);
327 unsigned char buf[3]; 339 unsigned char buf[3];
328 int rc; 340 int rc;
329 341
330 buf[0] = cSyncRestart; 342 buf[0] = cSyncRestart;
331 if (rbds) 343 if (mmbs)
332 buf[0] |= cProcessingModeRBDS; 344 buf[0] |= cProcessingModeRBDS;
333 345
334 buf[1] = cFlywheelDefault; 346 buf[1] = cFlywheelDefault;
@@ -374,8 +386,6 @@ static int saa6588_configure(struct saa6588 *s)
374 rc = i2c_master_send(client, buf, 3); 386 rc = i2c_master_send(client, buf, 3);
375 if (rc != 3) 387 if (rc != 3)
376 printk(PREFIX "i2c i/o error: rc == %d (should be 3)\n", rc); 388 printk(PREFIX "i2c i/o error: rc == %d (should be 3)\n", rc);
377
378 return 0;
379} 389}
380 390
381/* ---------------------------------------------------------------------- */ 391/* ---------------------------------------------------------------------- */
@@ -416,6 +426,24 @@ static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
416 return 0; 426 return 0;
417} 427}
418 428
429static int saa6588_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
430{
431 struct saa6588 *s = to_saa6588(sd);
432
433 vt->capability |= V4L2_TUNER_CAP_RDS;
434 if (s->sync)
435 vt->rxsubchans |= V4L2_TUNER_SUB_RDS;
436 return 0;
437}
438
439static int saa6588_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
440{
441 struct saa6588 *s = to_saa6588(sd);
442
443 saa6588_configure(s);
444 return 0;
445}
446
419static int saa6588_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) 447static int saa6588_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
420{ 448{
421 struct i2c_client *client = v4l2_get_subdevdata(sd); 449 struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -430,8 +458,14 @@ static const struct v4l2_subdev_core_ops saa6588_core_ops = {
430 .ioctl = saa6588_ioctl, 458 .ioctl = saa6588_ioctl,
431}; 459};
432 460
461static const struct v4l2_subdev_tuner_ops saa6588_tuner_ops = {
462 .g_tuner = saa6588_g_tuner,
463 .s_tuner = saa6588_s_tuner,
464};
465
433static const struct v4l2_subdev_ops saa6588_ops = { 466static const struct v4l2_subdev_ops saa6588_ops = {
434 .core = &saa6588_core_ops, 467 .core = &saa6588_core_ops,
468 .tuner = &saa6588_tuner_ops,
435}; 469};
436 470
437/* ---------------------------------------------------------------------- */ 471/* ---------------------------------------------------------------------- */
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index 5bcce092e804..22bfd62c9551 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -47,6 +47,7 @@ config VIDEO_SAA7134_DVB
47 select DVB_TDA10048 if !DVB_FE_CUSTOMISE 47 select DVB_TDA10048 if !DVB_FE_CUSTOMISE
48 select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE 48 select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
49 select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE 49 select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
50 select DVB_ZL10039 if !DVB_FE_CUSTOMISE
50 ---help--- 51 ---help---
51 This adds support for DVB cards based on the 52 This adds support for DVB cards based on the
52 Philips saa7134 chip. 53 Philips saa7134 chip.
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index 63c4b8f1f541..1eabff6b2456 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -468,7 +468,7 @@ static int handle_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
468 if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 && 468 if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
469 (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3)) 469 (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3))
470 return -ERANGE; 470 return -ERANGE;
471 new = old; 471 params->au_encoding = new;
472 break; 472 break;
473 case V4L2_CID_MPEG_AUDIO_L2_BITRATE: 473 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
474 old = params->au_l2_bitrate; 474 old = params->au_l2_bitrate;
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index 8b0b64a89874..d48c450ed77c 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -40,6 +40,7 @@ MODULE_PARM_DESC(debug,"enable debug messages [alsa]");
40 */ 40 */
41 41
42/* defaults */ 42/* defaults */
43#define MIXER_ADDR_UNSELECTED -1
43#define MIXER_ADDR_TVTUNER 0 44#define MIXER_ADDR_TVTUNER 0
44#define MIXER_ADDR_LINE1 1 45#define MIXER_ADDR_LINE1 1
45#define MIXER_ADDR_LINE2 2 46#define MIXER_ADDR_LINE2 2
@@ -68,7 +69,9 @@ typedef struct snd_card_saa7134 {
68 struct snd_card *card; 69 struct snd_card *card;
69 spinlock_t mixer_lock; 70 spinlock_t mixer_lock;
70 int mixer_volume[MIXER_ADDR_LAST+1][2]; 71 int mixer_volume[MIXER_ADDR_LAST+1][2];
71 int capture_source[MIXER_ADDR_LAST+1][2]; 72 int capture_source_addr;
73 int capture_source[2];
74 struct snd_kcontrol *capture_ctl[MIXER_ADDR_LAST+1];
72 struct pci_dev *pci; 75 struct pci_dev *pci;
73 struct saa7134_dev *dev; 76 struct saa7134_dev *dev;
74 77
@@ -314,6 +317,115 @@ static int dsp_buffer_free(struct saa7134_dev *dev)
314 return 0; 317 return 0;
315} 318}
316 319
320/*
321 * Setting the capture source and updating the ALSA controls
322 */
323static int snd_saa7134_capsrc_set(struct snd_kcontrol *kcontrol,
324 int left, int right, bool force_notify)
325{
326 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
327 int change = 0, addr = kcontrol->private_value;
328 int active, old_addr;
329 u32 anabar, xbarin;
330 int analog_io, rate;
331 struct saa7134_dev *dev;
332
333 dev = chip->dev;
334
335 spin_lock_irq(&chip->mixer_lock);
336
337 active = left != 0 || right != 0;
338 old_addr = chip->capture_source_addr;
339
340 /* The active capture source cannot be deactivated */
341 if (active) {
342 change = old_addr != addr ||
343 chip->capture_source[0] != left ||
344 chip->capture_source[1] != right;
345
346 chip->capture_source[0] = left;
347 chip->capture_source[1] = right;
348 chip->capture_source_addr = addr;
349 dev->dmasound.input = addr;
350 }
351 spin_unlock_irq(&chip->mixer_lock);
352
353 if (change) {
354 switch (dev->pci->device) {
355
356 case PCI_DEVICE_ID_PHILIPS_SAA7134:
357 switch (addr) {
358 case MIXER_ADDR_TVTUNER:
359 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL,
360 0xc0, 0xc0);
361 saa_andorb(SAA7134_SIF_SAMPLE_FREQ,
362 0x03, 0x00);
363 break;
364 case MIXER_ADDR_LINE1:
365 case MIXER_ADDR_LINE2:
366 analog_io = (MIXER_ADDR_LINE1 == addr) ?
367 0x00 : 0x08;
368 rate = (32000 == dev->dmasound.rate) ?
369 0x01 : 0x03;
370 saa_andorb(SAA7134_ANALOG_IO_SELECT,
371 0x08, analog_io);
372 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL,
373 0xc0, 0x80);
374 saa_andorb(SAA7134_SIF_SAMPLE_FREQ,
375 0x03, rate);
376 break;
377 }
378
379 break;
380 case PCI_DEVICE_ID_PHILIPS_SAA7133:
381 case PCI_DEVICE_ID_PHILIPS_SAA7135:
382 xbarin = 0x03; /* adc */
383 anabar = 0;
384 switch (addr) {
385 case MIXER_ADDR_TVTUNER:
386 xbarin = 0; /* Demodulator */
387 anabar = 2; /* DACs */
388 break;
389 case MIXER_ADDR_LINE1:
390 anabar = 0; /* aux1, aux1 */
391 break;
392 case MIXER_ADDR_LINE2:
393 anabar = 9; /* aux2, aux2 */
394 break;
395 }
396
397 /* output xbar always main channel */
398 saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1,
399 0xbbbb10);
400
401 if (left || right) {
402 /* We've got data, turn the input on */
403 saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1,
404 xbarin);
405 saa_writel(SAA7133_ANALOG_IO_SELECT, anabar);
406 } else {
407 saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1,
408 0);
409 saa_writel(SAA7133_ANALOG_IO_SELECT, 0);
410 }
411 break;
412 }
413 }
414
415 if (change) {
416 if (force_notify)
417 snd_ctl_notify(chip->card,
418 SNDRV_CTL_EVENT_MASK_VALUE,
419 &chip->capture_ctl[addr]->id);
420
421 if (old_addr != MIXER_ADDR_UNSELECTED && old_addr != addr)
422 snd_ctl_notify(chip->card,
423 SNDRV_CTL_EVENT_MASK_VALUE,
424 &chip->capture_ctl[old_addr]->id);
425 }
426
427 return change;
428}
317 429
318/* 430/*
319 * ALSA PCM preparation 431 * ALSA PCM preparation
@@ -401,6 +513,10 @@ static int snd_card_saa7134_capture_prepare(struct snd_pcm_substream * substream
401 513
402 dev->dmasound.rate = runtime->rate; 514 dev->dmasound.rate = runtime->rate;
403 515
516 /* Setup and update the card/ALSA controls */
517 snd_saa7134_capsrc_set(saa7134->capture_ctl[dev->dmasound.input], 1, 1,
518 true);
519
404 return 0; 520 return 0;
405 521
406} 522}
@@ -435,6 +551,16 @@ snd_card_saa7134_capture_pointer(struct snd_pcm_substream * substream)
435 551
436/* 552/*
437 * ALSA hardware capabilities definition 553 * ALSA hardware capabilities definition
554 *
555 * Report only 32kHz for ALSA:
556 *
557 * - SAA7133/35 uses DDEP (DemDec Easy Programming mode), which works in 32kHz
558 * only
559 * - SAA7134 for TV mode uses DemDec mode (32kHz)
560 * - Radio works in 32kHz only
561 * - When recording 48kHz from Line1/Line2, switching of capture source to TV
562 * means
563 * switching to 32kHz without any frequency translation
438 */ 564 */
439 565
440static struct snd_pcm_hardware snd_card_saa7134_capture = 566static struct snd_pcm_hardware snd_card_saa7134_capture =
@@ -448,9 +574,9 @@ static struct snd_pcm_hardware snd_card_saa7134_capture =
448 SNDRV_PCM_FMTBIT_U8 | \ 574 SNDRV_PCM_FMTBIT_U8 | \
449 SNDRV_PCM_FMTBIT_U16_LE | \ 575 SNDRV_PCM_FMTBIT_U16_LE | \
450 SNDRV_PCM_FMTBIT_U16_BE, 576 SNDRV_PCM_FMTBIT_U16_BE,
451 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000, 577 .rates = SNDRV_PCM_RATE_32000,
452 .rate_min = 32000, 578 .rate_min = 32000,
453 .rate_max = 48000, 579 .rate_max = 32000,
454 .channels_min = 1, 580 .channels_min = 1,
455 .channels_max = 2, 581 .channels_max = 2,
456 .buffer_bytes_max = (256*1024), 582 .buffer_bytes_max = (256*1024),
@@ -836,8 +962,13 @@ static int snd_saa7134_capsrc_get(struct snd_kcontrol * kcontrol,
836 int addr = kcontrol->private_value; 962 int addr = kcontrol->private_value;
837 963
838 spin_lock_irq(&chip->mixer_lock); 964 spin_lock_irq(&chip->mixer_lock);
839 ucontrol->value.integer.value[0] = chip->capture_source[addr][0]; 965 if (chip->capture_source_addr == addr) {
840 ucontrol->value.integer.value[1] = chip->capture_source[addr][1]; 966 ucontrol->value.integer.value[0] = chip->capture_source[0];
967 ucontrol->value.integer.value[1] = chip->capture_source[1];
968 } else {
969 ucontrol->value.integer.value[0] = 0;
970 ucontrol->value.integer.value[1] = 0;
971 }
841 spin_unlock_irq(&chip->mixer_lock); 972 spin_unlock_irq(&chip->mixer_lock);
842 973
843 return 0; 974 return 0;
@@ -846,87 +977,22 @@ static int snd_saa7134_capsrc_get(struct snd_kcontrol * kcontrol,
846static int snd_saa7134_capsrc_put(struct snd_kcontrol * kcontrol, 977static int snd_saa7134_capsrc_put(struct snd_kcontrol * kcontrol,
847 struct snd_ctl_elem_value * ucontrol) 978 struct snd_ctl_elem_value * ucontrol)
848{ 979{
849 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
850 int change, addr = kcontrol->private_value;
851 int left, right; 980 int left, right;
852 u32 anabar, xbarin;
853 int analog_io, rate;
854 struct saa7134_dev *dev;
855
856 dev = chip->dev;
857
858 left = ucontrol->value.integer.value[0] & 1; 981 left = ucontrol->value.integer.value[0] & 1;
859 right = ucontrol->value.integer.value[1] & 1; 982 right = ucontrol->value.integer.value[1] & 1;
860 spin_lock_irq(&chip->mixer_lock);
861
862 change = chip->capture_source[addr][0] != left ||
863 chip->capture_source[addr][1] != right;
864 chip->capture_source[addr][0] = left;
865 chip->capture_source[addr][1] = right;
866 dev->dmasound.input=addr;
867 spin_unlock_irq(&chip->mixer_lock);
868
869
870 if (change) {
871 switch (dev->pci->device) {
872
873 case PCI_DEVICE_ID_PHILIPS_SAA7134:
874 switch (addr) {
875 case MIXER_ADDR_TVTUNER:
876 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
877 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00);
878 break;
879 case MIXER_ADDR_LINE1:
880 case MIXER_ADDR_LINE2:
881 analog_io = (MIXER_ADDR_LINE1 == addr) ? 0x00 : 0x08;
882 rate = (32000 == dev->dmasound.rate) ? 0x01 : 0x03;
883 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io);
884 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
885 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate);
886 break;
887 }
888
889 break;
890 case PCI_DEVICE_ID_PHILIPS_SAA7133:
891 case PCI_DEVICE_ID_PHILIPS_SAA7135:
892 xbarin = 0x03; // adc
893 anabar = 0;
894 switch (addr) {
895 case MIXER_ADDR_TVTUNER:
896 xbarin = 0; // Demodulator
897 anabar = 2; // DACs
898 break;
899 case MIXER_ADDR_LINE1:
900 anabar = 0; // aux1, aux1
901 break;
902 case MIXER_ADDR_LINE2:
903 anabar = 9; // aux2, aux2
904 break;
905 }
906
907 /* output xbar always main channel */
908 saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1, 0xbbbb10);
909 983
910 if (left || right) { // We've got data, turn the input on 984 return snd_saa7134_capsrc_set(kcontrol, left, right, false);
911 saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, xbarin);
912 saa_writel(SAA7133_ANALOG_IO_SELECT, anabar);
913 } else {
914 saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, 0);
915 saa_writel(SAA7133_ANALOG_IO_SELECT, 0);
916 }
917 break;
918 }
919 }
920
921 return change;
922} 985}
923 986
924static struct snd_kcontrol_new snd_saa7134_controls[] = { 987static struct snd_kcontrol_new snd_saa7134_volume_controls[] = {
925SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER), 988SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER),
926SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER),
927SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1), 989SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1),
928SAA713x_CAPSRC("Line Capture Switch", 1, MIXER_ADDR_LINE1),
929SAA713x_VOLUME("Line Volume", 2, MIXER_ADDR_LINE2), 990SAA713x_VOLUME("Line Volume", 2, MIXER_ADDR_LINE2),
991};
992
993static struct snd_kcontrol_new snd_saa7134_capture_controls[] = {
994SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER),
995SAA713x_CAPSRC("Line Capture Switch", 1, MIXER_ADDR_LINE1),
930SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2), 996SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
931}; 997};
932 998
@@ -941,17 +1007,33 @@ SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
941static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip) 1007static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
942{ 1008{
943 struct snd_card *card = chip->card; 1009 struct snd_card *card = chip->card;
1010 struct snd_kcontrol *kcontrol;
944 unsigned int idx; 1011 unsigned int idx;
945 int err; 1012 int err, addr;
946 1013
947 if (snd_BUG_ON(!chip)) 1014 if (snd_BUG_ON(!chip))
948 return -EINVAL; 1015 return -EINVAL;
949 strcpy(card->mixername, "SAA7134 Mixer"); 1016 strcpy(card->mixername, "SAA7134 Mixer");
950 1017
951 for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_controls); idx++) { 1018 for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_volume_controls); idx++) {
952 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_saa7134_controls[idx], chip))) < 0) 1019 kcontrol = snd_ctl_new1(&snd_saa7134_volume_controls[idx],
1020 chip);
1021 err = snd_ctl_add(card, kcontrol);
1022 if (err < 0)
953 return err; 1023 return err;
954 } 1024 }
1025
1026 for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_capture_controls); idx++) {
1027 kcontrol = snd_ctl_new1(&snd_saa7134_capture_controls[idx],
1028 chip);
1029 addr = snd_saa7134_capture_controls[idx].private_value;
1030 chip->capture_ctl[addr] = kcontrol;
1031 err = snd_ctl_add(card, kcontrol);
1032 if (err < 0)
1033 return err;
1034 }
1035
1036 chip->capture_source_addr = MIXER_ADDR_UNSELECTED;
955 return 0; 1037 return 0;
956} 1038}
957 1039
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 6eebe3ef97d3..1b29487fd254 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -32,6 +32,7 @@
32#include <media/tveeprom.h> 32#include <media/tveeprom.h>
33#include "tea5767.h" 33#include "tea5767.h"
34#include "tda18271.h" 34#include "tda18271.h"
35#include "xc5000.h"
35 36
36/* commly used strings */ 37/* commly used strings */
37static char name_mute[] = "mute"; 38static char name_mute[] = "mute";
@@ -265,6 +266,56 @@ struct saa7134_board saa7134_boards[] = {
265 .gpio = 0x10000, 266 .gpio = 0x10000,
266 }, 267 },
267 }, 268 },
269 [SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM] = {
270 /* RoverMedia TV Link Pro FM (LR138 REV:I) */
271 /* Eugene Yudin <Eugene.Yudin@gmail.com> */
272 .name = "RoverMedia TV Link Pro FM",
273 .audio_clock = 0x00200000,
274 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* TCL MFPE05 2 */
275 .radio_type = UNSET,
276 .tuner_addr = ADDR_UNSET,
277 .radio_addr = ADDR_UNSET,
278 .tda9887_conf = TDA9887_PRESENT,
279 .gpiomask = 0xe000,
280 .inputs = { {
281 .name = name_tv,
282 .vmux = 1,
283 .amux = TV,
284 .gpio = 0x8000,
285 .tv = 1,
286 }, {
287 .name = name_tv_mono,
288 .vmux = 1,
289 .amux = LINE2,
290 .gpio = 0x0000,
291 .tv = 1,
292 }, {
293 .name = name_comp1,
294 .vmux = 0,
295 .amux = LINE2,
296 .gpio = 0x4000,
297 }, {
298 .name = name_comp2,
299 .vmux = 3,
300 .amux = LINE2,
301 .gpio = 0x4000,
302 }, {
303 .name = name_svideo,
304 .vmux = 8,
305 .amux = LINE2,
306 .gpio = 0x4000,
307 } },
308 .radio = {
309 .name = name_radio,
310 .amux = LINE2,
311 .gpio = 0x2000,
312 },
313 .mute = {
314 .name = name_mute,
315 .amux = TV,
316 .gpio = 0x8000,
317 },
318 },
268 [SAA7134_BOARD_EMPRESS] = { 319 [SAA7134_BOARD_EMPRESS] = {
269 /* "Gert Vervoort" <gert.vervoort@philips.com> */ 320 /* "Gert Vervoort" <gert.vervoort@philips.com> */
270 .name = "EMPRESS", 321 .name = "EMPRESS",
@@ -1364,6 +1415,42 @@ struct saa7134_board saa7134_boards[] = {
1364 .amux = LINE1, 1415 .amux = LINE1,
1365 }, 1416 },
1366 }, 1417 },
1418 [SAA7134_BOARD_AVERMEDIA_STUDIO_505] = {
1419 /* Vasiliy Temnikov <vaka@newmail.ru> */
1420 .name = "AverMedia AverTV Studio 505",
1421 .audio_clock = 0x00187de7,
1422 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
1423 .radio_type = UNSET,
1424 .tuner_addr = ADDR_UNSET,
1425 .radio_addr = ADDR_UNSET,
1426 .tda9887_conf = TDA9887_PRESENT,
1427 .inputs = { {
1428 .name = name_tv,
1429 .vmux = 1,
1430 .amux = LINE2,
1431 .tv = 1,
1432 }, {
1433 .name = name_comp1,
1434 .vmux = 0,
1435 .amux = LINE2,
1436 }, {
1437 .name = name_comp2,
1438 .vmux = 3,
1439 .amux = LINE2,
1440 },{
1441 .name = name_svideo,
1442 .vmux = 8,
1443 .amux = LINE2,
1444 } },
1445 .radio = {
1446 .name = name_radio,
1447 .amux = LINE2,
1448 },
1449 .mute = {
1450 .name = name_mute,
1451 .amux = LINE1,
1452 },
1453 },
1367 [SAA7134_BOARD_UPMOST_PURPLE_TV] = { 1454 [SAA7134_BOARD_UPMOST_PURPLE_TV] = {
1368 .name = "UPMOST PURPLE TV", 1455 .name = "UPMOST PURPLE TV",
1369 .audio_clock = 0x00187de7, 1456 .audio_clock = 0x00187de7,
@@ -1633,7 +1720,7 @@ struct saa7134_board saa7134_boards[] = {
1633 }}, 1720 }},
1634 .radio = { 1721 .radio = {
1635 .name = name_radio, 1722 .name = name_radio,
1636 .amux = LINE1, 1723 .amux = TV,
1637 .gpio = 0x00300001, 1724 .gpio = 0x00300001,
1638 }, 1725 },
1639 .mute = { 1726 .mute = {
@@ -3663,8 +3750,8 @@ struct saa7134_board saa7134_boards[] = {
3663 .amux = TV, 3750 .amux = TV,
3664 .gpio = 0x0200000, 3751 .gpio = 0x0200000,
3665 }, 3752 },
3666 }, 3753 },
3667 [SAA7134_BOARD_ASUSTeK_P7131_ANALOG] = { 3754 [SAA7134_BOARD_ASUSTeK_P7131_ANALOG] = {
3668 .name = "ASUSTeK P7131 Analog", 3755 .name = "ASUSTeK P7131 Analog",
3669 .audio_clock = 0x00187de7, 3756 .audio_clock = 0x00187de7,
3670 .tuner_type = TUNER_PHILIPS_TDA8290, 3757 .tuner_type = TUNER_PHILIPS_TDA8290,
@@ -4081,6 +4168,7 @@ struct saa7134_board saa7134_boards[] = {
4081 .radio_type = UNSET, 4168 .radio_type = UNSET,
4082 .tuner_addr = ADDR_UNSET, 4169 .tuner_addr = ADDR_UNSET,
4083 .radio_addr = ADDR_UNSET, 4170 .radio_addr = ADDR_UNSET,
4171 .rds_addr = 0x10,
4084 .tda9887_conf = TDA9887_PRESENT, 4172 .tda9887_conf = TDA9887_PRESENT,
4085 .gpiomask = 0x00008000, 4173 .gpiomask = 0x00008000,
4086 .inputs = {{ 4174 .inputs = {{
@@ -4145,6 +4233,7 @@ struct saa7134_board saa7134_boards[] = {
4145 .radio_type = UNSET, 4233 .radio_type = UNSET,
4146 .tuner_addr = ADDR_UNSET, 4234 .tuner_addr = ADDR_UNSET,
4147 .radio_addr = ADDR_UNSET, 4235 .radio_addr = ADDR_UNSET,
4236 .rds_addr = 0x10,
4148 .tda9887_conf = TDA9887_PRESENT, 4237 .tda9887_conf = TDA9887_PRESENT,
4149 .gpiomask = 0x00008000, 4238 .gpiomask = 0x00008000,
4150 .inputs = {{ 4239 .inputs = {{
@@ -4175,6 +4264,7 @@ struct saa7134_board saa7134_boards[] = {
4175 .radio_type = UNSET, 4264 .radio_type = UNSET,
4176 .tuner_addr = ADDR_UNSET, 4265 .tuner_addr = ADDR_UNSET,
4177 .radio_addr = ADDR_UNSET, 4266 .radio_addr = ADDR_UNSET,
4267 .rds_addr = 0x10,
4178 .tda9887_conf = TDA9887_PRESENT, 4268 .tda9887_conf = TDA9887_PRESENT,
4179 .gpiomask = 0x00008000, 4269 .gpiomask = 0x00008000,
4180 .inputs = {{ 4270 .inputs = {{
@@ -4350,6 +4440,7 @@ struct saa7134_board saa7134_boards[] = {
4350 .radio_type = UNSET, 4440 .radio_type = UNSET,
4351 .tuner_addr = ADDR_UNSET, 4441 .tuner_addr = ADDR_UNSET,
4352 .radio_addr = ADDR_UNSET, 4442 .radio_addr = ADDR_UNSET,
4443 .rds_addr = 0x10,
4353 .tda9887_conf = TDA9887_PRESENT, 4444 .tda9887_conf = TDA9887_PRESENT,
4354 .inputs = {{ 4445 .inputs = {{
4355 .name = name_tv, 4446 .name = name_tv,
@@ -4378,6 +4469,7 @@ struct saa7134_board saa7134_boards[] = {
4378 .radio_type = UNSET, 4469 .radio_type = UNSET,
4379 .tuner_addr = ADDR_UNSET, 4470 .tuner_addr = ADDR_UNSET,
4380 .radio_addr = ADDR_UNSET, 4471 .radio_addr = ADDR_UNSET,
4472 .rds_addr = 0x10,
4381 .tda9887_conf = TDA9887_PRESENT, 4473 .tda9887_conf = TDA9887_PRESENT,
4382 .inputs = {{ 4474 .inputs = {{
4383 .name = name_tv, 4475 .name = name_tv,
@@ -4406,6 +4498,7 @@ struct saa7134_board saa7134_boards[] = {
4406 .radio_type = UNSET, 4498 .radio_type = UNSET,
4407 .tuner_addr = ADDR_UNSET, 4499 .tuner_addr = ADDR_UNSET,
4408 .radio_addr = ADDR_UNSET, 4500 .radio_addr = ADDR_UNSET,
4501 .rds_addr = 0x10,
4409 .tda9887_conf = TDA9887_PRESENT, 4502 .tda9887_conf = TDA9887_PRESENT,
4410 .inputs = {{ 4503 .inputs = {{
4411 .name = name_tv, 4504 .name = name_tv,
@@ -4434,6 +4527,7 @@ struct saa7134_board saa7134_boards[] = {
4434 .radio_type = UNSET, 4527 .radio_type = UNSET,
4435 .tuner_addr = ADDR_UNSET, 4528 .tuner_addr = ADDR_UNSET,
4436 .radio_addr = ADDR_UNSET, 4529 .radio_addr = ADDR_UNSET,
4530 .rds_addr = 0x10,
4437 .tda9887_conf = TDA9887_PRESENT, 4531 .tda9887_conf = TDA9887_PRESENT,
4438 .inputs = {{ 4532 .inputs = {{
4439 .name = name_tv, 4533 .name = name_tv,
@@ -4540,6 +4634,7 @@ struct saa7134_board saa7134_boards[] = {
4540 .radio_type = UNSET, 4634 .radio_type = UNSET,
4541 .tuner_addr = ADDR_UNSET, 4635 .tuner_addr = ADDR_UNSET,
4542 .radio_addr = ADDR_UNSET, 4636 .radio_addr = ADDR_UNSET,
4637 .rds_addr = 0x10,
4543 .empress_addr = 0x20, 4638 .empress_addr = 0x20,
4544 .tda9887_conf = TDA9887_PRESENT, 4639 .tda9887_conf = TDA9887_PRESENT,
4545 .inputs = { { 4640 .inputs = { {
@@ -4861,7 +4956,7 @@ struct saa7134_board saa7134_boards[] = {
4861 /* Igor Kuznetsov <igk@igk.ru> */ 4956 /* Igor Kuznetsov <igk@igk.ru> */
4862 .name = "Beholder BeholdTV H6", 4957 .name = "Beholder BeholdTV H6",
4863 .audio_clock = 0x00187de7, 4958 .audio_clock = 0x00187de7,
4864 .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3, 4959 .tuner_type = TUNER_PHILIPS_FMD1216MEX_MK3,
4865 .radio_type = UNSET, 4960 .radio_type = UNSET,
4866 .tuner_addr = ADDR_UNSET, 4961 .tuner_addr = ADDR_UNSET,
4867 .radio_addr = ADDR_UNSET, 4962 .radio_addr = ADDR_UNSET,
@@ -5116,6 +5211,53 @@ struct saa7134_board saa7134_boards[] = {
5116 .gpio = 0x00, 5211 .gpio = 0x00,
5117 }, 5212 },
5118 }, 5213 },
5214 [SAA7134_BOARD_VIDEOMATE_S350] = {
5215 /* Jan D. Louw <jd.louw@mweb.co.za */
5216 .name = "Compro VideoMate S350/S300",
5217 .audio_clock = 0x00187de7,
5218 .tuner_type = TUNER_ABSENT,
5219 .radio_type = UNSET,
5220 .tuner_addr = ADDR_UNSET,
5221 .radio_addr = ADDR_UNSET,
5222 .mpeg = SAA7134_MPEG_DVB,
5223 .inputs = { {
5224 .name = name_comp1,
5225 .vmux = 0,
5226 .amux = LINE1,
5227 }, {
5228 .name = name_svideo,
5229 .vmux = 8, /* Not tested */
5230 .amux = LINE1
5231 } },
5232 },
5233 [SAA7134_BOARD_BEHOLD_X7] = {
5234 /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */
5235 .name = "Beholder BeholdTV X7",
5236 .audio_clock = 0x00187de7,
5237 .tuner_type = TUNER_XC5000,
5238 .radio_type = UNSET,
5239 .tuner_addr = ADDR_UNSET,
5240 .radio_addr = ADDR_UNSET,
5241 .inputs = { {
5242 .name = name_tv,
5243 .vmux = 2,
5244 .amux = TV,
5245 .tv = 1,
5246 }, {
5247 .name = name_comp1,
5248 .vmux = 0,
5249 .amux = LINE1,
5250 }, {
5251 .name = name_svideo,
5252 .vmux = 9,
5253 .amux = LINE1,
5254 } },
5255 .radio = {
5256 .name = name_radio,
5257 .amux = TV,
5258 },
5259 },
5260
5119}; 5261};
5120 5262
5121const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); 5263const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -5374,6 +5516,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
5374 .vendor = PCI_VENDOR_ID_PHILIPS, 5516 .vendor = PCI_VENDOR_ID_PHILIPS,
5375 .device = PCI_DEVICE_ID_PHILIPS_SAA7130, 5517 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
5376 .subvendor = 0x1461, /* Avermedia Technologies Inc */ 5518 .subvendor = 0x1461, /* Avermedia Technologies Inc */
5519 .subdevice = 0xa115,
5520 .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_505,
5521 }, {
5522 .vendor = PCI_VENDOR_ID_PHILIPS,
5523 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
5524 .subvendor = 0x1461, /* Avermedia Technologies Inc */
5377 .subdevice = 0x2108, 5525 .subdevice = 0x2108,
5378 .driver_data = SAA7134_BOARD_AVERMEDIA_305, 5526 .driver_data = SAA7134_BOARD_AVERMEDIA_305,
5379 },{ 5527 },{
@@ -6223,7 +6371,24 @@ struct pci_device_id saa7134_pci_tbl[] = {
6223 .subvendor = 0x1461, /* Avermedia Technologies Inc */ 6371 .subvendor = 0x1461, /* Avermedia Technologies Inc */
6224 .subdevice = 0xf31d, 6372 .subdevice = 0xf31d,
6225 .driver_data = SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS, 6373 .driver_data = SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS,
6226 6374 }, {
6375 .vendor = PCI_VENDOR_ID_PHILIPS,
6376 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
6377 .subvendor = 0x185b,
6378 .subdevice = 0xc900,
6379 .driver_data = SAA7134_BOARD_VIDEOMATE_S350,
6380 }, {
6381 .vendor = PCI_VENDOR_ID_PHILIPS,
6382 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
6383 .subvendor = 0x5ace, /* Beholder Intl. Ltd. */
6384 .subdevice = 0x7595,
6385 .driver_data = SAA7134_BOARD_BEHOLD_X7,
6386 }, {
6387 .vendor = PCI_VENDOR_ID_PHILIPS,
6388 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
6389 .subvendor = 0x19d1, /* RoverMedia */
6390 .subdevice = 0x0138, /* LifeView FlyTV Prime30 OEM */
6391 .driver_data = SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM,
6227 }, { 6392 }, {
6228 /* --- boards without eeprom + subsystem ID --- */ 6393 /* --- boards without eeprom + subsystem ID --- */
6229 .vendor = PCI_VENDOR_ID_PHILIPS, 6394 .vendor = PCI_VENDOR_ID_PHILIPS,
@@ -6310,6 +6475,32 @@ static int saa7134_xc2028_callback(struct saa7134_dev *dev,
6310 return -EINVAL; 6475 return -EINVAL;
6311} 6476}
6312 6477
6478static int saa7134_xc5000_callback(struct saa7134_dev *dev,
6479 int command, int arg)
6480{
6481 switch (dev->board) {
6482 case SAA7134_BOARD_BEHOLD_X7:
6483 if (command == XC5000_TUNER_RESET) {
6484 /* Down and UP pheripherial RESET pin for reset all chips */
6485 saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
6486 msleep(10);
6487 saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
6488 msleep(10);
6489 }
6490 break;
6491 default:
6492 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x06e20000, 0x06e20000);
6493 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x06a20000, 0x06a20000);
6494 saa_andorl(SAA7133_ANALOG_IO_SELECT >> 2, 0x02, 0x02);
6495 saa_andorl(SAA7134_ANALOG_IN_CTRL1 >> 2, 0x81, 0x81);
6496 saa_andorl(SAA7134_AUDIO_CLOCK0 >> 2, 0x03187de7, 0x03187de7);
6497 saa_andorl(SAA7134_AUDIO_PLL_CTRL >> 2, 0x03, 0x03);
6498 saa_andorl(SAA7134_AUDIO_CLOCKS_PER_FIELD0 >> 2,
6499 0x0001e000, 0x0001e000);
6500 break;
6501 }
6502 return 0;
6503}
6313 6504
6314static int saa7134_tda8290_827x_callback(struct saa7134_dev *dev, 6505static int saa7134_tda8290_827x_callback(struct saa7134_dev *dev,
6315 int command, int arg) 6506 int command, int arg)
@@ -6406,6 +6597,8 @@ int saa7134_tuner_callback(void *priv, int component, int command, int arg)
6406 return saa7134_tda8290_callback(dev, command, arg); 6597 return saa7134_tda8290_callback(dev, command, arg);
6407 case TUNER_XC2028: 6598 case TUNER_XC2028:
6408 return saa7134_xc2028_callback(dev, command, arg); 6599 return saa7134_xc2028_callback(dev, command, arg);
6600 case TUNER_XC5000:
6601 return saa7134_xc5000_callback(dev, command, arg);
6409 } 6602 }
6410 } else { 6603 } else {
6411 printk(KERN_ERR "saa7134: Error - device struct undefined.\n"); 6604 printk(KERN_ERR "saa7134: Error - device struct undefined.\n");
@@ -6476,6 +6669,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
6476 case SAA7134_BOARD_KWORLD_VSTREAM_XPERT: 6669 case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
6477 case SAA7134_BOARD_KWORLD_XPERT: 6670 case SAA7134_BOARD_KWORLD_XPERT:
6478 case SAA7134_BOARD_AVERMEDIA_STUDIO_305: 6671 case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
6672 case SAA7134_BOARD_AVERMEDIA_STUDIO_505:
6479 case SAA7134_BOARD_AVERMEDIA_305: 6673 case SAA7134_BOARD_AVERMEDIA_305:
6480 case SAA7134_BOARD_AVERMEDIA_STUDIO_307: 6674 case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
6481 case SAA7134_BOARD_AVERMEDIA_307: 6675 case SAA7134_BOARD_AVERMEDIA_307:
@@ -6500,7 +6694,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
6500 case SAA7134_BOARD_FLYDVBT_LR301: 6694 case SAA7134_BOARD_FLYDVBT_LR301:
6501 case SAA7134_BOARD_ASUSTeK_P7131_DUAL: 6695 case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
6502 case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: 6696 case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
6503 case SAA7134_BOARD_ASUSTeK_P7131_ANALOG: 6697 case SAA7134_BOARD_ASUSTeK_P7131_ANALOG:
6504 case SAA7134_BOARD_FLYDVBTDUO: 6698 case SAA7134_BOARD_FLYDVBTDUO:
6505 case SAA7134_BOARD_PROTEUS_2309: 6699 case SAA7134_BOARD_PROTEUS_2309:
6506 case SAA7134_BOARD_AVERMEDIA_A16AR: 6700 case SAA7134_BOARD_AVERMEDIA_A16AR:
@@ -6525,6 +6719,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
6525 case SAA7134_BOARD_REAL_ANGEL_220: 6719 case SAA7134_BOARD_REAL_ANGEL_220:
6526 case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG: 6720 case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG:
6527 case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS: 6721 case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS:
6722 case SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM:
6528 dev->has_remote = SAA7134_REMOTE_GPIO; 6723 dev->has_remote = SAA7134_REMOTE_GPIO;
6529 break; 6724 break;
6530 case SAA7134_BOARD_FLYDVBS_LR300: 6725 case SAA7134_BOARD_FLYDVBS_LR300:
@@ -6653,6 +6848,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
6653 case SAA7134_BOARD_BEHOLD_M63: 6848 case SAA7134_BOARD_BEHOLD_M63:
6654 case SAA7134_BOARD_BEHOLD_M6_EXTRA: 6849 case SAA7134_BOARD_BEHOLD_M6_EXTRA:
6655 case SAA7134_BOARD_BEHOLD_H6: 6850 case SAA7134_BOARD_BEHOLD_H6:
6851 case SAA7134_BOARD_BEHOLD_X7:
6656 dev->has_remote = SAA7134_REMOTE_I2C; 6852 dev->has_remote = SAA7134_REMOTE_I2C;
6657 break; 6853 break;
6658 case SAA7134_BOARD_AVERMEDIA_A169_B: 6854 case SAA7134_BOARD_AVERMEDIA_A169_B:
@@ -6673,6 +6869,11 @@ int saa7134_board_init1(struct saa7134_dev *dev)
6673 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x80040100, 0x80040100); 6869 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x80040100, 0x80040100);
6674 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x80040100, 0x00040100); 6870 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x80040100, 0x00040100);
6675 break; 6871 break;
6872 case SAA7134_BOARD_VIDEOMATE_S350:
6873 dev->has_remote = SAA7134_REMOTE_GPIO;
6874 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00008000, 0x00008000);
6875 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00008000);
6876 break;
6676 } 6877 }
6677 return 0; 6878 return 0;
6678} 6879}
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 94a023a14bbc..cb78c956d810 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -1012,8 +1012,10 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
1012 sd = v4l2_i2c_new_probed_subdev_addr(&dev->v4l2_dev, 1012 sd = v4l2_i2c_new_probed_subdev_addr(&dev->v4l2_dev,
1013 &dev->i2c_adap, "saa6588", "saa6588", 1013 &dev->i2c_adap, "saa6588", "saa6588",
1014 saa7134_boards[dev->board].rds_addr); 1014 saa7134_boards[dev->board].rds_addr);
1015 if (sd) 1015 if (sd) {
1016 printk(KERN_INFO "%s: found RDS decoder\n", dev->name); 1016 printk(KERN_INFO "%s: found RDS decoder\n", dev->name);
1017 dev->has_rds = 1;
1018 }
1017 } 1019 }
1018 1020
1019 request_submodules(dev); 1021 request_submodules(dev);
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 98f3efd1e944..ebde21dba7e3 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -56,6 +56,7 @@
56#include "zl10353.h" 56#include "zl10353.h"
57 57
58#include "zl10036.h" 58#include "zl10036.h"
59#include "zl10039.h"
59#include "mt312.h" 60#include "mt312.h"
60 61
61MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 62MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
@@ -968,6 +969,10 @@ static struct zl10036_config avertv_a700_tuner = {
968 .tuner_address = 0x60, 969 .tuner_address = 0x60,
969}; 970};
970 971
972static struct mt312_config zl10313_compro_s350_config = {
973 .demod_address = 0x0e,
974};
975
971static struct lgdt3305_config hcw_lgdt3305_config = { 976static struct lgdt3305_config hcw_lgdt3305_config = {
972 .i2c_addr = 0x0e, 977 .i2c_addr = 0x0e,
973 .mpeg_mode = LGDT3305_MPEG_SERIAL, 978 .mpeg_mode = LGDT3305_MPEG_SERIAL,
@@ -1457,7 +1462,7 @@ static int dvb_init(struct saa7134_dev *dev)
1457 if (fe0->dvb.frontend) { 1462 if (fe0->dvb.frontend) {
1458 dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 1463 dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1459 &dev->i2c_adap, 0x61, 1464 &dev->i2c_adap, 0x61,
1460 TUNER_PHILIPS_FMD1216ME_MK3); 1465 TUNER_PHILIPS_FMD1216MEX_MK3);
1461 } 1466 }
1462 break; 1467 break;
1463 case SAA7134_BOARD_AVERMEDIA_A700_PRO: 1468 case SAA7134_BOARD_AVERMEDIA_A700_PRO:
@@ -1473,6 +1478,16 @@ static int dvb_init(struct saa7134_dev *dev)
1473 } 1478 }
1474 } 1479 }
1475 break; 1480 break;
1481 case SAA7134_BOARD_VIDEOMATE_S350:
1482 fe0->dvb.frontend = dvb_attach(mt312_attach,
1483 &zl10313_compro_s350_config, &dev->i2c_adap);
1484 if (fe0->dvb.frontend)
1485 if (dvb_attach(zl10039_attach, fe0->dvb.frontend,
1486 0x60, &dev->i2c_adap) == NULL)
1487 wprintk("%s: No zl10039 found!\n",
1488 __func__);
1489
1490 break;
1476 default: 1491 default:
1477 wprintk("Huh? unknown DVB card?\n"); 1492 wprintk("Huh? unknown DVB card?\n");
1478 break; 1493 break;
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 6e219c2db841..e1e83c7b966e 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -394,7 +394,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
394{ 394{
395 struct card_ir *ir; 395 struct card_ir *ir;
396 struct input_dev *input_dev; 396 struct input_dev *input_dev;
397 IR_KEYTAB_TYPE *ir_codes = NULL; 397 struct ir_scancode_table *ir_codes = NULL;
398 u32 mask_keycode = 0; 398 u32 mask_keycode = 0;
399 u32 mask_keydown = 0; 399 u32 mask_keydown = 0;
400 u32 mask_keyup = 0; 400 u32 mask_keyup = 0;
@@ -415,27 +415,28 @@ int saa7134_input_init1(struct saa7134_dev *dev)
415 case SAA7134_BOARD_FLYVIDEO3000: 415 case SAA7134_BOARD_FLYVIDEO3000:
416 case SAA7134_BOARD_FLYTVPLATINUM_FM: 416 case SAA7134_BOARD_FLYTVPLATINUM_FM:
417 case SAA7134_BOARD_FLYTVPLATINUM_MINI2: 417 case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
418 ir_codes = ir_codes_flyvideo; 418 case SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM:
419 ir_codes = &ir_codes_flyvideo_table;
419 mask_keycode = 0xEC00000; 420 mask_keycode = 0xEC00000;
420 mask_keydown = 0x0040000; 421 mask_keydown = 0x0040000;
421 break; 422 break;
422 case SAA7134_BOARD_CINERGY400: 423 case SAA7134_BOARD_CINERGY400:
423 case SAA7134_BOARD_CINERGY600: 424 case SAA7134_BOARD_CINERGY600:
424 case SAA7134_BOARD_CINERGY600_MK3: 425 case SAA7134_BOARD_CINERGY600_MK3:
425 ir_codes = ir_codes_cinergy; 426 ir_codes = &ir_codes_cinergy_table;
426 mask_keycode = 0x00003f; 427 mask_keycode = 0x00003f;
427 mask_keyup = 0x040000; 428 mask_keyup = 0x040000;
428 break; 429 break;
429 case SAA7134_BOARD_ECS_TVP3XP: 430 case SAA7134_BOARD_ECS_TVP3XP:
430 case SAA7134_BOARD_ECS_TVP3XP_4CB5: 431 case SAA7134_BOARD_ECS_TVP3XP_4CB5:
431 ir_codes = ir_codes_eztv; 432 ir_codes = &ir_codes_eztv_table;
432 mask_keycode = 0x00017c; 433 mask_keycode = 0x00017c;
433 mask_keyup = 0x000002; 434 mask_keyup = 0x000002;
434 polling = 50; // ms 435 polling = 50; // ms
435 break; 436 break;
436 case SAA7134_BOARD_KWORLD_XPERT: 437 case SAA7134_BOARD_KWORLD_XPERT:
437 case SAA7134_BOARD_AVACSSMARTTV: 438 case SAA7134_BOARD_AVACSSMARTTV:
438 ir_codes = ir_codes_pixelview; 439 ir_codes = &ir_codes_pixelview_table;
439 mask_keycode = 0x00001F; 440 mask_keycode = 0x00001F;
440 mask_keyup = 0x000020; 441 mask_keyup = 0x000020;
441 polling = 50; // ms 442 polling = 50; // ms
@@ -445,13 +446,14 @@ int saa7134_input_init1(struct saa7134_dev *dev)
445 case SAA7134_BOARD_AVERMEDIA_305: 446 case SAA7134_BOARD_AVERMEDIA_305:
446 case SAA7134_BOARD_AVERMEDIA_307: 447 case SAA7134_BOARD_AVERMEDIA_307:
447 case SAA7134_BOARD_AVERMEDIA_STUDIO_305: 448 case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
449 case SAA7134_BOARD_AVERMEDIA_STUDIO_505:
448 case SAA7134_BOARD_AVERMEDIA_STUDIO_307: 450 case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
449 case SAA7134_BOARD_AVERMEDIA_STUDIO_507: 451 case SAA7134_BOARD_AVERMEDIA_STUDIO_507:
450 case SAA7134_BOARD_AVERMEDIA_STUDIO_507UA: 452 case SAA7134_BOARD_AVERMEDIA_STUDIO_507UA:
451 case SAA7134_BOARD_AVERMEDIA_GO_007_FM: 453 case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
452 case SAA7134_BOARD_AVERMEDIA_M102: 454 case SAA7134_BOARD_AVERMEDIA_M102:
453 case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS: 455 case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS:
454 ir_codes = ir_codes_avermedia; 456 ir_codes = &ir_codes_avermedia_table;
455 mask_keycode = 0x0007C8; 457 mask_keycode = 0x0007C8;
456 mask_keydown = 0x000010; 458 mask_keydown = 0x000010;
457 polling = 50; // ms 459 polling = 50; // ms
@@ -460,14 +462,14 @@ int saa7134_input_init1(struct saa7134_dev *dev)
460 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); 462 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
461 break; 463 break;
462 case SAA7134_BOARD_AVERMEDIA_M135A: 464 case SAA7134_BOARD_AVERMEDIA_M135A:
463 ir_codes = ir_codes_avermedia_m135a; 465 ir_codes = &ir_codes_avermedia_m135a_table;
464 mask_keydown = 0x0040000; 466 mask_keydown = 0x0040000;
465 mask_keycode = 0x00013f; 467 mask_keycode = 0x00013f;
466 nec_gpio = 1; 468 nec_gpio = 1;
467 break; 469 break;
468 case SAA7134_BOARD_AVERMEDIA_777: 470 case SAA7134_BOARD_AVERMEDIA_777:
469 case SAA7134_BOARD_AVERMEDIA_A16AR: 471 case SAA7134_BOARD_AVERMEDIA_A16AR:
470 ir_codes = ir_codes_avermedia; 472 ir_codes = &ir_codes_avermedia_table;
471 mask_keycode = 0x02F200; 473 mask_keycode = 0x02F200;
472 mask_keydown = 0x000400; 474 mask_keydown = 0x000400;
473 polling = 50; // ms 475 polling = 50; // ms
@@ -476,7 +478,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
476 saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1); 478 saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
477 break; 479 break;
478 case SAA7134_BOARD_AVERMEDIA_A16D: 480 case SAA7134_BOARD_AVERMEDIA_A16D:
479 ir_codes = ir_codes_avermedia_a16d; 481 ir_codes = &ir_codes_avermedia_a16d_table;
480 mask_keycode = 0x02F200; 482 mask_keycode = 0x02F200;
481 mask_keydown = 0x000400; 483 mask_keydown = 0x000400;
482 polling = 50; /* ms */ 484 polling = 50; /* ms */
@@ -485,14 +487,14 @@ int saa7134_input_init1(struct saa7134_dev *dev)
485 saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1); 487 saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
486 break; 488 break;
487 case SAA7134_BOARD_KWORLD_TERMINATOR: 489 case SAA7134_BOARD_KWORLD_TERMINATOR:
488 ir_codes = ir_codes_pixelview; 490 ir_codes = &ir_codes_pixelview_table;
489 mask_keycode = 0x00001f; 491 mask_keycode = 0x00001f;
490 mask_keyup = 0x000060; 492 mask_keyup = 0x000060;
491 polling = 50; // ms 493 polling = 50; // ms
492 break; 494 break;
493 case SAA7134_BOARD_MANLI_MTV001: 495 case SAA7134_BOARD_MANLI_MTV001:
494 case SAA7134_BOARD_MANLI_MTV002: 496 case SAA7134_BOARD_MANLI_MTV002:
495 ir_codes = ir_codes_manli; 497 ir_codes = &ir_codes_manli_table;
496 mask_keycode = 0x001f00; 498 mask_keycode = 0x001f00;
497 mask_keyup = 0x004000; 499 mask_keyup = 0x004000;
498 polling = 50; /* ms */ 500 polling = 50; /* ms */
@@ -511,25 +513,25 @@ int saa7134_input_init1(struct saa7134_dev *dev)
511 case SAA7134_BOARD_BEHOLD_507_9FM: 513 case SAA7134_BOARD_BEHOLD_507_9FM:
512 case SAA7134_BOARD_BEHOLD_507RDS_MK3: 514 case SAA7134_BOARD_BEHOLD_507RDS_MK3:
513 case SAA7134_BOARD_BEHOLD_507RDS_MK5: 515 case SAA7134_BOARD_BEHOLD_507RDS_MK5:
514 ir_codes = ir_codes_manli; 516 ir_codes = &ir_codes_manli_table;
515 mask_keycode = 0x003f00; 517 mask_keycode = 0x003f00;
516 mask_keyup = 0x004000; 518 mask_keyup = 0x004000;
517 polling = 50; /* ms */ 519 polling = 50; /* ms */
518 break; 520 break;
519 case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM: 521 case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
520 ir_codes = ir_codes_behold_columbus; 522 ir_codes = &ir_codes_behold_columbus_table;
521 mask_keycode = 0x003f00; 523 mask_keycode = 0x003f00;
522 mask_keyup = 0x004000; 524 mask_keyup = 0x004000;
523 polling = 50; // ms 525 polling = 50; // ms
524 break; 526 break;
525 case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS: 527 case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
526 ir_codes = ir_codes_pctv_sedna; 528 ir_codes = &ir_codes_pctv_sedna_table;
527 mask_keycode = 0x001f00; 529 mask_keycode = 0x001f00;
528 mask_keyup = 0x004000; 530 mask_keyup = 0x004000;
529 polling = 50; // ms 531 polling = 50; // ms
530 break; 532 break;
531 case SAA7134_BOARD_GOTVIEW_7135: 533 case SAA7134_BOARD_GOTVIEW_7135:
532 ir_codes = ir_codes_gotview7135; 534 ir_codes = &ir_codes_gotview7135_table;
533 mask_keycode = 0x0003CC; 535 mask_keycode = 0x0003CC;
534 mask_keydown = 0x000010; 536 mask_keydown = 0x000010;
535 polling = 5; /* ms */ 537 polling = 5; /* ms */
@@ -538,73 +540,78 @@ int saa7134_input_init1(struct saa7134_dev *dev)
538 case SAA7134_BOARD_VIDEOMATE_TV_PVR: 540 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
539 case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS: 541 case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS:
540 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: 542 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
541 ir_codes = ir_codes_videomate_tv_pvr; 543 ir_codes = &ir_codes_videomate_tv_pvr_table;
542 mask_keycode = 0x00003F; 544 mask_keycode = 0x00003F;
543 mask_keyup = 0x400000; 545 mask_keyup = 0x400000;
544 polling = 50; // ms 546 polling = 50; // ms
545 break; 547 break;
546 case SAA7134_BOARD_PROTEUS_2309: 548 case SAA7134_BOARD_PROTEUS_2309:
547 ir_codes = ir_codes_proteus_2309; 549 ir_codes = &ir_codes_proteus_2309_table;
548 mask_keycode = 0x00007F; 550 mask_keycode = 0x00007F;
549 mask_keyup = 0x000080; 551 mask_keyup = 0x000080;
550 polling = 50; // ms 552 polling = 50; // ms
551 break; 553 break;
552 case SAA7134_BOARD_VIDEOMATE_DVBT_300: 554 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
553 case SAA7134_BOARD_VIDEOMATE_DVBT_200: 555 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
554 ir_codes = ir_codes_videomate_tv_pvr; 556 ir_codes = &ir_codes_videomate_tv_pvr_table;
555 mask_keycode = 0x003F00; 557 mask_keycode = 0x003F00;
556 mask_keyup = 0x040000; 558 mask_keyup = 0x040000;
557 break; 559 break;
558 case SAA7134_BOARD_FLYDVBS_LR300: 560 case SAA7134_BOARD_FLYDVBS_LR300:
559 case SAA7134_BOARD_FLYDVBT_LR301: 561 case SAA7134_BOARD_FLYDVBT_LR301:
560 case SAA7134_BOARD_FLYDVBTDUO: 562 case SAA7134_BOARD_FLYDVBTDUO:
561 ir_codes = ir_codes_flydvb; 563 ir_codes = &ir_codes_flydvb_table;
562 mask_keycode = 0x0001F00; 564 mask_keycode = 0x0001F00;
563 mask_keydown = 0x0040000; 565 mask_keydown = 0x0040000;
564 break; 566 break;
565 case SAA7134_BOARD_ASUSTeK_P7131_DUAL: 567 case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
566 case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: 568 case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
567 case SAA7134_BOARD_ASUSTeK_P7131_ANALOG: 569 case SAA7134_BOARD_ASUSTeK_P7131_ANALOG:
568 ir_codes = ir_codes_asus_pc39; 570 ir_codes = &ir_codes_asus_pc39_table;
569 mask_keydown = 0x0040000; 571 mask_keydown = 0x0040000;
570 rc5_gpio = 1; 572 rc5_gpio = 1;
571 break; 573 break;
572 case SAA7134_BOARD_ENCORE_ENLTV: 574 case SAA7134_BOARD_ENCORE_ENLTV:
573 case SAA7134_BOARD_ENCORE_ENLTV_FM: 575 case SAA7134_BOARD_ENCORE_ENLTV_FM:
574 ir_codes = ir_codes_encore_enltv; 576 ir_codes = &ir_codes_encore_enltv_table;
575 mask_keycode = 0x00007f; 577 mask_keycode = 0x00007f;
576 mask_keyup = 0x040000; 578 mask_keyup = 0x040000;
577 polling = 50; // ms 579 polling = 50; // ms
578 break; 580 break;
579 case SAA7134_BOARD_ENCORE_ENLTV_FM53: 581 case SAA7134_BOARD_ENCORE_ENLTV_FM53:
580 ir_codes = ir_codes_encore_enltv_fm53; 582 ir_codes = &ir_codes_encore_enltv_fm53_table;
581 mask_keydown = 0x0040000; 583 mask_keydown = 0x0040000;
582 mask_keycode = 0x00007f; 584 mask_keycode = 0x00007f;
583 nec_gpio = 1; 585 nec_gpio = 1;
584 break; 586 break;
585 case SAA7134_BOARD_10MOONSTVMASTER3: 587 case SAA7134_BOARD_10MOONSTVMASTER3:
586 ir_codes = ir_codes_encore_enltv; 588 ir_codes = &ir_codes_encore_enltv_table;
587 mask_keycode = 0x5f80000; 589 mask_keycode = 0x5f80000;
588 mask_keyup = 0x8000000; 590 mask_keyup = 0x8000000;
589 polling = 50; //ms 591 polling = 50; //ms
590 break; 592 break;
591 case SAA7134_BOARD_GENIUS_TVGO_A11MCE: 593 case SAA7134_BOARD_GENIUS_TVGO_A11MCE:
592 ir_codes = ir_codes_genius_tvgo_a11mce; 594 ir_codes = &ir_codes_genius_tvgo_a11mce_table;
593 mask_keycode = 0xff; 595 mask_keycode = 0xff;
594 mask_keydown = 0xf00000; 596 mask_keydown = 0xf00000;
595 polling = 50; /* ms */ 597 polling = 50; /* ms */
596 break; 598 break;
597 case SAA7134_BOARD_REAL_ANGEL_220: 599 case SAA7134_BOARD_REAL_ANGEL_220:
598 ir_codes = ir_codes_real_audio_220_32_keys; 600 ir_codes = &ir_codes_real_audio_220_32_keys_table;
599 mask_keycode = 0x3f00; 601 mask_keycode = 0x3f00;
600 mask_keyup = 0x4000; 602 mask_keyup = 0x4000;
601 polling = 50; /* ms */ 603 polling = 50; /* ms */
602 break; 604 break;
603 case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG: 605 case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG:
604 ir_codes = ir_codes_kworld_plus_tv_analog; 606 ir_codes = &ir_codes_kworld_plus_tv_analog_table;
605 mask_keycode = 0x7f; 607 mask_keycode = 0x7f;
606 polling = 40; /* ms */ 608 polling = 40; /* ms */
607 break; 609 break;
610 case SAA7134_BOARD_VIDEOMATE_S350:
611 ir_codes = &ir_codes_videomate_s350_table;
612 mask_keycode = 0x003f00;
613 mask_keydown = 0x040000;
614 break;
608 } 615 }
609 if (NULL == ir_codes) { 616 if (NULL == ir_codes) {
610 printk("%s: Oops: IR config error [card=%d]\n", 617 printk("%s: Oops: IR config error [card=%d]\n",
@@ -684,8 +691,6 @@ void saa7134_input_fini(struct saa7134_dev *dev)
684 691
685void saa7134_probe_i2c_ir(struct saa7134_dev *dev) 692void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
686{ 693{
687 struct i2c_board_info info;
688 struct IR_i2c_init_data init_data;
689 const unsigned short addr_list[] = { 694 const unsigned short addr_list[] = {
690 0x7a, 0x47, 0x71, 0x2d, 695 0x7a, 0x47, 0x71, 0x2d,
691 I2C_CLIENT_END 696 I2C_CLIENT_END
@@ -705,32 +710,34 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
705 return; 710 return;
706 } 711 }
707 712
708 memset(&info, 0, sizeof(struct i2c_board_info)); 713 memset(&dev->info, 0, sizeof(dev->info));
709 memset(&init_data, 0, sizeof(struct IR_i2c_init_data)); 714 memset(&dev->init_data, 0, sizeof(dev->init_data));
710 strlcpy(info.type, "ir_video", I2C_NAME_SIZE); 715 strlcpy(dev->info.type, "ir_video", I2C_NAME_SIZE);
711 716
712 switch (dev->board) { 717 switch (dev->board) {
713 case SAA7134_BOARD_PINNACLE_PCTV_110i: 718 case SAA7134_BOARD_PINNACLE_PCTV_110i:
714 case SAA7134_BOARD_PINNACLE_PCTV_310i: 719 case SAA7134_BOARD_PINNACLE_PCTV_310i:
715 init_data.name = "Pinnacle PCTV"; 720 dev->init_data.name = "Pinnacle PCTV";
716 if (pinnacle_remote == 0) { 721 if (pinnacle_remote == 0) {
717 init_data.get_key = get_key_pinnacle_color; 722 dev->init_data.get_key = get_key_pinnacle_color;
718 init_data.ir_codes = ir_codes_pinnacle_color; 723 dev->init_data.ir_codes = &ir_codes_pinnacle_color_table;
724 dev->info.addr = 0x47;
719 } else { 725 } else {
720 init_data.get_key = get_key_pinnacle_grey; 726 dev->init_data.get_key = get_key_pinnacle_grey;
721 init_data.ir_codes = ir_codes_pinnacle_grey; 727 dev->init_data.ir_codes = &ir_codes_pinnacle_grey_table;
728 dev->info.addr = 0x47;
722 } 729 }
723 break; 730 break;
724 case SAA7134_BOARD_UPMOST_PURPLE_TV: 731 case SAA7134_BOARD_UPMOST_PURPLE_TV:
725 init_data.name = "Purple TV"; 732 dev->init_data.name = "Purple TV";
726 init_data.get_key = get_key_purpletv; 733 dev->init_data.get_key = get_key_purpletv;
727 init_data.ir_codes = ir_codes_purpletv; 734 dev->init_data.ir_codes = &ir_codes_purpletv_table;
728 break; 735 break;
729 case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS: 736 case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
730 init_data.name = "MSI TV@nywhere Plus"; 737 dev->init_data.name = "MSI TV@nywhere Plus";
731 init_data.get_key = get_key_msi_tvanywhere_plus; 738 dev->init_data.get_key = get_key_msi_tvanywhere_plus;
732 init_data.ir_codes = ir_codes_msi_tvanywhere_plus; 739 dev->init_data.ir_codes = &ir_codes_msi_tvanywhere_plus_table;
733 info.addr = 0x30; 740 dev->info.addr = 0x30;
734 /* MSI TV@nywhere Plus controller doesn't seem to 741 /* MSI TV@nywhere Plus controller doesn't seem to
735 respond to probes unless we read something from 742 respond to probes unless we read something from
736 an existing device. Weird... 743 an existing device. Weird...
@@ -741,9 +748,9 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
741 (1 == rc) ? "yes" : "no"); 748 (1 == rc) ? "yes" : "no");
742 break; 749 break;
743 case SAA7134_BOARD_HAUPPAUGE_HVR1110: 750 case SAA7134_BOARD_HAUPPAUGE_HVR1110:
744 init_data.name = "HVR 1110"; 751 dev->init_data.name = "HVR 1110";
745 init_data.get_key = get_key_hvr1110; 752 dev->init_data.get_key = get_key_hvr1110;
746 init_data.ir_codes = ir_codes_hauppauge_new; 753 dev->init_data.ir_codes = &ir_codes_hauppauge_new_table;
747 break; 754 break;
748 case SAA7134_BOARD_BEHOLD_607FM_MK3: 755 case SAA7134_BOARD_BEHOLD_607FM_MK3:
749 case SAA7134_BOARD_BEHOLD_607FM_MK5: 756 case SAA7134_BOARD_BEHOLD_607FM_MK5:
@@ -757,26 +764,27 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
757 case SAA7134_BOARD_BEHOLD_M63: 764 case SAA7134_BOARD_BEHOLD_M63:
758 case SAA7134_BOARD_BEHOLD_M6_EXTRA: 765 case SAA7134_BOARD_BEHOLD_M6_EXTRA:
759 case SAA7134_BOARD_BEHOLD_H6: 766 case SAA7134_BOARD_BEHOLD_H6:
760 init_data.name = "BeholdTV"; 767 case SAA7134_BOARD_BEHOLD_X7:
761 init_data.get_key = get_key_beholdm6xx; 768 dev->init_data.name = "BeholdTV";
762 init_data.ir_codes = ir_codes_behold; 769 dev->init_data.get_key = get_key_beholdm6xx;
770 dev->init_data.ir_codes = &ir_codes_behold_table;
763 break; 771 break;
764 case SAA7134_BOARD_AVERMEDIA_CARDBUS_501: 772 case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
765 case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: 773 case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
766 info.addr = 0x40; 774 dev->info.addr = 0x40;
767 break; 775 break;
768 } 776 }
769 777
770 if (init_data.name) 778 if (dev->init_data.name)
771 info.platform_data = &init_data; 779 dev->info.platform_data = &dev->init_data;
772 /* No need to probe if address is known */ 780 /* No need to probe if address is known */
773 if (info.addr) { 781 if (dev->info.addr) {
774 i2c_new_device(&dev->i2c_adap, &info); 782 i2c_new_device(&dev->i2c_adap, &dev->info);
775 return; 783 return;
776 } 784 }
777 785
778 /* Address not known, fallback to probing */ 786 /* Address not known, fallback to probing */
779 i2c_new_probed_device(&dev->i2c_adap, &info, addr_list); 787 i2c_new_probed_device(&dev->i2c_adap, &dev->info, addr_list);
780} 788}
781 789
782static int saa7134_rc5_irq(struct saa7134_dev *dev) 790static int saa7134_rc5_irq(struct saa7134_dev *dev)
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index ba87128542e0..da26f476a302 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1444,7 +1444,6 @@ video_poll(struct file *file, struct poll_table_struct *wait)
1444 fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); 1444 fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
1445 fh->cap.read_off = 0; 1445 fh->cap.read_off = 0;
1446 } 1446 }
1447 mutex_unlock(&fh->cap.vb_lock);
1448 buf = fh->cap.read_buf; 1447 buf = fh->cap.read_buf;
1449 } 1448 }
1450 1449
@@ -1790,7 +1789,7 @@ static int saa7134_s_input(struct file *file, void *priv, unsigned int i)
1790 if (0 != err) 1789 if (0 != err)
1791 return err; 1790 return err;
1792 1791
1793 if (i < 0 || i >= SAA7134_INPUT_MAX) 1792 if (i >= SAA7134_INPUT_MAX)
1794 return -EINVAL; 1793 return -EINVAL;
1795 if (NULL == card_in(dev, i).name) 1794 if (NULL == card_in(dev, i).name)
1796 return -EINVAL; 1795 return -EINVAL;
@@ -1819,6 +1818,8 @@ static int saa7134_querycap(struct file *file, void *priv,
1819 V4L2_CAP_READWRITE | 1818 V4L2_CAP_READWRITE |
1820 V4L2_CAP_STREAMING | 1819 V4L2_CAP_STREAMING |
1821 V4L2_CAP_TUNER; 1820 V4L2_CAP_TUNER;
1821 if (dev->has_rds)
1822 cap->capabilities |= V4L2_CAP_RDS_CAPTURE;
1822 if (saa7134_no_overlay <= 0) 1823 if (saa7134_no_overlay <= 0)
1823 cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; 1824 cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
1824 1825
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index fb564f14887c..d18bb9643856 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -292,6 +292,10 @@ struct saa7134_format {
292#define SAA7134_BOARD_BEHOLD_607RDS_MK5 166 292#define SAA7134_BOARD_BEHOLD_607RDS_MK5 166
293#define SAA7134_BOARD_BEHOLD_609RDS_MK3 167 293#define SAA7134_BOARD_BEHOLD_609RDS_MK3 167
294#define SAA7134_BOARD_BEHOLD_609RDS_MK5 168 294#define SAA7134_BOARD_BEHOLD_609RDS_MK5 168
295#define SAA7134_BOARD_VIDEOMATE_S350 169
296#define SAA7134_BOARD_AVERMEDIA_STUDIO_505 170
297#define SAA7134_BOARD_BEHOLD_X7 171
298#define SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM 172
295 299
296#define SAA7134_MAXBOARDS 32 300#define SAA7134_MAXBOARDS 32
297#define SAA7134_INPUT_MAX 8 301#define SAA7134_INPUT_MAX 8
@@ -539,6 +543,7 @@ struct saa7134_dev {
539 struct i2c_adapter i2c_adap; 543 struct i2c_adapter i2c_adap;
540 struct i2c_client i2c_client; 544 struct i2c_client i2c_client;
541 unsigned char eedata[256]; 545 unsigned char eedata[256];
546 int has_rds;
542 547
543 /* video overlay */ 548 /* video overlay */
544 struct v4l2_framebuffer ovbuf; 549 struct v4l2_framebuffer ovbuf;
@@ -584,6 +589,10 @@ struct saa7134_dev {
584 int nosignal; 589 int nosignal;
585 unsigned int insuspend; 590 unsigned int insuspend;
586 591
592 /* I2C keyboard data */
593 struct i2c_board_info info;
594 struct IR_i2c_init_data init_data;
595
587 /* SAA7134_MPEG_* */ 596 /* SAA7134_MPEG_* */
588 struct saa7134_ts ts; 597 struct saa7134_ts ts;
589 struct saa7134_dmaqueue ts_q; 598 struct saa7134_dmaqueue ts_q;
diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h
index 38a716020d7f..36ee43a9ee95 100644
--- a/drivers/media/video/sn9c102/sn9c102_devtable.h
+++ b/drivers/media/video/sn9c102/sn9c102_devtable.h
@@ -123,8 +123,8 @@ static const struct usb_device_id sn9c102_id_table[] = {
123 { SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), }, 123 { SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), },
124#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE 124#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
125 { SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), }, 125 { SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), },
126#endif
127 { SN9C102_USB_DEVICE(0x0c45, 0x613e, BRIDGE_SN9C120), }, 126 { SN9C102_USB_DEVICE(0x0c45, 0x613e, BRIDGE_SN9C120), },
127#endif
128 { } 128 { }
129}; 129};
130 130
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
index b154bd961e3b..0b996ea4134e 100644
--- a/drivers/media/video/stk-webcam.c
+++ b/drivers/media/video/stk-webcam.c
@@ -1400,7 +1400,6 @@ static int stk_camera_probe(struct usb_interface *interface,
1400 } 1400 }
1401 1401
1402 stk_create_sysfs_files(&dev->vdev); 1402 stk_create_sysfs_files(&dev->vdev);
1403 usb_autopm_enable(dev->interface);
1404 1403
1405 return 0; 1404 return 0;
1406 1405
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c
index 8b4e7dafce7b..6a91714125d2 100644
--- a/drivers/media/video/stv680.c
+++ b/drivers/media/video/stv680.c
@@ -734,10 +734,6 @@ static int stv680_start_stream (struct usb_stv *stv680)
734 return 0; 734 return 0;
735 735
736 nomem_err: 736 nomem_err:
737 for (i = 0; i < STV680_NUMSCRATCH; i++) {
738 kfree(stv680->scratch[i].data);
739 stv680->scratch[i].data = NULL;
740 }
741 for (i = 0; i < STV680_NUMSBUF; i++) { 737 for (i = 0; i < STV680_NUMSBUF; i++) {
742 usb_kill_urb(stv680->urb[i]); 738 usb_kill_urb(stv680->urb[i]);
743 usb_free_urb(stv680->urb[i]); 739 usb_free_urb(stv680->urb[i]);
@@ -745,6 +741,11 @@ static int stv680_start_stream (struct usb_stv *stv680)
745 kfree(stv680->sbuf[i].data); 741 kfree(stv680->sbuf[i].data);
746 stv680->sbuf[i].data = NULL; 742 stv680->sbuf[i].data = NULL;
747 } 743 }
744 /* used in irq, free only as all URBs are dead */
745 for (i = 0; i < STV680_NUMSCRATCH; i++) {
746 kfree(stv680->scratch[i].data);
747 stv680->scratch[i].data = NULL;
748 }
748 return -ENOMEM; 749 return -ENOMEM;
749 750
750} 751}
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 537594211a90..2816f1839230 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -819,8 +819,8 @@ static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
819 819
820 fe_tuner_ops->get_frequency(&t->fe, &abs_freq); 820 fe_tuner_ops->get_frequency(&t->fe, &abs_freq);
821 f->frequency = (V4L2_TUNER_RADIO == t->mode) ? 821 f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
822 (abs_freq * 2 + 125/2) / 125 : 822 DIV_ROUND_CLOSEST(abs_freq * 2, 125) :
823 (abs_freq + 62500/2) / 62500; 823 DIV_ROUND_CLOSEST(abs_freq, 62500);
824 return 0; 824 return 0;
825 } 825 }
826 f->frequency = (V4L2_TUNER_RADIO == t->mode) ? 826 f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index ac02808106c1..d533ea57e7b1 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -646,14 +646,14 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
646 tvee->has_radio = 1; 646 tvee->has_radio = 1;
647 } 647 }
648 648
649 if (tuner1 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) { 649 if (tuner1 < ARRAY_SIZE(hauppauge_tuner)) {
650 tvee->tuner_type = hauppauge_tuner[tuner1].id; 650 tvee->tuner_type = hauppauge_tuner[tuner1].id;
651 t_name1 = hauppauge_tuner[tuner1].name; 651 t_name1 = hauppauge_tuner[tuner1].name;
652 } else { 652 } else {
653 t_name1 = "unknown"; 653 t_name1 = "unknown";
654 } 654 }
655 655
656 if (tuner2 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) { 656 if (tuner2 < ARRAY_SIZE(hauppauge_tuner)) {
657 tvee->tuner2_type = hauppauge_tuner[tuner2].id; 657 tvee->tuner2_type = hauppauge_tuner[tuner2].id;
658 t_name2 = hauppauge_tuner[tuner2].name; 658 t_name2 = hauppauge_tuner[tuner2].name;
659 } else { 659 } else {
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 36a6ba92df27..c3225a561748 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -34,7 +34,7 @@
34static struct uvc_control_info uvc_ctrls[] = { 34static struct uvc_control_info uvc_ctrls[] = {
35 { 35 {
36 .entity = UVC_GUID_UVC_PROCESSING, 36 .entity = UVC_GUID_UVC_PROCESSING,
37 .selector = PU_BRIGHTNESS_CONTROL, 37 .selector = UVC_PU_BRIGHTNESS_CONTROL,
38 .index = 0, 38 .index = 0,
39 .size = 2, 39 .size = 2,
40 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 40 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -42,7 +42,7 @@ static struct uvc_control_info uvc_ctrls[] = {
42 }, 42 },
43 { 43 {
44 .entity = UVC_GUID_UVC_PROCESSING, 44 .entity = UVC_GUID_UVC_PROCESSING,
45 .selector = PU_CONTRAST_CONTROL, 45 .selector = UVC_PU_CONTRAST_CONTROL,
46 .index = 1, 46 .index = 1,
47 .size = 2, 47 .size = 2,
48 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 48 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -50,7 +50,7 @@ static struct uvc_control_info uvc_ctrls[] = {
50 }, 50 },
51 { 51 {
52 .entity = UVC_GUID_UVC_PROCESSING, 52 .entity = UVC_GUID_UVC_PROCESSING,
53 .selector = PU_HUE_CONTROL, 53 .selector = UVC_PU_HUE_CONTROL,
54 .index = 2, 54 .index = 2,
55 .size = 2, 55 .size = 2,
56 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 56 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -58,7 +58,7 @@ static struct uvc_control_info uvc_ctrls[] = {
58 }, 58 },
59 { 59 {
60 .entity = UVC_GUID_UVC_PROCESSING, 60 .entity = UVC_GUID_UVC_PROCESSING,
61 .selector = PU_SATURATION_CONTROL, 61 .selector = UVC_PU_SATURATION_CONTROL,
62 .index = 3, 62 .index = 3,
63 .size = 2, 63 .size = 2,
64 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 64 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -66,7 +66,7 @@ static struct uvc_control_info uvc_ctrls[] = {
66 }, 66 },
67 { 67 {
68 .entity = UVC_GUID_UVC_PROCESSING, 68 .entity = UVC_GUID_UVC_PROCESSING,
69 .selector = PU_SHARPNESS_CONTROL, 69 .selector = UVC_PU_SHARPNESS_CONTROL,
70 .index = 4, 70 .index = 4,
71 .size = 2, 71 .size = 2,
72 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 72 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -74,7 +74,7 @@ static struct uvc_control_info uvc_ctrls[] = {
74 }, 74 },
75 { 75 {
76 .entity = UVC_GUID_UVC_PROCESSING, 76 .entity = UVC_GUID_UVC_PROCESSING,
77 .selector = PU_GAMMA_CONTROL, 77 .selector = UVC_PU_GAMMA_CONTROL,
78 .index = 5, 78 .index = 5,
79 .size = 2, 79 .size = 2,
80 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 80 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -82,7 +82,7 @@ static struct uvc_control_info uvc_ctrls[] = {
82 }, 82 },
83 { 83 {
84 .entity = UVC_GUID_UVC_PROCESSING, 84 .entity = UVC_GUID_UVC_PROCESSING,
85 .selector = PU_WHITE_BALANCE_TEMPERATURE_CONTROL, 85 .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
86 .index = 6, 86 .index = 6,
87 .size = 2, 87 .size = 2,
88 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 88 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -90,7 +90,7 @@ static struct uvc_control_info uvc_ctrls[] = {
90 }, 90 },
91 { 91 {
92 .entity = UVC_GUID_UVC_PROCESSING, 92 .entity = UVC_GUID_UVC_PROCESSING,
93 .selector = PU_WHITE_BALANCE_COMPONENT_CONTROL, 93 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,
94 .index = 7, 94 .index = 7,
95 .size = 4, 95 .size = 4,
96 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 96 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -98,7 +98,7 @@ static struct uvc_control_info uvc_ctrls[] = {
98 }, 98 },
99 { 99 {
100 .entity = UVC_GUID_UVC_PROCESSING, 100 .entity = UVC_GUID_UVC_PROCESSING,
101 .selector = PU_BACKLIGHT_COMPENSATION_CONTROL, 101 .selector = UVC_PU_BACKLIGHT_COMPENSATION_CONTROL,
102 .index = 8, 102 .index = 8,
103 .size = 2, 103 .size = 2,
104 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 104 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -106,7 +106,7 @@ static struct uvc_control_info uvc_ctrls[] = {
106 }, 106 },
107 { 107 {
108 .entity = UVC_GUID_UVC_PROCESSING, 108 .entity = UVC_GUID_UVC_PROCESSING,
109 .selector = PU_GAIN_CONTROL, 109 .selector = UVC_PU_GAIN_CONTROL,
110 .index = 9, 110 .index = 9,
111 .size = 2, 111 .size = 2,
112 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 112 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -114,7 +114,7 @@ static struct uvc_control_info uvc_ctrls[] = {
114 }, 114 },
115 { 115 {
116 .entity = UVC_GUID_UVC_PROCESSING, 116 .entity = UVC_GUID_UVC_PROCESSING,
117 .selector = PU_POWER_LINE_FREQUENCY_CONTROL, 117 .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
118 .index = 10, 118 .index = 10,
119 .size = 1, 119 .size = 1,
120 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 120 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -122,7 +122,7 @@ static struct uvc_control_info uvc_ctrls[] = {
122 }, 122 },
123 { 123 {
124 .entity = UVC_GUID_UVC_PROCESSING, 124 .entity = UVC_GUID_UVC_PROCESSING,
125 .selector = PU_HUE_AUTO_CONTROL, 125 .selector = UVC_PU_HUE_AUTO_CONTROL,
126 .index = 11, 126 .index = 11,
127 .size = 1, 127 .size = 1,
128 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 128 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
@@ -130,7 +130,7 @@ static struct uvc_control_info uvc_ctrls[] = {
130 }, 130 },
131 { 131 {
132 .entity = UVC_GUID_UVC_PROCESSING, 132 .entity = UVC_GUID_UVC_PROCESSING,
133 .selector = PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL, 133 .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
134 .index = 12, 134 .index = 12,
135 .size = 1, 135 .size = 1,
136 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 136 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
@@ -138,7 +138,7 @@ static struct uvc_control_info uvc_ctrls[] = {
138 }, 138 },
139 { 139 {
140 .entity = UVC_GUID_UVC_PROCESSING, 140 .entity = UVC_GUID_UVC_PROCESSING,
141 .selector = PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL, 141 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
142 .index = 13, 142 .index = 13,
143 .size = 1, 143 .size = 1,
144 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 144 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
@@ -146,7 +146,7 @@ static struct uvc_control_info uvc_ctrls[] = {
146 }, 146 },
147 { 147 {
148 .entity = UVC_GUID_UVC_PROCESSING, 148 .entity = UVC_GUID_UVC_PROCESSING,
149 .selector = PU_DIGITAL_MULTIPLIER_CONTROL, 149 .selector = UVC_PU_DIGITAL_MULTIPLIER_CONTROL,
150 .index = 14, 150 .index = 14,
151 .size = 2, 151 .size = 2,
152 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 152 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -154,7 +154,7 @@ static struct uvc_control_info uvc_ctrls[] = {
154 }, 154 },
155 { 155 {
156 .entity = UVC_GUID_UVC_PROCESSING, 156 .entity = UVC_GUID_UVC_PROCESSING,
157 .selector = PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL, 157 .selector = UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL,
158 .index = 15, 158 .index = 15,
159 .size = 2, 159 .size = 2,
160 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 160 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -162,21 +162,21 @@ static struct uvc_control_info uvc_ctrls[] = {
162 }, 162 },
163 { 163 {
164 .entity = UVC_GUID_UVC_PROCESSING, 164 .entity = UVC_GUID_UVC_PROCESSING,
165 .selector = PU_ANALOG_VIDEO_STANDARD_CONTROL, 165 .selector = UVC_PU_ANALOG_VIDEO_STANDARD_CONTROL,
166 .index = 16, 166 .index = 16,
167 .size = 1, 167 .size = 1,
168 .flags = UVC_CONTROL_GET_CUR, 168 .flags = UVC_CONTROL_GET_CUR,
169 }, 169 },
170 { 170 {
171 .entity = UVC_GUID_UVC_PROCESSING, 171 .entity = UVC_GUID_UVC_PROCESSING,
172 .selector = PU_ANALOG_LOCK_STATUS_CONTROL, 172 .selector = UVC_PU_ANALOG_LOCK_STATUS_CONTROL,
173 .index = 17, 173 .index = 17,
174 .size = 1, 174 .size = 1,
175 .flags = UVC_CONTROL_GET_CUR, 175 .flags = UVC_CONTROL_GET_CUR,
176 }, 176 },
177 { 177 {
178 .entity = UVC_GUID_UVC_CAMERA, 178 .entity = UVC_GUID_UVC_CAMERA,
179 .selector = CT_SCANNING_MODE_CONTROL, 179 .selector = UVC_CT_SCANNING_MODE_CONTROL,
180 .index = 0, 180 .index = 0,
181 .size = 1, 181 .size = 1,
182 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 182 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
@@ -184,7 +184,7 @@ static struct uvc_control_info uvc_ctrls[] = {
184 }, 184 },
185 { 185 {
186 .entity = UVC_GUID_UVC_CAMERA, 186 .entity = UVC_GUID_UVC_CAMERA,
187 .selector = CT_AE_MODE_CONTROL, 187 .selector = UVC_CT_AE_MODE_CONTROL,
188 .index = 1, 188 .index = 1,
189 .size = 1, 189 .size = 1,
190 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 190 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
@@ -193,7 +193,7 @@ static struct uvc_control_info uvc_ctrls[] = {
193 }, 193 },
194 { 194 {
195 .entity = UVC_GUID_UVC_CAMERA, 195 .entity = UVC_GUID_UVC_CAMERA,
196 .selector = CT_AE_PRIORITY_CONTROL, 196 .selector = UVC_CT_AE_PRIORITY_CONTROL,
197 .index = 2, 197 .index = 2,
198 .size = 1, 198 .size = 1,
199 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 199 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
@@ -201,7 +201,7 @@ static struct uvc_control_info uvc_ctrls[] = {
201 }, 201 },
202 { 202 {
203 .entity = UVC_GUID_UVC_CAMERA, 203 .entity = UVC_GUID_UVC_CAMERA,
204 .selector = CT_EXPOSURE_TIME_ABSOLUTE_CONTROL, 204 .selector = UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,
205 .index = 3, 205 .index = 3,
206 .size = 4, 206 .size = 4,
207 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 207 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -209,7 +209,7 @@ static struct uvc_control_info uvc_ctrls[] = {
209 }, 209 },
210 { 210 {
211 .entity = UVC_GUID_UVC_CAMERA, 211 .entity = UVC_GUID_UVC_CAMERA,
212 .selector = CT_EXPOSURE_TIME_RELATIVE_CONTROL, 212 .selector = UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL,
213 .index = 4, 213 .index = 4,
214 .size = 1, 214 .size = 1,
215 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 215 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
@@ -217,7 +217,7 @@ static struct uvc_control_info uvc_ctrls[] = {
217 }, 217 },
218 { 218 {
219 .entity = UVC_GUID_UVC_CAMERA, 219 .entity = UVC_GUID_UVC_CAMERA,
220 .selector = CT_FOCUS_ABSOLUTE_CONTROL, 220 .selector = UVC_CT_FOCUS_ABSOLUTE_CONTROL,
221 .index = 5, 221 .index = 5,
222 .size = 2, 222 .size = 2,
223 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 223 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -225,7 +225,7 @@ static struct uvc_control_info uvc_ctrls[] = {
225 }, 225 },
226 { 226 {
227 .entity = UVC_GUID_UVC_CAMERA, 227 .entity = UVC_GUID_UVC_CAMERA,
228 .selector = CT_FOCUS_RELATIVE_CONTROL, 228 .selector = UVC_CT_FOCUS_RELATIVE_CONTROL,
229 .index = 6, 229 .index = 6,
230 .size = 2, 230 .size = 2,
231 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 231 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -233,7 +233,7 @@ static struct uvc_control_info uvc_ctrls[] = {
233 }, 233 },
234 { 234 {
235 .entity = UVC_GUID_UVC_CAMERA, 235 .entity = UVC_GUID_UVC_CAMERA,
236 .selector = CT_IRIS_ABSOLUTE_CONTROL, 236 .selector = UVC_CT_IRIS_ABSOLUTE_CONTROL,
237 .index = 7, 237 .index = 7,
238 .size = 2, 238 .size = 2,
239 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 239 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -241,7 +241,7 @@ static struct uvc_control_info uvc_ctrls[] = {
241 }, 241 },
242 { 242 {
243 .entity = UVC_GUID_UVC_CAMERA, 243 .entity = UVC_GUID_UVC_CAMERA,
244 .selector = CT_IRIS_RELATIVE_CONTROL, 244 .selector = UVC_CT_IRIS_RELATIVE_CONTROL,
245 .index = 8, 245 .index = 8,
246 .size = 1, 246 .size = 1,
247 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 247 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
@@ -249,7 +249,7 @@ static struct uvc_control_info uvc_ctrls[] = {
249 }, 249 },
250 { 250 {
251 .entity = UVC_GUID_UVC_CAMERA, 251 .entity = UVC_GUID_UVC_CAMERA,
252 .selector = CT_ZOOM_ABSOLUTE_CONTROL, 252 .selector = UVC_CT_ZOOM_ABSOLUTE_CONTROL,
253 .index = 9, 253 .index = 9,
254 .size = 2, 254 .size = 2,
255 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 255 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -257,7 +257,7 @@ static struct uvc_control_info uvc_ctrls[] = {
257 }, 257 },
258 { 258 {
259 .entity = UVC_GUID_UVC_CAMERA, 259 .entity = UVC_GUID_UVC_CAMERA,
260 .selector = CT_ZOOM_RELATIVE_CONTROL, 260 .selector = UVC_CT_ZOOM_RELATIVE_CONTROL,
261 .index = 10, 261 .index = 10,
262 .size = 3, 262 .size = 3,
263 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 263 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -265,7 +265,7 @@ static struct uvc_control_info uvc_ctrls[] = {
265 }, 265 },
266 { 266 {
267 .entity = UVC_GUID_UVC_CAMERA, 267 .entity = UVC_GUID_UVC_CAMERA,
268 .selector = CT_PANTILT_ABSOLUTE_CONTROL, 268 .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL,
269 .index = 11, 269 .index = 11,
270 .size = 8, 270 .size = 8,
271 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 271 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -273,7 +273,7 @@ static struct uvc_control_info uvc_ctrls[] = {
273 }, 273 },
274 { 274 {
275 .entity = UVC_GUID_UVC_CAMERA, 275 .entity = UVC_GUID_UVC_CAMERA,
276 .selector = CT_PANTILT_RELATIVE_CONTROL, 276 .selector = UVC_CT_PANTILT_RELATIVE_CONTROL,
277 .index = 12, 277 .index = 12,
278 .size = 4, 278 .size = 4,
279 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 279 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -281,7 +281,7 @@ static struct uvc_control_info uvc_ctrls[] = {
281 }, 281 },
282 { 282 {
283 .entity = UVC_GUID_UVC_CAMERA, 283 .entity = UVC_GUID_UVC_CAMERA,
284 .selector = CT_ROLL_ABSOLUTE_CONTROL, 284 .selector = UVC_CT_ROLL_ABSOLUTE_CONTROL,
285 .index = 13, 285 .index = 13,
286 .size = 2, 286 .size = 2,
287 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 287 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -289,7 +289,7 @@ static struct uvc_control_info uvc_ctrls[] = {
289 }, 289 },
290 { 290 {
291 .entity = UVC_GUID_UVC_CAMERA, 291 .entity = UVC_GUID_UVC_CAMERA,
292 .selector = CT_ROLL_RELATIVE_CONTROL, 292 .selector = UVC_CT_ROLL_RELATIVE_CONTROL,
293 .index = 14, 293 .index = 14,
294 .size = 2, 294 .size = 2,
295 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE 295 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -297,7 +297,7 @@ static struct uvc_control_info uvc_ctrls[] = {
297 }, 297 },
298 { 298 {
299 .entity = UVC_GUID_UVC_CAMERA, 299 .entity = UVC_GUID_UVC_CAMERA,
300 .selector = CT_FOCUS_AUTO_CONTROL, 300 .selector = UVC_CT_FOCUS_AUTO_CONTROL,
301 .index = 17, 301 .index = 17,
302 .size = 1, 302 .size = 1,
303 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 303 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
@@ -305,7 +305,7 @@ static struct uvc_control_info uvc_ctrls[] = {
305 }, 305 },
306 { 306 {
307 .entity = UVC_GUID_UVC_CAMERA, 307 .entity = UVC_GUID_UVC_CAMERA,
308 .selector = CT_PRIVACY_CONTROL, 308 .selector = UVC_CT_PRIVACY_CONTROL,
309 .index = 18, 309 .index = 18,
310 .size = 1, 310 .size = 1,
311 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR 311 .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
@@ -332,13 +332,13 @@ static __s32 uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping,
332 __s8 zoom = (__s8)data[0]; 332 __s8 zoom = (__s8)data[0];
333 333
334 switch (query) { 334 switch (query) {
335 case GET_CUR: 335 case UVC_GET_CUR:
336 return (zoom == 0) ? 0 : (zoom > 0 ? data[2] : -data[2]); 336 return (zoom == 0) ? 0 : (zoom > 0 ? data[2] : -data[2]);
337 337
338 case GET_MIN: 338 case UVC_GET_MIN:
339 case GET_MAX: 339 case UVC_GET_MAX:
340 case GET_RES: 340 case UVC_GET_RES:
341 case GET_DEF: 341 case UVC_GET_DEF:
342 default: 342 default:
343 return data[2]; 343 return data[2];
344 } 344 }
@@ -356,7 +356,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
356 .id = V4L2_CID_BRIGHTNESS, 356 .id = V4L2_CID_BRIGHTNESS,
357 .name = "Brightness", 357 .name = "Brightness",
358 .entity = UVC_GUID_UVC_PROCESSING, 358 .entity = UVC_GUID_UVC_PROCESSING,
359 .selector = PU_BRIGHTNESS_CONTROL, 359 .selector = UVC_PU_BRIGHTNESS_CONTROL,
360 .size = 16, 360 .size = 16,
361 .offset = 0, 361 .offset = 0,
362 .v4l2_type = V4L2_CTRL_TYPE_INTEGER, 362 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
@@ -366,7 +366,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
366 .id = V4L2_CID_CONTRAST, 366 .id = V4L2_CID_CONTRAST,
367 .name = "Contrast", 367 .name = "Contrast",
368 .entity = UVC_GUID_UVC_PROCESSING, 368 .entity = UVC_GUID_UVC_PROCESSING,
369 .selector = PU_CONTRAST_CONTROL, 369 .selector = UVC_PU_CONTRAST_CONTROL,
370 .size = 16, 370 .size = 16,
371 .offset = 0, 371 .offset = 0,
372 .v4l2_type = V4L2_CTRL_TYPE_INTEGER, 372 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
@@ -376,7 +376,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
376 .id = V4L2_CID_HUE, 376 .id = V4L2_CID_HUE,
377 .name = "Hue", 377 .name = "Hue",
378 .entity = UVC_GUID_UVC_PROCESSING, 378 .entity = UVC_GUID_UVC_PROCESSING,
379 .selector = PU_HUE_CONTROL, 379 .selector = UVC_PU_HUE_CONTROL,
380 .size = 16, 380 .size = 16,
381 .offset = 0, 381 .offset = 0,
382 .v4l2_type = V4L2_CTRL_TYPE_INTEGER, 382 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
@@ -386,7 +386,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
386 .id = V4L2_CID_SATURATION, 386 .id = V4L2_CID_SATURATION,
387 .name = "Saturation", 387 .name = "Saturation",
388 .entity = UVC_GUID_UVC_PROCESSING, 388 .entity = UVC_GUID_UVC_PROCESSING,
389 .selector = PU_SATURATION_CONTROL, 389 .selector = UVC_PU_SATURATION_CONTROL,
390 .size = 16, 390 .size = 16,
391 .offset = 0, 391 .offset = 0,
392 .v4l2_type = V4L2_CTRL_TYPE_INTEGER, 392 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
@@ -396,7 +396,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
396 .id = V4L2_CID_SHARPNESS, 396 .id = V4L2_CID_SHARPNESS,
397 .name = "Sharpness", 397 .name = "Sharpness",
398 .entity = UVC_GUID_UVC_PROCESSING, 398 .entity = UVC_GUID_UVC_PROCESSING,
399 .selector = PU_SHARPNESS_CONTROL, 399 .selector = UVC_PU_SHARPNESS_CONTROL,
400 .size = 16, 400 .size = 16,
401 .offset = 0, 401 .offset = 0,
402 .v4l2_type = V4L2_CTRL_TYPE_INTEGER, 402 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
@@ -406,7 +406,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
406 .id = V4L2_CID_GAMMA, 406 .id = V4L2_CID_GAMMA,
407 .name = "Gamma", 407 .name = "Gamma",
408 .entity = UVC_GUID_UVC_PROCESSING, 408 .entity = UVC_GUID_UVC_PROCESSING,
409 .selector = PU_GAMMA_CONTROL, 409 .selector = UVC_PU_GAMMA_CONTROL,
410 .size = 16, 410 .size = 16,
411 .offset = 0, 411 .offset = 0,
412 .v4l2_type = V4L2_CTRL_TYPE_INTEGER, 412 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
@@ -416,7 +416,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
416 .id = V4L2_CID_BACKLIGHT_COMPENSATION, 416 .id = V4L2_CID_BACKLIGHT_COMPENSATION,
417 .name = "Backlight Compensation", 417 .name = "Backlight Compensation",
418 .entity = UVC_GUID_UVC_PROCESSING, 418 .entity = UVC_GUID_UVC_PROCESSING,
419 .selector = PU_BACKLIGHT_COMPENSATION_CONTROL, 419 .selector = UVC_PU_BACKLIGHT_COMPENSATION_CONTROL,
420 .size = 16, 420 .size = 16,
421 .offset = 0, 421 .offset = 0,
422 .v4l2_type = V4L2_CTRL_TYPE_INTEGER, 422 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
@@ -426,7 +426,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
426 .id = V4L2_CID_GAIN, 426 .id = V4L2_CID_GAIN,
427 .name = "Gain", 427 .name = "Gain",
428 .entity = UVC_GUID_UVC_PROCESSING, 428 .entity = UVC_GUID_UVC_PROCESSING,
429 .selector = PU_GAIN_CONTROL, 429 .selector = UVC_PU_GAIN_CONTROL,
430 .size = 16, 430 .size = 16,
431 .offset = 0, 431 .offset = 0,
432 .v4l2_type = V4L2_CTRL_TYPE_INTEGER, 432 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
@@ -436,7 +436,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
436 .id = V4L2_CID_POWER_LINE_FREQUENCY, 436 .id = V4L2_CID_POWER_LINE_FREQUENCY,
437 .name = "Power Line Frequency", 437 .name = "Power Line Frequency",
438 .entity = UVC_GUID_UVC_PROCESSING, 438 .entity = UVC_GUID_UVC_PROCESSING,
439 .selector = PU_POWER_LINE_FREQUENCY_CONTROL, 439 .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
440 .size = 2, 440 .size = 2,
441 .offset = 0, 441 .offset = 0,
442 .v4l2_type = V4L2_CTRL_TYPE_MENU, 442 .v4l2_type = V4L2_CTRL_TYPE_MENU,
@@ -448,7 +448,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
448 .id = V4L2_CID_HUE_AUTO, 448 .id = V4L2_CID_HUE_AUTO,
449 .name = "Hue, Auto", 449 .name = "Hue, Auto",
450 .entity = UVC_GUID_UVC_PROCESSING, 450 .entity = UVC_GUID_UVC_PROCESSING,
451 .selector = PU_HUE_AUTO_CONTROL, 451 .selector = UVC_PU_HUE_AUTO_CONTROL,
452 .size = 1, 452 .size = 1,
453 .offset = 0, 453 .offset = 0,
454 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, 454 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -458,7 +458,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
458 .id = V4L2_CID_EXPOSURE_AUTO, 458 .id = V4L2_CID_EXPOSURE_AUTO,
459 .name = "Exposure, Auto", 459 .name = "Exposure, Auto",
460 .entity = UVC_GUID_UVC_CAMERA, 460 .entity = UVC_GUID_UVC_CAMERA,
461 .selector = CT_AE_MODE_CONTROL, 461 .selector = UVC_CT_AE_MODE_CONTROL,
462 .size = 4, 462 .size = 4,
463 .offset = 0, 463 .offset = 0,
464 .v4l2_type = V4L2_CTRL_TYPE_MENU, 464 .v4l2_type = V4L2_CTRL_TYPE_MENU,
@@ -470,7 +470,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
470 .id = V4L2_CID_EXPOSURE_AUTO_PRIORITY, 470 .id = V4L2_CID_EXPOSURE_AUTO_PRIORITY,
471 .name = "Exposure, Auto Priority", 471 .name = "Exposure, Auto Priority",
472 .entity = UVC_GUID_UVC_CAMERA, 472 .entity = UVC_GUID_UVC_CAMERA,
473 .selector = CT_AE_PRIORITY_CONTROL, 473 .selector = UVC_CT_AE_PRIORITY_CONTROL,
474 .size = 1, 474 .size = 1,
475 .offset = 0, 475 .offset = 0,
476 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, 476 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -480,7 +480,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
480 .id = V4L2_CID_EXPOSURE_ABSOLUTE, 480 .id = V4L2_CID_EXPOSURE_ABSOLUTE,
481 .name = "Exposure (Absolute)", 481 .name = "Exposure (Absolute)",
482 .entity = UVC_GUID_UVC_CAMERA, 482 .entity = UVC_GUID_UVC_CAMERA,
483 .selector = CT_EXPOSURE_TIME_ABSOLUTE_CONTROL, 483 .selector = UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,
484 .size = 32, 484 .size = 32,
485 .offset = 0, 485 .offset = 0,
486 .v4l2_type = V4L2_CTRL_TYPE_INTEGER, 486 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
@@ -490,7 +490,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
490 .id = V4L2_CID_AUTO_WHITE_BALANCE, 490 .id = V4L2_CID_AUTO_WHITE_BALANCE,
491 .name = "White Balance Temperature, Auto", 491 .name = "White Balance Temperature, Auto",
492 .entity = UVC_GUID_UVC_PROCESSING, 492 .entity = UVC_GUID_UVC_PROCESSING,
493 .selector = PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL, 493 .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
494 .size = 1, 494 .size = 1,
495 .offset = 0, 495 .offset = 0,
496 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, 496 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -500,7 +500,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
500 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE, 500 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
501 .name = "White Balance Temperature", 501 .name = "White Balance Temperature",
502 .entity = UVC_GUID_UVC_PROCESSING, 502 .entity = UVC_GUID_UVC_PROCESSING,
503 .selector = PU_WHITE_BALANCE_TEMPERATURE_CONTROL, 503 .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
504 .size = 16, 504 .size = 16,
505 .offset = 0, 505 .offset = 0,
506 .v4l2_type = V4L2_CTRL_TYPE_INTEGER, 506 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
@@ -510,7 +510,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
510 .id = V4L2_CID_AUTO_WHITE_BALANCE, 510 .id = V4L2_CID_AUTO_WHITE_BALANCE,
511 .name = "White Balance Component, Auto", 511 .name = "White Balance Component, Auto",
512 .entity = UVC_GUID_UVC_PROCESSING, 512 .entity = UVC_GUID_UVC_PROCESSING,
513 .selector = PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL, 513 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
514 .size = 1, 514 .size = 1,
515 .offset = 0, 515 .offset = 0,
516 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, 516 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -520,7 +520,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
520 .id = V4L2_CID_BLUE_BALANCE, 520 .id = V4L2_CID_BLUE_BALANCE,
521 .name = "White Balance Blue Component", 521 .name = "White Balance Blue Component",
522 .entity = UVC_GUID_UVC_PROCESSING, 522 .entity = UVC_GUID_UVC_PROCESSING,
523 .selector = PU_WHITE_BALANCE_COMPONENT_CONTROL, 523 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,
524 .size = 16, 524 .size = 16,
525 .offset = 0, 525 .offset = 0,
526 .v4l2_type = V4L2_CTRL_TYPE_INTEGER, 526 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
@@ -530,7 +530,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
530 .id = V4L2_CID_RED_BALANCE, 530 .id = V4L2_CID_RED_BALANCE,
531 .name = "White Balance Red Component", 531 .name = "White Balance Red Component",
532 .entity = UVC_GUID_UVC_PROCESSING, 532 .entity = UVC_GUID_UVC_PROCESSING,
533 .selector = PU_WHITE_BALANCE_COMPONENT_CONTROL, 533 .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,
534 .size = 16, 534 .size = 16,
535 .offset = 16, 535 .offset = 16,
536 .v4l2_type = V4L2_CTRL_TYPE_INTEGER, 536 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
@@ -540,7 +540,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
540 .id = V4L2_CID_FOCUS_ABSOLUTE, 540 .id = V4L2_CID_FOCUS_ABSOLUTE,
541 .name = "Focus (absolute)", 541 .name = "Focus (absolute)",
542 .entity = UVC_GUID_UVC_CAMERA, 542 .entity = UVC_GUID_UVC_CAMERA,
543 .selector = CT_FOCUS_ABSOLUTE_CONTROL, 543 .selector = UVC_CT_FOCUS_ABSOLUTE_CONTROL,
544 .size = 16, 544 .size = 16,
545 .offset = 0, 545 .offset = 0,
546 .v4l2_type = V4L2_CTRL_TYPE_INTEGER, 546 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
@@ -550,7 +550,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
550 .id = V4L2_CID_FOCUS_AUTO, 550 .id = V4L2_CID_FOCUS_AUTO,
551 .name = "Focus, Auto", 551 .name = "Focus, Auto",
552 .entity = UVC_GUID_UVC_CAMERA, 552 .entity = UVC_GUID_UVC_CAMERA,
553 .selector = CT_FOCUS_AUTO_CONTROL, 553 .selector = UVC_CT_FOCUS_AUTO_CONTROL,
554 .size = 1, 554 .size = 1,
555 .offset = 0, 555 .offset = 0,
556 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, 556 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -560,7 +560,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
560 .id = V4L2_CID_ZOOM_ABSOLUTE, 560 .id = V4L2_CID_ZOOM_ABSOLUTE,
561 .name = "Zoom, Absolute", 561 .name = "Zoom, Absolute",
562 .entity = UVC_GUID_UVC_CAMERA, 562 .entity = UVC_GUID_UVC_CAMERA,
563 .selector = CT_ZOOM_ABSOLUTE_CONTROL, 563 .selector = UVC_CT_ZOOM_ABSOLUTE_CONTROL,
564 .size = 16, 564 .size = 16,
565 .offset = 0, 565 .offset = 0,
566 .v4l2_type = V4L2_CTRL_TYPE_INTEGER, 566 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
@@ -570,7 +570,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
570 .id = V4L2_CID_ZOOM_CONTINUOUS, 570 .id = V4L2_CID_ZOOM_CONTINUOUS,
571 .name = "Zoom, Continuous", 571 .name = "Zoom, Continuous",
572 .entity = UVC_GUID_UVC_CAMERA, 572 .entity = UVC_GUID_UVC_CAMERA,
573 .selector = CT_ZOOM_RELATIVE_CONTROL, 573 .selector = UVC_CT_ZOOM_RELATIVE_CONTROL,
574 .size = 0, 574 .size = 0,
575 .offset = 0, 575 .offset = 0,
576 .v4l2_type = V4L2_CTRL_TYPE_INTEGER, 576 .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
@@ -582,7 +582,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
582 .id = V4L2_CID_PRIVACY, 582 .id = V4L2_CID_PRIVACY,
583 .name = "Privacy", 583 .name = "Privacy",
584 .entity = UVC_GUID_UVC_CAMERA, 584 .entity = UVC_GUID_UVC_CAMERA,
585 .selector = CT_PRIVACY_CONTROL, 585 .selector = UVC_CT_PRIVACY_CONTROL,
586 .size = 1, 586 .size = 1,
587 .offset = 0, 587 .offset = 0,
588 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, 588 .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -675,16 +675,16 @@ static const __u8 uvc_media_transport_input_guid[16] =
675static int uvc_entity_match_guid(struct uvc_entity *entity, __u8 guid[16]) 675static int uvc_entity_match_guid(struct uvc_entity *entity, __u8 guid[16])
676{ 676{
677 switch (UVC_ENTITY_TYPE(entity)) { 677 switch (UVC_ENTITY_TYPE(entity)) {
678 case ITT_CAMERA: 678 case UVC_ITT_CAMERA:
679 return memcmp(uvc_camera_guid, guid, 16) == 0; 679 return memcmp(uvc_camera_guid, guid, 16) == 0;
680 680
681 case ITT_MEDIA_TRANSPORT_INPUT: 681 case UVC_ITT_MEDIA_TRANSPORT_INPUT:
682 return memcmp(uvc_media_transport_input_guid, guid, 16) == 0; 682 return memcmp(uvc_media_transport_input_guid, guid, 16) == 0;
683 683
684 case VC_PROCESSING_UNIT: 684 case UVC_VC_PROCESSING_UNIT:
685 return memcmp(uvc_processing_guid, guid, 16) == 0; 685 return memcmp(uvc_processing_guid, guid, 16) == 0;
686 686
687 case VC_EXTENSION_UNIT: 687 case UVC_VC_EXTENSION_UNIT:
688 return memcmp(entity->extension.guidExtensionCode, 688 return memcmp(entity->extension.guidExtensionCode,
689 guid, 16) == 0; 689 guid, 16) == 0;
690 690
@@ -729,7 +729,7 @@ static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id,
729 } 729 }
730} 730}
731 731
732struct uvc_control *uvc_find_control(struct uvc_video_device *video, 732struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
733 __u32 v4l2_id, struct uvc_control_mapping **mapping) 733 __u32 v4l2_id, struct uvc_control_mapping **mapping)
734{ 734{
735 struct uvc_control *ctrl = NULL; 735 struct uvc_control *ctrl = NULL;
@@ -742,17 +742,17 @@ struct uvc_control *uvc_find_control(struct uvc_video_device *video,
742 v4l2_id &= V4L2_CTRL_ID_MASK; 742 v4l2_id &= V4L2_CTRL_ID_MASK;
743 743
744 /* Find the control. */ 744 /* Find the control. */
745 __uvc_find_control(video->processing, v4l2_id, mapping, &ctrl, next); 745 __uvc_find_control(chain->processing, v4l2_id, mapping, &ctrl, next);
746 if (ctrl && !next) 746 if (ctrl && !next)
747 return ctrl; 747 return ctrl;
748 748
749 list_for_each_entry(entity, &video->iterms, chain) { 749 list_for_each_entry(entity, &chain->iterms, chain) {
750 __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next); 750 __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
751 if (ctrl && !next) 751 if (ctrl && !next)
752 return ctrl; 752 return ctrl;
753 } 753 }
754 754
755 list_for_each_entry(entity, &video->extensions, chain) { 755 list_for_each_entry(entity, &chain->extensions, chain) {
756 __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next); 756 __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
757 if (ctrl && !next) 757 if (ctrl && !next)
758 return ctrl; 758 return ctrl;
@@ -765,7 +765,7 @@ struct uvc_control *uvc_find_control(struct uvc_video_device *video,
765 return ctrl; 765 return ctrl;
766} 766}
767 767
768int uvc_query_v4l2_ctrl(struct uvc_video_device *video, 768int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
769 struct v4l2_queryctrl *v4l2_ctrl) 769 struct v4l2_queryctrl *v4l2_ctrl)
770{ 770{
771 struct uvc_control *ctrl; 771 struct uvc_control *ctrl;
@@ -775,7 +775,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
775 __u8 *data; 775 __u8 *data;
776 int ret; 776 int ret;
777 777
778 ctrl = uvc_find_control(video, v4l2_ctrl->id, &mapping); 778 ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping);
779 if (ctrl == NULL) 779 if (ctrl == NULL)
780 return -EINVAL; 780 return -EINVAL;
781 781
@@ -793,11 +793,13 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
793 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; 793 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
794 794
795 if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { 795 if (ctrl->info->flags & UVC_CONTROL_GET_DEF) {
796 if ((ret = uvc_query_ctrl(video->dev, GET_DEF, ctrl->entity->id, 796 ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id,
797 video->dev->intfnum, ctrl->info->selector, 797 chain->dev->intfnum, ctrl->info->selector,
798 data, ctrl->info->size)) < 0) 798 data, ctrl->info->size);
799 if (ret < 0)
799 goto out; 800 goto out;
800 v4l2_ctrl->default_value = mapping->get(mapping, GET_DEF, data); 801 v4l2_ctrl->default_value =
802 mapping->get(mapping, UVC_GET_DEF, data);
801 } 803 }
802 804
803 switch (mapping->v4l2_type) { 805 switch (mapping->v4l2_type) {
@@ -829,25 +831,28 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
829 } 831 }
830 832
831 if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { 833 if (ctrl->info->flags & UVC_CONTROL_GET_MIN) {
832 if ((ret = uvc_query_ctrl(video->dev, GET_MIN, ctrl->entity->id, 834 ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id,
833 video->dev->intfnum, ctrl->info->selector, 835 chain->dev->intfnum, ctrl->info->selector,
834 data, ctrl->info->size)) < 0) 836 data, ctrl->info->size);
837 if (ret < 0)
835 goto out; 838 goto out;
836 v4l2_ctrl->minimum = mapping->get(mapping, GET_MIN, data); 839 v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN, data);
837 } 840 }
838 if (ctrl->info->flags & UVC_CONTROL_GET_MAX) { 841 if (ctrl->info->flags & UVC_CONTROL_GET_MAX) {
839 if ((ret = uvc_query_ctrl(video->dev, GET_MAX, ctrl->entity->id, 842 ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id,
840 video->dev->intfnum, ctrl->info->selector, 843 chain->dev->intfnum, ctrl->info->selector,
841 data, ctrl->info->size)) < 0) 844 data, ctrl->info->size);
845 if (ret < 0)
842 goto out; 846 goto out;
843 v4l2_ctrl->maximum = mapping->get(mapping, GET_MAX, data); 847 v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX, data);
844 } 848 }
845 if (ctrl->info->flags & UVC_CONTROL_GET_RES) { 849 if (ctrl->info->flags & UVC_CONTROL_GET_RES) {
846 if ((ret = uvc_query_ctrl(video->dev, GET_RES, ctrl->entity->id, 850 ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id,
847 video->dev->intfnum, ctrl->info->selector, 851 chain->dev->intfnum, ctrl->info->selector,
848 data, ctrl->info->size)) < 0) 852 data, ctrl->info->size);
853 if (ret < 0)
849 goto out; 854 goto out;
850 v4l2_ctrl->step = mapping->get(mapping, GET_RES, data); 855 v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, data);
851 } 856 }
852 857
853 ret = 0; 858 ret = 0;
@@ -881,9 +886,9 @@ out:
881 * (UVC_CTRL_DATA_BACKUP) for all dirty controls. Both functions release the 886 * (UVC_CTRL_DATA_BACKUP) for all dirty controls. Both functions release the
882 * control lock. 887 * control lock.
883 */ 888 */
884int uvc_ctrl_begin(struct uvc_video_device *video) 889int uvc_ctrl_begin(struct uvc_video_chain *chain)
885{ 890{
886 return mutex_lock_interruptible(&video->ctrl_mutex) ? -ERESTARTSYS : 0; 891 return mutex_lock_interruptible(&chain->ctrl_mutex) ? -ERESTARTSYS : 0;
887} 892}
888 893
889static int uvc_ctrl_commit_entity(struct uvc_device *dev, 894static int uvc_ctrl_commit_entity(struct uvc_device *dev,
@@ -912,7 +917,7 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
912 continue; 917 continue;
913 918
914 if (!rollback) 919 if (!rollback)
915 ret = uvc_query_ctrl(dev, SET_CUR, ctrl->entity->id, 920 ret = uvc_query_ctrl(dev, UVC_SET_CUR, ctrl->entity->id,
916 dev->intfnum, ctrl->info->selector, 921 dev->intfnum, ctrl->info->selector,
917 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), 922 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
918 ctrl->info->size); 923 ctrl->info->size);
@@ -933,34 +938,34 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
933 return 0; 938 return 0;
934} 939}
935 940
936int __uvc_ctrl_commit(struct uvc_video_device *video, int rollback) 941int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback)
937{ 942{
938 struct uvc_entity *entity; 943 struct uvc_entity *entity;
939 int ret = 0; 944 int ret = 0;
940 945
941 /* Find the control. */ 946 /* Find the control. */
942 ret = uvc_ctrl_commit_entity(video->dev, video->processing, rollback); 947 ret = uvc_ctrl_commit_entity(chain->dev, chain->processing, rollback);
943 if (ret < 0) 948 if (ret < 0)
944 goto done; 949 goto done;
945 950
946 list_for_each_entry(entity, &video->iterms, chain) { 951 list_for_each_entry(entity, &chain->iterms, chain) {
947 ret = uvc_ctrl_commit_entity(video->dev, entity, rollback); 952 ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
948 if (ret < 0) 953 if (ret < 0)
949 goto done; 954 goto done;
950 } 955 }
951 956
952 list_for_each_entry(entity, &video->extensions, chain) { 957 list_for_each_entry(entity, &chain->extensions, chain) {
953 ret = uvc_ctrl_commit_entity(video->dev, entity, rollback); 958 ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
954 if (ret < 0) 959 if (ret < 0)
955 goto done; 960 goto done;
956 } 961 }
957 962
958done: 963done:
959 mutex_unlock(&video->ctrl_mutex); 964 mutex_unlock(&chain->ctrl_mutex);
960 return ret; 965 return ret;
961} 966}
962 967
963int uvc_ctrl_get(struct uvc_video_device *video, 968int uvc_ctrl_get(struct uvc_video_chain *chain,
964 struct v4l2_ext_control *xctrl) 969 struct v4l2_ext_control *xctrl)
965{ 970{
966 struct uvc_control *ctrl; 971 struct uvc_control *ctrl;
@@ -969,13 +974,13 @@ int uvc_ctrl_get(struct uvc_video_device *video,
969 unsigned int i; 974 unsigned int i;
970 int ret; 975 int ret;
971 976
972 ctrl = uvc_find_control(video, xctrl->id, &mapping); 977 ctrl = uvc_find_control(chain, xctrl->id, &mapping);
973 if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) 978 if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0)
974 return -EINVAL; 979 return -EINVAL;
975 980
976 if (!ctrl->loaded) { 981 if (!ctrl->loaded) {
977 ret = uvc_query_ctrl(video->dev, GET_CUR, ctrl->entity->id, 982 ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ctrl->entity->id,
978 video->dev->intfnum, ctrl->info->selector, 983 chain->dev->intfnum, ctrl->info->selector,
979 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), 984 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
980 ctrl->info->size); 985 ctrl->info->size);
981 if (ret < 0) 986 if (ret < 0)
@@ -984,7 +989,7 @@ int uvc_ctrl_get(struct uvc_video_device *video,
984 ctrl->loaded = 1; 989 ctrl->loaded = 1;
985 } 990 }
986 991
987 xctrl->value = mapping->get(mapping, GET_CUR, 992 xctrl->value = mapping->get(mapping, UVC_GET_CUR,
988 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT)); 993 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
989 994
990 if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) { 995 if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) {
@@ -1000,7 +1005,7 @@ int uvc_ctrl_get(struct uvc_video_device *video,
1000 return 0; 1005 return 0;
1001} 1006}
1002 1007
1003int uvc_ctrl_set(struct uvc_video_device *video, 1008int uvc_ctrl_set(struct uvc_video_chain *chain,
1004 struct v4l2_ext_control *xctrl) 1009 struct v4l2_ext_control *xctrl)
1005{ 1010{
1006 struct uvc_control *ctrl; 1011 struct uvc_control *ctrl;
@@ -1008,7 +1013,7 @@ int uvc_ctrl_set(struct uvc_video_device *video,
1008 s32 value = xctrl->value; 1013 s32 value = xctrl->value;
1009 int ret; 1014 int ret;
1010 1015
1011 ctrl = uvc_find_control(video, xctrl->id, &mapping); 1016 ctrl = uvc_find_control(chain, xctrl->id, &mapping);
1012 if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_SET_CUR) == 0) 1017 if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_SET_CUR) == 0)
1013 return -EINVAL; 1018 return -EINVAL;
1014 1019
@@ -1023,8 +1028,8 @@ int uvc_ctrl_set(struct uvc_video_device *video,
1023 memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), 1028 memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1024 0, ctrl->info->size); 1029 0, ctrl->info->size);
1025 } else { 1030 } else {
1026 ret = uvc_query_ctrl(video->dev, GET_CUR, 1031 ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
1027 ctrl->entity->id, video->dev->intfnum, 1032 ctrl->entity->id, chain->dev->intfnum,
1028 ctrl->info->selector, 1033 ctrl->info->selector,
1029 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), 1034 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1030 ctrl->info->size); 1035 ctrl->info->size);
@@ -1053,7 +1058,7 @@ int uvc_ctrl_set(struct uvc_video_device *video,
1053 * Dynamic controls 1058 * Dynamic controls
1054 */ 1059 */
1055 1060
1056int uvc_xu_ctrl_query(struct uvc_video_device *video, 1061int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
1057 struct uvc_xu_control *xctrl, int set) 1062 struct uvc_xu_control *xctrl, int set)
1058{ 1063{
1059 struct uvc_entity *entity; 1064 struct uvc_entity *entity;
@@ -1063,7 +1068,7 @@ int uvc_xu_ctrl_query(struct uvc_video_device *video,
1063 int ret; 1068 int ret;
1064 1069
1065 /* Find the extension unit. */ 1070 /* Find the extension unit. */
1066 list_for_each_entry(entity, &video->extensions, chain) { 1071 list_for_each_entry(entity, &chain->extensions, chain) {
1067 if (entity->id == xctrl->unit) 1072 if (entity->id == xctrl->unit)
1068 break; 1073 break;
1069 } 1074 }
@@ -1102,7 +1107,7 @@ int uvc_xu_ctrl_query(struct uvc_video_device *video,
1102 (!set && !(ctrl->info->flags & UVC_CONTROL_GET_CUR))) 1107 (!set && !(ctrl->info->flags & UVC_CONTROL_GET_CUR)))
1103 return -EINVAL; 1108 return -EINVAL;
1104 1109
1105 if (mutex_lock_interruptible(&video->ctrl_mutex)) 1110 if (mutex_lock_interruptible(&chain->ctrl_mutex))
1106 return -ERESTARTSYS; 1111 return -ERESTARTSYS;
1107 1112
1108 memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), 1113 memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
@@ -1115,9 +1120,9 @@ int uvc_xu_ctrl_query(struct uvc_video_device *video,
1115 goto out; 1120 goto out;
1116 } 1121 }
1117 1122
1118 ret = uvc_query_ctrl(video->dev, set ? SET_CUR : GET_CUR, xctrl->unit, 1123 ret = uvc_query_ctrl(chain->dev, set ? UVC_SET_CUR : UVC_GET_CUR,
1119 video->dev->intfnum, xctrl->selector, data, 1124 xctrl->unit, chain->dev->intfnum, xctrl->selector,
1120 xctrl->size); 1125 data, xctrl->size);
1121 if (ret < 0) 1126 if (ret < 0)
1122 goto out; 1127 goto out;
1123 1128
@@ -1132,7 +1137,7 @@ out:
1132 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), 1137 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
1133 xctrl->size); 1138 xctrl->size);
1134 1139
1135 mutex_unlock(&video->ctrl_mutex); 1140 mutex_unlock(&chain->ctrl_mutex);
1136 return ret; 1141 return ret;
1137} 1142}
1138 1143
@@ -1211,7 +1216,7 @@ static void uvc_ctrl_add_ctrl(struct uvc_device *dev,
1211 if (!found) 1216 if (!found)
1212 return; 1217 return;
1213 1218
1214 if (UVC_ENTITY_TYPE(entity) == VC_EXTENSION_UNIT) { 1219 if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) {
1215 /* Check if the device control information and length match 1220 /* Check if the device control information and length match
1216 * the user supplied information. 1221 * the user supplied information.
1217 */ 1222 */
@@ -1219,8 +1224,9 @@ static void uvc_ctrl_add_ctrl(struct uvc_device *dev,
1219 __le16 size; 1224 __le16 size;
1220 __u8 inf; 1225 __u8 inf;
1221 1226
1222 if ((ret = uvc_query_ctrl(dev, GET_LEN, ctrl->entity->id, 1227 ret = uvc_query_ctrl(dev, UVC_GET_LEN, ctrl->entity->id,
1223 dev->intfnum, info->selector, (__u8 *)&size, 2)) < 0) { 1228 dev->intfnum, info->selector, (__u8 *)&size, 2);
1229 if (ret < 0) {
1224 uvc_trace(UVC_TRACE_CONTROL, "GET_LEN failed on " 1230 uvc_trace(UVC_TRACE_CONTROL, "GET_LEN failed on "
1225 "control " UVC_GUID_FORMAT "/%u (%d).\n", 1231 "control " UVC_GUID_FORMAT "/%u (%d).\n",
1226 UVC_GUID_ARGS(info->entity), info->selector, 1232 UVC_GUID_ARGS(info->entity), info->selector,
@@ -1236,8 +1242,9 @@ static void uvc_ctrl_add_ctrl(struct uvc_device *dev,
1236 return; 1242 return;
1237 } 1243 }
1238 1244
1239 if ((ret = uvc_query_ctrl(dev, GET_INFO, ctrl->entity->id, 1245 ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id,
1240 dev->intfnum, info->selector, &inf, 1)) < 0) { 1246 dev->intfnum, info->selector, &inf, 1);
1247 if (ret < 0) {
1241 uvc_trace(UVC_TRACE_CONTROL, "GET_INFO failed on " 1248 uvc_trace(UVC_TRACE_CONTROL, "GET_INFO failed on "
1242 "control " UVC_GUID_FORMAT "/%u (%d).\n", 1249 "control " UVC_GUID_FORMAT "/%u (%d).\n",
1243 UVC_GUID_ARGS(info->entity), info->selector, 1250 UVC_GUID_ARGS(info->entity), info->selector,
@@ -1391,7 +1398,7 @@ uvc_ctrl_prune_entity(struct uvc_device *dev, struct uvc_entity *entity)
1391 unsigned int size; 1398 unsigned int size;
1392 unsigned int i; 1399 unsigned int i;
1393 1400
1394 if (UVC_ENTITY_TYPE(entity) != VC_PROCESSING_UNIT) 1401 if (UVC_ENTITY_TYPE(entity) != UVC_VC_PROCESSING_UNIT)
1395 return; 1402 return;
1396 1403
1397 controls = entity->processing.bmControls; 1404 controls = entity->processing.bmControls;
@@ -1427,13 +1434,13 @@ int uvc_ctrl_init_device(struct uvc_device *dev)
1427 unsigned int bControlSize = 0, ncontrols = 0; 1434 unsigned int bControlSize = 0, ncontrols = 0;
1428 __u8 *bmControls = NULL; 1435 __u8 *bmControls = NULL;
1429 1436
1430 if (UVC_ENTITY_TYPE(entity) == VC_EXTENSION_UNIT) { 1437 if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) {
1431 bmControls = entity->extension.bmControls; 1438 bmControls = entity->extension.bmControls;
1432 bControlSize = entity->extension.bControlSize; 1439 bControlSize = entity->extension.bControlSize;
1433 } else if (UVC_ENTITY_TYPE(entity) == VC_PROCESSING_UNIT) { 1440 } else if (UVC_ENTITY_TYPE(entity) == UVC_VC_PROCESSING_UNIT) {
1434 bmControls = entity->processing.bmControls; 1441 bmControls = entity->processing.bmControls;
1435 bControlSize = entity->processing.bControlSize; 1442 bControlSize = entity->processing.bControlSize;
1436 } else if (UVC_ENTITY_TYPE(entity) == ITT_CAMERA) { 1443 } else if (UVC_ENTITY_TYPE(entity) == UVC_ITT_CAMERA) {
1437 bmControls = entity->camera.bmControls; 1444 bmControls = entity->camera.bmControls;
1438 bControlSize = entity->camera.bControlSize; 1445 bControlSize = entity->camera.bControlSize;
1439 } 1446 }
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 04b47832fa0a..8756be569154 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -249,23 +249,23 @@ static struct uvc_entity *uvc_entity_by_reference(struct uvc_device *dev,
249 249
250 list_for_each_entry_continue(entity, &dev->entities, list) { 250 list_for_each_entry_continue(entity, &dev->entities, list) {
251 switch (UVC_ENTITY_TYPE(entity)) { 251 switch (UVC_ENTITY_TYPE(entity)) {
252 case TT_STREAMING: 252 case UVC_TT_STREAMING:
253 if (entity->output.bSourceID == id) 253 if (entity->output.bSourceID == id)
254 return entity; 254 return entity;
255 break; 255 break;
256 256
257 case VC_PROCESSING_UNIT: 257 case UVC_VC_PROCESSING_UNIT:
258 if (entity->processing.bSourceID == id) 258 if (entity->processing.bSourceID == id)
259 return entity; 259 return entity;
260 break; 260 break;
261 261
262 case VC_SELECTOR_UNIT: 262 case UVC_VC_SELECTOR_UNIT:
263 for (i = 0; i < entity->selector.bNrInPins; ++i) 263 for (i = 0; i < entity->selector.bNrInPins; ++i)
264 if (entity->selector.baSourceID[i] == id) 264 if (entity->selector.baSourceID[i] == id)
265 return entity; 265 return entity;
266 break; 266 break;
267 267
268 case VC_EXTENSION_UNIT: 268 case UVC_VC_EXTENSION_UNIT:
269 for (i = 0; i < entity->extension.bNrInPins; ++i) 269 for (i = 0; i < entity->extension.bNrInPins; ++i)
270 if (entity->extension.baSourceID[i] == id) 270 if (entity->extension.baSourceID[i] == id)
271 return entity; 271 return entity;
@@ -276,8 +276,20 @@ static struct uvc_entity *uvc_entity_by_reference(struct uvc_device *dev,
276 return NULL; 276 return NULL;
277} 277}
278 278
279static struct uvc_streaming *uvc_stream_by_id(struct uvc_device *dev, int id)
280{
281 struct uvc_streaming *stream;
282
283 list_for_each_entry(stream, &dev->streams, list) {
284 if (stream->header.bTerminalLink == id)
285 return stream;
286 }
287
288 return NULL;
289}
290
279/* ------------------------------------------------------------------------ 291/* ------------------------------------------------------------------------
280 * Descriptors handling 292 * Descriptors parsing
281 */ 293 */
282 294
283static int uvc_parse_format(struct uvc_device *dev, 295static int uvc_parse_format(struct uvc_device *dev,
@@ -297,9 +309,9 @@ static int uvc_parse_format(struct uvc_device *dev,
297 format->index = buffer[3]; 309 format->index = buffer[3];
298 310
299 switch (buffer[2]) { 311 switch (buffer[2]) {
300 case VS_FORMAT_UNCOMPRESSED: 312 case UVC_VS_FORMAT_UNCOMPRESSED:
301 case VS_FORMAT_FRAME_BASED: 313 case UVC_VS_FORMAT_FRAME_BASED:
302 n = buffer[2] == VS_FORMAT_UNCOMPRESSED ? 27 : 28; 314 n = buffer[2] == UVC_VS_FORMAT_UNCOMPRESSED ? 27 : 28;
303 if (buflen < n) { 315 if (buflen < n) {
304 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " 316 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
305 "interface %d FORMAT error\n", 317 "interface %d FORMAT error\n",
@@ -325,16 +337,16 @@ static int uvc_parse_format(struct uvc_device *dev,
325 } 337 }
326 338
327 format->bpp = buffer[21]; 339 format->bpp = buffer[21];
328 if (buffer[2] == VS_FORMAT_UNCOMPRESSED) { 340 if (buffer[2] == UVC_VS_FORMAT_UNCOMPRESSED) {
329 ftype = VS_FRAME_UNCOMPRESSED; 341 ftype = UVC_VS_FRAME_UNCOMPRESSED;
330 } else { 342 } else {
331 ftype = VS_FRAME_FRAME_BASED; 343 ftype = UVC_VS_FRAME_FRAME_BASED;
332 if (buffer[27]) 344 if (buffer[27])
333 format->flags = UVC_FMT_FLAG_COMPRESSED; 345 format->flags = UVC_FMT_FLAG_COMPRESSED;
334 } 346 }
335 break; 347 break;
336 348
337 case VS_FORMAT_MJPEG: 349 case UVC_VS_FORMAT_MJPEG:
338 if (buflen < 11) { 350 if (buflen < 11) {
339 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " 351 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
340 "interface %d FORMAT error\n", 352 "interface %d FORMAT error\n",
@@ -347,10 +359,10 @@ static int uvc_parse_format(struct uvc_device *dev,
347 format->fcc = V4L2_PIX_FMT_MJPEG; 359 format->fcc = V4L2_PIX_FMT_MJPEG;
348 format->flags = UVC_FMT_FLAG_COMPRESSED; 360 format->flags = UVC_FMT_FLAG_COMPRESSED;
349 format->bpp = 0; 361 format->bpp = 0;
350 ftype = VS_FRAME_MJPEG; 362 ftype = UVC_VS_FRAME_MJPEG;
351 break; 363 break;
352 364
353 case VS_FORMAT_DV: 365 case UVC_VS_FORMAT_DV:
354 if (buflen < 9) { 366 if (buflen < 9) {
355 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " 367 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
356 "interface %d FORMAT error\n", 368 "interface %d FORMAT error\n",
@@ -395,8 +407,8 @@ static int uvc_parse_format(struct uvc_device *dev,
395 format->nframes = 1; 407 format->nframes = 1;
396 break; 408 break;
397 409
398 case VS_FORMAT_MPEG2TS: 410 case UVC_VS_FORMAT_MPEG2TS:
399 case VS_FORMAT_STREAM_BASED: 411 case UVC_VS_FORMAT_STREAM_BASED:
400 /* Not supported yet. */ 412 /* Not supported yet. */
401 default: 413 default:
402 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " 414 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
@@ -416,7 +428,7 @@ static int uvc_parse_format(struct uvc_device *dev,
416 */ 428 */
417 while (buflen > 2 && buffer[2] == ftype) { 429 while (buflen > 2 && buffer[2] == ftype) {
418 frame = &format->frame[format->nframes]; 430 frame = &format->frame[format->nframes];
419 if (ftype != VS_FRAME_FRAME_BASED) 431 if (ftype != UVC_VS_FRAME_FRAME_BASED)
420 n = buflen > 25 ? buffer[25] : 0; 432 n = buflen > 25 ? buffer[25] : 0;
421 else 433 else
422 n = buflen > 21 ? buffer[21] : 0; 434 n = buflen > 21 ? buffer[21] : 0;
@@ -436,7 +448,7 @@ static int uvc_parse_format(struct uvc_device *dev,
436 frame->wHeight = get_unaligned_le16(&buffer[7]); 448 frame->wHeight = get_unaligned_le16(&buffer[7]);
437 frame->dwMinBitRate = get_unaligned_le32(&buffer[9]); 449 frame->dwMinBitRate = get_unaligned_le32(&buffer[9]);
438 frame->dwMaxBitRate = get_unaligned_le32(&buffer[13]); 450 frame->dwMaxBitRate = get_unaligned_le32(&buffer[13]);
439 if (ftype != VS_FRAME_FRAME_BASED) { 451 if (ftype != UVC_VS_FRAME_FRAME_BASED) {
440 frame->dwMaxVideoFrameBufferSize = 452 frame->dwMaxVideoFrameBufferSize =
441 get_unaligned_le32(&buffer[17]); 453 get_unaligned_le32(&buffer[17]);
442 frame->dwDefaultFrameInterval = 454 frame->dwDefaultFrameInterval =
@@ -491,12 +503,12 @@ static int uvc_parse_format(struct uvc_device *dev,
491 buffer += buffer[0]; 503 buffer += buffer[0];
492 } 504 }
493 505
494 if (buflen > 2 && buffer[2] == VS_STILL_IMAGE_FRAME) { 506 if (buflen > 2 && buffer[2] == UVC_VS_STILL_IMAGE_FRAME) {
495 buflen -= buffer[0]; 507 buflen -= buffer[0];
496 buffer += buffer[0]; 508 buffer += buffer[0];
497 } 509 }
498 510
499 if (buflen > 2 && buffer[2] == VS_COLORFORMAT) { 511 if (buflen > 2 && buffer[2] == UVC_VS_COLORFORMAT) {
500 if (buflen < 6) { 512 if (buflen < 6) {
501 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " 513 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
502 "interface %d COLORFORMAT error\n", 514 "interface %d COLORFORMAT error\n",
@@ -530,7 +542,7 @@ static int uvc_parse_streaming(struct uvc_device *dev,
530 int ret = -EINVAL; 542 int ret = -EINVAL;
531 543
532 if (intf->cur_altsetting->desc.bInterfaceSubClass 544 if (intf->cur_altsetting->desc.bInterfaceSubClass
533 != SC_VIDEOSTREAMING) { 545 != UVC_SC_VIDEOSTREAMING) {
534 uvc_trace(UVC_TRACE_DESCR, "device %d interface %d isn't a " 546 uvc_trace(UVC_TRACE_DESCR, "device %d interface %d isn't a "
535 "video streaming interface\n", dev->udev->devnum, 547 "video streaming interface\n", dev->udev->devnum,
536 intf->altsetting[0].desc.bInterfaceNumber); 548 intf->altsetting[0].desc.bInterfaceNumber);
@@ -551,6 +563,7 @@ static int uvc_parse_streaming(struct uvc_device *dev,
551 } 563 }
552 564
553 mutex_init(&streaming->mutex); 565 mutex_init(&streaming->mutex);
566 streaming->dev = dev;
554 streaming->intf = usb_get_intf(intf); 567 streaming->intf = usb_get_intf(intf);
555 streaming->intfnum = intf->cur_altsetting->desc.bInterfaceNumber; 568 streaming->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
556 569
@@ -589,12 +602,12 @@ static int uvc_parse_streaming(struct uvc_device *dev,
589 602
590 /* Parse the header descriptor. */ 603 /* Parse the header descriptor. */
591 switch (buffer[2]) { 604 switch (buffer[2]) {
592 case VS_OUTPUT_HEADER: 605 case UVC_VS_OUTPUT_HEADER:
593 streaming->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 606 streaming->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
594 size = 9; 607 size = 9;
595 break; 608 break;
596 609
597 case VS_INPUT_HEADER: 610 case UVC_VS_INPUT_HEADER:
598 streaming->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 611 streaming->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
599 size = 13; 612 size = 13;
600 break; 613 break;
@@ -618,7 +631,7 @@ static int uvc_parse_streaming(struct uvc_device *dev,
618 631
619 streaming->header.bNumFormats = p; 632 streaming->header.bNumFormats = p;
620 streaming->header.bEndpointAddress = buffer[6]; 633 streaming->header.bEndpointAddress = buffer[6];
621 if (buffer[2] == VS_INPUT_HEADER) { 634 if (buffer[2] == UVC_VS_INPUT_HEADER) {
622 streaming->header.bmInfo = buffer[7]; 635 streaming->header.bmInfo = buffer[7];
623 streaming->header.bTerminalLink = buffer[8]; 636 streaming->header.bTerminalLink = buffer[8];
624 streaming->header.bStillCaptureMethod = buffer[9]; 637 streaming->header.bStillCaptureMethod = buffer[9];
@@ -644,15 +657,15 @@ static int uvc_parse_streaming(struct uvc_device *dev,
644 _buflen = buflen; 657 _buflen = buflen;
645 658
646 /* Count the format and frame descriptors. */ 659 /* Count the format and frame descriptors. */
647 while (_buflen > 2 && _buffer[1] == CS_INTERFACE) { 660 while (_buflen > 2 && _buffer[1] == USB_DT_CS_INTERFACE) {
648 switch (_buffer[2]) { 661 switch (_buffer[2]) {
649 case VS_FORMAT_UNCOMPRESSED: 662 case UVC_VS_FORMAT_UNCOMPRESSED:
650 case VS_FORMAT_MJPEG: 663 case UVC_VS_FORMAT_MJPEG:
651 case VS_FORMAT_FRAME_BASED: 664 case UVC_VS_FORMAT_FRAME_BASED:
652 nformats++; 665 nformats++;
653 break; 666 break;
654 667
655 case VS_FORMAT_DV: 668 case UVC_VS_FORMAT_DV:
656 /* DV format has no frame descriptor. We will create a 669 /* DV format has no frame descriptor. We will create a
657 * dummy frame descriptor with a dummy frame interval. 670 * dummy frame descriptor with a dummy frame interval.
658 */ 671 */
@@ -661,22 +674,22 @@ static int uvc_parse_streaming(struct uvc_device *dev,
661 nintervals++; 674 nintervals++;
662 break; 675 break;
663 676
664 case VS_FORMAT_MPEG2TS: 677 case UVC_VS_FORMAT_MPEG2TS:
665 case VS_FORMAT_STREAM_BASED: 678 case UVC_VS_FORMAT_STREAM_BASED:
666 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " 679 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
667 "interface %d FORMAT %u is not supported.\n", 680 "interface %d FORMAT %u is not supported.\n",
668 dev->udev->devnum, 681 dev->udev->devnum,
669 alts->desc.bInterfaceNumber, _buffer[2]); 682 alts->desc.bInterfaceNumber, _buffer[2]);
670 break; 683 break;
671 684
672 case VS_FRAME_UNCOMPRESSED: 685 case UVC_VS_FRAME_UNCOMPRESSED:
673 case VS_FRAME_MJPEG: 686 case UVC_VS_FRAME_MJPEG:
674 nframes++; 687 nframes++;
675 if (_buflen > 25) 688 if (_buflen > 25)
676 nintervals += _buffer[25] ? _buffer[25] : 3; 689 nintervals += _buffer[25] ? _buffer[25] : 3;
677 break; 690 break;
678 691
679 case VS_FRAME_FRAME_BASED: 692 case UVC_VS_FRAME_FRAME_BASED:
680 nframes++; 693 nframes++;
681 if (_buflen > 21) 694 if (_buflen > 21)
682 nintervals += _buffer[21] ? _buffer[21] : 3; 695 nintervals += _buffer[21] ? _buffer[21] : 3;
@@ -709,12 +722,12 @@ static int uvc_parse_streaming(struct uvc_device *dev,
709 streaming->nformats = nformats; 722 streaming->nformats = nformats;
710 723
711 /* Parse the format descriptors. */ 724 /* Parse the format descriptors. */
712 while (buflen > 2 && buffer[1] == CS_INTERFACE) { 725 while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE) {
713 switch (buffer[2]) { 726 switch (buffer[2]) {
714 case VS_FORMAT_UNCOMPRESSED: 727 case UVC_VS_FORMAT_UNCOMPRESSED:
715 case VS_FORMAT_MJPEG: 728 case UVC_VS_FORMAT_MJPEG:
716 case VS_FORMAT_DV: 729 case UVC_VS_FORMAT_DV:
717 case VS_FORMAT_FRAME_BASED: 730 case UVC_VS_FORMAT_FRAME_BASED:
718 format->frame = frame; 731 format->frame = frame;
719 ret = uvc_parse_format(dev, streaming, format, 732 ret = uvc_parse_format(dev, streaming, format,
720 &interval, buffer, buflen); 733 &interval, buffer, buflen);
@@ -751,7 +764,7 @@ static int uvc_parse_streaming(struct uvc_device *dev,
751 streaming->maxpsize = psize; 764 streaming->maxpsize = psize;
752 } 765 }
753 766
754 list_add_tail(&streaming->list, &dev->streaming); 767 list_add_tail(&streaming->list, &dev->streams);
755 return 0; 768 return 0;
756 769
757error: 770error:
@@ -819,7 +832,7 @@ static int uvc_parse_vendor_control(struct uvc_device *dev,
819 return -ENOMEM; 832 return -ENOMEM;
820 833
821 unit->id = buffer[3]; 834 unit->id = buffer[3];
822 unit->type = VC_EXTENSION_UNIT; 835 unit->type = UVC_VC_EXTENSION_UNIT;
823 memcpy(unit->extension.guidExtensionCode, &buffer[4], 16); 836 memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
824 unit->extension.bNumControls = buffer[20]; 837 unit->extension.bNumControls = buffer[20];
825 unit->extension.bNrInPins = get_unaligned_le16(&buffer[21]); 838 unit->extension.bNrInPins = get_unaligned_le16(&buffer[21]);
@@ -856,7 +869,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
856 __u16 type; 869 __u16 type;
857 870
858 switch (buffer[2]) { 871 switch (buffer[2]) {
859 case VC_HEADER: 872 case UVC_VC_HEADER:
860 n = buflen >= 12 ? buffer[11] : 0; 873 n = buflen >= 12 ? buffer[11] : 0;
861 874
862 if (buflen < 12 || buflen < 12 + n) { 875 if (buflen < 12 || buflen < 12 + n) {
@@ -883,7 +896,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
883 } 896 }
884 break; 897 break;
885 898
886 case VC_INPUT_TERMINAL: 899 case UVC_VC_INPUT_TERMINAL:
887 if (buflen < 8) { 900 if (buflen < 8) {
888 uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol " 901 uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
889 "interface %d INPUT_TERMINAL error\n", 902 "interface %d INPUT_TERMINAL error\n",
@@ -908,11 +921,11 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
908 p = 0; 921 p = 0;
909 len = 8; 922 len = 8;
910 923
911 if (type == ITT_CAMERA) { 924 if (type == UVC_ITT_CAMERA) {
912 n = buflen >= 15 ? buffer[14] : 0; 925 n = buflen >= 15 ? buffer[14] : 0;
913 len = 15; 926 len = 15;
914 927
915 } else if (type == ITT_MEDIA_TRANSPORT_INPUT) { 928 } else if (type == UVC_ITT_MEDIA_TRANSPORT_INPUT) {
916 n = buflen >= 9 ? buffer[8] : 0; 929 n = buflen >= 9 ? buffer[8] : 0;
917 p = buflen >= 10 + n ? buffer[9+n] : 0; 930 p = buflen >= 10 + n ? buffer[9+n] : 0;
918 len = 10; 931 len = 10;
@@ -932,7 +945,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
932 term->id = buffer[3]; 945 term->id = buffer[3];
933 term->type = type | UVC_TERM_INPUT; 946 term->type = type | UVC_TERM_INPUT;
934 947
935 if (UVC_ENTITY_TYPE(term) == ITT_CAMERA) { 948 if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) {
936 term->camera.bControlSize = n; 949 term->camera.bControlSize = n;
937 term->camera.bmControls = (__u8 *)term + sizeof *term; 950 term->camera.bmControls = (__u8 *)term + sizeof *term;
938 term->camera.wObjectiveFocalLengthMin = 951 term->camera.wObjectiveFocalLengthMin =
@@ -942,7 +955,8 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
942 term->camera.wOcularFocalLength = 955 term->camera.wOcularFocalLength =
943 get_unaligned_le16(&buffer[12]); 956 get_unaligned_le16(&buffer[12]);
944 memcpy(term->camera.bmControls, &buffer[15], n); 957 memcpy(term->camera.bmControls, &buffer[15], n);
945 } else if (UVC_ENTITY_TYPE(term) == ITT_MEDIA_TRANSPORT_INPUT) { 958 } else if (UVC_ENTITY_TYPE(term) ==
959 UVC_ITT_MEDIA_TRANSPORT_INPUT) {
946 term->media.bControlSize = n; 960 term->media.bControlSize = n;
947 term->media.bmControls = (__u8 *)term + sizeof *term; 961 term->media.bmControls = (__u8 *)term + sizeof *term;
948 term->media.bTransportModeSize = p; 962 term->media.bTransportModeSize = p;
@@ -955,9 +969,9 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
955 if (buffer[7] != 0) 969 if (buffer[7] != 0)
956 usb_string(udev, buffer[7], term->name, 970 usb_string(udev, buffer[7], term->name,
957 sizeof term->name); 971 sizeof term->name);
958 else if (UVC_ENTITY_TYPE(term) == ITT_CAMERA) 972 else if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA)
959 sprintf(term->name, "Camera %u", buffer[3]); 973 sprintf(term->name, "Camera %u", buffer[3]);
960 else if (UVC_ENTITY_TYPE(term) == ITT_MEDIA_TRANSPORT_INPUT) 974 else if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT)
961 sprintf(term->name, "Media %u", buffer[3]); 975 sprintf(term->name, "Media %u", buffer[3]);
962 else 976 else
963 sprintf(term->name, "Input %u", buffer[3]); 977 sprintf(term->name, "Input %u", buffer[3]);
@@ -965,7 +979,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
965 list_add_tail(&term->list, &dev->entities); 979 list_add_tail(&term->list, &dev->entities);
966 break; 980 break;
967 981
968 case VC_OUTPUT_TERMINAL: 982 case UVC_VC_OUTPUT_TERMINAL:
969 if (buflen < 9) { 983 if (buflen < 9) {
970 uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol " 984 uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
971 "interface %d OUTPUT_TERMINAL error\n", 985 "interface %d OUTPUT_TERMINAL error\n",
@@ -1002,7 +1016,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
1002 list_add_tail(&term->list, &dev->entities); 1016 list_add_tail(&term->list, &dev->entities);
1003 break; 1017 break;
1004 1018
1005 case VC_SELECTOR_UNIT: 1019 case UVC_VC_SELECTOR_UNIT:
1006 p = buflen >= 5 ? buffer[4] : 0; 1020 p = buflen >= 5 ? buffer[4] : 0;
1007 1021
1008 if (buflen < 5 || buflen < 6 + p) { 1022 if (buflen < 5 || buflen < 6 + p) {
@@ -1031,7 +1045,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
1031 list_add_tail(&unit->list, &dev->entities); 1045 list_add_tail(&unit->list, &dev->entities);
1032 break; 1046 break;
1033 1047
1034 case VC_PROCESSING_UNIT: 1048 case UVC_VC_PROCESSING_UNIT:
1035 n = buflen >= 8 ? buffer[7] : 0; 1049 n = buflen >= 8 ? buffer[7] : 0;
1036 p = dev->uvc_version >= 0x0110 ? 10 : 9; 1050 p = dev->uvc_version >= 0x0110 ? 10 : 9;
1037 1051
@@ -1066,7 +1080,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
1066 list_add_tail(&unit->list, &dev->entities); 1080 list_add_tail(&unit->list, &dev->entities);
1067 break; 1081 break;
1068 1082
1069 case VC_EXTENSION_UNIT: 1083 case UVC_VC_EXTENSION_UNIT:
1070 p = buflen >= 22 ? buffer[21] : 0; 1084 p = buflen >= 22 ? buffer[21] : 0;
1071 n = buflen >= 24 + p ? buffer[22+p] : 0; 1085 n = buflen >= 24 + p ? buffer[22+p] : 0;
1072 1086
@@ -1158,43 +1172,40 @@ next_descriptor:
1158} 1172}
1159 1173
1160/* ------------------------------------------------------------------------ 1174/* ------------------------------------------------------------------------
1161 * USB probe and disconnect 1175 * UVC device scan
1162 */ 1176 */
1163 1177
1164/* 1178/*
1165 * Unregister the video devices.
1166 */
1167static void uvc_unregister_video(struct uvc_device *dev)
1168{
1169 if (dev->video.vdev) {
1170 if (dev->video.vdev->minor == -1)
1171 video_device_release(dev->video.vdev);
1172 else
1173 video_unregister_device(dev->video.vdev);
1174 dev->video.vdev = NULL;
1175 }
1176}
1177
1178/*
1179 * Scan the UVC descriptors to locate a chain starting at an Output Terminal 1179 * Scan the UVC descriptors to locate a chain starting at an Output Terminal
1180 * and containing the following units: 1180 * and containing the following units:
1181 * 1181 *
1182 * - one Output Terminal (USB Streaming or Display) 1182 * - one or more Output Terminals (USB Streaming or Display)
1183 * - zero or one Processing Unit 1183 * - zero or one Processing Unit
1184 * - zero, one or mode single-input Selector Units 1184 * - zero, one or more single-input Selector Units
1185 * - zero or one multiple-input Selector Units, provided all inputs are 1185 * - zero or one multiple-input Selector Units, provided all inputs are
1186 * connected to input terminals 1186 * connected to input terminals
1187 * - zero, one or mode single-input Extension Units 1187 * - zero, one or mode single-input Extension Units
1188 * - one or more Input Terminals (Camera, External or USB Streaming) 1188 * - one or more Input Terminals (Camera, External or USB Streaming)
1189 * 1189 *
1190 * A side forward scan is made on each detected entity to check for additional 1190 * The terminal and units must match on of the following structures:
1191 * extension units. 1191 *
1192 * ITT_*(0) -> +---------+ +---------+ +---------+ -> TT_STREAMING(0)
1193 * ... | SU{0,1} | -> | PU{0,1} | -> | XU{0,n} | ...
1194 * ITT_*(n) -> +---------+ +---------+ +---------+ -> TT_STREAMING(n)
1195 *
1196 * +---------+ +---------+ -> OTT_*(0)
1197 * TT_STREAMING -> | PU{0,1} | -> | XU{0,n} | ...
1198 * +---------+ +---------+ -> OTT_*(n)
1199 *
1200 * The Processing Unit and Extension Units can be in any order. Additional
1201 * Extension Units connected to the main chain as single-unit branches are
1202 * also supported. Single-input Selector Units are ignored.
1192 */ 1203 */
1193static int uvc_scan_chain_entity(struct uvc_video_device *video, 1204static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
1194 struct uvc_entity *entity) 1205 struct uvc_entity *entity)
1195{ 1206{
1196 switch (UVC_ENTITY_TYPE(entity)) { 1207 switch (UVC_ENTITY_TYPE(entity)) {
1197 case VC_EXTENSION_UNIT: 1208 case UVC_VC_EXTENSION_UNIT:
1198 if (uvc_trace_param & UVC_TRACE_PROBE) 1209 if (uvc_trace_param & UVC_TRACE_PROBE)
1199 printk(" <- XU %d", entity->id); 1210 printk(" <- XU %d", entity->id);
1200 1211
@@ -1204,23 +1215,23 @@ static int uvc_scan_chain_entity(struct uvc_video_device *video,
1204 return -1; 1215 return -1;
1205 } 1216 }
1206 1217
1207 list_add_tail(&entity->chain, &video->extensions); 1218 list_add_tail(&entity->chain, &chain->extensions);
1208 break; 1219 break;
1209 1220
1210 case VC_PROCESSING_UNIT: 1221 case UVC_VC_PROCESSING_UNIT:
1211 if (uvc_trace_param & UVC_TRACE_PROBE) 1222 if (uvc_trace_param & UVC_TRACE_PROBE)
1212 printk(" <- PU %d", entity->id); 1223 printk(" <- PU %d", entity->id);
1213 1224
1214 if (video->processing != NULL) { 1225 if (chain->processing != NULL) {
1215 uvc_trace(UVC_TRACE_DESCR, "Found multiple " 1226 uvc_trace(UVC_TRACE_DESCR, "Found multiple "
1216 "Processing Units in chain.\n"); 1227 "Processing Units in chain.\n");
1217 return -1; 1228 return -1;
1218 } 1229 }
1219 1230
1220 video->processing = entity; 1231 chain->processing = entity;
1221 break; 1232 break;
1222 1233
1223 case VC_SELECTOR_UNIT: 1234 case UVC_VC_SELECTOR_UNIT:
1224 if (uvc_trace_param & UVC_TRACE_PROBE) 1235 if (uvc_trace_param & UVC_TRACE_PROBE)
1225 printk(" <- SU %d", entity->id); 1236 printk(" <- SU %d", entity->id);
1226 1237
@@ -1228,25 +1239,25 @@ static int uvc_scan_chain_entity(struct uvc_video_device *video,
1228 if (entity->selector.bNrInPins == 1) 1239 if (entity->selector.bNrInPins == 1)
1229 break; 1240 break;
1230 1241
1231 if (video->selector != NULL) { 1242 if (chain->selector != NULL) {
1232 uvc_trace(UVC_TRACE_DESCR, "Found multiple Selector " 1243 uvc_trace(UVC_TRACE_DESCR, "Found multiple Selector "
1233 "Units in chain.\n"); 1244 "Units in chain.\n");
1234 return -1; 1245 return -1;
1235 } 1246 }
1236 1247
1237 video->selector = entity; 1248 chain->selector = entity;
1238 break; 1249 break;
1239 1250
1240 case ITT_VENDOR_SPECIFIC: 1251 case UVC_ITT_VENDOR_SPECIFIC:
1241 case ITT_CAMERA: 1252 case UVC_ITT_CAMERA:
1242 case ITT_MEDIA_TRANSPORT_INPUT: 1253 case UVC_ITT_MEDIA_TRANSPORT_INPUT:
1243 if (uvc_trace_param & UVC_TRACE_PROBE) 1254 if (uvc_trace_param & UVC_TRACE_PROBE)
1244 printk(" <- IT %d\n", entity->id); 1255 printk(" <- IT %d\n", entity->id);
1245 1256
1246 list_add_tail(&entity->chain, &video->iterms); 1257 list_add_tail(&entity->chain, &chain->iterms);
1247 break; 1258 break;
1248 1259
1249 case TT_STREAMING: 1260 case UVC_TT_STREAMING:
1250 if (uvc_trace_param & UVC_TRACE_PROBE) 1261 if (uvc_trace_param & UVC_TRACE_PROBE)
1251 printk(" <- IT %d\n", entity->id); 1262 printk(" <- IT %d\n", entity->id);
1252 1263
@@ -1256,14 +1267,7 @@ static int uvc_scan_chain_entity(struct uvc_video_device *video,
1256 return -1; 1267 return -1;
1257 } 1268 }
1258 1269
1259 if (video->sterm != NULL) { 1270 list_add_tail(&entity->chain, &chain->iterms);
1260 uvc_trace(UVC_TRACE_DESCR, "Found multiple streaming "
1261 "entities in chain.\n");
1262 return -1;
1263 }
1264
1265 list_add_tail(&entity->chain, &video->iterms);
1266 video->sterm = entity;
1267 break; 1271 break;
1268 1272
1269 default: 1273 default:
@@ -1275,7 +1279,7 @@ static int uvc_scan_chain_entity(struct uvc_video_device *video,
1275 return 0; 1279 return 0;
1276} 1280}
1277 1281
1278static int uvc_scan_chain_forward(struct uvc_video_device *video, 1282static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
1279 struct uvc_entity *entity, struct uvc_entity *prev) 1283 struct uvc_entity *entity, struct uvc_entity *prev)
1280{ 1284{
1281 struct uvc_entity *forward; 1285 struct uvc_entity *forward;
@@ -1286,28 +1290,51 @@ static int uvc_scan_chain_forward(struct uvc_video_device *video,
1286 found = 0; 1290 found = 0;
1287 1291
1288 while (1) { 1292 while (1) {
1289 forward = uvc_entity_by_reference(video->dev, entity->id, 1293 forward = uvc_entity_by_reference(chain->dev, entity->id,
1290 forward); 1294 forward);
1291 if (forward == NULL) 1295 if (forward == NULL)
1292 break; 1296 break;
1293 1297 if (forward == prev)
1294 if (UVC_ENTITY_TYPE(forward) != VC_EXTENSION_UNIT ||
1295 forward == prev)
1296 continue; 1298 continue;
1297 1299
1298 if (forward->extension.bNrInPins != 1) { 1300 switch (UVC_ENTITY_TYPE(forward)) {
1299 uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has " 1301 case UVC_VC_EXTENSION_UNIT:
1300 "more than 1 input pin.\n", entity->id); 1302 if (forward->extension.bNrInPins != 1) {
1301 return -1; 1303 uvc_trace(UVC_TRACE_DESCR, "Extension unit %d "
1302 } 1304 "has more than 1 input pin.\n",
1305 entity->id);
1306 return -EINVAL;
1307 }
1308
1309 list_add_tail(&forward->chain, &chain->extensions);
1310 if (uvc_trace_param & UVC_TRACE_PROBE) {
1311 if (!found)
1312 printk(" (->");
1303 1313
1304 list_add_tail(&forward->chain, &video->extensions); 1314 printk(" XU %d", forward->id);
1305 if (uvc_trace_param & UVC_TRACE_PROBE) { 1315 found = 1;
1306 if (!found) 1316 }
1307 printk(" (-> XU"); 1317 break;
1318
1319 case UVC_OTT_VENDOR_SPECIFIC:
1320 case UVC_OTT_DISPLAY:
1321 case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
1322 case UVC_TT_STREAMING:
1323 if (UVC_ENTITY_IS_ITERM(forward)) {
1324 uvc_trace(UVC_TRACE_DESCR, "Unsupported input "
1325 "terminal %u.\n", forward->id);
1326 return -EINVAL;
1327 }
1308 1328
1309 printk(" %d", forward->id); 1329 list_add_tail(&forward->chain, &chain->oterms);
1310 found = 1; 1330 if (uvc_trace_param & UVC_TRACE_PROBE) {
1331 if (!found)
1332 printk(" (->");
1333
1334 printk(" OT %d", forward->id);
1335 found = 1;
1336 }
1337 break;
1311 } 1338 }
1312 } 1339 }
1313 if (found) 1340 if (found)
@@ -1316,22 +1343,22 @@ static int uvc_scan_chain_forward(struct uvc_video_device *video,
1316 return 0; 1343 return 0;
1317} 1344}
1318 1345
1319static int uvc_scan_chain_backward(struct uvc_video_device *video, 1346static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
1320 struct uvc_entity *entity) 1347 struct uvc_entity *entity)
1321{ 1348{
1322 struct uvc_entity *term; 1349 struct uvc_entity *term;
1323 int id = -1, i; 1350 int id = -1, i;
1324 1351
1325 switch (UVC_ENTITY_TYPE(entity)) { 1352 switch (UVC_ENTITY_TYPE(entity)) {
1326 case VC_EXTENSION_UNIT: 1353 case UVC_VC_EXTENSION_UNIT:
1327 id = entity->extension.baSourceID[0]; 1354 id = entity->extension.baSourceID[0];
1328 break; 1355 break;
1329 1356
1330 case VC_PROCESSING_UNIT: 1357 case UVC_VC_PROCESSING_UNIT:
1331 id = entity->processing.bSourceID; 1358 id = entity->processing.bSourceID;
1332 break; 1359 break;
1333 1360
1334 case VC_SELECTOR_UNIT: 1361 case UVC_VC_SELECTOR_UNIT:
1335 /* Single-input selector units are ignored. */ 1362 /* Single-input selector units are ignored. */
1336 if (entity->selector.bNrInPins == 1) { 1363 if (entity->selector.bNrInPins == 1) {
1337 id = entity->selector.baSourceID[0]; 1364 id = entity->selector.baSourceID[0];
@@ -1341,10 +1368,10 @@ static int uvc_scan_chain_backward(struct uvc_video_device *video,
1341 if (uvc_trace_param & UVC_TRACE_PROBE) 1368 if (uvc_trace_param & UVC_TRACE_PROBE)
1342 printk(" <- IT"); 1369 printk(" <- IT");
1343 1370
1344 video->selector = entity; 1371 chain->selector = entity;
1345 for (i = 0; i < entity->selector.bNrInPins; ++i) { 1372 for (i = 0; i < entity->selector.bNrInPins; ++i) {
1346 id = entity->selector.baSourceID[i]; 1373 id = entity->selector.baSourceID[i];
1347 term = uvc_entity_by_id(video->dev, id); 1374 term = uvc_entity_by_id(chain->dev, id);
1348 if (term == NULL || !UVC_ENTITY_IS_ITERM(term)) { 1375 if (term == NULL || !UVC_ENTITY_IS_ITERM(term)) {
1349 uvc_trace(UVC_TRACE_DESCR, "Selector unit %d " 1376 uvc_trace(UVC_TRACE_DESCR, "Selector unit %d "
1350 "input %d isn't connected to an " 1377 "input %d isn't connected to an "
@@ -1355,8 +1382,8 @@ static int uvc_scan_chain_backward(struct uvc_video_device *video,
1355 if (uvc_trace_param & UVC_TRACE_PROBE) 1382 if (uvc_trace_param & UVC_TRACE_PROBE)
1356 printk(" %d", term->id); 1383 printk(" %d", term->id);
1357 1384
1358 list_add_tail(&term->chain, &video->iterms); 1385 list_add_tail(&term->chain, &chain->iterms);
1359 uvc_scan_chain_forward(video, term, entity); 1386 uvc_scan_chain_forward(chain, term, entity);
1360 } 1387 }
1361 1388
1362 if (uvc_trace_param & UVC_TRACE_PROBE) 1389 if (uvc_trace_param & UVC_TRACE_PROBE)
@@ -1369,125 +1396,170 @@ static int uvc_scan_chain_backward(struct uvc_video_device *video,
1369 return id; 1396 return id;
1370} 1397}
1371 1398
1372static int uvc_scan_chain(struct uvc_video_device *video) 1399static int uvc_scan_chain(struct uvc_video_chain *chain,
1400 struct uvc_entity *oterm)
1373{ 1401{
1374 struct uvc_entity *entity, *prev; 1402 struct uvc_entity *entity, *prev;
1375 int id; 1403 int id;
1376 1404
1377 entity = video->oterm; 1405 entity = oterm;
1406 list_add_tail(&entity->chain, &chain->oterms);
1378 uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id); 1407 uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id);
1379 1408
1380 if (UVC_ENTITY_TYPE(entity) == TT_STREAMING)
1381 video->sterm = entity;
1382
1383 id = entity->output.bSourceID; 1409 id = entity->output.bSourceID;
1384 while (id != 0) { 1410 while (id != 0) {
1385 prev = entity; 1411 prev = entity;
1386 entity = uvc_entity_by_id(video->dev, id); 1412 entity = uvc_entity_by_id(chain->dev, id);
1387 if (entity == NULL) { 1413 if (entity == NULL) {
1388 uvc_trace(UVC_TRACE_DESCR, "Found reference to " 1414 uvc_trace(UVC_TRACE_DESCR, "Found reference to "
1389 "unknown entity %d.\n", id); 1415 "unknown entity %d.\n", id);
1390 return -1; 1416 return -EINVAL;
1417 }
1418
1419 if (entity->chain.next || entity->chain.prev) {
1420 uvc_trace(UVC_TRACE_DESCR, "Found reference to "
1421 "entity %d already in chain.\n", id);
1422 return -EINVAL;
1391 } 1423 }
1392 1424
1393 /* Process entity */ 1425 /* Process entity */
1394 if (uvc_scan_chain_entity(video, entity) < 0) 1426 if (uvc_scan_chain_entity(chain, entity) < 0)
1395 return -1; 1427 return -EINVAL;
1396 1428
1397 /* Forward scan */ 1429 /* Forward scan */
1398 if (uvc_scan_chain_forward(video, entity, prev) < 0) 1430 if (uvc_scan_chain_forward(chain, entity, prev) < 0)
1399 return -1; 1431 return -EINVAL;
1400 1432
1401 /* Stop when a terminal is found. */ 1433 /* Stop when a terminal is found. */
1402 if (!UVC_ENTITY_IS_UNIT(entity)) 1434 if (UVC_ENTITY_IS_TERM(entity))
1403 break; 1435 break;
1404 1436
1405 /* Backward scan */ 1437 /* Backward scan */
1406 id = uvc_scan_chain_backward(video, entity); 1438 id = uvc_scan_chain_backward(chain, entity);
1407 if (id < 0) 1439 if (id < 0)
1408 return id; 1440 return id;
1409 } 1441 }
1410 1442
1411 if (video->sterm == NULL) { 1443 return 0;
1412 uvc_trace(UVC_TRACE_DESCR, "No streaming entity found in " 1444}
1413 "chain.\n"); 1445
1414 return -1; 1446static unsigned int uvc_print_terms(struct list_head *terms, char *buffer)
1447{
1448 struct uvc_entity *term;
1449 unsigned int nterms = 0;
1450 char *p = buffer;
1451
1452 list_for_each_entry(term, terms, chain) {
1453 p += sprintf(p, "%u", term->id);
1454 if (term->chain.next != terms) {
1455 p += sprintf(p, ",");
1456 if (++nterms >= 4) {
1457 p += sprintf(p, "...");
1458 break;
1459 }
1460 }
1415 } 1461 }
1416 1462
1417 return 0; 1463 return p - buffer;
1464}
1465
1466static const char *uvc_print_chain(struct uvc_video_chain *chain)
1467{
1468 static char buffer[43];
1469 char *p = buffer;
1470
1471 p += uvc_print_terms(&chain->iterms, p);
1472 p += sprintf(p, " -> ");
1473 uvc_print_terms(&chain->oterms, p);
1474
1475 return buffer;
1418} 1476}
1419 1477
1420/* 1478/*
1421 * Register the video devices. 1479 * Scan the device for video chains and register video devices.
1422 *
1423 * The driver currently supports a single video device per control interface
1424 * only. The terminal and units must match the following structure:
1425 * 1480 *
1426 * ITT_* -> VC_PROCESSING_UNIT -> VC_EXTENSION_UNIT{0,n} -> TT_STREAMING 1481 * Chains are scanned starting at their output terminals and walked backwards.
1427 * TT_STREAMING -> VC_PROCESSING_UNIT -> VC_EXTENSION_UNIT{0,n} -> OTT_*
1428 *
1429 * The Extension Units, if present, must have a single input pin. The
1430 * Processing Unit and Extension Units can be in any order. Additional
1431 * Extension Units connected to the main chain as single-unit branches are
1432 * also supported.
1433 */ 1482 */
1434static int uvc_register_video(struct uvc_device *dev) 1483static int uvc_scan_device(struct uvc_device *dev)
1435{ 1484{
1436 struct video_device *vdev; 1485 struct uvc_video_chain *chain;
1437 struct uvc_entity *term; 1486 struct uvc_entity *term;
1438 int found = 0, ret;
1439 1487
1440 /* Check if the control interface matches the structure we expect. */
1441 list_for_each_entry(term, &dev->entities, list) { 1488 list_for_each_entry(term, &dev->entities, list) {
1442 struct uvc_streaming *streaming; 1489 if (!UVC_ENTITY_IS_OTERM(term))
1443
1444 if (!UVC_ENTITY_IS_TERM(term) || !UVC_ENTITY_IS_OTERM(term))
1445 continue; 1490 continue;
1446 1491
1447 memset(&dev->video, 0, sizeof dev->video); 1492 /* If the terminal is already included in a chain, skip it.
1448 mutex_init(&dev->video.ctrl_mutex); 1493 * This can happen for chains that have multiple output
1449 INIT_LIST_HEAD(&dev->video.iterms); 1494 * terminals, where all output terminals beside the first one
1450 INIT_LIST_HEAD(&dev->video.extensions); 1495 * will be inserted in the chain in forward scans.
1451 dev->video.oterm = term; 1496 */
1452 dev->video.dev = dev; 1497 if (term->chain.next || term->chain.prev)
1453 if (uvc_scan_chain(&dev->video) < 0)
1454 continue; 1498 continue;
1455 1499
1456 list_for_each_entry(streaming, &dev->streaming, list) { 1500 chain = kzalloc(sizeof(*chain), GFP_KERNEL);
1457 if (streaming->header.bTerminalLink == 1501 if (chain == NULL)
1458 dev->video.sterm->id) { 1502 return -ENOMEM;
1459 dev->video.streaming = streaming; 1503
1460 found = 1; 1504 INIT_LIST_HEAD(&chain->iterms);
1461 break; 1505 INIT_LIST_HEAD(&chain->oterms);
1462 } 1506 INIT_LIST_HEAD(&chain->extensions);
1507 mutex_init(&chain->ctrl_mutex);
1508 chain->dev = dev;
1509
1510 if (uvc_scan_chain(chain, term) < 0) {
1511 kfree(chain);
1512 continue;
1463 } 1513 }
1464 1514
1465 if (found) 1515 uvc_trace(UVC_TRACE_PROBE, "Found a valid video chain (%s).\n",
1466 break; 1516 uvc_print_chain(chain));
1517
1518 list_add_tail(&chain->list, &dev->chains);
1467 } 1519 }
1468 1520
1469 if (!found) { 1521 if (list_empty(&dev->chains)) {
1470 uvc_printk(KERN_INFO, "No valid video chain found.\n"); 1522 uvc_printk(KERN_INFO, "No valid video chain found.\n");
1471 return -1; 1523 return -1;
1472 } 1524 }
1473 1525
1474 if (uvc_trace_param & UVC_TRACE_PROBE) { 1526 return 0;
1475 uvc_printk(KERN_INFO, "Found a valid video chain ("); 1527}
1476 list_for_each_entry(term, &dev->video.iterms, chain) { 1528
1477 printk("%d", term->id); 1529/* ------------------------------------------------------------------------
1478 if (term->chain.next != &dev->video.iterms) 1530 * Video device registration and unregistration
1479 printk(","); 1531 */
1480 } 1532
1481 printk(" -> %d).\n", dev->video.oterm->id); 1533/*
1534 * Unregister the video devices.
1535 */
1536static void uvc_unregister_video(struct uvc_device *dev)
1537{
1538 struct uvc_streaming *stream;
1539
1540 list_for_each_entry(stream, &dev->streams, list) {
1541 if (stream->vdev == NULL)
1542 continue;
1543
1544 if (stream->vdev->minor == -1)
1545 video_device_release(stream->vdev);
1546 else
1547 video_unregister_device(stream->vdev);
1548 stream->vdev = NULL;
1482 } 1549 }
1550}
1483 1551
1484 /* Initialize the video buffers queue. */ 1552static int uvc_register_video(struct uvc_device *dev,
1485 uvc_queue_init(&dev->video.queue, dev->video.streaming->type); 1553 struct uvc_streaming *stream)
1554{
1555 struct video_device *vdev;
1556 int ret;
1486 1557
1487 /* Initialize the streaming interface with default streaming 1558 /* Initialize the streaming interface with default streaming
1488 * parameters. 1559 * parameters.
1489 */ 1560 */
1490 if ((ret = uvc_video_init(&dev->video)) < 0) { 1561 ret = uvc_video_init(stream);
1562 if (ret < 0) {
1491 uvc_printk(KERN_ERR, "Failed to initialize the device " 1563 uvc_printk(KERN_ERR, "Failed to initialize the device "
1492 "(%d).\n", ret); 1564 "(%d).\n", ret);
1493 return ret; 1565 return ret;
@@ -1495,8 +1567,11 @@ static int uvc_register_video(struct uvc_device *dev)
1495 1567
1496 /* Register the device with V4L. */ 1568 /* Register the device with V4L. */
1497 vdev = video_device_alloc(); 1569 vdev = video_device_alloc();
1498 if (vdev == NULL) 1570 if (vdev == NULL) {
1499 return -1; 1571 uvc_printk(KERN_ERR, "Failed to allocate video device (%d).\n",
1572 ret);
1573 return -ENOMEM;
1574 }
1500 1575
1501 /* We already hold a reference to dev->udev. The video device will be 1576 /* We already hold a reference to dev->udev. The video device will be
1502 * unregistered before the reference is released, so we don't need to 1577 * unregistered before the reference is released, so we don't need to
@@ -1511,19 +1586,74 @@ static int uvc_register_video(struct uvc_device *dev)
1511 /* Set the driver data before calling video_register_device, otherwise 1586 /* Set the driver data before calling video_register_device, otherwise
1512 * uvc_v4l2_open might race us. 1587 * uvc_v4l2_open might race us.
1513 */ 1588 */
1514 dev->video.vdev = vdev; 1589 stream->vdev = vdev;
1515 video_set_drvdata(vdev, &dev->video); 1590 video_set_drvdata(vdev, stream);
1516 1591
1517 if (video_register_device(vdev, VFL_TYPE_GRABBER, -1) < 0) { 1592 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
1518 dev->video.vdev = NULL; 1593 if (ret < 0) {
1594 uvc_printk(KERN_ERR, "Failed to register video device (%d).\n",
1595 ret);
1596 stream->vdev = NULL;
1519 video_device_release(vdev); 1597 video_device_release(vdev);
1520 return -1; 1598 return ret;
1521 } 1599 }
1522 1600
1523 return 0; 1601 return 0;
1524} 1602}
1525 1603
1526/* 1604/*
1605 * Register all video devices in all chains.
1606 */
1607static int uvc_register_terms(struct uvc_device *dev,
1608 struct uvc_video_chain *chain, struct list_head *terms)
1609{
1610 struct uvc_streaming *stream;
1611 struct uvc_entity *term;
1612 int ret;
1613
1614 list_for_each_entry(term, terms, chain) {
1615 if (UVC_ENTITY_TYPE(term) != UVC_TT_STREAMING)
1616 continue;
1617
1618 stream = uvc_stream_by_id(dev, term->id);
1619 if (stream == NULL) {
1620 uvc_printk(KERN_INFO, "No streaming interface found "
1621 "for terminal %u.", term->id);
1622 continue;
1623 }
1624
1625 stream->chain = chain;
1626 ret = uvc_register_video(dev, stream);
1627 if (ret < 0)
1628 return ret;
1629 }
1630
1631 return 0;
1632}
1633
1634static int uvc_register_chains(struct uvc_device *dev)
1635{
1636 struct uvc_video_chain *chain;
1637 int ret;
1638
1639 list_for_each_entry(chain, &dev->chains, list) {
1640 ret = uvc_register_terms(dev, chain, &chain->iterms);
1641 if (ret < 0)
1642 return ret;
1643
1644 ret = uvc_register_terms(dev, chain, &chain->oterms);
1645 if (ret < 0)
1646 return ret;
1647 }
1648
1649 return 0;
1650}
1651
1652/* ------------------------------------------------------------------------
1653 * USB probe, disconnect, suspend and resume
1654 */
1655
1656/*
1527 * Delete the UVC device. 1657 * Delete the UVC device.
1528 * 1658 *
1529 * Called by the kernel when the last reference to the uvc_device structure 1659 * Called by the kernel when the last reference to the uvc_device structure
@@ -1544,7 +1674,7 @@ void uvc_delete(struct kref *kref)
1544 struct uvc_device *dev = container_of(kref, struct uvc_device, kref); 1674 struct uvc_device *dev = container_of(kref, struct uvc_device, kref);
1545 struct list_head *p, *n; 1675 struct list_head *p, *n;
1546 1676
1547 /* Unregister the video device. */ 1677 /* Unregister the video devices. */
1548 uvc_unregister_video(dev); 1678 uvc_unregister_video(dev);
1549 usb_put_intf(dev->intf); 1679 usb_put_intf(dev->intf);
1550 usb_put_dev(dev->udev); 1680 usb_put_dev(dev->udev);
@@ -1552,13 +1682,19 @@ void uvc_delete(struct kref *kref)
1552 uvc_status_cleanup(dev); 1682 uvc_status_cleanup(dev);
1553 uvc_ctrl_cleanup_device(dev); 1683 uvc_ctrl_cleanup_device(dev);
1554 1684
1685 list_for_each_safe(p, n, &dev->chains) {
1686 struct uvc_video_chain *chain;
1687 chain = list_entry(p, struct uvc_video_chain, list);
1688 kfree(chain);
1689 }
1690
1555 list_for_each_safe(p, n, &dev->entities) { 1691 list_for_each_safe(p, n, &dev->entities) {
1556 struct uvc_entity *entity; 1692 struct uvc_entity *entity;
1557 entity = list_entry(p, struct uvc_entity, list); 1693 entity = list_entry(p, struct uvc_entity, list);
1558 kfree(entity); 1694 kfree(entity);
1559 } 1695 }
1560 1696
1561 list_for_each_safe(p, n, &dev->streaming) { 1697 list_for_each_safe(p, n, &dev->streams) {
1562 struct uvc_streaming *streaming; 1698 struct uvc_streaming *streaming;
1563 streaming = list_entry(p, struct uvc_streaming, list); 1699 streaming = list_entry(p, struct uvc_streaming, list);
1564 usb_driver_release_interface(&uvc_driver.driver, 1700 usb_driver_release_interface(&uvc_driver.driver,
@@ -1592,7 +1728,8 @@ static int uvc_probe(struct usb_interface *intf,
1592 return -ENOMEM; 1728 return -ENOMEM;
1593 1729
1594 INIT_LIST_HEAD(&dev->entities); 1730 INIT_LIST_HEAD(&dev->entities);
1595 INIT_LIST_HEAD(&dev->streaming); 1731 INIT_LIST_HEAD(&dev->chains);
1732 INIT_LIST_HEAD(&dev->streams);
1596 kref_init(&dev->kref); 1733 kref_init(&dev->kref);
1597 atomic_set(&dev->users, 0); 1734 atomic_set(&dev->users, 0);
1598 1735
@@ -1633,8 +1770,12 @@ static int uvc_probe(struct usb_interface *intf,
1633 if (uvc_ctrl_init_device(dev) < 0) 1770 if (uvc_ctrl_init_device(dev) < 0)
1634 goto error; 1771 goto error;
1635 1772
1636 /* Register the video devices. */ 1773 /* Scan the device for video chains. */
1637 if (uvc_register_video(dev) < 0) 1774 if (uvc_scan_device(dev) < 0)
1775 goto error;
1776
1777 /* Register video devices. */
1778 if (uvc_register_chains(dev) < 0)
1638 goto error; 1779 goto error;
1639 1780
1640 /* Save our data pointer in the interface data. */ 1781 /* Save our data pointer in the interface data. */
@@ -1664,7 +1805,8 @@ static void uvc_disconnect(struct usb_interface *intf)
1664 */ 1805 */
1665 usb_set_intfdata(intf, NULL); 1806 usb_set_intfdata(intf, NULL);
1666 1807
1667 if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOSTREAMING) 1808 if (intf->cur_altsetting->desc.bInterfaceSubClass ==
1809 UVC_SC_VIDEOSTREAMING)
1668 return; 1810 return;
1669 1811
1670 /* uvc_v4l2_open() might race uvc_disconnect(). A static driver-wide 1812 /* uvc_v4l2_open() might race uvc_disconnect(). A static driver-wide
@@ -1687,31 +1829,36 @@ static void uvc_disconnect(struct usb_interface *intf)
1687static int uvc_suspend(struct usb_interface *intf, pm_message_t message) 1829static int uvc_suspend(struct usb_interface *intf, pm_message_t message)
1688{ 1830{
1689 struct uvc_device *dev = usb_get_intfdata(intf); 1831 struct uvc_device *dev = usb_get_intfdata(intf);
1832 struct uvc_streaming *stream;
1690 1833
1691 uvc_trace(UVC_TRACE_SUSPEND, "Suspending interface %u\n", 1834 uvc_trace(UVC_TRACE_SUSPEND, "Suspending interface %u\n",
1692 intf->cur_altsetting->desc.bInterfaceNumber); 1835 intf->cur_altsetting->desc.bInterfaceNumber);
1693 1836
1694 /* Controls are cached on the fly so they don't need to be saved. */ 1837 /* Controls are cached on the fly so they don't need to be saved. */
1695 if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOCONTROL) 1838 if (intf->cur_altsetting->desc.bInterfaceSubClass ==
1839 UVC_SC_VIDEOCONTROL)
1696 return uvc_status_suspend(dev); 1840 return uvc_status_suspend(dev);
1697 1841
1698 if (dev->video.streaming->intf != intf) { 1842 list_for_each_entry(stream, &dev->streams, list) {
1699 uvc_trace(UVC_TRACE_SUSPEND, "Suspend: video streaming USB " 1843 if (stream->intf == intf)
1700 "interface mismatch.\n"); 1844 return uvc_video_suspend(stream);
1701 return -EINVAL;
1702 } 1845 }
1703 1846
1704 return uvc_video_suspend(&dev->video); 1847 uvc_trace(UVC_TRACE_SUSPEND, "Suspend: video streaming USB interface "
1848 "mismatch.\n");
1849 return -EINVAL;
1705} 1850}
1706 1851
1707static int __uvc_resume(struct usb_interface *intf, int reset) 1852static int __uvc_resume(struct usb_interface *intf, int reset)
1708{ 1853{
1709 struct uvc_device *dev = usb_get_intfdata(intf); 1854 struct uvc_device *dev = usb_get_intfdata(intf);
1855 struct uvc_streaming *stream;
1710 1856
1711 uvc_trace(UVC_TRACE_SUSPEND, "Resuming interface %u\n", 1857 uvc_trace(UVC_TRACE_SUSPEND, "Resuming interface %u\n",
1712 intf->cur_altsetting->desc.bInterfaceNumber); 1858 intf->cur_altsetting->desc.bInterfaceNumber);
1713 1859
1714 if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOCONTROL) { 1860 if (intf->cur_altsetting->desc.bInterfaceSubClass ==
1861 UVC_SC_VIDEOCONTROL) {
1715 if (reset) { 1862 if (reset) {
1716 int ret = uvc_ctrl_resume_device(dev); 1863 int ret = uvc_ctrl_resume_device(dev);
1717 1864
@@ -1722,13 +1869,14 @@ static int __uvc_resume(struct usb_interface *intf, int reset)
1722 return uvc_status_resume(dev); 1869 return uvc_status_resume(dev);
1723 } 1870 }
1724 1871
1725 if (dev->video.streaming->intf != intf) { 1872 list_for_each_entry(stream, &dev->streams, list) {
1726 uvc_trace(UVC_TRACE_SUSPEND, "Resume: video streaming USB " 1873 if (stream->intf == intf)
1727 "interface mismatch.\n"); 1874 return uvc_video_resume(stream);
1728 return -EINVAL;
1729 } 1875 }
1730 1876
1731 return uvc_video_resume(&dev->video); 1877 uvc_trace(UVC_TRACE_SUSPEND, "Resume: video streaming USB interface "
1878 "mismatch.\n");
1879 return -EINVAL;
1732} 1880}
1733 1881
1734static int uvc_resume(struct usb_interface *intf) 1882static int uvc_resume(struct usb_interface *intf)
@@ -1880,7 +2028,8 @@ static struct usb_device_id uvc_ids[] = {
1880 .bInterfaceClass = USB_CLASS_VIDEO, 2028 .bInterfaceClass = USB_CLASS_VIDEO,
1881 .bInterfaceSubClass = 1, 2029 .bInterfaceSubClass = 1,
1882 .bInterfaceProtocol = 0, 2030 .bInterfaceProtocol = 0,
1883 .driver_info = UVC_QUIRK_PROBE_MINMAX }, 2031 .driver_info = UVC_QUIRK_PROBE_MINMAX
2032 | UVC_QUIRK_PROBE_DEF },
1884 /* Syntek (HP Spartan) */ 2033 /* Syntek (HP Spartan) */
1885 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 2034 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1886 | USB_DEVICE_ID_MATCH_INT_INFO, 2035 | USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1943,7 +2092,8 @@ static struct usb_device_id uvc_ids[] = {
1943 .bInterfaceClass = USB_CLASS_VIDEO, 2092 .bInterfaceClass = USB_CLASS_VIDEO,
1944 .bInterfaceSubClass = 1, 2093 .bInterfaceSubClass = 1,
1945 .bInterfaceProtocol = 0, 2094 .bInterfaceProtocol = 0,
1946 .driver_info = UVC_QUIRK_PROBE_EXTRAFIELDS }, 2095 .driver_info = UVC_QUIRK_PROBE_MINMAX
2096 | UVC_QUIRK_PROBE_EXTRAFIELDS },
1947 /* Ecamm Pico iMage */ 2097 /* Ecamm Pico iMage */
1948 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 2098 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1949 | USB_DEVICE_ID_MATCH_INT_INFO, 2099 | USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/drivers/media/video/uvc/uvc_isight.c b/drivers/media/video/uvc/uvc_isight.c
index 436f462685a0..a9285b570dbe 100644
--- a/drivers/media/video/uvc/uvc_isight.c
+++ b/drivers/media/video/uvc/uvc_isight.c
@@ -99,7 +99,7 @@ static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf,
99 return 0; 99 return 0;
100} 100}
101 101
102void uvc_video_decode_isight(struct urb *urb, struct uvc_video_device *video, 102void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream,
103 struct uvc_buffer *buf) 103 struct uvc_buffer *buf)
104{ 104{
105 int ret, i; 105 int ret, i;
@@ -120,7 +120,7 @@ void uvc_video_decode_isight(struct urb *urb, struct uvc_video_device *video,
120 * processes the data of the first payload of the new frame. 120 * processes the data of the first payload of the new frame.
121 */ 121 */
122 do { 122 do {
123 ret = isight_decode(&video->queue, buf, 123 ret = isight_decode(&stream->queue, buf,
124 urb->transfer_buffer + 124 urb->transfer_buffer +
125 urb->iso_frame_desc[i].offset, 125 urb->iso_frame_desc[i].offset,
126 urb->iso_frame_desc[i].actual_length); 126 urb->iso_frame_desc[i].actual_length);
@@ -130,7 +130,8 @@ void uvc_video_decode_isight(struct urb *urb, struct uvc_video_device *video,
130 130
131 if (buf->state == UVC_BUF_STATE_DONE || 131 if (buf->state == UVC_BUF_STATE_DONE ||
132 buf->state == UVC_BUF_STATE_ERROR) 132 buf->state == UVC_BUF_STATE_ERROR)
133 buf = uvc_queue_next_buffer(&video->queue, buf); 133 buf = uvc_queue_next_buffer(&stream->queue,
134 buf);
134 } while (ret == -EAGAIN); 135 } while (ret == -EAGAIN);
135 } 136 }
136} 137}
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 5e77cad29690..9e7351569b5d 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -40,7 +40,7 @@
40 * table for the controls that can be mapped directly, and handle the others 40 * table for the controls that can be mapped directly, and handle the others
41 * manually. 41 * manually.
42 */ 42 */
43static int uvc_v4l2_query_menu(struct uvc_video_device *video, 43static int uvc_v4l2_query_menu(struct uvc_video_chain *chain,
44 struct v4l2_querymenu *query_menu) 44 struct v4l2_querymenu *query_menu)
45{ 45{
46 struct uvc_menu_info *menu_info; 46 struct uvc_menu_info *menu_info;
@@ -49,7 +49,7 @@ static int uvc_v4l2_query_menu(struct uvc_video_device *video,
49 u32 index = query_menu->index; 49 u32 index = query_menu->index;
50 u32 id = query_menu->id; 50 u32 id = query_menu->id;
51 51
52 ctrl = uvc_find_control(video, query_menu->id, &mapping); 52 ctrl = uvc_find_control(chain, query_menu->id, &mapping);
53 if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) 53 if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU)
54 return -EINVAL; 54 return -EINVAL;
55 55
@@ -103,7 +103,7 @@ static __u32 uvc_try_frame_interval(struct uvc_frame *frame, __u32 interval)
103 return interval; 103 return interval;
104} 104}
105 105
106static int uvc_v4l2_try_format(struct uvc_video_device *video, 106static int uvc_v4l2_try_format(struct uvc_streaming *stream,
107 struct v4l2_format *fmt, struct uvc_streaming_control *probe, 107 struct v4l2_format *fmt, struct uvc_streaming_control *probe,
108 struct uvc_format **uvc_format, struct uvc_frame **uvc_frame) 108 struct uvc_format **uvc_format, struct uvc_frame **uvc_frame)
109{ 109{
@@ -116,7 +116,7 @@ static int uvc_v4l2_try_format(struct uvc_video_device *video,
116 int ret = 0; 116 int ret = 0;
117 __u8 *fcc; 117 __u8 *fcc;
118 118
119 if (fmt->type != video->streaming->type) 119 if (fmt->type != stream->type)
120 return -EINVAL; 120 return -EINVAL;
121 121
122 fcc = (__u8 *)&fmt->fmt.pix.pixelformat; 122 fcc = (__u8 *)&fmt->fmt.pix.pixelformat;
@@ -126,8 +126,8 @@ static int uvc_v4l2_try_format(struct uvc_video_device *video,
126 fmt->fmt.pix.width, fmt->fmt.pix.height); 126 fmt->fmt.pix.width, fmt->fmt.pix.height);
127 127
128 /* Check if the hardware supports the requested format. */ 128 /* Check if the hardware supports the requested format. */
129 for (i = 0; i < video->streaming->nformats; ++i) { 129 for (i = 0; i < stream->nformats; ++i) {
130 format = &video->streaming->format[i]; 130 format = &stream->format[i];
131 if (format->fcc == fmt->fmt.pix.pixelformat) 131 if (format->fcc == fmt->fmt.pix.pixelformat)
132 break; 132 break;
133 } 133 }
@@ -191,12 +191,13 @@ static int uvc_v4l2_try_format(struct uvc_video_device *video,
191 * developers test their webcams with the Linux driver as well as with 191 * developers test their webcams with the Linux driver as well as with
192 * the Windows driver). 192 * the Windows driver).
193 */ 193 */
194 if (video->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS) 194 if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS)
195 probe->dwMaxVideoFrameSize = 195 probe->dwMaxVideoFrameSize =
196 video->streaming->ctrl.dwMaxVideoFrameSize; 196 stream->ctrl.dwMaxVideoFrameSize;
197 197
198 /* Probe the device. */ 198 /* Probe the device. */
199 if ((ret = uvc_probe_video(video, probe)) < 0) 199 ret = uvc_probe_video(stream, probe);
200 if (ret < 0)
200 goto done; 201 goto done;
201 202
202 fmt->fmt.pix.width = frame->wWidth; 203 fmt->fmt.pix.width = frame->wWidth;
@@ -216,13 +217,13 @@ done:
216 return ret; 217 return ret;
217} 218}
218 219
219static int uvc_v4l2_get_format(struct uvc_video_device *video, 220static int uvc_v4l2_get_format(struct uvc_streaming *stream,
220 struct v4l2_format *fmt) 221 struct v4l2_format *fmt)
221{ 222{
222 struct uvc_format *format = video->streaming->cur_format; 223 struct uvc_format *format = stream->cur_format;
223 struct uvc_frame *frame = video->streaming->cur_frame; 224 struct uvc_frame *frame = stream->cur_frame;
224 225
225 if (fmt->type != video->streaming->type) 226 if (fmt->type != stream->type)
226 return -EINVAL; 227 return -EINVAL;
227 228
228 if (format == NULL || frame == NULL) 229 if (format == NULL || frame == NULL)
@@ -233,14 +234,14 @@ static int uvc_v4l2_get_format(struct uvc_video_device *video,
233 fmt->fmt.pix.height = frame->wHeight; 234 fmt->fmt.pix.height = frame->wHeight;
234 fmt->fmt.pix.field = V4L2_FIELD_NONE; 235 fmt->fmt.pix.field = V4L2_FIELD_NONE;
235 fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8; 236 fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8;
236 fmt->fmt.pix.sizeimage = video->streaming->ctrl.dwMaxVideoFrameSize; 237 fmt->fmt.pix.sizeimage = stream->ctrl.dwMaxVideoFrameSize;
237 fmt->fmt.pix.colorspace = format->colorspace; 238 fmt->fmt.pix.colorspace = format->colorspace;
238 fmt->fmt.pix.priv = 0; 239 fmt->fmt.pix.priv = 0;
239 240
240 return 0; 241 return 0;
241} 242}
242 243
243static int uvc_v4l2_set_format(struct uvc_video_device *video, 244static int uvc_v4l2_set_format(struct uvc_streaming *stream,
244 struct v4l2_format *fmt) 245 struct v4l2_format *fmt)
245{ 246{
246 struct uvc_streaming_control probe; 247 struct uvc_streaming_control probe;
@@ -248,39 +249,39 @@ static int uvc_v4l2_set_format(struct uvc_video_device *video,
248 struct uvc_frame *frame; 249 struct uvc_frame *frame;
249 int ret; 250 int ret;
250 251
251 if (fmt->type != video->streaming->type) 252 if (fmt->type != stream->type)
252 return -EINVAL; 253 return -EINVAL;
253 254
254 if (uvc_queue_allocated(&video->queue)) 255 if (uvc_queue_allocated(&stream->queue))
255 return -EBUSY; 256 return -EBUSY;
256 257
257 ret = uvc_v4l2_try_format(video, fmt, &probe, &format, &frame); 258 ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame);
258 if (ret < 0) 259 if (ret < 0)
259 return ret; 260 return ret;
260 261
261 memcpy(&video->streaming->ctrl, &probe, sizeof probe); 262 memcpy(&stream->ctrl, &probe, sizeof probe);
262 video->streaming->cur_format = format; 263 stream->cur_format = format;
263 video->streaming->cur_frame = frame; 264 stream->cur_frame = frame;
264 265
265 return 0; 266 return 0;
266} 267}
267 268
268static int uvc_v4l2_get_streamparm(struct uvc_video_device *video, 269static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
269 struct v4l2_streamparm *parm) 270 struct v4l2_streamparm *parm)
270{ 271{
271 uint32_t numerator, denominator; 272 uint32_t numerator, denominator;
272 273
273 if (parm->type != video->streaming->type) 274 if (parm->type != stream->type)
274 return -EINVAL; 275 return -EINVAL;
275 276
276 numerator = video->streaming->ctrl.dwFrameInterval; 277 numerator = stream->ctrl.dwFrameInterval;
277 denominator = 10000000; 278 denominator = 10000000;
278 uvc_simplify_fraction(&numerator, &denominator, 8, 333); 279 uvc_simplify_fraction(&numerator, &denominator, 8, 333);
279 280
280 memset(parm, 0, sizeof *parm); 281 memset(parm, 0, sizeof *parm);
281 parm->type = video->streaming->type; 282 parm->type = stream->type;
282 283
283 if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 284 if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
284 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; 285 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
285 parm->parm.capture.capturemode = 0; 286 parm->parm.capture.capturemode = 0;
286 parm->parm.capture.timeperframe.numerator = numerator; 287 parm->parm.capture.timeperframe.numerator = numerator;
@@ -297,19 +298,19 @@ static int uvc_v4l2_get_streamparm(struct uvc_video_device *video,
297 return 0; 298 return 0;
298} 299}
299 300
300static int uvc_v4l2_set_streamparm(struct uvc_video_device *video, 301static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
301 struct v4l2_streamparm *parm) 302 struct v4l2_streamparm *parm)
302{ 303{
303 struct uvc_frame *frame = video->streaming->cur_frame; 304 struct uvc_frame *frame = stream->cur_frame;
304 struct uvc_streaming_control probe; 305 struct uvc_streaming_control probe;
305 struct v4l2_fract timeperframe; 306 struct v4l2_fract timeperframe;
306 uint32_t interval; 307 uint32_t interval;
307 int ret; 308 int ret;
308 309
309 if (parm->type != video->streaming->type) 310 if (parm->type != stream->type)
310 return -EINVAL; 311 return -EINVAL;
311 312
312 if (uvc_queue_streaming(&video->queue)) 313 if (uvc_queue_streaming(&stream->queue))
313 return -EBUSY; 314 return -EBUSY;
314 315
315 if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 316 if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -317,7 +318,7 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video,
317 else 318 else
318 timeperframe = parm->parm.output.timeperframe; 319 timeperframe = parm->parm.output.timeperframe;
319 320
320 memcpy(&probe, &video->streaming->ctrl, sizeof probe); 321 memcpy(&probe, &stream->ctrl, sizeof probe);
321 interval = uvc_fraction_to_interval(timeperframe.numerator, 322 interval = uvc_fraction_to_interval(timeperframe.numerator,
322 timeperframe.denominator); 323 timeperframe.denominator);
323 324
@@ -326,10 +327,11 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video,
326 probe.dwFrameInterval = uvc_try_frame_interval(frame, interval); 327 probe.dwFrameInterval = uvc_try_frame_interval(frame, interval);
327 328
328 /* Probe the device with the new settings. */ 329 /* Probe the device with the new settings. */
329 if ((ret = uvc_probe_video(video, &probe)) < 0) 330 ret = uvc_probe_video(stream, &probe);
331 if (ret < 0)
330 return ret; 332 return ret;
331 333
332 memcpy(&video->streaming->ctrl, &probe, sizeof probe); 334 memcpy(&stream->ctrl, &probe, sizeof probe);
333 335
334 /* Return the actual frame period. */ 336 /* Return the actual frame period. */
335 timeperframe.numerator = probe.dwFrameInterval; 337 timeperframe.numerator = probe.dwFrameInterval;
@@ -382,8 +384,8 @@ static int uvc_acquire_privileges(struct uvc_fh *handle)
382 384
383 /* Check if the device already has a privileged handle. */ 385 /* Check if the device already has a privileged handle. */
384 mutex_lock(&uvc_driver.open_mutex); 386 mutex_lock(&uvc_driver.open_mutex);
385 if (atomic_inc_return(&handle->device->active) != 1) { 387 if (atomic_inc_return(&handle->stream->active) != 1) {
386 atomic_dec(&handle->device->active); 388 atomic_dec(&handle->stream->active);
387 ret = -EBUSY; 389 ret = -EBUSY;
388 goto done; 390 goto done;
389 } 391 }
@@ -398,7 +400,7 @@ done:
398static void uvc_dismiss_privileges(struct uvc_fh *handle) 400static void uvc_dismiss_privileges(struct uvc_fh *handle)
399{ 401{
400 if (handle->state == UVC_HANDLE_ACTIVE) 402 if (handle->state == UVC_HANDLE_ACTIVE)
401 atomic_dec(&handle->device->active); 403 atomic_dec(&handle->stream->active);
402 404
403 handle->state = UVC_HANDLE_PASSIVE; 405 handle->state = UVC_HANDLE_PASSIVE;
404} 406}
@@ -414,45 +416,47 @@ static int uvc_has_privileges(struct uvc_fh *handle)
414 416
415static int uvc_v4l2_open(struct file *file) 417static int uvc_v4l2_open(struct file *file)
416{ 418{
417 struct uvc_video_device *video; 419 struct uvc_streaming *stream;
418 struct uvc_fh *handle; 420 struct uvc_fh *handle;
419 int ret = 0; 421 int ret = 0;
420 422
421 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n"); 423 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n");
422 mutex_lock(&uvc_driver.open_mutex); 424 mutex_lock(&uvc_driver.open_mutex);
423 video = video_drvdata(file); 425 stream = video_drvdata(file);
424 426
425 if (video->dev->state & UVC_DEV_DISCONNECTED) { 427 if (stream->dev->state & UVC_DEV_DISCONNECTED) {
426 ret = -ENODEV; 428 ret = -ENODEV;
427 goto done; 429 goto done;
428 } 430 }
429 431
430 ret = usb_autopm_get_interface(video->dev->intf); 432 ret = usb_autopm_get_interface(stream->dev->intf);
431 if (ret < 0) 433 if (ret < 0)
432 goto done; 434 goto done;
433 435
434 /* Create the device handle. */ 436 /* Create the device handle. */
435 handle = kzalloc(sizeof *handle, GFP_KERNEL); 437 handle = kzalloc(sizeof *handle, GFP_KERNEL);
436 if (handle == NULL) { 438 if (handle == NULL) {
437 usb_autopm_put_interface(video->dev->intf); 439 usb_autopm_put_interface(stream->dev->intf);
438 ret = -ENOMEM; 440 ret = -ENOMEM;
439 goto done; 441 goto done;
440 } 442 }
441 443
442 if (atomic_inc_return(&video->dev->users) == 1) { 444 if (atomic_inc_return(&stream->dev->users) == 1) {
443 if ((ret = uvc_status_start(video->dev)) < 0) { 445 ret = uvc_status_start(stream->dev);
444 usb_autopm_put_interface(video->dev->intf); 446 if (ret < 0) {
445 atomic_dec(&video->dev->users); 447 usb_autopm_put_interface(stream->dev->intf);
448 atomic_dec(&stream->dev->users);
446 kfree(handle); 449 kfree(handle);
447 goto done; 450 goto done;
448 } 451 }
449 } 452 }
450 453
451 handle->device = video; 454 handle->chain = stream->chain;
455 handle->stream = stream;
452 handle->state = UVC_HANDLE_PASSIVE; 456 handle->state = UVC_HANDLE_PASSIVE;
453 file->private_data = handle; 457 file->private_data = handle;
454 458
455 kref_get(&video->dev->kref); 459 kref_get(&stream->dev->kref);
456 460
457done: 461done:
458 mutex_unlock(&uvc_driver.open_mutex); 462 mutex_unlock(&uvc_driver.open_mutex);
@@ -461,20 +465,20 @@ done:
461 465
462static int uvc_v4l2_release(struct file *file) 466static int uvc_v4l2_release(struct file *file)
463{ 467{
464 struct uvc_video_device *video = video_drvdata(file);
465 struct uvc_fh *handle = (struct uvc_fh *)file->private_data; 468 struct uvc_fh *handle = (struct uvc_fh *)file->private_data;
469 struct uvc_streaming *stream = handle->stream;
466 470
467 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_release\n"); 471 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_release\n");
468 472
469 /* Only free resources if this is a privileged handle. */ 473 /* Only free resources if this is a privileged handle. */
470 if (uvc_has_privileges(handle)) { 474 if (uvc_has_privileges(handle)) {
471 uvc_video_enable(video, 0); 475 uvc_video_enable(stream, 0);
472 476
473 mutex_lock(&video->queue.mutex); 477 mutex_lock(&stream->queue.mutex);
474 if (uvc_free_buffers(&video->queue) < 0) 478 if (uvc_free_buffers(&stream->queue) < 0)
475 uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to " 479 uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to "
476 "free buffers.\n"); 480 "free buffers.\n");
477 mutex_unlock(&video->queue.mutex); 481 mutex_unlock(&stream->queue.mutex);
478 } 482 }
479 483
480 /* Release the file handle. */ 484 /* Release the file handle. */
@@ -482,19 +486,20 @@ static int uvc_v4l2_release(struct file *file)
482 kfree(handle); 486 kfree(handle);
483 file->private_data = NULL; 487 file->private_data = NULL;
484 488
485 if (atomic_dec_return(&video->dev->users) == 0) 489 if (atomic_dec_return(&stream->dev->users) == 0)
486 uvc_status_stop(video->dev); 490 uvc_status_stop(stream->dev);
487 491
488 usb_autopm_put_interface(video->dev->intf); 492 usb_autopm_put_interface(stream->dev->intf);
489 kref_put(&video->dev->kref, uvc_delete); 493 kref_put(&stream->dev->kref, uvc_delete);
490 return 0; 494 return 0;
491} 495}
492 496
493static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) 497static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
494{ 498{
495 struct video_device *vdev = video_devdata(file); 499 struct video_device *vdev = video_devdata(file);
496 struct uvc_video_device *video = video_get_drvdata(vdev);
497 struct uvc_fh *handle = (struct uvc_fh *)file->private_data; 500 struct uvc_fh *handle = (struct uvc_fh *)file->private_data;
501 struct uvc_video_chain *chain = handle->chain;
502 struct uvc_streaming *stream = handle->stream;
498 long ret = 0; 503 long ret = 0;
499 504
500 switch (cmd) { 505 switch (cmd) {
@@ -506,10 +511,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
506 memset(cap, 0, sizeof *cap); 511 memset(cap, 0, sizeof *cap);
507 strlcpy(cap->driver, "uvcvideo", sizeof cap->driver); 512 strlcpy(cap->driver, "uvcvideo", sizeof cap->driver);
508 strlcpy(cap->card, vdev->name, sizeof cap->card); 513 strlcpy(cap->card, vdev->name, sizeof cap->card);
509 usb_make_path(video->dev->udev, 514 usb_make_path(stream->dev->udev,
510 cap->bus_info, sizeof(cap->bus_info)); 515 cap->bus_info, sizeof(cap->bus_info));
511 cap->version = DRIVER_VERSION_NUMBER; 516 cap->version = DRIVER_VERSION_NUMBER;
512 if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 517 if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
513 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE 518 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
514 | V4L2_CAP_STREAMING; 519 | V4L2_CAP_STREAMING;
515 else 520 else
@@ -520,7 +525,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
520 525
521 /* Get, Set & Query control */ 526 /* Get, Set & Query control */
522 case VIDIOC_QUERYCTRL: 527 case VIDIOC_QUERYCTRL:
523 return uvc_query_v4l2_ctrl(video, arg); 528 return uvc_query_v4l2_ctrl(chain, arg);
524 529
525 case VIDIOC_G_CTRL: 530 case VIDIOC_G_CTRL:
526 { 531 {
@@ -530,12 +535,12 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
530 memset(&xctrl, 0, sizeof xctrl); 535 memset(&xctrl, 0, sizeof xctrl);
531 xctrl.id = ctrl->id; 536 xctrl.id = ctrl->id;
532 537
533 ret = uvc_ctrl_begin(video); 538 ret = uvc_ctrl_begin(chain);
534 if (ret < 0) 539 if (ret < 0)
535 return ret; 540 return ret;
536 541
537 ret = uvc_ctrl_get(video, &xctrl); 542 ret = uvc_ctrl_get(chain, &xctrl);
538 uvc_ctrl_rollback(video); 543 uvc_ctrl_rollback(chain);
539 if (ret >= 0) 544 if (ret >= 0)
540 ctrl->value = xctrl.value; 545 ctrl->value = xctrl.value;
541 break; 546 break;
@@ -550,21 +555,21 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
550 xctrl.id = ctrl->id; 555 xctrl.id = ctrl->id;
551 xctrl.value = ctrl->value; 556 xctrl.value = ctrl->value;
552 557
553 ret = uvc_ctrl_begin(video); 558 uvc_ctrl_begin(chain);
554 if (ret < 0) 559 if (ret < 0)
555 return ret; 560 return ret;
556 561
557 ret = uvc_ctrl_set(video, &xctrl); 562 ret = uvc_ctrl_set(chain, &xctrl);
558 if (ret < 0) { 563 if (ret < 0) {
559 uvc_ctrl_rollback(video); 564 uvc_ctrl_rollback(chain);
560 return ret; 565 return ret;
561 } 566 }
562 ret = uvc_ctrl_commit(video); 567 ret = uvc_ctrl_commit(chain);
563 break; 568 break;
564 } 569 }
565 570
566 case VIDIOC_QUERYMENU: 571 case VIDIOC_QUERYMENU:
567 return uvc_v4l2_query_menu(video, arg); 572 return uvc_v4l2_query_menu(chain, arg);
568 573
569 case VIDIOC_G_EXT_CTRLS: 574 case VIDIOC_G_EXT_CTRLS:
570 { 575 {
@@ -572,20 +577,20 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
572 struct v4l2_ext_control *ctrl = ctrls->controls; 577 struct v4l2_ext_control *ctrl = ctrls->controls;
573 unsigned int i; 578 unsigned int i;
574 579
575 ret = uvc_ctrl_begin(video); 580 ret = uvc_ctrl_begin(chain);
576 if (ret < 0) 581 if (ret < 0)
577 return ret; 582 return ret;
578 583
579 for (i = 0; i < ctrls->count; ++ctrl, ++i) { 584 for (i = 0; i < ctrls->count; ++ctrl, ++i) {
580 ret = uvc_ctrl_get(video, ctrl); 585 ret = uvc_ctrl_get(chain, ctrl);
581 if (ret < 0) { 586 if (ret < 0) {
582 uvc_ctrl_rollback(video); 587 uvc_ctrl_rollback(chain);
583 ctrls->error_idx = i; 588 ctrls->error_idx = i;
584 return ret; 589 return ret;
585 } 590 }
586 } 591 }
587 ctrls->error_idx = 0; 592 ctrls->error_idx = 0;
588 ret = uvc_ctrl_rollback(video); 593 ret = uvc_ctrl_rollback(chain);
589 break; 594 break;
590 } 595 }
591 596
@@ -596,14 +601,14 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
596 struct v4l2_ext_control *ctrl = ctrls->controls; 601 struct v4l2_ext_control *ctrl = ctrls->controls;
597 unsigned int i; 602 unsigned int i;
598 603
599 ret = uvc_ctrl_begin(video); 604 ret = uvc_ctrl_begin(chain);
600 if (ret < 0) 605 if (ret < 0)
601 return ret; 606 return ret;
602 607
603 for (i = 0; i < ctrls->count; ++ctrl, ++i) { 608 for (i = 0; i < ctrls->count; ++ctrl, ++i) {
604 ret = uvc_ctrl_set(video, ctrl); 609 ret = uvc_ctrl_set(chain, ctrl);
605 if (ret < 0) { 610 if (ret < 0) {
606 uvc_ctrl_rollback(video); 611 uvc_ctrl_rollback(chain);
607 ctrls->error_idx = i; 612 ctrls->error_idx = i;
608 return ret; 613 return ret;
609 } 614 }
@@ -612,31 +617,31 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
612 ctrls->error_idx = 0; 617 ctrls->error_idx = 0;
613 618
614 if (cmd == VIDIOC_S_EXT_CTRLS) 619 if (cmd == VIDIOC_S_EXT_CTRLS)
615 ret = uvc_ctrl_commit(video); 620 ret = uvc_ctrl_commit(chain);
616 else 621 else
617 ret = uvc_ctrl_rollback(video); 622 ret = uvc_ctrl_rollback(chain);
618 break; 623 break;
619 } 624 }
620 625
621 /* Get, Set & Enum input */ 626 /* Get, Set & Enum input */
622 case VIDIOC_ENUMINPUT: 627 case VIDIOC_ENUMINPUT:
623 { 628 {
624 const struct uvc_entity *selector = video->selector; 629 const struct uvc_entity *selector = chain->selector;
625 struct v4l2_input *input = arg; 630 struct v4l2_input *input = arg;
626 struct uvc_entity *iterm = NULL; 631 struct uvc_entity *iterm = NULL;
627 u32 index = input->index; 632 u32 index = input->index;
628 int pin = 0; 633 int pin = 0;
629 634
630 if (selector == NULL || 635 if (selector == NULL ||
631 (video->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { 636 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
632 if (index != 0) 637 if (index != 0)
633 return -EINVAL; 638 return -EINVAL;
634 iterm = list_first_entry(&video->iterms, 639 iterm = list_first_entry(&chain->iterms,
635 struct uvc_entity, chain); 640 struct uvc_entity, chain);
636 pin = iterm->id; 641 pin = iterm->id;
637 } else if (pin < selector->selector.bNrInPins) { 642 } else if (pin < selector->selector.bNrInPins) {
638 pin = selector->selector.baSourceID[index]; 643 pin = selector->selector.baSourceID[index];
639 list_for_each_entry(iterm, video->iterms.next, chain) { 644 list_for_each_entry(iterm, chain->iterms.next, chain) {
640 if (iterm->id == pin) 645 if (iterm->id == pin)
641 break; 646 break;
642 } 647 }
@@ -648,7 +653,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
648 memset(input, 0, sizeof *input); 653 memset(input, 0, sizeof *input);
649 input->index = index; 654 input->index = index;
650 strlcpy(input->name, iterm->name, sizeof input->name); 655 strlcpy(input->name, iterm->name, sizeof input->name);
651 if (UVC_ENTITY_TYPE(iterm) == ITT_CAMERA) 656 if (UVC_ENTITY_TYPE(iterm) == UVC_ITT_CAMERA)
652 input->type = V4L2_INPUT_TYPE_CAMERA; 657 input->type = V4L2_INPUT_TYPE_CAMERA;
653 break; 658 break;
654 } 659 }
@@ -657,15 +662,15 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
657 { 662 {
658 u8 input; 663 u8 input;
659 664
660 if (video->selector == NULL || 665 if (chain->selector == NULL ||
661 (video->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { 666 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
662 *(int *)arg = 0; 667 *(int *)arg = 0;
663 break; 668 break;
664 } 669 }
665 670
666 ret = uvc_query_ctrl(video->dev, GET_CUR, video->selector->id, 671 ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
667 video->dev->intfnum, SU_INPUT_SELECT_CONTROL, 672 chain->selector->id, chain->dev->intfnum,
668 &input, 1); 673 UVC_SU_INPUT_SELECT_CONTROL, &input, 1);
669 if (ret < 0) 674 if (ret < 0)
670 return ret; 675 return ret;
671 676
@@ -680,19 +685,19 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
680 if ((ret = uvc_acquire_privileges(handle)) < 0) 685 if ((ret = uvc_acquire_privileges(handle)) < 0)
681 return ret; 686 return ret;
682 687
683 if (video->selector == NULL || 688 if (chain->selector == NULL ||
684 (video->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { 689 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
685 if (input != 1) 690 if (input != 1)
686 return -EINVAL; 691 return -EINVAL;
687 break; 692 break;
688 } 693 }
689 694
690 if (input == 0 || input > video->selector->selector.bNrInPins) 695 if (input == 0 || input > chain->selector->selector.bNrInPins)
691 return -EINVAL; 696 return -EINVAL;
692 697
693 return uvc_query_ctrl(video->dev, SET_CUR, video->selector->id, 698 return uvc_query_ctrl(chain->dev, UVC_SET_CUR,
694 video->dev->intfnum, SU_INPUT_SELECT_CONTROL, 699 chain->selector->id, chain->dev->intfnum,
695 &input, 1); 700 UVC_SU_INPUT_SELECT_CONTROL, &input, 1);
696 } 701 }
697 702
698 /* Try, Get, Set & Enum format */ 703 /* Try, Get, Set & Enum format */
@@ -703,15 +708,15 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
703 enum v4l2_buf_type type = fmt->type; 708 enum v4l2_buf_type type = fmt->type;
704 __u32 index = fmt->index; 709 __u32 index = fmt->index;
705 710
706 if (fmt->type != video->streaming->type || 711 if (fmt->type != stream->type ||
707 fmt->index >= video->streaming->nformats) 712 fmt->index >= stream->nformats)
708 return -EINVAL; 713 return -EINVAL;
709 714
710 memset(fmt, 0, sizeof(*fmt)); 715 memset(fmt, 0, sizeof(*fmt));
711 fmt->index = index; 716 fmt->index = index;
712 fmt->type = type; 717 fmt->type = type;
713 718
714 format = &video->streaming->format[fmt->index]; 719 format = &stream->format[fmt->index];
715 fmt->flags = 0; 720 fmt->flags = 0;
716 if (format->flags & UVC_FMT_FLAG_COMPRESSED) 721 if (format->flags & UVC_FMT_FLAG_COMPRESSED)
717 fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; 722 fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
@@ -729,17 +734,17 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
729 if ((ret = uvc_acquire_privileges(handle)) < 0) 734 if ((ret = uvc_acquire_privileges(handle)) < 0)
730 return ret; 735 return ret;
731 736
732 return uvc_v4l2_try_format(video, arg, &probe, NULL, NULL); 737 return uvc_v4l2_try_format(stream, arg, &probe, NULL, NULL);
733 } 738 }
734 739
735 case VIDIOC_S_FMT: 740 case VIDIOC_S_FMT:
736 if ((ret = uvc_acquire_privileges(handle)) < 0) 741 if ((ret = uvc_acquire_privileges(handle)) < 0)
737 return ret; 742 return ret;
738 743
739 return uvc_v4l2_set_format(video, arg); 744 return uvc_v4l2_set_format(stream, arg);
740 745
741 case VIDIOC_G_FMT: 746 case VIDIOC_G_FMT:
742 return uvc_v4l2_get_format(video, arg); 747 return uvc_v4l2_get_format(stream, arg);
743 748
744 /* Frame size enumeration */ 749 /* Frame size enumeration */
745 case VIDIOC_ENUM_FRAMESIZES: 750 case VIDIOC_ENUM_FRAMESIZES:
@@ -750,10 +755,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
750 int i; 755 int i;
751 756
752 /* Look for the given pixel format */ 757 /* Look for the given pixel format */
753 for (i = 0; i < video->streaming->nformats; i++) { 758 for (i = 0; i < stream->nformats; i++) {
754 if (video->streaming->format[i].fcc == 759 if (stream->format[i].fcc ==
755 fsize->pixel_format) { 760 fsize->pixel_format) {
756 format = &video->streaming->format[i]; 761 format = &stream->format[i];
757 break; 762 break;
758 } 763 }
759 } 764 }
@@ -779,10 +784,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
779 int i; 784 int i;
780 785
781 /* Look for the given pixel format and frame size */ 786 /* Look for the given pixel format and frame size */
782 for (i = 0; i < video->streaming->nformats; i++) { 787 for (i = 0; i < stream->nformats; i++) {
783 if (video->streaming->format[i].fcc == 788 if (stream->format[i].fcc ==
784 fival->pixel_format) { 789 fival->pixel_format) {
785 format = &video->streaming->format[i]; 790 format = &stream->format[i];
786 break; 791 break;
787 } 792 }
788 } 793 }
@@ -832,21 +837,21 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
832 837
833 /* Get & Set streaming parameters */ 838 /* Get & Set streaming parameters */
834 case VIDIOC_G_PARM: 839 case VIDIOC_G_PARM:
835 return uvc_v4l2_get_streamparm(video, arg); 840 return uvc_v4l2_get_streamparm(stream, arg);
836 841
837 case VIDIOC_S_PARM: 842 case VIDIOC_S_PARM:
838 if ((ret = uvc_acquire_privileges(handle)) < 0) 843 if ((ret = uvc_acquire_privileges(handle)) < 0)
839 return ret; 844 return ret;
840 845
841 return uvc_v4l2_set_streamparm(video, arg); 846 return uvc_v4l2_set_streamparm(stream, arg);
842 847
843 /* Cropping and scaling */ 848 /* Cropping and scaling */
844 case VIDIOC_CROPCAP: 849 case VIDIOC_CROPCAP:
845 { 850 {
846 struct v4l2_cropcap *ccap = arg; 851 struct v4l2_cropcap *ccap = arg;
847 struct uvc_frame *frame = video->streaming->cur_frame; 852 struct uvc_frame *frame = stream->cur_frame;
848 853
849 if (ccap->type != video->streaming->type) 854 if (ccap->type != stream->type)
850 return -EINVAL; 855 return -EINVAL;
851 856
852 ccap->bounds.left = 0; 857 ccap->bounds.left = 0;
@@ -870,16 +875,16 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
870 { 875 {
871 struct v4l2_requestbuffers *rb = arg; 876 struct v4l2_requestbuffers *rb = arg;
872 unsigned int bufsize = 877 unsigned int bufsize =
873 video->streaming->ctrl.dwMaxVideoFrameSize; 878 stream->ctrl.dwMaxVideoFrameSize;
874 879
875 if (rb->type != video->streaming->type || 880 if (rb->type != stream->type ||
876 rb->memory != V4L2_MEMORY_MMAP) 881 rb->memory != V4L2_MEMORY_MMAP)
877 return -EINVAL; 882 return -EINVAL;
878 883
879 if ((ret = uvc_acquire_privileges(handle)) < 0) 884 if ((ret = uvc_acquire_privileges(handle)) < 0)
880 return ret; 885 return ret;
881 886
882 ret = uvc_alloc_buffers(&video->queue, rb->count, bufsize); 887 ret = uvc_alloc_buffers(&stream->queue, rb->count, bufsize);
883 if (ret < 0) 888 if (ret < 0)
884 return ret; 889 return ret;
885 890
@@ -892,39 +897,40 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
892 { 897 {
893 struct v4l2_buffer *buf = arg; 898 struct v4l2_buffer *buf = arg;
894 899
895 if (buf->type != video->streaming->type) 900 if (buf->type != stream->type)
896 return -EINVAL; 901 return -EINVAL;
897 902
898 if (!uvc_has_privileges(handle)) 903 if (!uvc_has_privileges(handle))
899 return -EBUSY; 904 return -EBUSY;
900 905
901 return uvc_query_buffer(&video->queue, buf); 906 return uvc_query_buffer(&stream->queue, buf);
902 } 907 }
903 908
904 case VIDIOC_QBUF: 909 case VIDIOC_QBUF:
905 if (!uvc_has_privileges(handle)) 910 if (!uvc_has_privileges(handle))
906 return -EBUSY; 911 return -EBUSY;
907 912
908 return uvc_queue_buffer(&video->queue, arg); 913 return uvc_queue_buffer(&stream->queue, arg);
909 914
910 case VIDIOC_DQBUF: 915 case VIDIOC_DQBUF:
911 if (!uvc_has_privileges(handle)) 916 if (!uvc_has_privileges(handle))
912 return -EBUSY; 917 return -EBUSY;
913 918
914 return uvc_dequeue_buffer(&video->queue, arg, 919 return uvc_dequeue_buffer(&stream->queue, arg,
915 file->f_flags & O_NONBLOCK); 920 file->f_flags & O_NONBLOCK);
916 921
917 case VIDIOC_STREAMON: 922 case VIDIOC_STREAMON:
918 { 923 {
919 int *type = arg; 924 int *type = arg;
920 925
921 if (*type != video->streaming->type) 926 if (*type != stream->type)
922 return -EINVAL; 927 return -EINVAL;
923 928
924 if (!uvc_has_privileges(handle)) 929 if (!uvc_has_privileges(handle))
925 return -EBUSY; 930 return -EBUSY;
926 931
927 if ((ret = uvc_video_enable(video, 1)) < 0) 932 ret = uvc_video_enable(stream, 1);
933 if (ret < 0)
928 return ret; 934 return ret;
929 break; 935 break;
930 } 936 }
@@ -933,13 +939,13 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
933 { 939 {
934 int *type = arg; 940 int *type = arg;
935 941
936 if (*type != video->streaming->type) 942 if (*type != stream->type)
937 return -EINVAL; 943 return -EINVAL;
938 944
939 if (!uvc_has_privileges(handle)) 945 if (!uvc_has_privileges(handle))
940 return -EBUSY; 946 return -EBUSY;
941 947
942 return uvc_video_enable(video, 0); 948 return uvc_video_enable(stream, 0);
943 } 949 }
944 950
945 /* Analog video standards make no sense for digital cameras. */ 951 /* Analog video standards make no sense for digital cameras. */
@@ -1013,10 +1019,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1013 } 1019 }
1014 1020
1015 case UVCIOC_CTRL_GET: 1021 case UVCIOC_CTRL_GET:
1016 return uvc_xu_ctrl_query(video, arg, 0); 1022 return uvc_xu_ctrl_query(chain, arg, 0);
1017 1023
1018 case UVCIOC_CTRL_SET: 1024 case UVCIOC_CTRL_SET:
1019 return uvc_xu_ctrl_query(video, arg, 1); 1025 return uvc_xu_ctrl_query(chain, arg, 1);
1020 1026
1021 default: 1027 default:
1022 if ((ret = v4l_compat_translate_ioctl(file, cmd, arg, 1028 if ((ret = v4l_compat_translate_ioctl(file, cmd, arg,
@@ -1070,7 +1076,9 @@ static struct vm_operations_struct uvc_vm_ops = {
1070 1076
1071static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) 1077static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
1072{ 1078{
1073 struct uvc_video_device *video = video_drvdata(file); 1079 struct uvc_fh *handle = (struct uvc_fh *)file->private_data;
1080 struct uvc_streaming *stream = handle->stream;
1081 struct uvc_video_queue *queue = &stream->queue;
1074 struct uvc_buffer *uninitialized_var(buffer); 1082 struct uvc_buffer *uninitialized_var(buffer);
1075 struct page *page; 1083 struct page *page;
1076 unsigned long addr, start, size; 1084 unsigned long addr, start, size;
@@ -1082,15 +1090,15 @@ static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
1082 start = vma->vm_start; 1090 start = vma->vm_start;
1083 size = vma->vm_end - vma->vm_start; 1091 size = vma->vm_end - vma->vm_start;
1084 1092
1085 mutex_lock(&video->queue.mutex); 1093 mutex_lock(&queue->mutex);
1086 1094
1087 for (i = 0; i < video->queue.count; ++i) { 1095 for (i = 0; i < queue->count; ++i) {
1088 buffer = &video->queue.buffer[i]; 1096 buffer = &queue->buffer[i];
1089 if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff) 1097 if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
1090 break; 1098 break;
1091 } 1099 }
1092 1100
1093 if (i == video->queue.count || size != video->queue.buf_size) { 1101 if (i == queue->count || size != queue->buf_size) {
1094 ret = -EINVAL; 1102 ret = -EINVAL;
1095 goto done; 1103 goto done;
1096 } 1104 }
@@ -1101,7 +1109,7 @@ static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
1101 */ 1109 */
1102 vma->vm_flags |= VM_IO; 1110 vma->vm_flags |= VM_IO;
1103 1111
1104 addr = (unsigned long)video->queue.mem + buffer->buf.m.offset; 1112 addr = (unsigned long)queue->mem + buffer->buf.m.offset;
1105 while (size > 0) { 1113 while (size > 0) {
1106 page = vmalloc_to_page((void *)addr); 1114 page = vmalloc_to_page((void *)addr);
1107 if ((ret = vm_insert_page(vma, start, page)) < 0) 1115 if ((ret = vm_insert_page(vma, start, page)) < 0)
@@ -1117,17 +1125,18 @@ static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
1117 uvc_vm_open(vma); 1125 uvc_vm_open(vma);
1118 1126
1119done: 1127done:
1120 mutex_unlock(&video->queue.mutex); 1128 mutex_unlock(&queue->mutex);
1121 return ret; 1129 return ret;
1122} 1130}
1123 1131
1124static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait) 1132static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait)
1125{ 1133{
1126 struct uvc_video_device *video = video_drvdata(file); 1134 struct uvc_fh *handle = (struct uvc_fh *)file->private_data;
1135 struct uvc_streaming *stream = handle->stream;
1127 1136
1128 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_poll\n"); 1137 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_poll\n");
1129 1138
1130 return uvc_queue_poll(&video->queue, file, wait); 1139 return uvc_queue_poll(&stream->queue, file, wait);
1131} 1140}
1132 1141
1133const struct v4l2_file_operations uvc_fops = { 1142const struct v4l2_file_operations uvc_fops = {
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 01b633c73480..5b757f32d997 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -61,7 +61,7 @@ int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
61 return 0; 61 return 0;
62} 62}
63 63
64static void uvc_fixup_video_ctrl(struct uvc_video_device *video, 64static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
65 struct uvc_streaming_control *ctrl) 65 struct uvc_streaming_control *ctrl)
66{ 66{
67 struct uvc_format *format; 67 struct uvc_format *format;
@@ -69,10 +69,10 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video,
69 unsigned int i; 69 unsigned int i;
70 70
71 if (ctrl->bFormatIndex <= 0 || 71 if (ctrl->bFormatIndex <= 0 ||
72 ctrl->bFormatIndex > video->streaming->nformats) 72 ctrl->bFormatIndex > stream->nformats)
73 return; 73 return;
74 74
75 format = &video->streaming->format[ctrl->bFormatIndex - 1]; 75 format = &stream->format[ctrl->bFormatIndex - 1];
76 76
77 for (i = 0; i < format->nframes; ++i) { 77 for (i = 0; i < format->nframes; ++i) {
78 if (format->frame[i].bFrameIndex == ctrl->bFrameIndex) { 78 if (format->frame[i].bFrameIndex == ctrl->bFrameIndex) {
@@ -86,12 +86,12 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video,
86 86
87 if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) || 87 if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) ||
88 (ctrl->dwMaxVideoFrameSize == 0 && 88 (ctrl->dwMaxVideoFrameSize == 0 &&
89 video->dev->uvc_version < 0x0110)) 89 stream->dev->uvc_version < 0x0110))
90 ctrl->dwMaxVideoFrameSize = 90 ctrl->dwMaxVideoFrameSize =
91 frame->dwMaxVideoFrameBufferSize; 91 frame->dwMaxVideoFrameBufferSize;
92 92
93 if (video->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH && 93 if (stream->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH &&
94 video->streaming->intf->num_altsetting > 1) { 94 stream->intf->num_altsetting > 1) {
95 u32 interval; 95 u32 interval;
96 u32 bandwidth; 96 u32 bandwidth;
97 97
@@ -108,7 +108,7 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video,
108 bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp; 108 bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp;
109 bandwidth *= 10000000 / interval + 1; 109 bandwidth *= 10000000 / interval + 1;
110 bandwidth /= 1000; 110 bandwidth /= 1000;
111 if (video->dev->udev->speed == USB_SPEED_HIGH) 111 if (stream->dev->udev->speed == USB_SPEED_HIGH)
112 bandwidth /= 8; 112 bandwidth /= 8;
113 bandwidth += 12; 113 bandwidth += 12;
114 114
@@ -116,40 +116,43 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video,
116 } 116 }
117} 117}
118 118
119static int uvc_get_video_ctrl(struct uvc_video_device *video, 119static int uvc_get_video_ctrl(struct uvc_streaming *stream,
120 struct uvc_streaming_control *ctrl, int probe, __u8 query) 120 struct uvc_streaming_control *ctrl, int probe, __u8 query)
121{ 121{
122 __u8 *data; 122 __u8 *data;
123 __u16 size; 123 __u16 size;
124 int ret; 124 int ret;
125 125
126 size = video->dev->uvc_version >= 0x0110 ? 34 : 26; 126 size = stream->dev->uvc_version >= 0x0110 ? 34 : 26;
127 data = kmalloc(size, GFP_KERNEL); 127 data = kmalloc(size, GFP_KERNEL);
128 if (data == NULL) 128 if (data == NULL)
129 return -ENOMEM; 129 return -ENOMEM;
130 130
131 ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum, 131 if ((stream->dev->quirks & UVC_QUIRK_PROBE_DEF) && query == UVC_GET_DEF)
132 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size, 132 return -EIO;
133 UVC_CTRL_STREAMING_TIMEOUT); 133
134 ret = __uvc_query_ctrl(stream->dev, query, 0, stream->intfnum,
135 probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data,
136 size, UVC_CTRL_STREAMING_TIMEOUT);
134 137
135 if ((query == GET_MIN || query == GET_MAX) && ret == 2) { 138 if ((query == UVC_GET_MIN || query == UVC_GET_MAX) && ret == 2) {
136 /* Some cameras, mostly based on Bison Electronics chipsets, 139 /* Some cameras, mostly based on Bison Electronics chipsets,
137 * answer a GET_MIN or GET_MAX request with the wCompQuality 140 * answer a GET_MIN or GET_MAX request with the wCompQuality
138 * field only. 141 * field only.
139 */ 142 */
140 uvc_warn_once(video->dev, UVC_WARN_MINMAX, "UVC non " 143 uvc_warn_once(stream->dev, UVC_WARN_MINMAX, "UVC non "
141 "compliance - GET_MIN/MAX(PROBE) incorrectly " 144 "compliance - GET_MIN/MAX(PROBE) incorrectly "
142 "supported. Enabling workaround.\n"); 145 "supported. Enabling workaround.\n");
143 memset(ctrl, 0, sizeof ctrl); 146 memset(ctrl, 0, sizeof ctrl);
144 ctrl->wCompQuality = le16_to_cpup((__le16 *)data); 147 ctrl->wCompQuality = le16_to_cpup((__le16 *)data);
145 ret = 0; 148 ret = 0;
146 goto out; 149 goto out;
147 } else if (query == GET_DEF && probe == 1 && ret != size) { 150 } else if (query == UVC_GET_DEF && probe == 1 && ret != size) {
148 /* Many cameras don't support the GET_DEF request on their 151 /* Many cameras don't support the GET_DEF request on their
149 * video probe control. Warn once and return, the caller will 152 * video probe control. Warn once and return, the caller will
150 * fall back to GET_CUR. 153 * fall back to GET_CUR.
151 */ 154 */
152 uvc_warn_once(video->dev, UVC_WARN_PROBE_DEF, "UVC non " 155 uvc_warn_once(stream->dev, UVC_WARN_PROBE_DEF, "UVC non "
153 "compliance - GET_DEF(PROBE) not supported. " 156 "compliance - GET_DEF(PROBE) not supported. "
154 "Enabling workaround.\n"); 157 "Enabling workaround.\n");
155 ret = -EIO; 158 ret = -EIO;
@@ -181,7 +184,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
181 ctrl->bMinVersion = data[32]; 184 ctrl->bMinVersion = data[32];
182 ctrl->bMaxVersion = data[33]; 185 ctrl->bMaxVersion = data[33];
183 } else { 186 } else {
184 ctrl->dwClockFrequency = video->dev->clock_frequency; 187 ctrl->dwClockFrequency = stream->dev->clock_frequency;
185 ctrl->bmFramingInfo = 0; 188 ctrl->bmFramingInfo = 0;
186 ctrl->bPreferedVersion = 0; 189 ctrl->bPreferedVersion = 0;
187 ctrl->bMinVersion = 0; 190 ctrl->bMinVersion = 0;
@@ -192,7 +195,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
192 * dwMaxPayloadTransferSize fields. Try to get the value from the 195 * dwMaxPayloadTransferSize fields. Try to get the value from the
193 * format and frame descriptors. 196 * format and frame descriptors.
194 */ 197 */
195 uvc_fixup_video_ctrl(video, ctrl); 198 uvc_fixup_video_ctrl(stream, ctrl);
196 ret = 0; 199 ret = 0;
197 200
198out: 201out:
@@ -200,14 +203,14 @@ out:
200 return ret; 203 return ret;
201} 204}
202 205
203static int uvc_set_video_ctrl(struct uvc_video_device *video, 206static int uvc_set_video_ctrl(struct uvc_streaming *stream,
204 struct uvc_streaming_control *ctrl, int probe) 207 struct uvc_streaming_control *ctrl, int probe)
205{ 208{
206 __u8 *data; 209 __u8 *data;
207 __u16 size; 210 __u16 size;
208 int ret; 211 int ret;
209 212
210 size = video->dev->uvc_version >= 0x0110 ? 34 : 26; 213 size = stream->dev->uvc_version >= 0x0110 ? 34 : 26;
211 data = kzalloc(size, GFP_KERNEL); 214 data = kzalloc(size, GFP_KERNEL);
212 if (data == NULL) 215 if (data == NULL)
213 return -ENOMEM; 216 return -ENOMEM;
@@ -232,10 +235,9 @@ static int uvc_set_video_ctrl(struct uvc_video_device *video,
232 data[33] = ctrl->bMaxVersion; 235 data[33] = ctrl->bMaxVersion;
233 } 236 }
234 237
235 ret = __uvc_query_ctrl(video->dev, SET_CUR, 0, 238 ret = __uvc_query_ctrl(stream->dev, UVC_SET_CUR, 0, stream->intfnum,
236 video->streaming->intfnum, 239 probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data,
237 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size, 240 size, UVC_CTRL_STREAMING_TIMEOUT);
238 UVC_CTRL_STREAMING_TIMEOUT);
239 if (ret != size) { 241 if (ret != size) {
240 uvc_printk(KERN_ERR, "Failed to set UVC %s control : " 242 uvc_printk(KERN_ERR, "Failed to set UVC %s control : "
241 "%d (exp. %u).\n", probe ? "probe" : "commit", 243 "%d (exp. %u).\n", probe ? "probe" : "commit",
@@ -247,7 +249,7 @@ static int uvc_set_video_ctrl(struct uvc_video_device *video,
247 return ret; 249 return ret;
248} 250}
249 251
250int uvc_probe_video(struct uvc_video_device *video, 252int uvc_probe_video(struct uvc_streaming *stream,
251 struct uvc_streaming_control *probe) 253 struct uvc_streaming_control *probe)
252{ 254{
253 struct uvc_streaming_control probe_min, probe_max; 255 struct uvc_streaming_control probe_min, probe_max;
@@ -255,7 +257,7 @@ int uvc_probe_video(struct uvc_video_device *video,
255 unsigned int i; 257 unsigned int i;
256 int ret; 258 int ret;
257 259
258 mutex_lock(&video->streaming->mutex); 260 mutex_lock(&stream->mutex);
259 261
260 /* Perform probing. The device should adjust the requested values 262 /* Perform probing. The device should adjust the requested values
261 * according to its capabilities. However, some devices, namely the 263 * according to its capabilities. However, some devices, namely the
@@ -264,15 +266,16 @@ int uvc_probe_video(struct uvc_video_device *video,
264 * that reason, if the needed bandwidth exceeds the maximum available 266 * that reason, if the needed bandwidth exceeds the maximum available
265 * bandwidth, try to lower the quality. 267 * bandwidth, try to lower the quality.
266 */ 268 */
267 if ((ret = uvc_set_video_ctrl(video, probe, 1)) < 0) 269 ret = uvc_set_video_ctrl(stream, probe, 1);
270 if (ret < 0)
268 goto done; 271 goto done;
269 272
270 /* Get the minimum and maximum values for compression settings. */ 273 /* Get the minimum and maximum values for compression settings. */
271 if (!(video->dev->quirks & UVC_QUIRK_PROBE_MINMAX)) { 274 if (!(stream->dev->quirks & UVC_QUIRK_PROBE_MINMAX)) {
272 ret = uvc_get_video_ctrl(video, &probe_min, 1, GET_MIN); 275 ret = uvc_get_video_ctrl(stream, &probe_min, 1, UVC_GET_MIN);
273 if (ret < 0) 276 if (ret < 0)
274 goto done; 277 goto done;
275 ret = uvc_get_video_ctrl(video, &probe_max, 1, GET_MAX); 278 ret = uvc_get_video_ctrl(stream, &probe_max, 1, UVC_GET_MAX);
276 if (ret < 0) 279 if (ret < 0)
277 goto done; 280 goto done;
278 281
@@ -280,18 +283,21 @@ int uvc_probe_video(struct uvc_video_device *video,
280 } 283 }
281 284
282 for (i = 0; i < 2; ++i) { 285 for (i = 0; i < 2; ++i) {
283 if ((ret = uvc_set_video_ctrl(video, probe, 1)) < 0 || 286 ret = uvc_set_video_ctrl(stream, probe, 1);
284 (ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0) 287 if (ret < 0)
288 goto done;
289 ret = uvc_get_video_ctrl(stream, probe, 1, UVC_GET_CUR);
290 if (ret < 0)
285 goto done; 291 goto done;
286 292
287 if (video->streaming->intf->num_altsetting == 1) 293 if (stream->intf->num_altsetting == 1)
288 break; 294 break;
289 295
290 bandwidth = probe->dwMaxPayloadTransferSize; 296 bandwidth = probe->dwMaxPayloadTransferSize;
291 if (bandwidth <= video->streaming->maxpsize) 297 if (bandwidth <= stream->maxpsize)
292 break; 298 break;
293 299
294 if (video->dev->quirks & UVC_QUIRK_PROBE_MINMAX) { 300 if (stream->dev->quirks & UVC_QUIRK_PROBE_MINMAX) {
295 ret = -ENOSPC; 301 ret = -ENOSPC;
296 goto done; 302 goto done;
297 } 303 }
@@ -304,14 +310,14 @@ int uvc_probe_video(struct uvc_video_device *video,
304 } 310 }
305 311
306done: 312done:
307 mutex_unlock(&video->streaming->mutex); 313 mutex_unlock(&stream->mutex);
308 return ret; 314 return ret;
309} 315}
310 316
311int uvc_commit_video(struct uvc_video_device *video, 317int uvc_commit_video(struct uvc_streaming *stream,
312 struct uvc_streaming_control *probe) 318 struct uvc_streaming_control *probe)
313{ 319{
314 return uvc_set_video_ctrl(video, probe, 0); 320 return uvc_set_video_ctrl(stream, probe, 0);
315} 321}
316 322
317/* ------------------------------------------------------------------------ 323/* ------------------------------------------------------------------------
@@ -363,7 +369,7 @@ int uvc_commit_video(struct uvc_video_device *video,
363 * to be called with a NULL buf parameter. uvc_video_decode_data and 369 * to be called with a NULL buf parameter. uvc_video_decode_data and
364 * uvc_video_decode_end will never be called with a NULL buffer. 370 * uvc_video_decode_end will never be called with a NULL buffer.
365 */ 371 */
366static int uvc_video_decode_start(struct uvc_video_device *video, 372static int uvc_video_decode_start(struct uvc_streaming *stream,
367 struct uvc_buffer *buf, const __u8 *data, int len) 373 struct uvc_buffer *buf, const __u8 *data, int len)
368{ 374{
369 __u8 fid; 375 __u8 fid;
@@ -389,25 +395,25 @@ static int uvc_video_decode_start(struct uvc_video_device *video,
389 * NULL. 395 * NULL.
390 */ 396 */
391 if (buf == NULL) { 397 if (buf == NULL) {
392 video->last_fid = fid; 398 stream->last_fid = fid;
393 return -ENODATA; 399 return -ENODATA;
394 } 400 }
395 401
396 /* Synchronize to the input stream by waiting for the FID bit to be 402 /* Synchronize to the input stream by waiting for the FID bit to be
397 * toggled when the the buffer state is not UVC_BUF_STATE_ACTIVE. 403 * toggled when the the buffer state is not UVC_BUF_STATE_ACTIVE.
398 * video->last_fid is initialized to -1, so the first isochronous 404 * stream->last_fid is initialized to -1, so the first isochronous
399 * frame will always be in sync. 405 * frame will always be in sync.
400 * 406 *
401 * If the device doesn't toggle the FID bit, invert video->last_fid 407 * If the device doesn't toggle the FID bit, invert stream->last_fid
402 * when the EOF bit is set to force synchronisation on the next packet. 408 * when the EOF bit is set to force synchronisation on the next packet.
403 */ 409 */
404 if (buf->state != UVC_BUF_STATE_ACTIVE) { 410 if (buf->state != UVC_BUF_STATE_ACTIVE) {
405 if (fid == video->last_fid) { 411 if (fid == stream->last_fid) {
406 uvc_trace(UVC_TRACE_FRAME, "Dropping payload (out of " 412 uvc_trace(UVC_TRACE_FRAME, "Dropping payload (out of "
407 "sync).\n"); 413 "sync).\n");
408 if ((video->dev->quirks & UVC_QUIRK_STREAM_NO_FID) && 414 if ((stream->dev->quirks & UVC_QUIRK_STREAM_NO_FID) &&
409 (data[1] & UVC_STREAM_EOF)) 415 (data[1] & UVC_STREAM_EOF))
410 video->last_fid ^= UVC_STREAM_FID; 416 stream->last_fid ^= UVC_STREAM_FID;
411 return -ENODATA; 417 return -ENODATA;
412 } 418 }
413 419
@@ -422,7 +428,7 @@ static int uvc_video_decode_start(struct uvc_video_device *video,
422 * last payload can be lost anyway). We thus must check if the FID has 428 * last payload can be lost anyway). We thus must check if the FID has
423 * been toggled. 429 * been toggled.
424 * 430 *
425 * video->last_fid is initialized to -1, so the first isochronous 431 * stream->last_fid is initialized to -1, so the first isochronous
426 * frame will never trigger an end of frame detection. 432 * frame will never trigger an end of frame detection.
427 * 433 *
428 * Empty buffers (bytesused == 0) don't trigger end of frame detection 434 * Empty buffers (bytesused == 0) don't trigger end of frame detection
@@ -430,22 +436,22 @@ static int uvc_video_decode_start(struct uvc_video_device *video,
430 * avoids detecting end of frame conditions at FID toggling if the 436 * avoids detecting end of frame conditions at FID toggling if the
431 * previous payload had the EOF bit set. 437 * previous payload had the EOF bit set.
432 */ 438 */
433 if (fid != video->last_fid && buf->buf.bytesused != 0) { 439 if (fid != stream->last_fid && buf->buf.bytesused != 0) {
434 uvc_trace(UVC_TRACE_FRAME, "Frame complete (FID bit " 440 uvc_trace(UVC_TRACE_FRAME, "Frame complete (FID bit "
435 "toggled).\n"); 441 "toggled).\n");
436 buf->state = UVC_BUF_STATE_DONE; 442 buf->state = UVC_BUF_STATE_DONE;
437 return -EAGAIN; 443 return -EAGAIN;
438 } 444 }
439 445
440 video->last_fid = fid; 446 stream->last_fid = fid;
441 447
442 return data[0]; 448 return data[0];
443} 449}
444 450
445static void uvc_video_decode_data(struct uvc_video_device *video, 451static void uvc_video_decode_data(struct uvc_streaming *stream,
446 struct uvc_buffer *buf, const __u8 *data, int len) 452 struct uvc_buffer *buf, const __u8 *data, int len)
447{ 453{
448 struct uvc_video_queue *queue = &video->queue; 454 struct uvc_video_queue *queue = &stream->queue;
449 unsigned int maxlen, nbytes; 455 unsigned int maxlen, nbytes;
450 void *mem; 456 void *mem;
451 457
@@ -466,7 +472,7 @@ static void uvc_video_decode_data(struct uvc_video_device *video,
466 } 472 }
467} 473}
468 474
469static void uvc_video_decode_end(struct uvc_video_device *video, 475static void uvc_video_decode_end(struct uvc_streaming *stream,
470 struct uvc_buffer *buf, const __u8 *data, int len) 476 struct uvc_buffer *buf, const __u8 *data, int len)
471{ 477{
472 /* Mark the buffer as done if the EOF marker is set. */ 478 /* Mark the buffer as done if the EOF marker is set. */
@@ -475,8 +481,8 @@ static void uvc_video_decode_end(struct uvc_video_device *video,
475 if (data[0] == len) 481 if (data[0] == len)
476 uvc_trace(UVC_TRACE_FRAME, "EOF in empty payload.\n"); 482 uvc_trace(UVC_TRACE_FRAME, "EOF in empty payload.\n");
477 buf->state = UVC_BUF_STATE_DONE; 483 buf->state = UVC_BUF_STATE_DONE;
478 if (video->dev->quirks & UVC_QUIRK_STREAM_NO_FID) 484 if (stream->dev->quirks & UVC_QUIRK_STREAM_NO_FID)
479 video->last_fid ^= UVC_STREAM_FID; 485 stream->last_fid ^= UVC_STREAM_FID;
480 } 486 }
481} 487}
482 488
@@ -491,26 +497,26 @@ static void uvc_video_decode_end(struct uvc_video_device *video,
491 * uvc_video_encode_data is called for every URB and copies the data from the 497 * uvc_video_encode_data is called for every URB and copies the data from the
492 * video buffer to the transfer buffer. 498 * video buffer to the transfer buffer.
493 */ 499 */
494static int uvc_video_encode_header(struct uvc_video_device *video, 500static int uvc_video_encode_header(struct uvc_streaming *stream,
495 struct uvc_buffer *buf, __u8 *data, int len) 501 struct uvc_buffer *buf, __u8 *data, int len)
496{ 502{
497 data[0] = 2; /* Header length */ 503 data[0] = 2; /* Header length */
498 data[1] = UVC_STREAM_EOH | UVC_STREAM_EOF 504 data[1] = UVC_STREAM_EOH | UVC_STREAM_EOF
499 | (video->last_fid & UVC_STREAM_FID); 505 | (stream->last_fid & UVC_STREAM_FID);
500 return 2; 506 return 2;
501} 507}
502 508
503static int uvc_video_encode_data(struct uvc_video_device *video, 509static int uvc_video_encode_data(struct uvc_streaming *stream,
504 struct uvc_buffer *buf, __u8 *data, int len) 510 struct uvc_buffer *buf, __u8 *data, int len)
505{ 511{
506 struct uvc_video_queue *queue = &video->queue; 512 struct uvc_video_queue *queue = &stream->queue;
507 unsigned int nbytes; 513 unsigned int nbytes;
508 void *mem; 514 void *mem;
509 515
510 /* Copy video data to the URB buffer. */ 516 /* Copy video data to the URB buffer. */
511 mem = queue->mem + buf->buf.m.offset + queue->buf_used; 517 mem = queue->mem + buf->buf.m.offset + queue->buf_used;
512 nbytes = min((unsigned int)len, buf->buf.bytesused - queue->buf_used); 518 nbytes = min((unsigned int)len, buf->buf.bytesused - queue->buf_used);
513 nbytes = min(video->bulk.max_payload_size - video->bulk.payload_size, 519 nbytes = min(stream->bulk.max_payload_size - stream->bulk.payload_size,
514 nbytes); 520 nbytes);
515 memcpy(data, mem, nbytes); 521 memcpy(data, mem, nbytes);
516 522
@@ -526,8 +532,8 @@ static int uvc_video_encode_data(struct uvc_video_device *video,
526/* 532/*
527 * Completion handler for video URBs. 533 * Completion handler for video URBs.
528 */ 534 */
529static void uvc_video_decode_isoc(struct urb *urb, 535static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream,
530 struct uvc_video_device *video, struct uvc_buffer *buf) 536 struct uvc_buffer *buf)
531{ 537{
532 u8 *mem; 538 u8 *mem;
533 int ret, i; 539 int ret, i;
@@ -542,31 +548,32 @@ static void uvc_video_decode_isoc(struct urb *urb,
542 /* Decode the payload header. */ 548 /* Decode the payload header. */
543 mem = urb->transfer_buffer + urb->iso_frame_desc[i].offset; 549 mem = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
544 do { 550 do {
545 ret = uvc_video_decode_start(video, buf, mem, 551 ret = uvc_video_decode_start(stream, buf, mem,
546 urb->iso_frame_desc[i].actual_length); 552 urb->iso_frame_desc[i].actual_length);
547 if (ret == -EAGAIN) 553 if (ret == -EAGAIN)
548 buf = uvc_queue_next_buffer(&video->queue, buf); 554 buf = uvc_queue_next_buffer(&stream->queue,
555 buf);
549 } while (ret == -EAGAIN); 556 } while (ret == -EAGAIN);
550 557
551 if (ret < 0) 558 if (ret < 0)
552 continue; 559 continue;
553 560
554 /* Decode the payload data. */ 561 /* Decode the payload data. */
555 uvc_video_decode_data(video, buf, mem + ret, 562 uvc_video_decode_data(stream, buf, mem + ret,
556 urb->iso_frame_desc[i].actual_length - ret); 563 urb->iso_frame_desc[i].actual_length - ret);
557 564
558 /* Process the header again. */ 565 /* Process the header again. */
559 uvc_video_decode_end(video, buf, mem, 566 uvc_video_decode_end(stream, buf, mem,
560 urb->iso_frame_desc[i].actual_length); 567 urb->iso_frame_desc[i].actual_length);
561 568
562 if (buf->state == UVC_BUF_STATE_DONE || 569 if (buf->state == UVC_BUF_STATE_DONE ||
563 buf->state == UVC_BUF_STATE_ERROR) 570 buf->state == UVC_BUF_STATE_ERROR)
564 buf = uvc_queue_next_buffer(&video->queue, buf); 571 buf = uvc_queue_next_buffer(&stream->queue, buf);
565 } 572 }
566} 573}
567 574
568static void uvc_video_decode_bulk(struct urb *urb, 575static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream,
569 struct uvc_video_device *video, struct uvc_buffer *buf) 576 struct uvc_buffer *buf)
570{ 577{
571 u8 *mem; 578 u8 *mem;
572 int len, ret; 579 int len, ret;
@@ -576,24 +583,25 @@ static void uvc_video_decode_bulk(struct urb *urb,
576 583
577 mem = urb->transfer_buffer; 584 mem = urb->transfer_buffer;
578 len = urb->actual_length; 585 len = urb->actual_length;
579 video->bulk.payload_size += len; 586 stream->bulk.payload_size += len;
580 587
581 /* If the URB is the first of its payload, decode and save the 588 /* If the URB is the first of its payload, decode and save the
582 * header. 589 * header.
583 */ 590 */
584 if (video->bulk.header_size == 0 && !video->bulk.skip_payload) { 591 if (stream->bulk.header_size == 0 && !stream->bulk.skip_payload) {
585 do { 592 do {
586 ret = uvc_video_decode_start(video, buf, mem, len); 593 ret = uvc_video_decode_start(stream, buf, mem, len);
587 if (ret == -EAGAIN) 594 if (ret == -EAGAIN)
588 buf = uvc_queue_next_buffer(&video->queue, buf); 595 buf = uvc_queue_next_buffer(&stream->queue,
596 buf);
589 } while (ret == -EAGAIN); 597 } while (ret == -EAGAIN);
590 598
591 /* If an error occured skip the rest of the payload. */ 599 /* If an error occured skip the rest of the payload. */
592 if (ret < 0 || buf == NULL) { 600 if (ret < 0 || buf == NULL) {
593 video->bulk.skip_payload = 1; 601 stream->bulk.skip_payload = 1;
594 } else { 602 } else {
595 memcpy(video->bulk.header, mem, ret); 603 memcpy(stream->bulk.header, mem, ret);
596 video->bulk.header_size = ret; 604 stream->bulk.header_size = ret;
597 605
598 mem += ret; 606 mem += ret;
599 len -= ret; 607 len -= ret;
@@ -606,33 +614,34 @@ static void uvc_video_decode_bulk(struct urb *urb,
606 */ 614 */
607 615
608 /* Process video data. */ 616 /* Process video data. */
609 if (!video->bulk.skip_payload && buf != NULL) 617 if (!stream->bulk.skip_payload && buf != NULL)
610 uvc_video_decode_data(video, buf, mem, len); 618 uvc_video_decode_data(stream, buf, mem, len);
611 619
612 /* Detect the payload end by a URB smaller than the maximum size (or 620 /* Detect the payload end by a URB smaller than the maximum size (or
613 * a payload size equal to the maximum) and process the header again. 621 * a payload size equal to the maximum) and process the header again.
614 */ 622 */
615 if (urb->actual_length < urb->transfer_buffer_length || 623 if (urb->actual_length < urb->transfer_buffer_length ||
616 video->bulk.payload_size >= video->bulk.max_payload_size) { 624 stream->bulk.payload_size >= stream->bulk.max_payload_size) {
617 if (!video->bulk.skip_payload && buf != NULL) { 625 if (!stream->bulk.skip_payload && buf != NULL) {
618 uvc_video_decode_end(video, buf, video->bulk.header, 626 uvc_video_decode_end(stream, buf, stream->bulk.header,
619 video->bulk.payload_size); 627 stream->bulk.payload_size);
620 if (buf->state == UVC_BUF_STATE_DONE || 628 if (buf->state == UVC_BUF_STATE_DONE ||
621 buf->state == UVC_BUF_STATE_ERROR) 629 buf->state == UVC_BUF_STATE_ERROR)
622 buf = uvc_queue_next_buffer(&video->queue, buf); 630 buf = uvc_queue_next_buffer(&stream->queue,
631 buf);
623 } 632 }
624 633
625 video->bulk.header_size = 0; 634 stream->bulk.header_size = 0;
626 video->bulk.skip_payload = 0; 635 stream->bulk.skip_payload = 0;
627 video->bulk.payload_size = 0; 636 stream->bulk.payload_size = 0;
628 } 637 }
629} 638}
630 639
631static void uvc_video_encode_bulk(struct urb *urb, 640static void uvc_video_encode_bulk(struct urb *urb, struct uvc_streaming *stream,
632 struct uvc_video_device *video, struct uvc_buffer *buf) 641 struct uvc_buffer *buf)
633{ 642{
634 u8 *mem = urb->transfer_buffer; 643 u8 *mem = urb->transfer_buffer;
635 int len = video->urb_size, ret; 644 int len = stream->urb_size, ret;
636 645
637 if (buf == NULL) { 646 if (buf == NULL) {
638 urb->transfer_buffer_length = 0; 647 urb->transfer_buffer_length = 0;
@@ -640,40 +649,40 @@ static void uvc_video_encode_bulk(struct urb *urb,
640 } 649 }
641 650
642 /* If the URB is the first of its payload, add the header. */ 651 /* If the URB is the first of its payload, add the header. */
643 if (video->bulk.header_size == 0) { 652 if (stream->bulk.header_size == 0) {
644 ret = uvc_video_encode_header(video, buf, mem, len); 653 ret = uvc_video_encode_header(stream, buf, mem, len);
645 video->bulk.header_size = ret; 654 stream->bulk.header_size = ret;
646 video->bulk.payload_size += ret; 655 stream->bulk.payload_size += ret;
647 mem += ret; 656 mem += ret;
648 len -= ret; 657 len -= ret;
649 } 658 }
650 659
651 /* Process video data. */ 660 /* Process video data. */
652 ret = uvc_video_encode_data(video, buf, mem, len); 661 ret = uvc_video_encode_data(stream, buf, mem, len);
653 662
654 video->bulk.payload_size += ret; 663 stream->bulk.payload_size += ret;
655 len -= ret; 664 len -= ret;
656 665
657 if (buf->buf.bytesused == video->queue.buf_used || 666 if (buf->buf.bytesused == stream->queue.buf_used ||
658 video->bulk.payload_size == video->bulk.max_payload_size) { 667 stream->bulk.payload_size == stream->bulk.max_payload_size) {
659 if (buf->buf.bytesused == video->queue.buf_used) { 668 if (buf->buf.bytesused == stream->queue.buf_used) {
660 video->queue.buf_used = 0; 669 stream->queue.buf_used = 0;
661 buf->state = UVC_BUF_STATE_DONE; 670 buf->state = UVC_BUF_STATE_DONE;
662 uvc_queue_next_buffer(&video->queue, buf); 671 uvc_queue_next_buffer(&stream->queue, buf);
663 video->last_fid ^= UVC_STREAM_FID; 672 stream->last_fid ^= UVC_STREAM_FID;
664 } 673 }
665 674
666 video->bulk.header_size = 0; 675 stream->bulk.header_size = 0;
667 video->bulk.payload_size = 0; 676 stream->bulk.payload_size = 0;
668 } 677 }
669 678
670 urb->transfer_buffer_length = video->urb_size - len; 679 urb->transfer_buffer_length = stream->urb_size - len;
671} 680}
672 681
673static void uvc_video_complete(struct urb *urb) 682static void uvc_video_complete(struct urb *urb)
674{ 683{
675 struct uvc_video_device *video = urb->context; 684 struct uvc_streaming *stream = urb->context;
676 struct uvc_video_queue *queue = &video->queue; 685 struct uvc_video_queue *queue = &stream->queue;
677 struct uvc_buffer *buf = NULL; 686 struct uvc_buffer *buf = NULL;
678 unsigned long flags; 687 unsigned long flags;
679 int ret; 688 int ret;
@@ -687,7 +696,7 @@ static void uvc_video_complete(struct urb *urb)
687 "completion handler.\n", urb->status); 696 "completion handler.\n", urb->status);
688 697
689 case -ENOENT: /* usb_kill_urb() called. */ 698 case -ENOENT: /* usb_kill_urb() called. */
690 if (video->frozen) 699 if (stream->frozen)
691 return; 700 return;
692 701
693 case -ECONNRESET: /* usb_unlink_urb() called. */ 702 case -ECONNRESET: /* usb_unlink_urb() called. */
@@ -702,7 +711,7 @@ static void uvc_video_complete(struct urb *urb)
702 queue); 711 queue);
703 spin_unlock_irqrestore(&queue->irqlock, flags); 712 spin_unlock_irqrestore(&queue->irqlock, flags);
704 713
705 video->decode(urb, video, buf); 714 stream->decode(urb, stream, buf);
706 715
707 if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { 716 if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
708 uvc_printk(KERN_ERR, "Failed to resubmit video URB (%d).\n", 717 uvc_printk(KERN_ERR, "Failed to resubmit video URB (%d).\n",
@@ -713,19 +722,19 @@ static void uvc_video_complete(struct urb *urb)
713/* 722/*
714 * Free transfer buffers. 723 * Free transfer buffers.
715 */ 724 */
716static void uvc_free_urb_buffers(struct uvc_video_device *video) 725static void uvc_free_urb_buffers(struct uvc_streaming *stream)
717{ 726{
718 unsigned int i; 727 unsigned int i;
719 728
720 for (i = 0; i < UVC_URBS; ++i) { 729 for (i = 0; i < UVC_URBS; ++i) {
721 if (video->urb_buffer[i]) { 730 if (stream->urb_buffer[i]) {
722 usb_buffer_free(video->dev->udev, video->urb_size, 731 usb_buffer_free(stream->dev->udev, stream->urb_size,
723 video->urb_buffer[i], video->urb_dma[i]); 732 stream->urb_buffer[i], stream->urb_dma[i]);
724 video->urb_buffer[i] = NULL; 733 stream->urb_buffer[i] = NULL;
725 } 734 }
726 } 735 }
727 736
728 video->urb_size = 0; 737 stream->urb_size = 0;
729} 738}
730 739
731/* 740/*
@@ -739,15 +748,15 @@ static void uvc_free_urb_buffers(struct uvc_video_device *video)
739 * 748 *
740 * Return the number of allocated packets on success or 0 when out of memory. 749 * Return the number of allocated packets on success or 0 when out of memory.
741 */ 750 */
742static int uvc_alloc_urb_buffers(struct uvc_video_device *video, 751static int uvc_alloc_urb_buffers(struct uvc_streaming *stream,
743 unsigned int size, unsigned int psize, gfp_t gfp_flags) 752 unsigned int size, unsigned int psize, gfp_t gfp_flags)
744{ 753{
745 unsigned int npackets; 754 unsigned int npackets;
746 unsigned int i; 755 unsigned int i;
747 756
748 /* Buffers are already allocated, bail out. */ 757 /* Buffers are already allocated, bail out. */
749 if (video->urb_size) 758 if (stream->urb_size)
750 return video->urb_size / psize; 759 return stream->urb_size / psize;
751 760
752 /* Compute the number of packets. Bulk endpoints might transfer UVC 761 /* Compute the number of packets. Bulk endpoints might transfer UVC
753 * payloads accross multiple URBs. 762 * payloads accross multiple URBs.
@@ -759,17 +768,17 @@ static int uvc_alloc_urb_buffers(struct uvc_video_device *video,
759 /* Retry allocations until one succeed. */ 768 /* Retry allocations until one succeed. */
760 for (; npackets > 1; npackets /= 2) { 769 for (; npackets > 1; npackets /= 2) {
761 for (i = 0; i < UVC_URBS; ++i) { 770 for (i = 0; i < UVC_URBS; ++i) {
762 video->urb_buffer[i] = usb_buffer_alloc( 771 stream->urb_buffer[i] = usb_buffer_alloc(
763 video->dev->udev, psize * npackets, 772 stream->dev->udev, psize * npackets,
764 gfp_flags | __GFP_NOWARN, &video->urb_dma[i]); 773 gfp_flags | __GFP_NOWARN, &stream->urb_dma[i]);
765 if (!video->urb_buffer[i]) { 774 if (!stream->urb_buffer[i]) {
766 uvc_free_urb_buffers(video); 775 uvc_free_urb_buffers(stream);
767 break; 776 break;
768 } 777 }
769 } 778 }
770 779
771 if (i == UVC_URBS) { 780 if (i == UVC_URBS) {
772 video->urb_size = psize * npackets; 781 stream->urb_size = psize * npackets;
773 return npackets; 782 return npackets;
774 } 783 }
775 } 784 }
@@ -780,29 +789,30 @@ static int uvc_alloc_urb_buffers(struct uvc_video_device *video,
780/* 789/*
781 * Uninitialize isochronous/bulk URBs and free transfer buffers. 790 * Uninitialize isochronous/bulk URBs and free transfer buffers.
782 */ 791 */
783static void uvc_uninit_video(struct uvc_video_device *video, int free_buffers) 792static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers)
784{ 793{
785 struct urb *urb; 794 struct urb *urb;
786 unsigned int i; 795 unsigned int i;
787 796
788 for (i = 0; i < UVC_URBS; ++i) { 797 for (i = 0; i < UVC_URBS; ++i) {
789 if ((urb = video->urb[i]) == NULL) 798 urb = stream->urb[i];
799 if (urb == NULL)
790 continue; 800 continue;
791 801
792 usb_kill_urb(urb); 802 usb_kill_urb(urb);
793 usb_free_urb(urb); 803 usb_free_urb(urb);
794 video->urb[i] = NULL; 804 stream->urb[i] = NULL;
795 } 805 }
796 806
797 if (free_buffers) 807 if (free_buffers)
798 uvc_free_urb_buffers(video); 808 uvc_free_urb_buffers(stream);
799} 809}
800 810
801/* 811/*
802 * Initialize isochronous URBs and allocate transfer buffers. The packet size 812 * Initialize isochronous URBs and allocate transfer buffers. The packet size
803 * is given by the endpoint. 813 * is given by the endpoint.
804 */ 814 */
805static int uvc_init_video_isoc(struct uvc_video_device *video, 815static int uvc_init_video_isoc(struct uvc_streaming *stream,
806 struct usb_host_endpoint *ep, gfp_t gfp_flags) 816 struct usb_host_endpoint *ep, gfp_t gfp_flags)
807{ 817{
808 struct urb *urb; 818 struct urb *urb;
@@ -812,9 +822,9 @@ static int uvc_init_video_isoc(struct uvc_video_device *video,
812 822
813 psize = le16_to_cpu(ep->desc.wMaxPacketSize); 823 psize = le16_to_cpu(ep->desc.wMaxPacketSize);
814 psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); 824 psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
815 size = video->streaming->ctrl.dwMaxVideoFrameSize; 825 size = stream->ctrl.dwMaxVideoFrameSize;
816 826
817 npackets = uvc_alloc_urb_buffers(video, size, psize, gfp_flags); 827 npackets = uvc_alloc_urb_buffers(stream, size, psize, gfp_flags);
818 if (npackets == 0) 828 if (npackets == 0)
819 return -ENOMEM; 829 return -ENOMEM;
820 830
@@ -823,18 +833,18 @@ static int uvc_init_video_isoc(struct uvc_video_device *video,
823 for (i = 0; i < UVC_URBS; ++i) { 833 for (i = 0; i < UVC_URBS; ++i) {
824 urb = usb_alloc_urb(npackets, gfp_flags); 834 urb = usb_alloc_urb(npackets, gfp_flags);
825 if (urb == NULL) { 835 if (urb == NULL) {
826 uvc_uninit_video(video, 1); 836 uvc_uninit_video(stream, 1);
827 return -ENOMEM; 837 return -ENOMEM;
828 } 838 }
829 839
830 urb->dev = video->dev->udev; 840 urb->dev = stream->dev->udev;
831 urb->context = video; 841 urb->context = stream;
832 urb->pipe = usb_rcvisocpipe(video->dev->udev, 842 urb->pipe = usb_rcvisocpipe(stream->dev->udev,
833 ep->desc.bEndpointAddress); 843 ep->desc.bEndpointAddress);
834 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; 844 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
835 urb->interval = ep->desc.bInterval; 845 urb->interval = ep->desc.bInterval;
836 urb->transfer_buffer = video->urb_buffer[i]; 846 urb->transfer_buffer = stream->urb_buffer[i];
837 urb->transfer_dma = video->urb_dma[i]; 847 urb->transfer_dma = stream->urb_dma[i];
838 urb->complete = uvc_video_complete; 848 urb->complete = uvc_video_complete;
839 urb->number_of_packets = npackets; 849 urb->number_of_packets = npackets;
840 urb->transfer_buffer_length = size; 850 urb->transfer_buffer_length = size;
@@ -844,7 +854,7 @@ static int uvc_init_video_isoc(struct uvc_video_device *video,
844 urb->iso_frame_desc[j].length = psize; 854 urb->iso_frame_desc[j].length = psize;
845 } 855 }
846 856
847 video->urb[i] = urb; 857 stream->urb[i] = urb;
848 } 858 }
849 859
850 return 0; 860 return 0;
@@ -854,7 +864,7 @@ static int uvc_init_video_isoc(struct uvc_video_device *video,
854 * Initialize bulk URBs and allocate transfer buffers. The packet size is 864 * Initialize bulk URBs and allocate transfer buffers. The packet size is
855 * given by the endpoint. 865 * given by the endpoint.
856 */ 866 */
857static int uvc_init_video_bulk(struct uvc_video_device *video, 867static int uvc_init_video_bulk(struct uvc_streaming *stream,
858 struct usb_host_endpoint *ep, gfp_t gfp_flags) 868 struct usb_host_endpoint *ep, gfp_t gfp_flags)
859{ 869{
860 struct urb *urb; 870 struct urb *urb;
@@ -863,39 +873,39 @@ static int uvc_init_video_bulk(struct uvc_video_device *video,
863 u32 size; 873 u32 size;
864 874
865 psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff; 875 psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff;
866 size = video->streaming->ctrl.dwMaxPayloadTransferSize; 876 size = stream->ctrl.dwMaxPayloadTransferSize;
867 video->bulk.max_payload_size = size; 877 stream->bulk.max_payload_size = size;
868 878
869 npackets = uvc_alloc_urb_buffers(video, size, psize, gfp_flags); 879 npackets = uvc_alloc_urb_buffers(stream, size, psize, gfp_flags);
870 if (npackets == 0) 880 if (npackets == 0)
871 return -ENOMEM; 881 return -ENOMEM;
872 882
873 size = npackets * psize; 883 size = npackets * psize;
874 884
875 if (usb_endpoint_dir_in(&ep->desc)) 885 if (usb_endpoint_dir_in(&ep->desc))
876 pipe = usb_rcvbulkpipe(video->dev->udev, 886 pipe = usb_rcvbulkpipe(stream->dev->udev,
877 ep->desc.bEndpointAddress); 887 ep->desc.bEndpointAddress);
878 else 888 else
879 pipe = usb_sndbulkpipe(video->dev->udev, 889 pipe = usb_sndbulkpipe(stream->dev->udev,
880 ep->desc.bEndpointAddress); 890 ep->desc.bEndpointAddress);
881 891
882 if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) 892 if (stream->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
883 size = 0; 893 size = 0;
884 894
885 for (i = 0; i < UVC_URBS; ++i) { 895 for (i = 0; i < UVC_URBS; ++i) {
886 urb = usb_alloc_urb(0, gfp_flags); 896 urb = usb_alloc_urb(0, gfp_flags);
887 if (urb == NULL) { 897 if (urb == NULL) {
888 uvc_uninit_video(video, 1); 898 uvc_uninit_video(stream, 1);
889 return -ENOMEM; 899 return -ENOMEM;
890 } 900 }
891 901
892 usb_fill_bulk_urb(urb, video->dev->udev, pipe, 902 usb_fill_bulk_urb(urb, stream->dev->udev, pipe,
893 video->urb_buffer[i], size, uvc_video_complete, 903 stream->urb_buffer[i], size, uvc_video_complete,
894 video); 904 stream);
895 urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; 905 urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
896 urb->transfer_dma = video->urb_dma[i]; 906 urb->transfer_dma = stream->urb_dma[i];
897 907
898 video->urb[i] = urb; 908 stream->urb[i] = urb;
899 } 909 }
900 910
901 return 0; 911 return 0;
@@ -904,35 +914,35 @@ static int uvc_init_video_bulk(struct uvc_video_device *video,
904/* 914/*
905 * Initialize isochronous/bulk URBs and allocate transfer buffers. 915 * Initialize isochronous/bulk URBs and allocate transfer buffers.
906 */ 916 */
907static int uvc_init_video(struct uvc_video_device *video, gfp_t gfp_flags) 917static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
908{ 918{
909 struct usb_interface *intf = video->streaming->intf; 919 struct usb_interface *intf = stream->intf;
910 struct usb_host_interface *alts; 920 struct usb_host_interface *alts;
911 struct usb_host_endpoint *ep = NULL; 921 struct usb_host_endpoint *ep = NULL;
912 int intfnum = video->streaming->intfnum; 922 int intfnum = stream->intfnum;
913 unsigned int bandwidth, psize, i; 923 unsigned int bandwidth, psize, i;
914 int ret; 924 int ret;
915 925
916 video->last_fid = -1; 926 stream->last_fid = -1;
917 video->bulk.header_size = 0; 927 stream->bulk.header_size = 0;
918 video->bulk.skip_payload = 0; 928 stream->bulk.skip_payload = 0;
919 video->bulk.payload_size = 0; 929 stream->bulk.payload_size = 0;
920 930
921 if (intf->num_altsetting > 1) { 931 if (intf->num_altsetting > 1) {
922 /* Isochronous endpoint, select the alternate setting. */ 932 /* Isochronous endpoint, select the alternate setting. */
923 bandwidth = video->streaming->ctrl.dwMaxPayloadTransferSize; 933 bandwidth = stream->ctrl.dwMaxPayloadTransferSize;
924 934
925 if (bandwidth == 0) { 935 if (bandwidth == 0) {
926 uvc_printk(KERN_WARNING, "device %s requested null " 936 uvc_printk(KERN_WARNING, "device %s requested null "
927 "bandwidth, defaulting to lowest.\n", 937 "bandwidth, defaulting to lowest.\n",
928 video->vdev->name); 938 stream->dev->name);
929 bandwidth = 1; 939 bandwidth = 1;
930 } 940 }
931 941
932 for (i = 0; i < intf->num_altsetting; ++i) { 942 for (i = 0; i < intf->num_altsetting; ++i) {
933 alts = &intf->altsetting[i]; 943 alts = &intf->altsetting[i];
934 ep = uvc_find_endpoint(alts, 944 ep = uvc_find_endpoint(alts,
935 video->streaming->header.bEndpointAddress); 945 stream->header.bEndpointAddress);
936 if (ep == NULL) 946 if (ep == NULL)
937 continue; 947 continue;
938 948
@@ -946,18 +956,19 @@ static int uvc_init_video(struct uvc_video_device *video, gfp_t gfp_flags)
946 if (i >= intf->num_altsetting) 956 if (i >= intf->num_altsetting)
947 return -EIO; 957 return -EIO;
948 958
949 if ((ret = usb_set_interface(video->dev->udev, intfnum, i)) < 0) 959 ret = usb_set_interface(stream->dev->udev, intfnum, i);
960 if (ret < 0)
950 return ret; 961 return ret;
951 962
952 ret = uvc_init_video_isoc(video, ep, gfp_flags); 963 ret = uvc_init_video_isoc(stream, ep, gfp_flags);
953 } else { 964 } else {
954 /* Bulk endpoint, proceed to URB initialization. */ 965 /* Bulk endpoint, proceed to URB initialization. */
955 ep = uvc_find_endpoint(&intf->altsetting[0], 966 ep = uvc_find_endpoint(&intf->altsetting[0],
956 video->streaming->header.bEndpointAddress); 967 stream->header.bEndpointAddress);
957 if (ep == NULL) 968 if (ep == NULL)
958 return -EIO; 969 return -EIO;
959 970
960 ret = uvc_init_video_bulk(video, ep, gfp_flags); 971 ret = uvc_init_video_bulk(stream, ep, gfp_flags);
961 } 972 }
962 973
963 if (ret < 0) 974 if (ret < 0)
@@ -965,10 +976,11 @@ static int uvc_init_video(struct uvc_video_device *video, gfp_t gfp_flags)
965 976
966 /* Submit the URBs. */ 977 /* Submit the URBs. */
967 for (i = 0; i < UVC_URBS; ++i) { 978 for (i = 0; i < UVC_URBS; ++i) {
968 if ((ret = usb_submit_urb(video->urb[i], gfp_flags)) < 0) { 979 ret = usb_submit_urb(stream->urb[i], gfp_flags);
980 if (ret < 0) {
969 uvc_printk(KERN_ERR, "Failed to submit URB %u " 981 uvc_printk(KERN_ERR, "Failed to submit URB %u "
970 "(%d).\n", i, ret); 982 "(%d).\n", i, ret);
971 uvc_uninit_video(video, 1); 983 uvc_uninit_video(stream, 1);
972 return ret; 984 return ret;
973 } 985 }
974 } 986 }
@@ -987,14 +999,14 @@ static int uvc_init_video(struct uvc_video_device *video, gfp_t gfp_flags)
987 * video buffers in any way. We mark the device as frozen to make sure the URB 999 * video buffers in any way. We mark the device as frozen to make sure the URB
988 * completion handler won't try to cancel the queue when we kill the URBs. 1000 * completion handler won't try to cancel the queue when we kill the URBs.
989 */ 1001 */
990int uvc_video_suspend(struct uvc_video_device *video) 1002int uvc_video_suspend(struct uvc_streaming *stream)
991{ 1003{
992 if (!uvc_queue_streaming(&video->queue)) 1004 if (!uvc_queue_streaming(&stream->queue))
993 return 0; 1005 return 0;
994 1006
995 video->frozen = 1; 1007 stream->frozen = 1;
996 uvc_uninit_video(video, 0); 1008 uvc_uninit_video(stream, 0);
997 usb_set_interface(video->dev->udev, video->streaming->intfnum, 0); 1009 usb_set_interface(stream->dev->udev, stream->intfnum, 0);
998 return 0; 1010 return 0;
999} 1011}
1000 1012
@@ -1006,22 +1018,24 @@ int uvc_video_suspend(struct uvc_video_device *video)
1006 * buffers, making sure userspace applications are notified of the problem 1018 * buffers, making sure userspace applications are notified of the problem
1007 * instead of waiting forever. 1019 * instead of waiting forever.
1008 */ 1020 */
1009int uvc_video_resume(struct uvc_video_device *video) 1021int uvc_video_resume(struct uvc_streaming *stream)
1010{ 1022{
1011 int ret; 1023 int ret;
1012 1024
1013 video->frozen = 0; 1025 stream->frozen = 0;
1014 1026
1015 if ((ret = uvc_commit_video(video, &video->streaming->ctrl)) < 0) { 1027 ret = uvc_commit_video(stream, &stream->ctrl);
1016 uvc_queue_enable(&video->queue, 0); 1028 if (ret < 0) {
1029 uvc_queue_enable(&stream->queue, 0);
1017 return ret; 1030 return ret;
1018 } 1031 }
1019 1032
1020 if (!uvc_queue_streaming(&video->queue)) 1033 if (!uvc_queue_streaming(&stream->queue))
1021 return 0; 1034 return 0;
1022 1035
1023 if ((ret = uvc_init_video(video, GFP_NOIO)) < 0) 1036 ret = uvc_init_video(stream, GFP_NOIO);
1024 uvc_queue_enable(&video->queue, 0); 1037 if (ret < 0)
1038 uvc_queue_enable(&stream->queue, 0);
1025 1039
1026 return ret; 1040 return ret;
1027} 1041}
@@ -1040,47 +1054,53 @@ int uvc_video_resume(struct uvc_video_device *video)
1040 * 1054 *
1041 * This function is called before registering the device with V4L. 1055 * This function is called before registering the device with V4L.
1042 */ 1056 */
1043int uvc_video_init(struct uvc_video_device *video) 1057int uvc_video_init(struct uvc_streaming *stream)
1044{ 1058{
1045 struct uvc_streaming_control *probe = &video->streaming->ctrl; 1059 struct uvc_streaming_control *probe = &stream->ctrl;
1046 struct uvc_format *format = NULL; 1060 struct uvc_format *format = NULL;
1047 struct uvc_frame *frame = NULL; 1061 struct uvc_frame *frame = NULL;
1048 unsigned int i; 1062 unsigned int i;
1049 int ret; 1063 int ret;
1050 1064
1051 if (video->streaming->nformats == 0) { 1065 if (stream->nformats == 0) {
1052 uvc_printk(KERN_INFO, "No supported video formats found.\n"); 1066 uvc_printk(KERN_INFO, "No supported video formats found.\n");
1053 return -EINVAL; 1067 return -EINVAL;
1054 } 1068 }
1055 1069
1070 atomic_set(&stream->active, 0);
1071
1072 /* Initialize the video buffers queue. */
1073 uvc_queue_init(&stream->queue, stream->type);
1074
1056 /* Alternate setting 0 should be the default, yet the XBox Live Vision 1075 /* Alternate setting 0 should be the default, yet the XBox Live Vision
1057 * Cam (and possibly other devices) crash or otherwise misbehave if 1076 * Cam (and possibly other devices) crash or otherwise misbehave if
1058 * they don't receive a SET_INTERFACE request before any other video 1077 * they don't receive a SET_INTERFACE request before any other video
1059 * control request. 1078 * control request.
1060 */ 1079 */
1061 usb_set_interface(video->dev->udev, video->streaming->intfnum, 0); 1080 usb_set_interface(stream->dev->udev, stream->intfnum, 0);
1062 1081
1063 /* Set the streaming probe control with default streaming parameters 1082 /* Set the streaming probe control with default streaming parameters
1064 * retrieved from the device. Webcams that don't suport GET_DEF 1083 * retrieved from the device. Webcams that don't suport GET_DEF
1065 * requests on the probe control will just keep their current streaming 1084 * requests on the probe control will just keep their current streaming
1066 * parameters. 1085 * parameters.
1067 */ 1086 */
1068 if (uvc_get_video_ctrl(video, probe, 1, GET_DEF) == 0) 1087 if (uvc_get_video_ctrl(stream, probe, 1, UVC_GET_DEF) == 0)
1069 uvc_set_video_ctrl(video, probe, 1); 1088 uvc_set_video_ctrl(stream, probe, 1);
1070 1089
1071 /* Initialize the streaming parameters with the probe control current 1090 /* Initialize the streaming parameters with the probe control current
1072 * value. This makes sure SET_CUR requests on the streaming commit 1091 * value. This makes sure SET_CUR requests on the streaming commit
1073 * control will always use values retrieved from a successful GET_CUR 1092 * control will always use values retrieved from a successful GET_CUR
1074 * request on the probe control, as required by the UVC specification. 1093 * request on the probe control, as required by the UVC specification.
1075 */ 1094 */
1076 if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0) 1095 ret = uvc_get_video_ctrl(stream, probe, 1, UVC_GET_CUR);
1096 if (ret < 0)
1077 return ret; 1097 return ret;
1078 1098
1079 /* Check if the default format descriptor exists. Use the first 1099 /* Check if the default format descriptor exists. Use the first
1080 * available format otherwise. 1100 * available format otherwise.
1081 */ 1101 */
1082 for (i = video->streaming->nformats; i > 0; --i) { 1102 for (i = stream->nformats; i > 0; --i) {
1083 format = &video->streaming->format[i-1]; 1103 format = &stream->format[i-1];
1084 if (format->index == probe->bFormatIndex) 1104 if (format->index == probe->bFormatIndex)
1085 break; 1105 break;
1086 } 1106 }
@@ -1105,21 +1125,20 @@ int uvc_video_init(struct uvc_video_device *video)
1105 probe->bFormatIndex = format->index; 1125 probe->bFormatIndex = format->index;
1106 probe->bFrameIndex = frame->bFrameIndex; 1126 probe->bFrameIndex = frame->bFrameIndex;
1107 1127
1108 video->streaming->cur_format = format; 1128 stream->cur_format = format;
1109 video->streaming->cur_frame = frame; 1129 stream->cur_frame = frame;
1110 atomic_set(&video->active, 0);
1111 1130
1112 /* Select the video decoding function */ 1131 /* Select the video decoding function */
1113 if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1132 if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1114 if (video->dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT) 1133 if (stream->dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT)
1115 video->decode = uvc_video_decode_isight; 1134 stream->decode = uvc_video_decode_isight;
1116 else if (video->streaming->intf->num_altsetting > 1) 1135 else if (stream->intf->num_altsetting > 1)
1117 video->decode = uvc_video_decode_isoc; 1136 stream->decode = uvc_video_decode_isoc;
1118 else 1137 else
1119 video->decode = uvc_video_decode_bulk; 1138 stream->decode = uvc_video_decode_bulk;
1120 } else { 1139 } else {
1121 if (video->streaming->intf->num_altsetting == 1) 1140 if (stream->intf->num_altsetting == 1)
1122 video->decode = uvc_video_encode_bulk; 1141 stream->decode = uvc_video_encode_bulk;
1123 else { 1142 else {
1124 uvc_printk(KERN_INFO, "Isochronous endpoints are not " 1143 uvc_printk(KERN_INFO, "Isochronous endpoints are not "
1125 "supported for video output devices.\n"); 1144 "supported for video output devices.\n");
@@ -1133,31 +1152,32 @@ int uvc_video_init(struct uvc_video_device *video)
1133/* 1152/*
1134 * Enable or disable the video stream. 1153 * Enable or disable the video stream.
1135 */ 1154 */
1136int uvc_video_enable(struct uvc_video_device *video, int enable) 1155int uvc_video_enable(struct uvc_streaming *stream, int enable)
1137{ 1156{
1138 int ret; 1157 int ret;
1139 1158
1140 if (!enable) { 1159 if (!enable) {
1141 uvc_uninit_video(video, 1); 1160 uvc_uninit_video(stream, 1);
1142 usb_set_interface(video->dev->udev, 1161 usb_set_interface(stream->dev->udev, stream->intfnum, 0);
1143 video->streaming->intfnum, 0); 1162 uvc_queue_enable(&stream->queue, 0);
1144 uvc_queue_enable(&video->queue, 0);
1145 return 0; 1163 return 0;
1146 } 1164 }
1147 1165
1148 if ((video->streaming->cur_format->flags & UVC_FMT_FLAG_COMPRESSED) || 1166 if ((stream->cur_format->flags & UVC_FMT_FLAG_COMPRESSED) ||
1149 uvc_no_drop_param) 1167 uvc_no_drop_param)
1150 video->queue.flags &= ~UVC_QUEUE_DROP_INCOMPLETE; 1168 stream->queue.flags &= ~UVC_QUEUE_DROP_INCOMPLETE;
1151 else 1169 else
1152 video->queue.flags |= UVC_QUEUE_DROP_INCOMPLETE; 1170 stream->queue.flags |= UVC_QUEUE_DROP_INCOMPLETE;
1153 1171
1154 if ((ret = uvc_queue_enable(&video->queue, 1)) < 0) 1172 ret = uvc_queue_enable(&stream->queue, 1);
1173 if (ret < 0)
1155 return ret; 1174 return ret;
1156 1175
1157 /* Commit the streaming parameters. */ 1176 /* Commit the streaming parameters. */
1158 if ((ret = uvc_commit_video(video, &video->streaming->ctrl)) < 0) 1177 ret = uvc_commit_video(stream, &stream->ctrl);
1178 if (ret < 0)
1159 return ret; 1179 return ret;
1160 1180
1161 return uvc_init_video(video, GFP_KERNEL); 1181 return uvc_init_video(stream, GFP_KERNEL);
1162} 1182}
1163 1183
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index 3c78d3c1e4c0..e7958aa454ce 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -67,155 +67,12 @@ struct uvc_xu_control {
67#ifdef __KERNEL__ 67#ifdef __KERNEL__
68 68
69#include <linux/poll.h> 69#include <linux/poll.h>
70#include <linux/usb/video.h>
70 71
71/* -------------------------------------------------------------------------- 72/* --------------------------------------------------------------------------
72 * UVC constants 73 * UVC constants
73 */ 74 */
74 75
75#define SC_UNDEFINED 0x00
76#define SC_VIDEOCONTROL 0x01
77#define SC_VIDEOSTREAMING 0x02
78#define SC_VIDEO_INTERFACE_COLLECTION 0x03
79
80#define PC_PROTOCOL_UNDEFINED 0x00
81
82#define CS_UNDEFINED 0x20
83#define CS_DEVICE 0x21
84#define CS_CONFIGURATION 0x22
85#define CS_STRING 0x23
86#define CS_INTERFACE 0x24
87#define CS_ENDPOINT 0x25
88
89/* VideoControl class specific interface descriptor */
90#define VC_DESCRIPTOR_UNDEFINED 0x00
91#define VC_HEADER 0x01
92#define VC_INPUT_TERMINAL 0x02
93#define VC_OUTPUT_TERMINAL 0x03
94#define VC_SELECTOR_UNIT 0x04
95#define VC_PROCESSING_UNIT 0x05
96#define VC_EXTENSION_UNIT 0x06
97
98/* VideoStreaming class specific interface descriptor */
99#define VS_UNDEFINED 0x00
100#define VS_INPUT_HEADER 0x01
101#define VS_OUTPUT_HEADER 0x02
102#define VS_STILL_IMAGE_FRAME 0x03
103#define VS_FORMAT_UNCOMPRESSED 0x04
104#define VS_FRAME_UNCOMPRESSED 0x05
105#define VS_FORMAT_MJPEG 0x06
106#define VS_FRAME_MJPEG 0x07
107#define VS_FORMAT_MPEG2TS 0x0a
108#define VS_FORMAT_DV 0x0c
109#define VS_COLORFORMAT 0x0d
110#define VS_FORMAT_FRAME_BASED 0x10
111#define VS_FRAME_FRAME_BASED 0x11
112#define VS_FORMAT_STREAM_BASED 0x12
113
114/* Endpoint type */
115#define EP_UNDEFINED 0x00
116#define EP_GENERAL 0x01
117#define EP_ENDPOINT 0x02
118#define EP_INTERRUPT 0x03
119
120/* Request codes */
121#define RC_UNDEFINED 0x00
122#define SET_CUR 0x01
123#define GET_CUR 0x81
124#define GET_MIN 0x82
125#define GET_MAX 0x83
126#define GET_RES 0x84
127#define GET_LEN 0x85
128#define GET_INFO 0x86
129#define GET_DEF 0x87
130
131/* VideoControl interface controls */
132#define VC_CONTROL_UNDEFINED 0x00
133#define VC_VIDEO_POWER_MODE_CONTROL 0x01
134#define VC_REQUEST_ERROR_CODE_CONTROL 0x02
135
136/* Terminal controls */
137#define TE_CONTROL_UNDEFINED 0x00
138
139/* Selector Unit controls */
140#define SU_CONTROL_UNDEFINED 0x00
141#define SU_INPUT_SELECT_CONTROL 0x01
142
143/* Camera Terminal controls */
144#define CT_CONTROL_UNDEFINED 0x00
145#define CT_SCANNING_MODE_CONTROL 0x01
146#define CT_AE_MODE_CONTROL 0x02
147#define CT_AE_PRIORITY_CONTROL 0x03
148#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04
149#define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05
150#define CT_FOCUS_ABSOLUTE_CONTROL 0x06
151#define CT_FOCUS_RELATIVE_CONTROL 0x07
152#define CT_FOCUS_AUTO_CONTROL 0x08
153#define CT_IRIS_ABSOLUTE_CONTROL 0x09
154#define CT_IRIS_RELATIVE_CONTROL 0x0a
155#define CT_ZOOM_ABSOLUTE_CONTROL 0x0b
156#define CT_ZOOM_RELATIVE_CONTROL 0x0c
157#define CT_PANTILT_ABSOLUTE_CONTROL 0x0d
158#define CT_PANTILT_RELATIVE_CONTROL 0x0e
159#define CT_ROLL_ABSOLUTE_CONTROL 0x0f
160#define CT_ROLL_RELATIVE_CONTROL 0x10
161#define CT_PRIVACY_CONTROL 0x11
162
163/* Processing Unit controls */
164#define PU_CONTROL_UNDEFINED 0x00
165#define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01
166#define PU_BRIGHTNESS_CONTROL 0x02
167#define PU_CONTRAST_CONTROL 0x03
168#define PU_GAIN_CONTROL 0x04
169#define PU_POWER_LINE_FREQUENCY_CONTROL 0x05
170#define PU_HUE_CONTROL 0x06
171#define PU_SATURATION_CONTROL 0x07
172#define PU_SHARPNESS_CONTROL 0x08
173#define PU_GAMMA_CONTROL 0x09
174#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0a
175#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0b
176#define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0c
177#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0d
178#define PU_DIGITAL_MULTIPLIER_CONTROL 0x0e
179#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0f
180#define PU_HUE_AUTO_CONTROL 0x10
181#define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11
182#define PU_ANALOG_LOCK_STATUS_CONTROL 0x12
183
184#define LXU_MOTOR_PANTILT_RELATIVE_CONTROL 0x01
185#define LXU_MOTOR_PANTILT_RESET_CONTROL 0x02
186#define LXU_MOTOR_FOCUS_MOTOR_CONTROL 0x03
187
188/* VideoStreaming interface controls */
189#define VS_CONTROL_UNDEFINED 0x00
190#define VS_PROBE_CONTROL 0x01
191#define VS_COMMIT_CONTROL 0x02
192#define VS_STILL_PROBE_CONTROL 0x03
193#define VS_STILL_COMMIT_CONTROL 0x04
194#define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05
195#define VS_STREAM_ERROR_CODE_CONTROL 0x06
196#define VS_GENERATE_KEY_FRAME_CONTROL 0x07
197#define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08
198#define VS_SYNC_DELAY_CONTROL 0x09
199
200#define TT_VENDOR_SPECIFIC 0x0100
201#define TT_STREAMING 0x0101
202
203/* Input Terminal types */
204#define ITT_VENDOR_SPECIFIC 0x0200
205#define ITT_CAMERA 0x0201
206#define ITT_MEDIA_TRANSPORT_INPUT 0x0202
207
208/* Output Terminal types */
209#define OTT_VENDOR_SPECIFIC 0x0300
210#define OTT_DISPLAY 0x0301
211#define OTT_MEDIA_TRANSPORT_OUTPUT 0x0302
212
213/* External Terminal types */
214#define EXTERNAL_VENDOR_SPECIFIC 0x0400
215#define COMPOSITE_CONNECTOR 0x0401
216#define SVIDEO_CONNECTOR 0x0402
217#define COMPONENT_CONNECTOR 0x0403
218
219#define UVC_TERM_INPUT 0x0000 76#define UVC_TERM_INPUT 0x0000
220#define UVC_TERM_OUTPUT 0x8000 77#define UVC_TERM_OUTPUT 0x8000
221 78
@@ -223,12 +80,12 @@ struct uvc_xu_control {
223#define UVC_ENTITY_IS_UNIT(entity) (((entity)->type & 0xff00) == 0) 80#define UVC_ENTITY_IS_UNIT(entity) (((entity)->type & 0xff00) == 0)
224#define UVC_ENTITY_IS_TERM(entity) (((entity)->type & 0xff00) != 0) 81#define UVC_ENTITY_IS_TERM(entity) (((entity)->type & 0xff00) != 0)
225#define UVC_ENTITY_IS_ITERM(entity) \ 82#define UVC_ENTITY_IS_ITERM(entity) \
226 (((entity)->type & 0x8000) == UVC_TERM_INPUT) 83 (UVC_ENTITY_IS_TERM(entity) && \
84 ((entity)->type & 0x8000) == UVC_TERM_INPUT)
227#define UVC_ENTITY_IS_OTERM(entity) \ 85#define UVC_ENTITY_IS_OTERM(entity) \
228 (((entity)->type & 0x8000) == UVC_TERM_OUTPUT) 86 (UVC_ENTITY_IS_TERM(entity) && \
87 ((entity)->type & 0x8000) == UVC_TERM_OUTPUT)
229 88
230#define UVC_STATUS_TYPE_CONTROL 1
231#define UVC_STATUS_TYPE_STREAMING 2
232 89
233/* ------------------------------------------------------------------------ 90/* ------------------------------------------------------------------------
234 * GUIDs 91 * GUIDs
@@ -249,19 +106,6 @@ struct uvc_xu_control {
249 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 106 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
250 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02} 107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02}
251 108
252#define UVC_GUID_LOGITECH_DEV_INFO \
253 {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \
254 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x1e}
255#define UVC_GUID_LOGITECH_USER_HW \
256 {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \
257 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x1f}
258#define UVC_GUID_LOGITECH_VIDEO \
259 {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \
260 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x50}
261#define UVC_GUID_LOGITECH_MOTOR \
262 {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \
263 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x56}
264
265#define UVC_GUID_FORMAT_MJPEG \ 109#define UVC_GUID_FORMAT_MJPEG \
266 { 'M', 'J', 'P', 'G', 0x00, 0x00, 0x10, 0x00, \ 110 { 'M', 'J', 'P', 'G', 0x00, 0x00, 0x10, 0x00, \
267 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} 111 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
@@ -314,6 +158,7 @@ struct uvc_xu_control {
314#define UVC_QUIRK_STREAM_NO_FID 0x00000010 158#define UVC_QUIRK_STREAM_NO_FID 0x00000010
315#define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 159#define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020
316#define UVC_QUIRK_FIX_BANDWIDTH 0x00000080 160#define UVC_QUIRK_FIX_BANDWIDTH 0x00000080
161#define UVC_QUIRK_PROBE_DEF 0x00000100
317 162
318/* Format flags */ 163/* Format flags */
319#define UVC_FMT_FLAG_COMPRESSED 0x00000001 164#define UVC_FMT_FLAG_COMPRESSED 0x00000001
@@ -518,26 +363,6 @@ struct uvc_streaming_header {
518 __u8 bTriggerUsage; 363 __u8 bTriggerUsage;
519}; 364};
520 365
521struct uvc_streaming {
522 struct list_head list;
523
524 struct usb_interface *intf;
525 int intfnum;
526 __u16 maxpsize;
527
528 struct uvc_streaming_header header;
529 enum v4l2_buf_type type;
530
531 unsigned int nformats;
532 struct uvc_format *format;
533
534 struct uvc_streaming_control ctrl;
535 struct uvc_format *cur_format;
536 struct uvc_frame *cur_frame;
537
538 struct mutex mutex;
539};
540
541enum uvc_buffer_state { 366enum uvc_buffer_state {
542 UVC_BUF_STATE_IDLE = 0, 367 UVC_BUF_STATE_IDLE = 0,
543 UVC_BUF_STATE_QUEUED = 1, 368 UVC_BUF_STATE_QUEUED = 1,
@@ -579,26 +404,45 @@ struct uvc_video_queue {
579 struct list_head irqqueue; 404 struct list_head irqqueue;
580}; 405};
581 406
582struct uvc_video_device { 407struct uvc_video_chain {
583 struct uvc_device *dev; 408 struct uvc_device *dev;
584 struct video_device *vdev; 409 struct list_head list;
585 atomic_t active;
586 unsigned int frozen : 1;
587 410
588 struct list_head iterms; /* Input terminals */ 411 struct list_head iterms; /* Input terminals */
589 struct uvc_entity *oterm; /* Output terminal */ 412 struct list_head oterms; /* Output terminals */
590 struct uvc_entity *sterm; /* USB streaming terminal */ 413 struct uvc_entity *processing; /* Processing unit */
591 struct uvc_entity *processing; 414 struct uvc_entity *selector; /* Selector unit */
592 struct uvc_entity *selector; 415 struct list_head extensions; /* Extension units */
593 struct list_head extensions; 416
594 struct mutex ctrl_mutex; 417 struct mutex ctrl_mutex;
418};
595 419
596 struct uvc_video_queue queue; 420struct uvc_streaming {
421 struct list_head list;
422 struct uvc_device *dev;
423 struct video_device *vdev;
424 struct uvc_video_chain *chain;
425 atomic_t active;
597 426
598 /* Video streaming object, must always be non-NULL. */ 427 struct usb_interface *intf;
599 struct uvc_streaming *streaming; 428 int intfnum;
429 __u16 maxpsize;
600 430
601 void (*decode) (struct urb *urb, struct uvc_video_device *video, 431 struct uvc_streaming_header header;
432 enum v4l2_buf_type type;
433
434 unsigned int nformats;
435 struct uvc_format *format;
436
437 struct uvc_streaming_control ctrl;
438 struct uvc_format *cur_format;
439 struct uvc_frame *cur_frame;
440
441 struct mutex mutex;
442
443 unsigned int frozen : 1;
444 struct uvc_video_queue queue;
445 void (*decode) (struct urb *urb, struct uvc_streaming *video,
602 struct uvc_buffer *buf); 446 struct uvc_buffer *buf);
603 447
604 /* Context data used by the bulk completion handler. */ 448 /* Context data used by the bulk completion handler. */
@@ -640,8 +484,10 @@ struct uvc_device {
640 __u32 clock_frequency; 484 __u32 clock_frequency;
641 485
642 struct list_head entities; 486 struct list_head entities;
487 struct list_head chains;
643 488
644 struct uvc_video_device video; 489 /* Video Streaming interfaces */
490 struct list_head streams;
645 491
646 /* Status Interrupt Endpoint */ 492 /* Status Interrupt Endpoint */
647 struct usb_host_endpoint *int_ep; 493 struct usb_host_endpoint *int_ep;
@@ -649,9 +495,6 @@ struct uvc_device {
649 __u8 *status; 495 __u8 *status;
650 struct input_dev *input; 496 struct input_dev *input;
651 char input_phys[64]; 497 char input_phys[64];
652
653 /* Video Streaming interfaces */
654 struct list_head streaming;
655}; 498};
656 499
657enum uvc_handle_state { 500enum uvc_handle_state {
@@ -660,7 +503,8 @@ enum uvc_handle_state {
660}; 503};
661 504
662struct uvc_fh { 505struct uvc_fh {
663 struct uvc_video_device *device; 506 struct uvc_video_chain *chain;
507 struct uvc_streaming *stream;
664 enum uvc_handle_state state; 508 enum uvc_handle_state state;
665}; 509};
666 510
@@ -757,13 +601,13 @@ static inline int uvc_queue_streaming(struct uvc_video_queue *queue)
757extern const struct v4l2_file_operations uvc_fops; 601extern const struct v4l2_file_operations uvc_fops;
758 602
759/* Video */ 603/* Video */
760extern int uvc_video_init(struct uvc_video_device *video); 604extern int uvc_video_init(struct uvc_streaming *stream);
761extern int uvc_video_suspend(struct uvc_video_device *video); 605extern int uvc_video_suspend(struct uvc_streaming *stream);
762extern int uvc_video_resume(struct uvc_video_device *video); 606extern int uvc_video_resume(struct uvc_streaming *stream);
763extern int uvc_video_enable(struct uvc_video_device *video, int enable); 607extern int uvc_video_enable(struct uvc_streaming *stream, int enable);
764extern int uvc_probe_video(struct uvc_video_device *video, 608extern int uvc_probe_video(struct uvc_streaming *stream,
765 struct uvc_streaming_control *probe); 609 struct uvc_streaming_control *probe);
766extern int uvc_commit_video(struct uvc_video_device *video, 610extern int uvc_commit_video(struct uvc_streaming *stream,
767 struct uvc_streaming_control *ctrl); 611 struct uvc_streaming_control *ctrl);
768extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, 612extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
769 __u8 intfnum, __u8 cs, void *data, __u16 size); 613 __u8 intfnum, __u8 cs, void *data, __u16 size);
@@ -777,9 +621,9 @@ extern int uvc_status_suspend(struct uvc_device *dev);
777extern int uvc_status_resume(struct uvc_device *dev); 621extern int uvc_status_resume(struct uvc_device *dev);
778 622
779/* Controls */ 623/* Controls */
780extern struct uvc_control *uvc_find_control(struct uvc_video_device *video, 624extern struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
781 __u32 v4l2_id, struct uvc_control_mapping **mapping); 625 __u32 v4l2_id, struct uvc_control_mapping **mapping);
782extern int uvc_query_v4l2_ctrl(struct uvc_video_device *video, 626extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
783 struct v4l2_queryctrl *v4l2_ctrl); 627 struct v4l2_queryctrl *v4l2_ctrl);
784 628
785extern int uvc_ctrl_add_info(struct uvc_control_info *info); 629extern int uvc_ctrl_add_info(struct uvc_control_info *info);
@@ -789,23 +633,23 @@ extern void uvc_ctrl_cleanup_device(struct uvc_device *dev);
789extern int uvc_ctrl_resume_device(struct uvc_device *dev); 633extern int uvc_ctrl_resume_device(struct uvc_device *dev);
790extern void uvc_ctrl_init(void); 634extern void uvc_ctrl_init(void);
791 635
792extern int uvc_ctrl_begin(struct uvc_video_device *video); 636extern int uvc_ctrl_begin(struct uvc_video_chain *chain);
793extern int __uvc_ctrl_commit(struct uvc_video_device *video, int rollback); 637extern int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback);
794static inline int uvc_ctrl_commit(struct uvc_video_device *video) 638static inline int uvc_ctrl_commit(struct uvc_video_chain *chain)
795{ 639{
796 return __uvc_ctrl_commit(video, 0); 640 return __uvc_ctrl_commit(chain, 0);
797} 641}
798static inline int uvc_ctrl_rollback(struct uvc_video_device *video) 642static inline int uvc_ctrl_rollback(struct uvc_video_chain *chain)
799{ 643{
800 return __uvc_ctrl_commit(video, 1); 644 return __uvc_ctrl_commit(chain, 1);
801} 645}
802 646
803extern int uvc_ctrl_get(struct uvc_video_device *video, 647extern int uvc_ctrl_get(struct uvc_video_chain *chain,
804 struct v4l2_ext_control *xctrl); 648 struct v4l2_ext_control *xctrl);
805extern int uvc_ctrl_set(struct uvc_video_device *video, 649extern int uvc_ctrl_set(struct uvc_video_chain *chain,
806 struct v4l2_ext_control *xctrl); 650 struct v4l2_ext_control *xctrl);
807 651
808extern int uvc_xu_ctrl_query(struct uvc_video_device *video, 652extern int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
809 struct uvc_xu_control *ctrl, int set); 653 struct uvc_xu_control *ctrl, int set);
810 654
811/* Utility functions */ 655/* Utility functions */
@@ -817,7 +661,7 @@ extern struct usb_host_endpoint *uvc_find_endpoint(
817 struct usb_host_interface *alts, __u8 epaddr); 661 struct usb_host_interface *alts, __u8 epaddr);
818 662
819/* Quirks support */ 663/* Quirks support */
820void uvc_video_decode_isight(struct urb *urb, struct uvc_video_device *video, 664void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream,
821 struct uvc_buffer *buf); 665 struct uvc_buffer *buf);
822 666
823#endif /* __KERNEL__ */ 667#endif /* __KERNEL__ */
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index 02f2a6d18b45..761fbd64db58 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -76,9 +76,8 @@ get_v4l_control(struct file *file,
76 dprintk("VIDIOC_G_CTRL: %d\n", err); 76 dprintk("VIDIOC_G_CTRL: %d\n", err);
77 return 0; 77 return 0;
78 } 78 }
79 return ((ctrl2.value - qctrl2.minimum) * 65535 79 return DIV_ROUND_CLOSEST((ctrl2.value-qctrl2.minimum) * 65535,
80 + (qctrl2.maximum - qctrl2.minimum) / 2) 80 qctrl2.maximum - qctrl2.minimum);
81 / (qctrl2.maximum - qctrl2.minimum);
82 } 81 }
83 return 0; 82 return 0;
84} 83}
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index b91d66a767d7..3a0c64935b0e 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -156,6 +156,8 @@ int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl,
156 return -EINVAL; 156 return -EINVAL;
157 if (qctrl->flags & V4L2_CTRL_FLAG_GRABBED) 157 if (qctrl->flags & V4L2_CTRL_FLAG_GRABBED)
158 return -EBUSY; 158 return -EBUSY;
159 if (qctrl->type == V4L2_CTRL_TYPE_STRING)
160 return 0;
159 if (qctrl->type == V4L2_CTRL_TYPE_BUTTON || 161 if (qctrl->type == V4L2_CTRL_TYPE_BUTTON ||
160 qctrl->type == V4L2_CTRL_TYPE_INTEGER64 || 162 qctrl->type == V4L2_CTRL_TYPE_INTEGER64 ||
161 qctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS) 163 qctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS)
@@ -340,6 +342,12 @@ const char **v4l2_ctrl_get_menu(u32 id)
340 "Sepia", 342 "Sepia",
341 NULL 343 NULL
342 }; 344 };
345 static const char *tune_preemphasis[] = {
346 "No preemphasis",
347 "50 useconds",
348 "75 useconds",
349 NULL,
350 };
343 351
344 switch (id) { 352 switch (id) {
345 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: 353 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
@@ -378,6 +386,8 @@ const char **v4l2_ctrl_get_menu(u32 id)
378 return camera_exposure_auto; 386 return camera_exposure_auto;
379 case V4L2_CID_COLORFX: 387 case V4L2_CID_COLORFX:
380 return colorfx; 388 return colorfx;
389 case V4L2_CID_TUNE_PREEMPHASIS:
390 return tune_preemphasis;
381 default: 391 default:
382 return NULL; 392 return NULL;
383 } 393 }
@@ -476,6 +486,28 @@ const char *v4l2_ctrl_get_name(u32 id)
476 case V4L2_CID_ZOOM_CONTINUOUS: return "Zoom, Continuous"; 486 case V4L2_CID_ZOOM_CONTINUOUS: return "Zoom, Continuous";
477 case V4L2_CID_PRIVACY: return "Privacy"; 487 case V4L2_CID_PRIVACY: return "Privacy";
478 488
489 /* FM Radio Modulator control */
490 case V4L2_CID_FM_TX_CLASS: return "FM Radio Modulator Controls";
491 case V4L2_CID_RDS_TX_DEVIATION: return "RDS Signal Deviation";
492 case V4L2_CID_RDS_TX_PI: return "RDS Program ID";
493 case V4L2_CID_RDS_TX_PTY: return "RDS Program Type";
494 case V4L2_CID_RDS_TX_PS_NAME: return "RDS PS Name";
495 case V4L2_CID_RDS_TX_RADIO_TEXT: return "RDS Radio Text";
496 case V4L2_CID_AUDIO_LIMITER_ENABLED: return "Audio Limiter Feature Enabled";
497 case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: return "Audio Limiter Release Time";
498 case V4L2_CID_AUDIO_LIMITER_DEVIATION: return "Audio Limiter Deviation";
499 case V4L2_CID_AUDIO_COMPRESSION_ENABLED: return "Audio Compression Feature Enabled";
500 case V4L2_CID_AUDIO_COMPRESSION_GAIN: return "Audio Compression Gain";
501 case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD: return "Audio Compression Threshold";
502 case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME: return "Audio Compression Attack Time";
503 case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME: return "Audio Compression Release Time";
504 case V4L2_CID_PILOT_TONE_ENABLED: return "Pilot Tone Feature Enabled";
505 case V4L2_CID_PILOT_TONE_DEVIATION: return "Pilot Tone Deviation";
506 case V4L2_CID_PILOT_TONE_FREQUENCY: return "Pilot Tone Frequency";
507 case V4L2_CID_TUNE_PREEMPHASIS: return "Pre-emphasis settings";
508 case V4L2_CID_TUNE_POWER_LEVEL: return "Tune Power Level";
509 case V4L2_CID_TUNE_ANTENNA_CAPACITOR: return "Tune Antenna Capacitor";
510
479 default: 511 default:
480 return NULL; 512 return NULL;
481 } 513 }
@@ -508,6 +540,9 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
508 case V4L2_CID_EXPOSURE_AUTO_PRIORITY: 540 case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
509 case V4L2_CID_FOCUS_AUTO: 541 case V4L2_CID_FOCUS_AUTO:
510 case V4L2_CID_PRIVACY: 542 case V4L2_CID_PRIVACY:
543 case V4L2_CID_AUDIO_LIMITER_ENABLED:
544 case V4L2_CID_AUDIO_COMPRESSION_ENABLED:
545 case V4L2_CID_PILOT_TONE_ENABLED:
511 qctrl->type = V4L2_CTRL_TYPE_BOOLEAN; 546 qctrl->type = V4L2_CTRL_TYPE_BOOLEAN;
512 min = 0; 547 min = 0;
513 max = step = 1; 548 max = step = 1;
@@ -536,12 +571,18 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
536 case V4L2_CID_MPEG_STREAM_VBI_FMT: 571 case V4L2_CID_MPEG_STREAM_VBI_FMT:
537 case V4L2_CID_EXPOSURE_AUTO: 572 case V4L2_CID_EXPOSURE_AUTO:
538 case V4L2_CID_COLORFX: 573 case V4L2_CID_COLORFX:
574 case V4L2_CID_TUNE_PREEMPHASIS:
539 qctrl->type = V4L2_CTRL_TYPE_MENU; 575 qctrl->type = V4L2_CTRL_TYPE_MENU;
540 step = 1; 576 step = 1;
541 break; 577 break;
578 case V4L2_CID_RDS_TX_PS_NAME:
579 case V4L2_CID_RDS_TX_RADIO_TEXT:
580 qctrl->type = V4L2_CTRL_TYPE_STRING;
581 break;
542 case V4L2_CID_USER_CLASS: 582 case V4L2_CID_USER_CLASS:
543 case V4L2_CID_CAMERA_CLASS: 583 case V4L2_CID_CAMERA_CLASS:
544 case V4L2_CID_MPEG_CLASS: 584 case V4L2_CID_MPEG_CLASS:
585 case V4L2_CID_FM_TX_CLASS:
545 qctrl->type = V4L2_CTRL_TYPE_CTRL_CLASS; 586 qctrl->type = V4L2_CTRL_TYPE_CTRL_CLASS;
546 qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; 587 qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
547 min = max = step = def = 0; 588 min = max = step = def = 0;
@@ -570,6 +611,17 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
570 case V4L2_CID_BLUE_BALANCE: 611 case V4L2_CID_BLUE_BALANCE:
571 case V4L2_CID_GAMMA: 612 case V4L2_CID_GAMMA:
572 case V4L2_CID_SHARPNESS: 613 case V4L2_CID_SHARPNESS:
614 case V4L2_CID_RDS_TX_DEVIATION:
615 case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME:
616 case V4L2_CID_AUDIO_LIMITER_DEVIATION:
617 case V4L2_CID_AUDIO_COMPRESSION_GAIN:
618 case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD:
619 case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME:
620 case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME:
621 case V4L2_CID_PILOT_TONE_DEVIATION:
622 case V4L2_CID_PILOT_TONE_FREQUENCY:
623 case V4L2_CID_TUNE_POWER_LEVEL:
624 case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
573 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; 625 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
574 break; 626 break;
575 case V4L2_CID_PAN_RELATIVE: 627 case V4L2_CID_PAN_RELATIVE:
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index 0056b115b42e..997975d5e024 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -600,9 +600,37 @@ struct v4l2_ext_controls32 {
600 compat_caddr_t controls; /* actually struct v4l2_ext_control32 * */ 600 compat_caddr_t controls; /* actually struct v4l2_ext_control32 * */
601}; 601};
602 602
603struct v4l2_ext_control32 {
604 __u32 id;
605 __u32 size;
606 __u32 reserved2[1];
607 union {
608 __s32 value;
609 __s64 value64;
610 compat_caddr_t string; /* actually char * */
611 };
612} __attribute__ ((packed));
613
614/* The following function really belong in v4l2-common, but that causes
615 a circular dependency between modules. We need to think about this, but
616 for now this will do. */
617
618/* Return non-zero if this control is a pointer type. Currently only
619 type STRING is a pointer type. */
620static inline int ctrl_is_pointer(u32 id)
621{
622 switch (id) {
623 case V4L2_CID_RDS_TX_PS_NAME:
624 case V4L2_CID_RDS_TX_RADIO_TEXT:
625 return 1;
626 default:
627 return 0;
628 }
629}
630
603static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up) 631static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up)
604{ 632{
605 struct v4l2_ext_control __user *ucontrols; 633 struct v4l2_ext_control32 __user *ucontrols;
606 struct v4l2_ext_control __user *kcontrols; 634 struct v4l2_ext_control __user *kcontrols;
607 int n; 635 int n;
608 compat_caddr_t p; 636 compat_caddr_t p;
@@ -626,15 +654,17 @@ static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
626 kcontrols = compat_alloc_user_space(n * sizeof(struct v4l2_ext_control)); 654 kcontrols = compat_alloc_user_space(n * sizeof(struct v4l2_ext_control));
627 kp->controls = kcontrols; 655 kp->controls = kcontrols;
628 while (--n >= 0) { 656 while (--n >= 0) {
629 if (copy_in_user(&kcontrols->id, &ucontrols->id, sizeof(__u32))) 657 if (copy_in_user(kcontrols, ucontrols, sizeof(*kcontrols)))
630 return -EFAULT;
631 if (copy_in_user(&kcontrols->reserved2, &ucontrols->reserved2, sizeof(ucontrols->reserved2)))
632 return -EFAULT;
633 /* Note: if the void * part of the union ever becomes relevant
634 then we need to know the type of the control in order to do
635 the right thing here. Luckily, that is not yet an issue. */
636 if (copy_in_user(&kcontrols->value, &ucontrols->value, sizeof(ucontrols->value)))
637 return -EFAULT; 658 return -EFAULT;
659 if (ctrl_is_pointer(kcontrols->id)) {
660 void __user *s;
661
662 if (get_user(p, &ucontrols->string))
663 return -EFAULT;
664 s = compat_ptr(p);
665 if (put_user(s, &kcontrols->string))
666 return -EFAULT;
667 }
638 ucontrols++; 668 ucontrols++;
639 kcontrols++; 669 kcontrols++;
640 } 670 }
@@ -643,7 +673,7 @@ static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
643 673
644static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up) 674static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up)
645{ 675{
646 struct v4l2_ext_control __user *ucontrols; 676 struct v4l2_ext_control32 __user *ucontrols;
647 struct v4l2_ext_control __user *kcontrols = kp->controls; 677 struct v4l2_ext_control __user *kcontrols = kp->controls;
648 int n = kp->count; 678 int n = kp->count;
649 compat_caddr_t p; 679 compat_caddr_t p;
@@ -664,15 +694,14 @@ static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
664 return -EFAULT; 694 return -EFAULT;
665 695
666 while (--n >= 0) { 696 while (--n >= 0) {
667 if (copy_in_user(&ucontrols->id, &kcontrols->id, sizeof(__u32))) 697 unsigned size = sizeof(*ucontrols);
668 return -EFAULT; 698
669 if (copy_in_user(&ucontrols->reserved2, &kcontrols->reserved2, 699 /* Do not modify the pointer when copying a pointer control.
670 sizeof(ucontrols->reserved2))) 700 The contents of the pointer was changed, not the pointer
671 return -EFAULT; 701 itself. */
672 /* Note: if the void * part of the union ever becomes relevant 702 if (ctrl_is_pointer(kcontrols->id))
673 then we need to know the type of the control in order to do 703 size -= sizeof(ucontrols->value64);
674 the right thing here. Luckily, that is not yet an issue. */ 704 if (copy_in_user(ucontrols, kcontrols, size))
675 if (copy_in_user(&ucontrols->value, &kcontrols->value, sizeof(ucontrols->value)))
676 return -EFAULT; 705 return -EFAULT;
677 ucontrols++; 706 ucontrols++;
678 kcontrols++; 707 kcontrols++;
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index f2afc4e08379..30cc3347ae52 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -42,6 +42,12 @@
42 printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\ 42 printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\
43 } while (0) 43 } while (0)
44 44
45#define dbgarg3(fmt, arg...) \
46 do { \
47 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \
48 printk(KERN_CONT "%s: " fmt, vfd->name, ## arg);\
49 } while (0)
50
45/* Zero out the end of the struct pointed to by p. Everthing after, but 51/* Zero out the end of the struct pointed to by p. Everthing after, but
46 * not including, the specified field is cleared. */ 52 * not including, the specified field is cleared. */
47#define CLEAR_AFTER_FIELD(p, field) \ 53#define CLEAR_AFTER_FIELD(p, field) \
@@ -507,11 +513,12 @@ static inline void v4l_print_ext_ctrls(unsigned int cmd,
507 dbgarg(cmd, ""); 513 dbgarg(cmd, "");
508 printk(KERN_CONT "class=0x%x", c->ctrl_class); 514 printk(KERN_CONT "class=0x%x", c->ctrl_class);
509 for (i = 0; i < c->count; i++) { 515 for (i = 0; i < c->count; i++) {
510 if (show_vals) 516 if (show_vals && !c->controls[i].size)
511 printk(KERN_CONT " id/val=0x%x/0x%x", 517 printk(KERN_CONT " id/val=0x%x/0x%x",
512 c->controls[i].id, c->controls[i].value); 518 c->controls[i].id, c->controls[i].value);
513 else 519 else
514 printk(KERN_CONT " id=0x%x", c->controls[i].id); 520 printk(KERN_CONT " id=0x%x,size=%u",
521 c->controls[i].id, c->controls[i].size);
515 } 522 }
516 printk(KERN_CONT "\n"); 523 printk(KERN_CONT "\n");
517}; 524};
@@ -522,10 +529,9 @@ static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
522 529
523 /* zero the reserved fields */ 530 /* zero the reserved fields */
524 c->reserved[0] = c->reserved[1] = 0; 531 c->reserved[0] = c->reserved[1] = 0;
525 for (i = 0; i < c->count; i++) { 532 for (i = 0; i < c->count; i++)
526 c->controls[i].reserved2[0] = 0; 533 c->controls[i].reserved2[0] = 0;
527 c->controls[i].reserved2[1] = 0; 534
528 }
529 /* V4L2_CID_PRIVATE_BASE cannot be used as control class 535 /* V4L2_CID_PRIVATE_BASE cannot be used as control class
530 when using extended controls. 536 when using extended controls.
531 Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL 537 Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
@@ -1726,24 +1732,29 @@ static long __video_do_ioctl(struct file *file,
1726 1732
1727 ret = ops->vidioc_enum_framesizes(file, fh, p); 1733 ret = ops->vidioc_enum_framesizes(file, fh, p);
1728 dbgarg(cmd, 1734 dbgarg(cmd,
1729 "index=%d, pixelformat=%d, type=%d ", 1735 "index=%d, pixelformat=%c%c%c%c, type=%d ",
1730 p->index, p->pixel_format, p->type); 1736 p->index,
1737 (p->pixel_format & 0xff),
1738 (p->pixel_format >> 8) & 0xff,
1739 (p->pixel_format >> 16) & 0xff,
1740 (p->pixel_format >> 24) & 0xff,
1741 p->type);
1731 switch (p->type) { 1742 switch (p->type) {
1732 case V4L2_FRMSIZE_TYPE_DISCRETE: 1743 case V4L2_FRMSIZE_TYPE_DISCRETE:
1733 dbgarg2("width = %d, height=%d\n", 1744 dbgarg3("width = %d, height=%d\n",
1734 p->discrete.width, p->discrete.height); 1745 p->discrete.width, p->discrete.height);
1735 break; 1746 break;
1736 case V4L2_FRMSIZE_TYPE_STEPWISE: 1747 case V4L2_FRMSIZE_TYPE_STEPWISE:
1737 dbgarg2("min %dx%d, max %dx%d, step %dx%d\n", 1748 dbgarg3("min %dx%d, max %dx%d, step %dx%d\n",
1738 p->stepwise.min_width, p->stepwise.min_height, 1749 p->stepwise.min_width, p->stepwise.min_height,
1739 p->stepwise.step_width, p->stepwise.step_height, 1750 p->stepwise.step_width, p->stepwise.step_height,
1740 p->stepwise.max_width, p->stepwise.max_height); 1751 p->stepwise.max_width, p->stepwise.max_height);
1741 break; 1752 break;
1742 case V4L2_FRMSIZE_TYPE_CONTINUOUS: 1753 case V4L2_FRMSIZE_TYPE_CONTINUOUS:
1743 dbgarg2("continuous\n"); 1754 dbgarg3("continuous\n");
1744 break; 1755 break;
1745 default: 1756 default:
1746 dbgarg2("- Unknown type!\n"); 1757 dbgarg3("- Unknown type!\n");
1747 } 1758 }
1748 1759
1749 break; 1760 break;
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index 97b082fe4473..f3b6e15d91f2 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -1776,7 +1776,6 @@ static struct i2c_algo_sgi_data i2c_sgi_vino_data = {
1776 1776
1777static struct i2c_adapter vino_i2c_adapter = { 1777static struct i2c_adapter vino_i2c_adapter = {
1778 .name = "VINO I2C bus", 1778 .name = "VINO I2C bus",
1779 .id = I2C_HW_SGI_VINO,
1780 .algo = &sgi_algo, 1779 .algo = &sgi_algo,
1781 .algo_data = &i2c_sgi_vino_data, 1780 .algo_data = &i2c_sgi_vino_data,
1782 .owner = THIS_MODULE, 1781 .owner = THIS_MODULE,
diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c
index 6c3f23e31b5c..602484dd3da9 100644
--- a/drivers/media/video/w9968cf.c
+++ b/drivers/media/video/w9968cf.c
@@ -1497,7 +1497,6 @@ static int w9968cf_i2c_init(struct w9968cf_device* cam)
1497 }; 1497 };
1498 1498
1499 static struct i2c_adapter adap = { 1499 static struct i2c_adapter adap = {
1500 .id = I2C_HW_SMBUS_W9968CF,
1501 .owner = THIS_MODULE, 1500 .owner = THIS_MODULE,
1502 .algo = &algo, 1501 .algo = &algo,
1503 }; 1502 };
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index 03dc2f3cf84a..0c4d9b1f8e6f 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -732,7 +732,6 @@ zoran_register_i2c (struct zoran *zr)
732 memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template, 732 memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template,
733 sizeof(struct i2c_algo_bit_data)); 733 sizeof(struct i2c_algo_bit_data));
734 zr->i2c_algo.data = zr; 734 zr->i2c_algo.data = zr;
735 zr->i2c_adapter.id = I2C_HW_B_ZR36067;
736 strlcpy(zr->i2c_adapter.name, ZR_DEVNAME(zr), 735 strlcpy(zr->i2c_adapter.name, ZR_DEVNAME(zr),
737 sizeof(zr->i2c_adapter.name)); 736 sizeof(zr->i2c_adapter.name));
738 i2c_set_adapdata(&zr->i2c_adapter, &zr->v4l2_dev); 737 i2c_set_adapdata(&zr->i2c_adapter, &zr->v4l2_dev);
@@ -1169,7 +1168,7 @@ zoran_setup_videocodec (struct zoran *zr,
1169 m->type = 0; 1168 m->type = 0;
1170 1169
1171 m->flags = CODEC_FLAG_ENCODER | CODEC_FLAG_DECODER; 1170 m->flags = CODEC_FLAG_ENCODER | CODEC_FLAG_DECODER;
1172 strncpy(m->name, ZR_DEVNAME(zr), sizeof(m->name)); 1171 strlcpy(m->name, ZR_DEVNAME(zr), sizeof(m->name));
1173 m->data = zr; 1172 m->data = zr;
1174 1173
1175 switch (type) 1174 switch (type)
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index 2622a6e63da1..9aae011d92ab 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Zoran 364xx based USB webcam module version 0.72 2 * Zoran 364xx based USB webcam module version 0.73
3 * 3 *
4 * Allows you to use your USB webcam with V4L2 applications 4 * Allows you to use your USB webcam with V4L2 applications
5 * This is still in heavy developpement ! 5 * This is still in heavy developpement !
@@ -10,6 +10,8 @@
10 * Heavily inspired by usb-skeleton.c, vicam.c, cpia.c and spca50x.c drivers 10 * Heavily inspired by usb-skeleton.c, vicam.c, cpia.c and spca50x.c drivers
11 * V4L2 version inspired by meye.c driver 11 * V4L2 version inspired by meye.c driver
12 * 12 *
13 * Some video buffer code by Lamarque based on s2255drv.c and vivi.c drivers.
14 *
13 * This program is free software; you can redistribute it and/or modify 15 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by 16 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or 17 * the Free Software Foundation; either version 2 of the License, or
@@ -27,6 +29,7 @@
27 29
28 30
29#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/version.h>
30#include <linux/init.h> 33#include <linux/init.h>
31#include <linux/usb.h> 34#include <linux/usb.h>
32#include <linux/vmalloc.h> 35#include <linux/vmalloc.h>
@@ -35,24 +38,40 @@
35#include <linux/highmem.h> 38#include <linux/highmem.h>
36#include <media/v4l2-common.h> 39#include <media/v4l2-common.h>
37#include <media/v4l2-ioctl.h> 40#include <media/v4l2-ioctl.h>
41#include <media/videobuf-vmalloc.h>
38 42
39 43
40/* Version Information */ 44/* Version Information */
41#define DRIVER_VERSION "v0.72" 45#define DRIVER_VERSION "v0.73"
46#define ZR364XX_VERSION_CODE KERNEL_VERSION(0, 7, 3)
42#define DRIVER_AUTHOR "Antoine Jacquet, http://royale.zerezo.com/" 47#define DRIVER_AUTHOR "Antoine Jacquet, http://royale.zerezo.com/"
43#define DRIVER_DESC "Zoran 364xx" 48#define DRIVER_DESC "Zoran 364xx"
44 49
45 50
46/* Camera */ 51/* Camera */
47#define FRAMES 2 52#define FRAMES 1
48#define MAX_FRAME_SIZE 100000 53#define MAX_FRAME_SIZE 200000
49#define BUFFER_SIZE 0x1000 54#define BUFFER_SIZE 0x1000
50#define CTRL_TIMEOUT 500 55#define CTRL_TIMEOUT 500
51 56
57#define ZR364XX_DEF_BUFS 4
58#define ZR364XX_READ_IDLE 0
59#define ZR364XX_READ_FRAME 1
52 60
53/* Debug macro */ 61/* Debug macro */
54#define DBG(x...) if (debug) printk(KERN_INFO KBUILD_MODNAME x) 62#define DBG(fmt, args...) \
55 63 do { \
64 if (debug) { \
65 printk(KERN_INFO KBUILD_MODNAME " " fmt, ##args); \
66 } \
67 } while (0)
68
69/*#define FULL_DEBUG 1*/
70#ifdef FULL_DEBUG
71#define _DBG DBG
72#else
73#define _DBG(fmt, args...)
74#endif
56 75
57/* Init methods, need to find nicer names for these 76/* Init methods, need to find nicer names for these
58 * the exact names of the chipsets would be the best if someone finds it */ 77 * the exact names of the chipsets would be the best if someone finds it */
@@ -101,24 +120,93 @@ static struct usb_device_id device_table[] = {
101 120
102MODULE_DEVICE_TABLE(usb, device_table); 121MODULE_DEVICE_TABLE(usb, device_table);
103 122
123struct zr364xx_mode {
124 u32 color; /* output video color format */
125 u32 brightness; /* brightness */
126};
127
128/* frame structure */
129struct zr364xx_framei {
130 unsigned long ulState; /* ulState:ZR364XX_READ_IDLE,
131 ZR364XX_READ_FRAME */
132 void *lpvbits; /* image data */
133 unsigned long cur_size; /* current data copied to it */
134};
135
136/* image buffer structure */
137struct zr364xx_bufferi {
138 unsigned long dwFrames; /* number of frames in buffer */
139 struct zr364xx_framei frame[FRAMES]; /* array of FRAME structures */
140};
141
142struct zr364xx_dmaqueue {
143 struct list_head active;
144 struct zr364xx_camera *cam;
145};
146
147struct zr364xx_pipeinfo {
148 u32 transfer_size;
149 u8 *transfer_buffer;
150 u32 state;
151 void *stream_urb;
152 void *cam; /* back pointer to zr364xx_camera struct */
153 u32 err_count;
154 u32 idx;
155};
156
157struct zr364xx_fmt {
158 char *name;
159 u32 fourcc;
160 int depth;
161};
162
163/* image formats. */
164static const struct zr364xx_fmt formats[] = {
165 {
166 .name = "JPG",
167 .fourcc = V4L2_PIX_FMT_JPEG,
168 .depth = 24
169 }
170};
104 171
105/* Camera stuff */ 172/* Camera stuff */
106struct zr364xx_camera { 173struct zr364xx_camera {
107 struct usb_device *udev; /* save off the usb device pointer */ 174 struct usb_device *udev; /* save off the usb device pointer */
108 struct usb_interface *interface;/* the interface for this device */ 175 struct usb_interface *interface;/* the interface for this device */
109 struct video_device *vdev; /* v4l video device */ 176 struct video_device *vdev; /* v4l video device */
110 u8 *framebuf;
111 int nb; 177 int nb;
112 unsigned char *buffer; 178 struct zr364xx_bufferi buffer;
113 int skip; 179 int skip;
114 int brightness;
115 int width; 180 int width;
116 int height; 181 int height;
117 int method; 182 int method;
118 struct mutex lock; 183 struct mutex lock;
184 struct mutex open_lock;
119 int users; 185 int users;
186
187 spinlock_t slock;
188 struct zr364xx_dmaqueue vidq;
189 int resources;
190 int last_frame;
191 int cur_frame;
192 unsigned long frame_count;
193 int b_acquire;
194 struct zr364xx_pipeinfo pipe[1];
195
196 u8 read_endpoint;
197
198 const struct zr364xx_fmt *fmt;
199 struct videobuf_queue vb_vidq;
200 enum v4l2_buf_type type;
201 struct zr364xx_mode mode;
120}; 202};
121 203
204/* buffer for one video frame */
205struct zr364xx_buffer {
206 /* common v4l buffer stuff -- must be first */
207 struct videobuf_buffer vb;
208 const struct zr364xx_fmt *fmt;
209};
122 210
123/* function used to send initialisation commands to the camera */ 211/* function used to send initialisation commands to the camera */
124static int send_control_msg(struct usb_device *udev, u8 request, u16 value, 212static int send_control_msg(struct usb_device *udev, u8 request, u16 value,
@@ -272,139 +360,116 @@ static unsigned char header2[] = {
272}; 360};
273static unsigned char header3; 361static unsigned char header3;
274 362
363/* ------------------------------------------------------------------
364 Videobuf operations
365 ------------------------------------------------------------------*/
275 366
367static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
368 unsigned int *size)
369{
370 struct zr364xx_camera *cam = vq->priv_data;
276 371
277/********************/ 372 *size = cam->width * cam->height * (cam->fmt->depth >> 3);
278/* V4L2 integration */
279/********************/
280 373
281/* this function reads a full JPEG picture synchronously 374 if (*count == 0)
282 * TODO: do it asynchronously... */ 375 *count = ZR364XX_DEF_BUFS;
283static int read_frame(struct zr364xx_camera *cam, int framenum)
284{
285 int i, n, temp, head, size, actual_length;
286 unsigned char *ptr = NULL, *jpeg;
287
288 redo:
289 /* hardware brightness */
290 n = send_control_msg(cam->udev, 1, 0x2001, 0, NULL, 0);
291 temp = (0x60 << 8) + 127 - cam->brightness;
292 n = send_control_msg(cam->udev, 1, temp, 0, NULL, 0);
293
294 /* during the first loop we are going to insert JPEG header */
295 head = 0;
296 /* this is the place in memory where we are going to build
297 * the JPEG image */
298 jpeg = cam->framebuf + framenum * MAX_FRAME_SIZE;
299 /* read data... */
300 do {
301 n = usb_bulk_msg(cam->udev,
302 usb_rcvbulkpipe(cam->udev, 0x81),
303 cam->buffer, BUFFER_SIZE, &actual_length,
304 CTRL_TIMEOUT);
305 DBG("buffer : %d %d", cam->buffer[0], cam->buffer[1]);
306 DBG("bulk : n=%d size=%d", n, actual_length);
307 if (n < 0) {
308 dev_err(&cam->udev->dev, "error reading bulk msg\n");
309 return 0;
310 }
311 if (actual_length < 0 || actual_length > BUFFER_SIZE) {
312 dev_err(&cam->udev->dev, "wrong number of bytes\n");
313 return 0;
314 }
315 376
316 /* swap bytes if camera needs it */ 377 while (*size * (*count) > ZR364XX_DEF_BUFS * 1024 * 1024)
317 if (cam->method == METHOD0) { 378 (*count)--;
318 u16 *buf = (u16*)cam->buffer;
319 for (i = 0; i < BUFFER_SIZE/2; i++)
320 swab16s(buf + i);
321 }
322 379
323 /* write the JPEG header */ 380 return 0;
324 if (!head) { 381}
325 DBG("jpeg header");
326 ptr = jpeg;
327 memcpy(ptr, header1, sizeof(header1));
328 ptr += sizeof(header1);
329 header3 = 0;
330 memcpy(ptr, &header3, 1);
331 ptr++;
332 memcpy(ptr, cam->buffer, 64);
333 ptr += 64;
334 header3 = 1;
335 memcpy(ptr, &header3, 1);
336 ptr++;
337 memcpy(ptr, cam->buffer + 64, 64);
338 ptr += 64;
339 memcpy(ptr, header2, sizeof(header2));
340 ptr += sizeof(header2);
341 memcpy(ptr, cam->buffer + 128,
342 actual_length - 128);
343 ptr += actual_length - 128;
344 head = 1;
345 DBG("header : %d %d %d %d %d %d %d %d %d",
346 cam->buffer[0], cam->buffer[1], cam->buffer[2],
347 cam->buffer[3], cam->buffer[4], cam->buffer[5],
348 cam->buffer[6], cam->buffer[7], cam->buffer[8]);
349 } else {
350 memcpy(ptr, cam->buffer, actual_length);
351 ptr += actual_length;
352 }
353 }
354 /* ... until there is no more */
355 while (actual_length == BUFFER_SIZE);
356 382
357 /* we skip the 2 first frames which are usually buggy */ 383static void free_buffer(struct videobuf_queue *vq, struct zr364xx_buffer *buf)
358 if (cam->skip) { 384{
359 cam->skip--; 385 _DBG("%s\n", __func__);
360 goto redo;
361 }
362 386
363 /* go back to find the JPEG EOI marker */ 387 if (in_interrupt())
364 size = ptr - jpeg; 388 BUG();
365 ptr -= 2;
366 while (ptr > jpeg) {
367 if (*ptr == 0xFF && *(ptr + 1) == 0xD9
368 && *(ptr + 2) == 0xFF)
369 break;
370 ptr--;
371 }
372 if (ptr == jpeg)
373 DBG("No EOI marker");
374 389
375 /* Sometimes there is junk data in the middle of the picture, 390 videobuf_vmalloc_free(&buf->vb);
376 * we want to skip this bogus frames */ 391 buf->vb.state = VIDEOBUF_NEEDS_INIT;
377 while (ptr > jpeg) { 392}
378 if (*ptr == 0xFF && *(ptr + 1) == 0xFF 393
379 && *(ptr + 2) == 0xFF) 394static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
380 break; 395 enum v4l2_field field)
381 ptr--; 396{
397 struct zr364xx_camera *cam = vq->priv_data;
398 struct zr364xx_buffer *buf = container_of(vb, struct zr364xx_buffer,
399 vb);
400 int rc;
401
402 DBG("%s, field=%d, fmt name = %s\n", __func__, field, cam->fmt != NULL ?
403 cam->fmt->name : "");
404 if (cam->fmt == NULL)
405 return -EINVAL;
406
407 buf->vb.size = cam->width * cam->height * (cam->fmt->depth >> 3);
408
409 if (buf->vb.baddr != 0 && buf->vb.bsize < buf->vb.size) {
410 DBG("invalid buffer prepare\n");
411 return -EINVAL;
382 } 412 }
383 if (ptr != jpeg) { 413
384 DBG("Bogus frame ? %d", cam->nb); 414 buf->fmt = cam->fmt;
385 goto redo; 415 buf->vb.width = cam->width;
416 buf->vb.height = cam->height;
417 buf->vb.field = field;
418
419 if (buf->vb.state == VIDEOBUF_NEEDS_INIT) {
420 rc = videobuf_iolock(vq, &buf->vb, NULL);
421 if (rc < 0)
422 goto fail;
386 } 423 }
387 424
388 DBG("jpeg : %d %d %d %d %d %d %d %d", 425 buf->vb.state = VIDEOBUF_PREPARED;
389 jpeg[0], jpeg[1], jpeg[2], jpeg[3], 426 return 0;
390 jpeg[4], jpeg[5], jpeg[6], jpeg[7]); 427fail:
428 free_buffer(vq, buf);
429 return rc;
430}
431
432static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
433{
434 struct zr364xx_buffer *buf = container_of(vb, struct zr364xx_buffer,
435 vb);
436 struct zr364xx_camera *cam = vq->priv_data;
437
438 _DBG("%s\n", __func__);
439
440 buf->vb.state = VIDEOBUF_QUEUED;
441 list_add_tail(&buf->vb.queue, &cam->vidq.active);
442}
443
444static void buffer_release(struct videobuf_queue *vq,
445 struct videobuf_buffer *vb)
446{
447 struct zr364xx_buffer *buf = container_of(vb, struct zr364xx_buffer,
448 vb);
391 449
392 return size; 450 _DBG("%s\n", __func__);
451 free_buffer(vq, buf);
393} 452}
394 453
454static struct videobuf_queue_ops zr364xx_video_qops = {
455 .buf_setup = buffer_setup,
456 .buf_prepare = buffer_prepare,
457 .buf_queue = buffer_queue,
458 .buf_release = buffer_release,
459};
460
461/********************/
462/* V4L2 integration */
463/********************/
464static int zr364xx_vidioc_streamon(struct file *file, void *priv,
465 enum v4l2_buf_type type);
395 466
396static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t cnt, 467static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t count,
397 loff_t * ppos) 468 loff_t * ppos)
398{ 469{
399 unsigned long count = cnt; 470 struct zr364xx_camera *cam = video_drvdata(file);
400 struct video_device *vdev = video_devdata(file);
401 struct zr364xx_camera *cam;
402 471
403 DBG("zr364xx_read: read %d bytes.", (int) count); 472 _DBG("%s\n", __func__);
404
405 if (vdev == NULL)
406 return -ENODEV;
407 cam = video_get_drvdata(vdev);
408 473
409 if (!buf) 474 if (!buf)
410 return -EINVAL; 475 return -EINVAL;
@@ -412,21 +477,276 @@ static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t cnt,
412 if (!count) 477 if (!count)
413 return -EINVAL; 478 return -EINVAL;
414 479
415 /* NoMan Sux ! */ 480 if (cam->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
416 count = read_frame(cam, 0); 481 zr364xx_vidioc_streamon(file, cam, cam->type) == 0) {
482 DBG("%s: reading %d bytes at pos %d.\n", __func__, (int) count,
483 (int) *ppos);
484
485 /* NoMan Sux ! */
486 return videobuf_read_one(&cam->vb_vidq, buf, count, ppos,
487 file->f_flags & O_NONBLOCK);
488 }
489
490 return 0;
491}
492
493/* video buffer vmalloc implementation based partly on VIVI driver which is
494 * Copyright (c) 2006 by
495 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
496 * Ted Walther <ted--a.t--enumera.com>
497 * John Sokol <sokol--a.t--videotechnology.com>
498 * http://v4l.videotechnology.com/
499 *
500 */
501static void zr364xx_fillbuff(struct zr364xx_camera *cam,
502 struct zr364xx_buffer *buf,
503 int jpgsize)
504{
505 int pos = 0;
506 struct timeval ts;
507 const char *tmpbuf;
508 char *vbuf = videobuf_to_vmalloc(&buf->vb);
509 unsigned long last_frame;
510 struct zr364xx_framei *frm;
511
512 if (!vbuf)
513 return;
514
515 last_frame = cam->last_frame;
516 if (last_frame != -1) {
517 frm = &cam->buffer.frame[last_frame];
518 tmpbuf = (const char *)cam->buffer.frame[last_frame].lpvbits;
519 switch (buf->fmt->fourcc) {
520 case V4L2_PIX_FMT_JPEG:
521 buf->vb.size = jpgsize;
522 memcpy(vbuf, tmpbuf, buf->vb.size);
523 break;
524 default:
525 printk(KERN_DEBUG KBUILD_MODNAME ": unknown format?\n");
526 }
527 cam->last_frame = -1;
528 } else {
529 printk(KERN_ERR KBUILD_MODNAME ": =======no frame\n");
530 return;
531 }
532 DBG("%s: Buffer 0x%08lx size= %d\n", __func__,
533 (unsigned long)vbuf, pos);
534 /* tell v4l buffer was filled */
535
536 buf->vb.field_count = cam->frame_count * 2;
537 do_gettimeofday(&ts);
538 buf->vb.ts = ts;
539 buf->vb.state = VIDEOBUF_DONE;
540}
541
542static int zr364xx_got_frame(struct zr364xx_camera *cam, int jpgsize)
543{
544 struct zr364xx_dmaqueue *dma_q = &cam->vidq;
545 struct zr364xx_buffer *buf;
546 unsigned long flags = 0;
547 int rc = 0;
548
549 DBG("wakeup: %p\n", &dma_q);
550 spin_lock_irqsave(&cam->slock, flags);
551
552 if (list_empty(&dma_q->active)) {
553 DBG("No active queue to serve\n");
554 rc = -1;
555 goto unlock;
556 }
557 buf = list_entry(dma_q->active.next,
558 struct zr364xx_buffer, vb.queue);
559
560 if (!waitqueue_active(&buf->vb.done)) {
561 /* no one active */
562 rc = -1;
563 goto unlock;
564 }
565 list_del(&buf->vb.queue);
566 do_gettimeofday(&buf->vb.ts);
567 DBG("[%p/%d] wakeup\n", buf, buf->vb.i);
568 zr364xx_fillbuff(cam, buf, jpgsize);
569 wake_up(&buf->vb.done);
570 DBG("wakeup [buf/i] [%p/%d]\n", buf, buf->vb.i);
571unlock:
572 spin_unlock_irqrestore(&cam->slock, flags);
573 return 0;
574}
575
576/* this function moves the usb stream read pipe data
577 * into the system buffers.
578 * returns 0 on success, EAGAIN if more data to process (call this
579 * function again).
580 */
581static int zr364xx_read_video_callback(struct zr364xx_camera *cam,
582 struct zr364xx_pipeinfo *pipe_info,
583 struct urb *purb)
584{
585 unsigned char *pdest;
586 unsigned char *psrc;
587 s32 idx = -1;
588 struct zr364xx_framei *frm;
589 int i = 0;
590 unsigned char *ptr = NULL;
591
592 _DBG("buffer to user\n");
593 idx = cam->cur_frame;
594 frm = &cam->buffer.frame[idx];
595
596 /* swap bytes if camera needs it */
597 if (cam->method == METHOD0) {
598 u16 *buf = (u16 *)pipe_info->transfer_buffer;
599 for (i = 0; i < purb->actual_length/2; i++)
600 swab16s(buf + i);
601 }
602
603 /* search done. now find out if should be acquiring */
604 if (!cam->b_acquire) {
605 /* we found a frame, but this channel is turned off */
606 frm->ulState = ZR364XX_READ_IDLE;
607 return -EINVAL;
608 }
609
610 psrc = (u8 *)pipe_info->transfer_buffer;
611 ptr = pdest = frm->lpvbits;
612
613 if (frm->ulState == ZR364XX_READ_IDLE) {
614 frm->ulState = ZR364XX_READ_FRAME;
615 frm->cur_size = 0;
616
617 _DBG("jpeg header, ");
618 memcpy(ptr, header1, sizeof(header1));
619 ptr += sizeof(header1);
620 header3 = 0;
621 memcpy(ptr, &header3, 1);
622 ptr++;
623 memcpy(ptr, psrc, 64);
624 ptr += 64;
625 header3 = 1;
626 memcpy(ptr, &header3, 1);
627 ptr++;
628 memcpy(ptr, psrc + 64, 64);
629 ptr += 64;
630 memcpy(ptr, header2, sizeof(header2));
631 ptr += sizeof(header2);
632 memcpy(ptr, psrc + 128,
633 purb->actual_length - 128);
634 ptr += purb->actual_length - 128;
635 _DBG("header : %d %d %d %d %d %d %d %d %d\n",
636 psrc[0], psrc[1], psrc[2],
637 psrc[3], psrc[4], psrc[5],
638 psrc[6], psrc[7], psrc[8]);
639 frm->cur_size = ptr - pdest;
640 } else {
641 if (frm->cur_size + purb->actual_length > MAX_FRAME_SIZE) {
642 dev_info(&cam->udev->dev,
643 "%s: buffer (%d bytes) too small to hold "
644 "frame data. Discarding frame data.\n",
645 __func__, MAX_FRAME_SIZE);
646 } else {
647 pdest += frm->cur_size;
648 memcpy(pdest, psrc, purb->actual_length);
649 frm->cur_size += purb->actual_length;
650 }
651 }
652 /*_DBG("cur_size %lu urb size %d\n", frm->cur_size,
653 purb->actual_length);*/
654
655 if (purb->actual_length < pipe_info->transfer_size) {
656 _DBG("****************Buffer[%d]full*************\n", idx);
657 cam->last_frame = cam->cur_frame;
658 cam->cur_frame++;
659 /* end of system frame ring buffer, start at zero */
660 if (cam->cur_frame == cam->buffer.dwFrames)
661 cam->cur_frame = 0;
662
663 /* frame ready */
664 /* go back to find the JPEG EOI marker */
665 ptr = pdest = frm->lpvbits;
666 ptr += frm->cur_size - 2;
667 while (ptr > pdest) {
668 if (*ptr == 0xFF && *(ptr + 1) == 0xD9
669 && *(ptr + 2) == 0xFF)
670 break;
671 ptr--;
672 }
673 if (ptr == pdest)
674 DBG("No EOI marker\n");
675
676 /* Sometimes there is junk data in the middle of the picture,
677 * we want to skip this bogus frames */
678 while (ptr > pdest) {
679 if (*ptr == 0xFF && *(ptr + 1) == 0xFF
680 && *(ptr + 2) == 0xFF)
681 break;
682 ptr--;
683 }
684 if (ptr != pdest) {
685 DBG("Bogus frame ? %d\n", ++(cam->nb));
686 } else if (cam->b_acquire) {
687 /* we skip the 2 first frames which are usually buggy */
688 if (cam->skip)
689 cam->skip--;
690 else {
691 _DBG("jpeg(%lu): %d %d %d %d %d %d %d %d\n",
692 frm->cur_size,
693 pdest[0], pdest[1], pdest[2], pdest[3],
694 pdest[4], pdest[5], pdest[6], pdest[7]);
695
696 zr364xx_got_frame(cam, frm->cur_size);
697 }
698 }
699 cam->frame_count++;
700 frm->ulState = ZR364XX_READ_IDLE;
701 frm->cur_size = 0;
702 }
703 /* done successfully */
704 return 0;
705}
417 706
418 if (copy_to_user(buf, cam->framebuf, count)) 707static int res_get(struct zr364xx_camera *cam)
419 return -EFAULT; 708{
709 /* is it free? */
710 mutex_lock(&cam->lock);
711 if (cam->resources) {
712 /* no, someone else uses it */
713 mutex_unlock(&cam->lock);
714 return 0;
715 }
716 /* it's free, grab it */
717 cam->resources = 1;
718 _DBG("res: get\n");
719 mutex_unlock(&cam->lock);
720 return 1;
721}
420 722
421 return count; 723static inline int res_check(struct zr364xx_camera *cam)
724{
725 return cam->resources;
422} 726}
423 727
728static void res_free(struct zr364xx_camera *cam)
729{
730 mutex_lock(&cam->lock);
731 cam->resources = 0;
732 mutex_unlock(&cam->lock);
733 _DBG("res: put\n");
734}
424 735
425static int zr364xx_vidioc_querycap(struct file *file, void *priv, 736static int zr364xx_vidioc_querycap(struct file *file, void *priv,
426 struct v4l2_capability *cap) 737 struct v4l2_capability *cap)
427{ 738{
428 strcpy(cap->driver, DRIVER_DESC); 739 struct zr364xx_camera *cam = video_drvdata(file);
429 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; 740
741 strlcpy(cap->driver, DRIVER_DESC, sizeof(cap->driver));
742 strlcpy(cap->card, cam->udev->product, sizeof(cap->card));
743 strlcpy(cap->bus_info, dev_name(&cam->udev->dev),
744 sizeof(cap->bus_info));
745 cap->version = ZR364XX_VERSION_CODE;
746 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
747 V4L2_CAP_READWRITE |
748 V4L2_CAP_STREAMING;
749
430 return 0; 750 return 0;
431} 751}
432 752
@@ -458,12 +778,11 @@ static int zr364xx_vidioc_s_input(struct file *file, void *priv,
458static int zr364xx_vidioc_queryctrl(struct file *file, void *priv, 778static int zr364xx_vidioc_queryctrl(struct file *file, void *priv,
459 struct v4l2_queryctrl *c) 779 struct v4l2_queryctrl *c)
460{ 780{
461 struct video_device *vdev = video_devdata(file);
462 struct zr364xx_camera *cam; 781 struct zr364xx_camera *cam;
463 782
464 if (vdev == NULL) 783 if (file == NULL)
465 return -ENODEV; 784 return -ENODEV;
466 cam = video_get_drvdata(vdev); 785 cam = video_drvdata(file);
467 786
468 switch (c->id) { 787 switch (c->id) {
469 case V4L2_CID_BRIGHTNESS: 788 case V4L2_CID_BRIGHTNESS:
@@ -472,7 +791,7 @@ static int zr364xx_vidioc_queryctrl(struct file *file, void *priv,
472 c->minimum = 0; 791 c->minimum = 0;
473 c->maximum = 127; 792 c->maximum = 127;
474 c->step = 1; 793 c->step = 1;
475 c->default_value = cam->brightness; 794 c->default_value = cam->mode.brightness;
476 c->flags = 0; 795 c->flags = 0;
477 break; 796 break;
478 default: 797 default:
@@ -484,36 +803,42 @@ static int zr364xx_vidioc_queryctrl(struct file *file, void *priv,
484static int zr364xx_vidioc_s_ctrl(struct file *file, void *priv, 803static int zr364xx_vidioc_s_ctrl(struct file *file, void *priv,
485 struct v4l2_control *c) 804 struct v4l2_control *c)
486{ 805{
487 struct video_device *vdev = video_devdata(file);
488 struct zr364xx_camera *cam; 806 struct zr364xx_camera *cam;
807 int temp;
489 808
490 if (vdev == NULL) 809 if (file == NULL)
491 return -ENODEV; 810 return -ENODEV;
492 cam = video_get_drvdata(vdev); 811 cam = video_drvdata(file);
493 812
494 switch (c->id) { 813 switch (c->id) {
495 case V4L2_CID_BRIGHTNESS: 814 case V4L2_CID_BRIGHTNESS:
496 cam->brightness = c->value; 815 cam->mode.brightness = c->value;
816 /* hardware brightness */
817 mutex_lock(&cam->lock);
818 send_control_msg(cam->udev, 1, 0x2001, 0, NULL, 0);
819 temp = (0x60 << 8) + 127 - cam->mode.brightness;
820 send_control_msg(cam->udev, 1, temp, 0, NULL, 0);
821 mutex_unlock(&cam->lock);
497 break; 822 break;
498 default: 823 default:
499 return -EINVAL; 824 return -EINVAL;
500 } 825 }
826
501 return 0; 827 return 0;
502} 828}
503 829
504static int zr364xx_vidioc_g_ctrl(struct file *file, void *priv, 830static int zr364xx_vidioc_g_ctrl(struct file *file, void *priv,
505 struct v4l2_control *c) 831 struct v4l2_control *c)
506{ 832{
507 struct video_device *vdev = video_devdata(file);
508 struct zr364xx_camera *cam; 833 struct zr364xx_camera *cam;
509 834
510 if (vdev == NULL) 835 if (file == NULL)
511 return -ENODEV; 836 return -ENODEV;
512 cam = video_get_drvdata(vdev); 837 cam = video_drvdata(file);
513 838
514 switch (c->id) { 839 switch (c->id) {
515 case V4L2_CID_BRIGHTNESS: 840 case V4L2_CID_BRIGHTNESS:
516 c->value = cam->brightness; 841 c->value = cam->mode.brightness;
517 break; 842 break;
518 default: 843 default:
519 return -EINVAL; 844 return -EINVAL;
@@ -527,47 +852,63 @@ static int zr364xx_vidioc_enum_fmt_vid_cap(struct file *file,
527 if (f->index > 0) 852 if (f->index > 0)
528 return -EINVAL; 853 return -EINVAL;
529 f->flags = V4L2_FMT_FLAG_COMPRESSED; 854 f->flags = V4L2_FMT_FLAG_COMPRESSED;
530 strcpy(f->description, "JPEG"); 855 strcpy(f->description, formats[0].name);
531 f->pixelformat = V4L2_PIX_FMT_JPEG; 856 f->pixelformat = formats[0].fourcc;
532 return 0; 857 return 0;
533} 858}
534 859
860static char *decode_fourcc(__u32 pixelformat, char *buf)
861{
862 buf[0] = pixelformat & 0xff;
863 buf[1] = (pixelformat >> 8) & 0xff;
864 buf[2] = (pixelformat >> 16) & 0xff;
865 buf[3] = (pixelformat >> 24) & 0xff;
866 buf[4] = '\0';
867 return buf;
868}
869
535static int zr364xx_vidioc_try_fmt_vid_cap(struct file *file, void *priv, 870static int zr364xx_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
536 struct v4l2_format *f) 871 struct v4l2_format *f)
537{ 872{
538 struct video_device *vdev = video_devdata(file); 873 struct zr364xx_camera *cam = video_drvdata(file);
539 struct zr364xx_camera *cam; 874 char pixelformat_name[5];
540 875
541 if (vdev == NULL) 876 if (cam == NULL)
542 return -ENODEV; 877 return -ENODEV;
543 cam = video_get_drvdata(vdev);
544 878
545 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG) 879 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG) {
546 return -EINVAL; 880 DBG("%s: unsupported pixelformat V4L2_PIX_FMT_%s\n", __func__,
547 if (f->fmt.pix.field != V4L2_FIELD_ANY && 881 decode_fourcc(f->fmt.pix.pixelformat, pixelformat_name));
548 f->fmt.pix.field != V4L2_FIELD_NONE)
549 return -EINVAL; 882 return -EINVAL;
883 }
884
885 if (!(f->fmt.pix.width == 160 && f->fmt.pix.height == 120) &&
886 !(f->fmt.pix.width == 640 && f->fmt.pix.height == 480)) {
887 f->fmt.pix.width = 320;
888 f->fmt.pix.height = 240;
889 }
890
550 f->fmt.pix.field = V4L2_FIELD_NONE; 891 f->fmt.pix.field = V4L2_FIELD_NONE;
551 f->fmt.pix.width = cam->width;
552 f->fmt.pix.height = cam->height;
553 f->fmt.pix.bytesperline = f->fmt.pix.width * 2; 892 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
554 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; 893 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
555 f->fmt.pix.colorspace = 0; 894 f->fmt.pix.colorspace = 0;
556 f->fmt.pix.priv = 0; 895 f->fmt.pix.priv = 0;
896 DBG("%s: V4L2_PIX_FMT_%s (%d) ok!\n", __func__,
897 decode_fourcc(f->fmt.pix.pixelformat, pixelformat_name),
898 f->fmt.pix.field);
557 return 0; 899 return 0;
558} 900}
559 901
560static int zr364xx_vidioc_g_fmt_vid_cap(struct file *file, void *priv, 902static int zr364xx_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
561 struct v4l2_format *f) 903 struct v4l2_format *f)
562{ 904{
563 struct video_device *vdev = video_devdata(file);
564 struct zr364xx_camera *cam; 905 struct zr364xx_camera *cam;
565 906
566 if (vdev == NULL) 907 if (file == NULL)
567 return -ENODEV; 908 return -ENODEV;
568 cam = video_get_drvdata(vdev); 909 cam = video_drvdata(file);
569 910
570 f->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG; 911 f->fmt.pix.pixelformat = formats[0].fourcc;
571 f->fmt.pix.field = V4L2_FIELD_NONE; 912 f->fmt.pix.field = V4L2_FIELD_NONE;
572 f->fmt.pix.width = cam->width; 913 f->fmt.pix.width = cam->width;
573 f->fmt.pix.height = cam->height; 914 f->fmt.pix.height = cam->height;
@@ -581,38 +922,327 @@ static int zr364xx_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
581static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv, 922static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv,
582 struct v4l2_format *f) 923 struct v4l2_format *f)
583{ 924{
584 struct video_device *vdev = video_devdata(file); 925 struct zr364xx_camera *cam = video_drvdata(file);
585 struct zr364xx_camera *cam; 926 struct videobuf_queue *q = &cam->vb_vidq;
927 char pixelformat_name[5];
928 int ret = zr364xx_vidioc_try_fmt_vid_cap(file, cam, f);
929 int i;
586 930
587 if (vdev == NULL) 931 if (ret < 0)
588 return -ENODEV; 932 return ret;
589 cam = video_get_drvdata(vdev);
590 933
591 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG) 934 mutex_lock(&q->vb_lock);
592 return -EINVAL; 935
593 if (f->fmt.pix.field != V4L2_FIELD_ANY && 936 if (videobuf_queue_is_busy(&cam->vb_vidq)) {
594 f->fmt.pix.field != V4L2_FIELD_NONE) 937 DBG("%s queue busy\n", __func__);
595 return -EINVAL; 938 ret = -EBUSY;
596 f->fmt.pix.field = V4L2_FIELD_NONE; 939 goto out;
597 f->fmt.pix.width = cam->width; 940 }
598 f->fmt.pix.height = cam->height; 941
942 if (res_check(cam)) {
943 DBG("%s can't change format after started\n", __func__);
944 ret = -EBUSY;
945 goto out;
946 }
947
948 cam->width = f->fmt.pix.width;
949 cam->height = f->fmt.pix.height;
950 dev_info(&cam->udev->dev, "%s: %dx%d mode selected\n", __func__,
951 cam->width, cam->height);
599 f->fmt.pix.bytesperline = f->fmt.pix.width * 2; 952 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
600 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; 953 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
601 f->fmt.pix.colorspace = 0; 954 f->fmt.pix.colorspace = 0;
602 f->fmt.pix.priv = 0; 955 f->fmt.pix.priv = 0;
603 DBG("ok!"); 956 cam->vb_vidq.field = f->fmt.pix.field;
957 cam->mode.color = V4L2_PIX_FMT_JPEG;
958
959 if (f->fmt.pix.width == 160 && f->fmt.pix.height == 120)
960 mode = 1;
961 else if (f->fmt.pix.width == 640 && f->fmt.pix.height == 480)
962 mode = 2;
963 else
964 mode = 0;
965
966 m0d1[0] = mode;
967 m1[2].value = 0xf000 + mode;
968 m2[1].value = 0xf000 + mode;
969 header2[437] = cam->height / 256;
970 header2[438] = cam->height % 256;
971 header2[439] = cam->width / 256;
972 header2[440] = cam->width % 256;
973
974 for (i = 0; init[cam->method][i].size != -1; i++) {
975 ret =
976 send_control_msg(cam->udev, 1, init[cam->method][i].value,
977 0, init[cam->method][i].bytes,
978 init[cam->method][i].size);
979 if (ret < 0) {
980 dev_err(&cam->udev->dev,
981 "error during resolution change sequence: %d\n", i);
982 goto out;
983 }
984 }
985
986 /* Added some delay here, since opening/closing the camera quickly,
987 * like Ekiga does during its startup, can crash the webcam
988 */
989 mdelay(100);
990 cam->skip = 2;
991 ret = 0;
992
993out:
994 mutex_unlock(&q->vb_lock);
995
996 DBG("%s: V4L2_PIX_FMT_%s (%d) ok!\n", __func__,
997 decode_fourcc(f->fmt.pix.pixelformat, pixelformat_name),
998 f->fmt.pix.field);
999 return ret;
1000}
1001
1002static int zr364xx_vidioc_reqbufs(struct file *file, void *priv,
1003 struct v4l2_requestbuffers *p)
1004{
1005 int rc;
1006 struct zr364xx_camera *cam = video_drvdata(file);
1007 rc = videobuf_reqbufs(&cam->vb_vidq, p);
1008 return rc;
1009}
1010
1011static int zr364xx_vidioc_querybuf(struct file *file,
1012 void *priv,
1013 struct v4l2_buffer *p)
1014{
1015 int rc;
1016 struct zr364xx_camera *cam = video_drvdata(file);
1017 rc = videobuf_querybuf(&cam->vb_vidq, p);
1018 return rc;
1019}
1020
1021static int zr364xx_vidioc_qbuf(struct file *file,
1022 void *priv,
1023 struct v4l2_buffer *p)
1024{
1025 int rc;
1026 struct zr364xx_camera *cam = video_drvdata(file);
1027 _DBG("%s\n", __func__);
1028 rc = videobuf_qbuf(&cam->vb_vidq, p);
1029 return rc;
1030}
1031
1032static int zr364xx_vidioc_dqbuf(struct file *file,
1033 void *priv,
1034 struct v4l2_buffer *p)
1035{
1036 int rc;
1037 struct zr364xx_camera *cam = video_drvdata(file);
1038 _DBG("%s\n", __func__);
1039 rc = videobuf_dqbuf(&cam->vb_vidq, p, file->f_flags & O_NONBLOCK);
1040 return rc;
1041}
1042
1043static void read_pipe_completion(struct urb *purb)
1044{
1045 struct zr364xx_pipeinfo *pipe_info;
1046 struct zr364xx_camera *cam;
1047 int pipe;
1048
1049 pipe_info = purb->context;
1050 _DBG("%s %p, status %d\n", __func__, purb, purb->status);
1051 if (pipe_info == NULL) {
1052 printk(KERN_ERR KBUILD_MODNAME ": no context!\n");
1053 return;
1054 }
1055
1056 cam = pipe_info->cam;
1057 if (cam == NULL) {
1058 printk(KERN_ERR KBUILD_MODNAME ": no context!\n");
1059 return;
1060 }
1061
1062 /* if shutting down, do not resubmit, exit immediately */
1063 if (purb->status == -ESHUTDOWN) {
1064 DBG("%s, err shutdown\n", __func__);
1065 pipe_info->err_count++;
1066 return;
1067 }
1068
1069 if (pipe_info->state == 0) {
1070 DBG("exiting USB pipe\n");
1071 return;
1072 }
1073
1074 if (purb->actual_length < 0 ||
1075 purb->actual_length > pipe_info->transfer_size) {
1076 dev_err(&cam->udev->dev, "wrong number of bytes\n");
1077 return;
1078 }
1079
1080 if (purb->status == 0)
1081 zr364xx_read_video_callback(cam, pipe_info, purb);
1082 else {
1083 pipe_info->err_count++;
1084 DBG("%s: failed URB %d\n", __func__, purb->status);
1085 }
1086
1087 pipe = usb_rcvbulkpipe(cam->udev, cam->read_endpoint);
1088
1089 /* reuse urb */
1090 usb_fill_bulk_urb(pipe_info->stream_urb, cam->udev,
1091 pipe,
1092 pipe_info->transfer_buffer,
1093 pipe_info->transfer_size,
1094 read_pipe_completion, pipe_info);
1095
1096 if (pipe_info->state != 0) {
1097 purb->status = usb_submit_urb(pipe_info->stream_urb,
1098 GFP_ATOMIC);
1099
1100 if (purb->status)
1101 dev_err(&cam->udev->dev,
1102 "error submitting urb (error=%i)\n",
1103 purb->status);
1104 } else
1105 DBG("read pipe complete state 0\n");
1106}
1107
1108static int zr364xx_start_readpipe(struct zr364xx_camera *cam)
1109{
1110 int pipe;
1111 int retval;
1112 struct zr364xx_pipeinfo *pipe_info = cam->pipe;
1113 pipe = usb_rcvbulkpipe(cam->udev, cam->read_endpoint);
1114 DBG("%s: start pipe IN x%x\n", __func__, cam->read_endpoint);
1115
1116 pipe_info->state = 1;
1117 pipe_info->err_count = 0;
1118 pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
1119 if (!pipe_info->stream_urb) {
1120 dev_err(&cam->udev->dev, "ReadStream: Unable to alloc URB\n");
1121 return -ENOMEM;
1122 }
1123 /* transfer buffer allocated in board_init */
1124 usb_fill_bulk_urb(pipe_info->stream_urb, cam->udev,
1125 pipe,
1126 pipe_info->transfer_buffer,
1127 pipe_info->transfer_size,
1128 read_pipe_completion, pipe_info);
1129
1130 DBG("submitting URB %p\n", pipe_info->stream_urb);
1131 retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
1132 if (retval) {
1133 printk(KERN_ERR KBUILD_MODNAME ": start read pipe failed\n");
1134 return retval;
1135 }
1136
1137 return 0;
1138}
1139
1140static void zr364xx_stop_readpipe(struct zr364xx_camera *cam)
1141{
1142 struct zr364xx_pipeinfo *pipe_info;
1143
1144 if (cam == NULL) {
1145 printk(KERN_ERR KBUILD_MODNAME ": invalid device\n");
1146 return;
1147 }
1148 DBG("stop read pipe\n");
1149 pipe_info = cam->pipe;
1150 if (pipe_info) {
1151 if (pipe_info->state != 0)
1152 pipe_info->state = 0;
1153
1154 if (pipe_info->stream_urb) {
1155 /* cancel urb */
1156 usb_kill_urb(pipe_info->stream_urb);
1157 usb_free_urb(pipe_info->stream_urb);
1158 pipe_info->stream_urb = NULL;
1159 }
1160 }
1161 return;
1162}
1163
1164/* starts acquisition process */
1165static int zr364xx_start_acquire(struct zr364xx_camera *cam)
1166{
1167 int j;
1168
1169 DBG("start acquire\n");
1170
1171 cam->last_frame = -1;
1172 cam->cur_frame = 0;
1173 for (j = 0; j < FRAMES; j++) {
1174 cam->buffer.frame[j].ulState = ZR364XX_READ_IDLE;
1175 cam->buffer.frame[j].cur_size = 0;
1176 }
1177 cam->b_acquire = 1;
1178 return 0;
1179}
1180
1181static inline int zr364xx_stop_acquire(struct zr364xx_camera *cam)
1182{
1183 cam->b_acquire = 0;
604 return 0; 1184 return 0;
605} 1185}
606 1186
607static int zr364xx_vidioc_streamon(struct file *file, void *priv, 1187static int zr364xx_vidioc_streamon(struct file *file, void *priv,
608 enum v4l2_buf_type type) 1188 enum v4l2_buf_type type)
609{ 1189{
610 return 0; 1190 struct zr364xx_camera *cam = video_drvdata(file);
1191 int j;
1192 int res;
1193
1194 DBG("%s\n", __func__);
1195
1196 if (cam->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1197 dev_err(&cam->udev->dev, "invalid fh type0\n");
1198 return -EINVAL;
1199 }
1200 if (cam->type != type) {
1201 dev_err(&cam->udev->dev, "invalid fh type1\n");
1202 return -EINVAL;
1203 }
1204
1205 if (!res_get(cam)) {
1206 dev_err(&cam->udev->dev, "stream busy\n");
1207 return -EBUSY;
1208 }
1209
1210 cam->last_frame = -1;
1211 cam->cur_frame = 0;
1212 cam->frame_count = 0;
1213 for (j = 0; j < FRAMES; j++) {
1214 cam->buffer.frame[j].ulState = ZR364XX_READ_IDLE;
1215 cam->buffer.frame[j].cur_size = 0;
1216 }
1217 res = videobuf_streamon(&cam->vb_vidq);
1218 if (res == 0) {
1219 zr364xx_start_acquire(cam);
1220 } else {
1221 res_free(cam);
1222 }
1223 return res;
611} 1224}
612 1225
613static int zr364xx_vidioc_streamoff(struct file *file, void *priv, 1226static int zr364xx_vidioc_streamoff(struct file *file, void *priv,
614 enum v4l2_buf_type type) 1227 enum v4l2_buf_type type)
615{ 1228{
1229 int res;
1230 struct zr364xx_camera *cam = video_drvdata(file);
1231
1232 DBG("%s\n", __func__);
1233 if (cam->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1234 dev_err(&cam->udev->dev, "invalid fh type0\n");
1235 return -EINVAL;
1236 }
1237 if (cam->type != type) {
1238 dev_err(&cam->udev->dev, "invalid fh type1\n");
1239 return -EINVAL;
1240 }
1241 zr364xx_stop_acquire(cam);
1242 res = videobuf_streamoff(&cam->vb_vidq);
1243 if (res < 0)
1244 return res;
1245 res_free(cam);
616 return 0; 1246 return 0;
617} 1247}
618 1248
@@ -621,28 +1251,19 @@ static int zr364xx_vidioc_streamoff(struct file *file, void *priv,
621static int zr364xx_open(struct file *file) 1251static int zr364xx_open(struct file *file)
622{ 1252{
623 struct video_device *vdev = video_devdata(file); 1253 struct video_device *vdev = video_devdata(file);
624 struct zr364xx_camera *cam = video_get_drvdata(vdev); 1254 struct zr364xx_camera *cam = video_drvdata(file);
625 struct usb_device *udev = cam->udev; 1255 struct usb_device *udev = cam->udev;
626 int i, err; 1256 int i, err;
627 1257
628 DBG("zr364xx_open"); 1258 DBG("%s\n", __func__);
629 1259
630 mutex_lock(&cam->lock); 1260 mutex_lock(&cam->open_lock);
631 1261
632 if (cam->users) { 1262 if (cam->users) {
633 err = -EBUSY; 1263 err = -EBUSY;
634 goto out; 1264 goto out;
635 } 1265 }
636 1266
637 if (!cam->framebuf) {
638 cam->framebuf = vmalloc_32(MAX_FRAME_SIZE * FRAMES);
639 if (!cam->framebuf) {
640 dev_err(&cam->udev->dev, "vmalloc_32 failed!\n");
641 err = -ENOMEM;
642 goto out;
643 }
644 }
645
646 for (i = 0; init[cam->method][i].size != -1; i++) { 1267 for (i = 0; init[cam->method][i].size != -1; i++) {
647 err = 1268 err =
648 send_control_msg(udev, 1, init[cam->method][i].value, 1269 send_control_msg(udev, 1, init[cam->method][i].value,
@@ -658,6 +1279,14 @@ static int zr364xx_open(struct file *file)
658 cam->skip = 2; 1279 cam->skip = 2;
659 cam->users++; 1280 cam->users++;
660 file->private_data = vdev; 1281 file->private_data = vdev;
1282 cam->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1283 cam->fmt = formats;
1284
1285 videobuf_queue_vmalloc_init(&cam->vb_vidq, &zr364xx_video_qops,
1286 NULL, &cam->slock,
1287 cam->type,
1288 V4L2_FIELD_NONE,
1289 sizeof(struct zr364xx_buffer), cam);
661 1290
662 /* Added some delay here, since opening/closing the camera quickly, 1291 /* Added some delay here, since opening/closing the camera quickly,
663 * like Ekiga does during its startup, can crash the webcam 1292 * like Ekiga does during its startup, can crash the webcam
@@ -666,28 +1295,70 @@ static int zr364xx_open(struct file *file)
666 err = 0; 1295 err = 0;
667 1296
668out: 1297out:
669 mutex_unlock(&cam->lock); 1298 mutex_unlock(&cam->open_lock);
1299 DBG("%s: %d\n", __func__, err);
670 return err; 1300 return err;
671} 1301}
672 1302
1303static void zr364xx_destroy(struct zr364xx_camera *cam)
1304{
1305 unsigned long i;
1306
1307 if (!cam) {
1308 printk(KERN_ERR KBUILD_MODNAME ", %s: no device\n", __func__);
1309 return;
1310 }
1311 mutex_lock(&cam->open_lock);
1312 if (cam->vdev)
1313 video_unregister_device(cam->vdev);
1314 cam->vdev = NULL;
1315
1316 /* stops the read pipe if it is running */
1317 if (cam->b_acquire)
1318 zr364xx_stop_acquire(cam);
1319
1320 zr364xx_stop_readpipe(cam);
1321
1322 /* release sys buffers */
1323 for (i = 0; i < FRAMES; i++) {
1324 if (cam->buffer.frame[i].lpvbits) {
1325 DBG("vfree %p\n", cam->buffer.frame[i].lpvbits);
1326 vfree(cam->buffer.frame[i].lpvbits);
1327 }
1328 cam->buffer.frame[i].lpvbits = NULL;
1329 }
1330
1331 /* release transfer buffer */
1332 kfree(cam->pipe->transfer_buffer);
1333 cam->pipe->transfer_buffer = NULL;
1334 mutex_unlock(&cam->open_lock);
1335 kfree(cam);
1336 cam = NULL;
1337}
673 1338
674/* release the camera */ 1339/* release the camera */
675static int zr364xx_release(struct file *file) 1340static int zr364xx_release(struct file *file)
676{ 1341{
677 struct video_device *vdev = video_devdata(file);
678 struct zr364xx_camera *cam; 1342 struct zr364xx_camera *cam;
679 struct usb_device *udev; 1343 struct usb_device *udev;
680 int i, err; 1344 int i, err;
681 1345
682 DBG("zr364xx_release"); 1346 DBG("%s\n", __func__);
1347 cam = video_drvdata(file);
683 1348
684 if (vdev == NULL) 1349 if (!cam)
685 return -ENODEV; 1350 return -ENODEV;
686 cam = video_get_drvdata(vdev);
687 1351
1352 mutex_lock(&cam->open_lock);
688 udev = cam->udev; 1353 udev = cam->udev;
689 1354
690 mutex_lock(&cam->lock); 1355 /* turn off stream */
1356 if (res_check(cam)) {
1357 if (cam->b_acquire)
1358 zr364xx_stop_acquire(cam);
1359 videobuf_streamoff(&cam->vb_vidq);
1360 res_free(cam);
1361 }
691 1362
692 cam->users--; 1363 cam->users--;
693 file->private_data = NULL; 1364 file->private_data = NULL;
@@ -710,40 +1381,43 @@ static int zr364xx_release(struct file *file)
710 err = 0; 1381 err = 0;
711 1382
712out: 1383out:
713 mutex_unlock(&cam->lock); 1384 mutex_unlock(&cam->open_lock);
1385
714 return err; 1386 return err;
715} 1387}
716 1388
717 1389
718static int zr364xx_mmap(struct file *file, struct vm_area_struct *vma) 1390static int zr364xx_mmap(struct file *file, struct vm_area_struct *vma)
719{ 1391{
720 void *pos; 1392 struct zr364xx_camera *cam = video_drvdata(file);
721 unsigned long start = vma->vm_start; 1393 int ret;
722 unsigned long size = vma->vm_end - vma->vm_start;
723 struct video_device *vdev = video_devdata(file);
724 struct zr364xx_camera *cam;
725
726 DBG("zr364xx_mmap: %ld\n", size);
727 1394
728 if (vdev == NULL) 1395 if (cam == NULL) {
1396 DBG("%s: cam == NULL\n", __func__);
729 return -ENODEV; 1397 return -ENODEV;
730 cam = video_get_drvdata(vdev);
731
732 pos = cam->framebuf;
733 while (size > 0) {
734 if (vm_insert_page(vma, start, vmalloc_to_page(pos)))
735 return -EAGAIN;
736 start += PAGE_SIZE;
737 pos += PAGE_SIZE;
738 if (size > PAGE_SIZE)
739 size -= PAGE_SIZE;
740 else
741 size = 0;
742 } 1398 }
1399 DBG("mmap called, vma=0x%08lx\n", (unsigned long)vma);
743 1400
744 return 0; 1401 ret = videobuf_mmap_mapper(&cam->vb_vidq, vma);
1402
1403 DBG("vma start=0x%08lx, size=%ld, ret=%d\n",
1404 (unsigned long)vma->vm_start,
1405 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
1406 return ret;
745} 1407}
746 1408
1409static unsigned int zr364xx_poll(struct file *file,
1410 struct poll_table_struct *wait)
1411{
1412 struct zr364xx_camera *cam = video_drvdata(file);
1413 struct videobuf_queue *q = &cam->vb_vidq;
1414 _DBG("%s\n", __func__);
1415
1416 if (cam->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1417 return POLLERR;
1418
1419 return videobuf_poll_stream(file, q, wait);
1420}
747 1421
748static const struct v4l2_file_operations zr364xx_fops = { 1422static const struct v4l2_file_operations zr364xx_fops = {
749 .owner = THIS_MODULE, 1423 .owner = THIS_MODULE,
@@ -752,6 +1426,7 @@ static const struct v4l2_file_operations zr364xx_fops = {
752 .read = zr364xx_read, 1426 .read = zr364xx_read,
753 .mmap = zr364xx_mmap, 1427 .mmap = zr364xx_mmap,
754 .ioctl = video_ioctl2, 1428 .ioctl = video_ioctl2,
1429 .poll = zr364xx_poll,
755}; 1430};
756 1431
757static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = { 1432static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = {
@@ -768,6 +1443,10 @@ static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = {
768 .vidioc_queryctrl = zr364xx_vidioc_queryctrl, 1443 .vidioc_queryctrl = zr364xx_vidioc_queryctrl,
769 .vidioc_g_ctrl = zr364xx_vidioc_g_ctrl, 1444 .vidioc_g_ctrl = zr364xx_vidioc_g_ctrl,
770 .vidioc_s_ctrl = zr364xx_vidioc_s_ctrl, 1445 .vidioc_s_ctrl = zr364xx_vidioc_s_ctrl,
1446 .vidioc_reqbufs = zr364xx_vidioc_reqbufs,
1447 .vidioc_querybuf = zr364xx_vidioc_querybuf,
1448 .vidioc_qbuf = zr364xx_vidioc_qbuf,
1449 .vidioc_dqbuf = zr364xx_vidioc_dqbuf,
771}; 1450};
772 1451
773static struct video_device zr364xx_template = { 1452static struct video_device zr364xx_template = {
@@ -783,15 +1462,76 @@ static struct video_device zr364xx_template = {
783/*******************/ 1462/*******************/
784/* USB integration */ 1463/* USB integration */
785/*******************/ 1464/*******************/
1465static int zr364xx_board_init(struct zr364xx_camera *cam)
1466{
1467 struct zr364xx_pipeinfo *pipe = cam->pipe;
1468 unsigned long i;
1469
1470 DBG("board init: %p\n", cam);
1471 memset(pipe, 0, sizeof(*pipe));
1472 pipe->cam = cam;
1473 pipe->transfer_size = BUFFER_SIZE;
1474
1475 pipe->transfer_buffer = kzalloc(pipe->transfer_size,
1476 GFP_KERNEL);
1477 if (pipe->transfer_buffer == NULL) {
1478 DBG("out of memory!\n");
1479 return -ENOMEM;
1480 }
1481
1482 cam->b_acquire = 0;
1483 cam->frame_count = 0;
1484
1485 /*** start create system buffers ***/
1486 for (i = 0; i < FRAMES; i++) {
1487 /* always allocate maximum size for system buffers */
1488 cam->buffer.frame[i].lpvbits = vmalloc(MAX_FRAME_SIZE);
1489
1490 DBG("valloc %p, idx %lu, pdata %p\n",
1491 &cam->buffer.frame[i], i,
1492 cam->buffer.frame[i].lpvbits);
1493 if (cam->buffer.frame[i].lpvbits == NULL) {
1494 printk(KERN_INFO KBUILD_MODNAME ": out of memory. "
1495 "Using less frames\n");
1496 break;
1497 }
1498 }
1499
1500 if (i == 0) {
1501 printk(KERN_INFO KBUILD_MODNAME ": out of memory. Aborting\n");
1502 kfree(cam->pipe->transfer_buffer);
1503 cam->pipe->transfer_buffer = NULL;
1504 return -ENOMEM;
1505 } else
1506 cam->buffer.dwFrames = i;
1507
1508 /* make sure internal states are set */
1509 for (i = 0; i < FRAMES; i++) {
1510 cam->buffer.frame[i].ulState = ZR364XX_READ_IDLE;
1511 cam->buffer.frame[i].cur_size = 0;
1512 }
1513
1514 cam->cur_frame = 0;
1515 cam->last_frame = -1;
1516 /*** end create system buffers ***/
1517
1518 /* start read pipe */
1519 zr364xx_start_readpipe(cam);
1520 DBG(": board initialized\n");
1521 return 0;
1522}
786 1523
787static int zr364xx_probe(struct usb_interface *intf, 1524static int zr364xx_probe(struct usb_interface *intf,
788 const struct usb_device_id *id) 1525 const struct usb_device_id *id)
789{ 1526{
790 struct usb_device *udev = interface_to_usbdev(intf); 1527 struct usb_device *udev = interface_to_usbdev(intf);
791 struct zr364xx_camera *cam = NULL; 1528 struct zr364xx_camera *cam = NULL;
1529 struct usb_host_interface *iface_desc;
1530 struct usb_endpoint_descriptor *endpoint;
792 int err; 1531 int err;
1532 int i;
793 1533
794 DBG("probing..."); 1534 DBG("probing...\n");
795 1535
796 dev_info(&intf->dev, DRIVER_DESC " compatible webcam plugged\n"); 1536 dev_info(&intf->dev, DRIVER_DESC " compatible webcam plugged\n");
797 dev_info(&intf->dev, "model %04x:%04x detected\n", 1537 dev_info(&intf->dev, "model %04x:%04x detected\n",
@@ -810,22 +1550,17 @@ static int zr364xx_probe(struct usb_interface *intf,
810 if (cam->vdev == NULL) { 1550 if (cam->vdev == NULL) {
811 dev_err(&udev->dev, "cam->vdev: out of memory !\n"); 1551 dev_err(&udev->dev, "cam->vdev: out of memory !\n");
812 kfree(cam); 1552 kfree(cam);
1553 cam = NULL;
813 return -ENOMEM; 1554 return -ENOMEM;
814 } 1555 }
815 memcpy(cam->vdev, &zr364xx_template, sizeof(zr364xx_template)); 1556 memcpy(cam->vdev, &zr364xx_template, sizeof(zr364xx_template));
1557 cam->vdev->parent = &intf->dev;
816 video_set_drvdata(cam->vdev, cam); 1558 video_set_drvdata(cam->vdev, cam);
817 if (debug) 1559 if (debug)
818 cam->vdev->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; 1560 cam->vdev->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
819 1561
820 cam->udev = udev; 1562 cam->udev = udev;
821 1563
822 if ((cam->buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL)) == NULL) {
823 dev_info(&udev->dev, "cam->buffer: out of memory !\n");
824 video_device_release(cam->vdev);
825 kfree(cam);
826 return -ENODEV;
827 }
828
829 switch (mode) { 1564 switch (mode) {
830 case 1: 1565 case 1:
831 dev_info(&udev->dev, "160x120 mode selected\n"); 1566 dev_info(&udev->dev, "160x120 mode selected\n");
@@ -852,21 +1587,53 @@ static int zr364xx_probe(struct usb_interface *intf,
852 header2[439] = cam->width / 256; 1587 header2[439] = cam->width / 256;
853 header2[440] = cam->width % 256; 1588 header2[440] = cam->width % 256;
854 1589
1590 cam->users = 0;
855 cam->nb = 0; 1591 cam->nb = 0;
856 cam->brightness = 64; 1592 cam->mode.brightness = 64;
857 mutex_init(&cam->lock); 1593 mutex_init(&cam->lock);
1594 mutex_init(&cam->open_lock);
1595
1596 DBG("dev: %p, udev %p interface %p\n", cam, cam->udev, intf);
1597
1598 /* set up the endpoint information */
1599 iface_desc = intf->cur_altsetting;
1600 DBG("num endpoints %d\n", iface_desc->desc.bNumEndpoints);
1601 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
1602 endpoint = &iface_desc->endpoint[i].desc;
1603 if (!cam->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
1604 /* we found the bulk in endpoint */
1605 cam->read_endpoint = endpoint->bEndpointAddress;
1606 }
1607 }
1608
1609 if (!cam->read_endpoint) {
1610 dev_err(&intf->dev, "Could not find bulk-in endpoint\n");
1611 return -ENOMEM;
1612 }
858 1613
1614 /* v4l */
1615 INIT_LIST_HEAD(&cam->vidq.active);
1616 cam->vidq.cam = cam;
859 err = video_register_device(cam->vdev, VFL_TYPE_GRABBER, -1); 1617 err = video_register_device(cam->vdev, VFL_TYPE_GRABBER, -1);
860 if (err) { 1618 if (err) {
861 dev_err(&udev->dev, "video_register_device failed\n"); 1619 dev_err(&udev->dev, "video_register_device failed\n");
862 video_device_release(cam->vdev); 1620 video_device_release(cam->vdev);
863 kfree(cam->buffer);
864 kfree(cam); 1621 kfree(cam);
1622 cam = NULL;
865 return err; 1623 return err;
866 } 1624 }
867 1625
868 usb_set_intfdata(intf, cam); 1626 usb_set_intfdata(intf, cam);
869 1627
1628 /* load zr364xx board specific */
1629 err = zr364xx_board_init(cam);
1630 if (err) {
1631 spin_lock_init(&cam->slock);
1632 return err;
1633 }
1634
1635 spin_lock_init(&cam->slock);
1636
870 dev_info(&udev->dev, DRIVER_DESC " controlling video device %d\n", 1637 dev_info(&udev->dev, DRIVER_DESC " controlling video device %d\n",
871 cam->vdev->num); 1638 cam->vdev->num);
872 return 0; 1639 return 0;
@@ -876,17 +1643,10 @@ static int zr364xx_probe(struct usb_interface *intf,
876static void zr364xx_disconnect(struct usb_interface *intf) 1643static void zr364xx_disconnect(struct usb_interface *intf)
877{ 1644{
878 struct zr364xx_camera *cam = usb_get_intfdata(intf); 1645 struct zr364xx_camera *cam = usb_get_intfdata(intf);
1646 videobuf_mmap_free(&cam->vb_vidq);
879 usb_set_intfdata(intf, NULL); 1647 usb_set_intfdata(intf, NULL);
880 dev_info(&intf->dev, DRIVER_DESC " webcam unplugged\n"); 1648 dev_info(&intf->dev, DRIVER_DESC " webcam unplugged\n");
881 if (cam->vdev) 1649 zr364xx_destroy(cam);
882 video_unregister_device(cam->vdev);
883 cam->vdev = NULL;
884 kfree(cam->buffer);
885 cam->buffer = NULL;
886 vfree(cam->framebuf);
887 cam->framebuf = NULL;
888 kfree(cam);
889 cam = NULL;
890} 1650}
891 1651
892 1652