diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-15 12:22:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-15 12:22:18 -0400 |
commit | 043fe50f8085c12651c96f04576eae4d8a22f3d8 (patch) | |
tree | 214b4f985ce7d3b1a4961620e2c2f4f5f06e1c35 /drivers | |
parent | 227423904c709a8e60245c97081bbeb4fb500655 (diff) | |
parent | ea47689e74a1637fac4f5fc44890f3662c976849 (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')
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 | ||
60 | void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, | 60 | void 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 */ |
28 | IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = { | 32 | static struct ir_scancode ir_codes_empty[] = { |
29 | [ 0x2a ] = KEY_COFFEE, | 33 | { 0x2a, KEY_COFFEE }, |
30 | }; | 34 | }; |
31 | 35 | ||
32 | EXPORT_SYMBOL_GPL(ir_codes_empty); | 36 | struct ir_scancode_table ir_codes_empty_table = { |
37 | .scan = ir_codes_empty, | ||
38 | .size = ARRAY_SIZE(ir_codes_empty), | ||
39 | }; | ||
40 | EXPORT_SYMBOL_GPL(ir_codes_empty_table); | ||
33 | 41 | ||
34 | /* Michal Majchrowicz <mmajchrowicz@gmail.com> */ | 42 | /* Michal Majchrowicz <mmajchrowicz@gmail.com> */ |
35 | IR_KEYTAB_TYPE ir_codes_proteus_2309[IR_KEYTAB_SIZE] = { | 43 | static 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 | ||
64 | EXPORT_SYMBOL_GPL(ir_codes_proteus_2309); | 72 | struct ir_scancode_table ir_codes_proteus_2309_table = { |
73 | .scan = ir_codes_proteus_2309, | ||
74 | .size = ARRAY_SIZE(ir_codes_proteus_2309), | ||
75 | }; | ||
76 | EXPORT_SYMBOL_GPL(ir_codes_proteus_2309_table); | ||
77 | |||
65 | /* Matt Jesson <dvb@jesson.eclipse.co.uk */ | 78 | /* Matt Jesson <dvb@jesson.eclipse.co.uk */ |
66 | IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE] = { | 79 | static 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 | ||
104 | EXPORT_SYMBOL_GPL(ir_codes_avermedia_dvbt); | 117 | struct ir_scancode_table ir_codes_avermedia_dvbt_table = { |
118 | .scan = ir_codes_avermedia_dvbt, | ||
119 | .size = ARRAY_SIZE(ir_codes_avermedia_dvbt), | ||
120 | }; | ||
121 | EXPORT_SYMBOL_GPL(ir_codes_avermedia_dvbt_table); | ||
105 | 122 | ||
106 | /* Mauro Carvalho Chehab <mchehab@infradead.org> */ | 123 | /* Mauro Carvalho Chehab <mchehab@infradead.org> */ |
107 | IR_KEYTAB_TYPE ir_codes_avermedia_m135a[IR_KEYTAB_SIZE] = { | 124 | static 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 | }; |
154 | EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a); | 171 | |
172 | struct ir_scancode_table ir_codes_avermedia_m135a_table = { | ||
173 | .scan = ir_codes_avermedia_m135a, | ||
174 | .size = ARRAY_SIZE(ir_codes_avermedia_m135a), | ||
175 | }; | ||
176 | EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a_table); | ||
155 | 177 | ||
156 | /* Oldrich Jedlicka <oldium.pro@seznam.cz> */ | 178 | /* Oldrich Jedlicka <oldium.pro@seznam.cz> */ |
157 | IR_KEYTAB_TYPE ir_codes_avermedia_cardbus[IR_KEYTAB_SIZE] = { | 179 | static 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 | }; |
213 | EXPORT_SYMBOL_GPL(ir_codes_avermedia_cardbus); | 235 | |
236 | struct ir_scancode_table ir_codes_avermedia_cardbus_table = { | ||
237 | .scan = ir_codes_avermedia_cardbus, | ||
238 | .size = ARRAY_SIZE(ir_codes_avermedia_cardbus), | ||
239 | }; | ||
240 | EXPORT_SYMBOL_GPL(ir_codes_avermedia_cardbus_table); | ||
214 | 241 | ||
215 | /* Attila Kondoros <attila.kondoros@chello.hu> */ | 242 | /* Attila Kondoros <attila.kondoros@chello.hu> */ |
216 | IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = { | 243 | static 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 | ||
256 | EXPORT_SYMBOL_GPL(ir_codes_apac_viewcomp); | 283 | struct ir_scancode_table ir_codes_apac_viewcomp_table = { |
284 | .scan = ir_codes_apac_viewcomp, | ||
285 | .size = ARRAY_SIZE(ir_codes_apac_viewcomp), | ||
286 | }; | ||
287 | EXPORT_SYMBOL_GPL(ir_codes_apac_viewcomp_table); | ||
257 | 288 | ||
258 | /* ---------------------------------------------------------------------- */ | 289 | /* ---------------------------------------------------------------------- */ |
259 | 290 | ||
260 | IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = { | 291 | static 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 | ||
322 | EXPORT_SYMBOL_GPL(ir_codes_pixelview); | 335 | struct ir_scancode_table ir_codes_pixelview_table = { |
336 | .scan = ir_codes_pixelview, | ||
337 | .size = ARRAY_SIZE(ir_codes_pixelview), | ||
338 | }; | ||
339 | EXPORT_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 | */ |
328 | IR_KEYTAB_TYPE ir_codes_pixelview_new[IR_KEYTAB_SIZE] = { | 345 | static 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 | }; |
367 | EXPORT_SYMBOL_GPL(ir_codes_pixelview_new); | 384 | |
368 | 385 | struct ir_scancode_table ir_codes_pixelview_new_table = { | |
369 | IR_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, | 389 | EXPORT_SYMBOL_GPL(ir_codes_pixelview_new_table); |
373 | [ 0x03 ] = KEY_3, | 390 | |
374 | [ 0x04 ] = KEY_4, | 391 | static 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 */ | |
427 | EXPORT_SYMBOL_GPL(ir_codes_nebula); | 444 | { 0x34, KEY_EMAIL }, |
445 | { 0x35, KEY_PHONE }, | ||
446 | { 0x36, KEY_PC }, | ||
447 | }; | ||
448 | |||
449 | struct ir_scancode_table ir_codes_nebula_table = { | ||
450 | .scan = ir_codes_nebula, | ||
451 | .size = ARRAY_SIZE(ir_codes_nebula), | ||
452 | }; | ||
453 | EXPORT_SYMBOL_GPL(ir_codes_nebula_table); | ||
428 | 454 | ||
429 | /* DigitalNow DNTV Live DVB-T Remote */ | 455 | /* DigitalNow DNTV Live DVB-T Remote */ |
430 | IR_KEYTAB_TYPE ir_codes_dntv_live_dvb_t[IR_KEYTAB_SIZE] = { | 456 | static 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 | ||
468 | EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvb_t); | 494 | struct 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 | }; | ||
498 | EXPORT_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 */ |
473 | IR_KEYTAB_TYPE ir_codes_iodata_bctv7e[IR_KEYTAB_SIZE] = { | 503 | static 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 | ||
521 | EXPORT_SYMBOL_GPL(ir_codes_iodata_bctv7e); | 551 | struct ir_scancode_table ir_codes_iodata_bctv7e_table = { |
552 | .scan = ir_codes_iodata_bctv7e, | ||
553 | .size = ARRAY_SIZE(ir_codes_iodata_bctv7e), | ||
554 | }; | ||
555 | EXPORT_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 */ |
526 | IR_KEYTAB_TYPE ir_codes_adstech_dvb_t_pci[IR_KEYTAB_SIZE] = { | 560 | static 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 | ||
575 | EXPORT_SYMBOL_GPL(ir_codes_adstech_dvb_t_pci); | 609 | struct 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 | }; | ||
613 | EXPORT_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 | ||
581 | IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE] = { | 619 | static 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 | ||
610 | EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere); | 648 | struct ir_scancode_table ir_codes_msi_tvanywhere_table = { |
649 | .scan = ir_codes_msi_tvanywhere, | ||
650 | .size = ARRAY_SIZE(ir_codes_msi_tvanywhere), | ||
651 | }; | ||
652 | EXPORT_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 | ||
629 | IR_KEYTAB_TYPE ir_codes_msi_tvanywhere_plus[IR_KEYTAB_SIZE] = { | 671 | static 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, /* << */ | 742 | struct 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 | }; |
699 | EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_plus); | 746 | EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_plus_table); |
700 | 747 | ||
701 | /* ---------------------------------------------------------------------- */ | 748 | /* ---------------------------------------------------------------------- */ |
702 | 749 | ||
703 | /* Cinergy 1400 DVB-T */ | 750 | /* Cinergy 1400 DVB-T */ |
704 | IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = { | 751 | static 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 | ||
748 | EXPORT_SYMBOL_GPL(ir_codes_cinergy_1400); | 795 | struct ir_scancode_table ir_codes_cinergy_1400_table = { |
796 | .scan = ir_codes_cinergy_1400, | ||
797 | .size = ARRAY_SIZE(ir_codes_cinergy_1400), | ||
798 | }; | ||
799 | EXPORT_SYMBOL_GPL(ir_codes_cinergy_1400_table); | ||
749 | 800 | ||
750 | /* ---------------------------------------------------------------------- */ | 801 | /* ---------------------------------------------------------------------- */ |
751 | 802 | ||
752 | /* AVERTV STUDIO 303 Remote */ | 803 | /* AVERTV STUDIO 303 Remote */ |
753 | IR_KEYTAB_TYPE ir_codes_avertv_303[IR_KEYTAB_SIZE] = { | 804 | static 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 | ||
798 | EXPORT_SYMBOL_GPL(ir_codes_avertv_303); | 849 | struct ir_scancode_table ir_codes_avertv_303_table = { |
850 | .scan = ir_codes_avertv_303, | ||
851 | .size = ARRAY_SIZE(ir_codes_avertv_303), | ||
852 | }; | ||
853 | EXPORT_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 */ |
803 | IR_KEYTAB_TYPE ir_codes_dntv_live_dvbt_pro[IR_KEYTAB_SIZE] = { | 858 | static 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 | ||
860 | EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvbt_pro); | 915 | struct ir_scancode_table ir_codes_dntv_live_dvbt_pro_table = { |
861 | 916 | .scan = ir_codes_dntv_live_dvbt_pro, | |
862 | IR_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, | 919 | EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvbt_pro_table); |
865 | [ 0x03 ] = KEY_MUTE, | 920 | |
866 | [ 0x04 ] = KEY_POWER, | 921 | static 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 }, | |
893 | EXPORT_SYMBOL_GPL(ir_codes_em_terratec); | 948 | { 0x1e, KEY_STOP }, |
894 | 949 | { 0x40, KEY_ZOOM }, | |
895 | IR_KEYTAB_TYPE ir_codes_pinnacle_grey[IR_KEYTAB_SIZE] = { | 950 | }; |
896 | [ 0x3a ] = KEY_0, | 951 | |
897 | [ 0x31 ] = KEY_1, | 952 | struct 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, | 956 | EXPORT_SYMBOL_GPL(ir_codes_em_terratec_table); |
902 | [ 0x36 ] = KEY_6, | 957 | |
903 | [ 0x37 ] = KEY_7, | 958 | static 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 }, | |
946 | EXPORT_SYMBOL_GPL(ir_codes_pinnacle_grey); | 1001 | { 0x07, KEY_FORWARD }, |
947 | 1002 | { 0x27, KEY_RECORD }, | |
948 | IR_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, | 1009 | struct 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, | 1013 | EXPORT_SYMBOL_GPL(ir_codes_pinnacle_grey_table); |
959 | 1014 | ||
960 | [ 0x0e ] = KEY_MODE, // Air/Cable | 1015 | static 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 */ | |
980 | EXPORT_SYMBOL_GPL(ir_codes_flyvideo); | 1035 | { 0x14, KEY_VOLUMEUP }, /* Volume + */ |
981 | 1036 | { 0x17, KEY_VOLUMEDOWN },/* Volume - */ | |
982 | IR_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, | 1047 | struct 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, | 1051 | EXPORT_SYMBOL_GPL(ir_codes_flyvideo_table); |
997 | [ 0x10 ] = KEY_MUTE, // Mute | 1052 | |
998 | [ 0x02 ] = KEY_RADIO, // TV/Radio | 1053 | static 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- */ | |
1021 | EXPORT_SYMBOL_GPL(ir_codes_flydvb); | 1076 | { 0x1d, KEY_ENTER }, /* Enter */ |
1022 | 1077 | ||
1023 | IR_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 | 1092 | struct 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, | 1096 | EXPORT_SYMBOL_GPL(ir_codes_flydvb_table); |
1042 | [ 0x11 ] = KEY_TUNER, // AV | 1097 | |
1043 | [ 0x12 ] = KEY_NUMLOCK, // -/-- | 1098 | static 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 */ | |
1063 | EXPORT_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 | |||
1138 | struct ir_scancode_table ir_codes_cinergy_table = { | ||
1139 | .scan = ir_codes_cinergy, | ||
1140 | .size = ARRAY_SIZE(ir_codes_cinergy), | ||
1141 | }; | ||
1142 | EXPORT_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> */ |
1067 | IR_KEYTAB_TYPE ir_codes_eztv[IR_KEYTAB_SIZE] = { | 1146 | static 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 | ||
1122 | EXPORT_SYMBOL_GPL(ir_codes_eztv); | 1201 | struct ir_scancode_table ir_codes_eztv_table = { |
1202 | .scan = ir_codes_eztv, | ||
1203 | .size = ARRAY_SIZE(ir_codes_eztv), | ||
1204 | }; | ||
1205 | EXPORT_SYMBOL_GPL(ir_codes_eztv_table); | ||
1123 | 1206 | ||
1124 | /* Alex Hermann <gaaf@gmx.net> */ | 1207 | /* Alex Hermann <gaaf@gmx.net> */ |
1125 | IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE] = { | 1208 | static 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 | ||
1171 | EXPORT_SYMBOL_GPL(ir_codes_avermedia); | 1254 | struct ir_scancode_table ir_codes_avermedia_table = { |
1172 | 1255 | .scan = ir_codes_avermedia, | |
1173 | IR_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, | 1258 | EXPORT_SYMBOL_GPL(ir_codes_avermedia_table); |
1176 | 1259 | ||
1177 | [ 0x01 ] = KEY_DVD, | 1260 | static 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 | ||
1222 | EXPORT_SYMBOL_GPL(ir_codes_videomate_tv_pvr); | 1305 | { 0x20, KEY_LANGUAGE }, |
1306 | { 0x21, KEY_SLEEP }, | ||
1307 | }; | ||
1308 | |||
1309 | struct 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 | }; | ||
1313 | EXPORT_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 | */ |
1233 | IR_KEYTAB_TYPE ir_codes_manli[IR_KEYTAB_SIZE] = { | 1324 | static 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 | ||
1320 | EXPORT_SYMBOL_GPL(ir_codes_manli); | 1411 | struct ir_scancode_table ir_codes_manli_table = { |
1412 | .scan = ir_codes_manli, | ||
1413 | .size = ARRAY_SIZE(ir_codes_manli), | ||
1414 | }; | ||
1415 | EXPORT_SYMBOL_GPL(ir_codes_manli_table); | ||
1321 | 1416 | ||
1322 | /* Mike Baikov <mike@baikov.com> */ | 1417 | /* Mike Baikov <mike@baikov.com> */ |
1323 | IR_KEYTAB_TYPE ir_codes_gotview7135[IR_KEYTAB_SIZE] = { | 1418 | static 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 | ||
1362 | EXPORT_SYMBOL_GPL(ir_codes_gotview7135); | 1457 | struct ir_scancode_table ir_codes_gotview7135_table = { |
1363 | 1458 | .scan = ir_codes_gotview7135, | |
1364 | IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = { | 1459 | .size = ARRAY_SIZE(ir_codes_gotview7135), |
1365 | [ 0x03 ] = KEY_POWER, | 1460 | }; |
1366 | [ 0x6f ] = KEY_MUTE, | 1461 | EXPORT_SYMBOL_GPL(ir_codes_gotview7135_table); |
1367 | [ 0x10 ] = KEY_BACKSPACE, /* Recall */ | 1462 | |
1368 | 1463 | static 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 }, | |
1404 | EXPORT_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 | |||
1506 | struct ir_scancode_table ir_codes_purpletv_table = { | ||
1507 | .scan = ir_codes_purpletv, | ||
1508 | .size = ARRAY_SIZE(ir_codes_purpletv), | ||
1509 | }; | ||
1510 | EXPORT_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 */ |
1410 | IR_KEYTAB_TYPE ir_codes_pctv_sedna[IR_KEYTAB_SIZE] = { | 1516 | static 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 | ||
1447 | EXPORT_SYMBOL_GPL(ir_codes_pctv_sedna); | 1553 | struct ir_scancode_table ir_codes_pctv_sedna_table = { |
1554 | .scan = ir_codes_pctv_sedna, | ||
1555 | .size = ARRAY_SIZE(ir_codes_pctv_sedna), | ||
1556 | }; | ||
1557 | EXPORT_SYMBOL_GPL(ir_codes_pctv_sedna_table); | ||
1448 | 1558 | ||
1449 | /* Mark Phalan <phalanm@o2.ie> */ | 1559 | /* Mark Phalan <phalanm@o2.ie> */ |
1450 | IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = { | 1560 | static 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 | ||
1488 | EXPORT_SYMBOL_GPL(ir_codes_pv951); | 1598 | struct ir_scancode_table ir_codes_pv951_table = { |
1599 | .scan = ir_codes_pv951, | ||
1600 | .size = ARRAY_SIZE(ir_codes_pv951), | ||
1601 | }; | ||
1602 | EXPORT_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 */ |
1493 | IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE] = { | 1607 | static 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 | ||
1532 | EXPORT_SYMBOL_GPL(ir_codes_rc5_tv); | 1646 | struct ir_scancode_table ir_codes_rc5_tv_table = { |
1647 | .scan = ir_codes_rc5_tv, | ||
1648 | .size = ARRAY_SIZE(ir_codes_rc5_tv), | ||
1649 | }; | ||
1650 | EXPORT_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 */ |
1535 | IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { | 1653 | static 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 | ||
1596 | EXPORT_SYMBOL_GPL(ir_codes_winfast); | 1714 | struct ir_scancode_table ir_codes_winfast_table = { |
1597 | 1715 | .scan = ir_codes_winfast, | |
1598 | IR_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, | 1718 | EXPORT_SYMBOL_GPL(ir_codes_winfast_table); |
1601 | 1719 | ||
1602 | [ 0x18 ] = KEY_TEXT, | 1720 | static 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 }, | |
1656 | EXPORT_SYMBOL_GPL(ir_codes_pinnacle_color); | 1774 | }; |
1775 | |||
1776 | struct ir_scancode_table ir_codes_pinnacle_color_table = { | ||
1777 | .scan = ir_codes_pinnacle_color, | ||
1778 | .size = ARRAY_SIZE(ir_codes_pinnacle_color), | ||
1779 | }; | ||
1780 | EXPORT_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 */ |
1661 | IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = { | 1785 | static 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 | ||
1719 | EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new); | 1843 | struct ir_scancode_table ir_codes_hauppauge_new_table = { |
1720 | 1844 | .scan = ir_codes_hauppauge_new, | |
1721 | IR_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, | 1847 | EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table); |
1724 | 1848 | ||
1725 | [ 0x3e ] = KEY_1, | 1849 | static 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 }, | |
1763 | EXPORT_SYMBOL_GPL(ir_codes_npgtech); | 1887 | { 0x10, KEY_POWER }, |
1888 | |||
1889 | }; | ||
1890 | |||
1891 | struct ir_scancode_table ir_codes_npgtech_table = { | ||
1892 | .scan = ir_codes_npgtech, | ||
1893 | .size = ARRAY_SIZE(ir_codes_npgtech), | ||
1894 | }; | ||
1895 | EXPORT_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 */ |
1768 | IR_KEYTAB_TYPE ir_codes_norwood[IR_KEYTAB_SIZE] = { | 1900 | static 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 | ||
1811 | EXPORT_SYMBOL_GPL(ir_codes_norwood); | 1943 | struct ir_scancode_table ir_codes_norwood_table = { |
1944 | .scan = ir_codes_norwood, | ||
1945 | .size = ARRAY_SIZE(ir_codes_norwood), | ||
1946 | }; | ||
1947 | EXPORT_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 | */ |
1818 | IR_KEYTAB_TYPE ir_codes_budget_ci_old[IR_KEYTAB_SIZE] = { | 1954 | static 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 | ||
1866 | EXPORT_SYMBOL_GPL(ir_codes_budget_ci_old); | 2002 | struct 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 | }; | ||
2006 | EXPORT_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 | */ |
1873 | IR_KEYTAB_TYPE ir_codes_asus_pc39[IR_KEYTAB_SIZE] = { | 2013 | static 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 | ||
1920 | EXPORT_SYMBOL_GPL(ir_codes_asus_pc39); | 2060 | struct ir_scancode_table ir_codes_asus_pc39_table = { |
2061 | .scan = ir_codes_asus_pc39, | ||
2062 | .size = ARRAY_SIZE(ir_codes_asus_pc39), | ||
2063 | }; | ||
2064 | EXPORT_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> */ |
1925 | IR_KEYTAB_TYPE ir_codes_encore_enltv[IR_KEYTAB_SIZE] = { | 2069 | static 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 | }; |
1995 | EXPORT_SYMBOL_GPL(ir_codes_encore_enltv); | 2139 | |
2140 | struct ir_scancode_table ir_codes_encore_enltv_table = { | ||
2141 | .scan = ir_codes_encore_enltv, | ||
2142 | .size = ARRAY_SIZE(ir_codes_encore_enltv), | ||
2143 | }; | ||
2144 | EXPORT_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> */ |
1999 | IR_KEYTAB_TYPE ir_codes_encore_enltv2[IR_KEYTAB_SIZE] = { | 2148 | static 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 | }; |
2047 | EXPORT_SYMBOL_GPL(ir_codes_encore_enltv2); | 2196 | |
2197 | struct ir_scancode_table ir_codes_encore_enltv2_table = { | ||
2198 | .scan = ir_codes_encore_enltv2, | ||
2199 | .size = ARRAY_SIZE(ir_codes_encore_enltv2), | ||
2200 | }; | ||
2201 | EXPORT_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): */ |
2050 | IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE] = { | 2204 | static 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 | ||
2092 | EXPORT_SYMBOL_GPL(ir_codes_tt_1500); | 2246 | struct ir_scancode_table ir_codes_tt_1500_table = { |
2247 | .scan = ir_codes_tt_1500, | ||
2248 | .size = ARRAY_SIZE(ir_codes_tt_1500), | ||
2249 | }; | ||
2250 | EXPORT_SYMBOL_GPL(ir_codes_tt_1500_table); | ||
2093 | 2251 | ||
2094 | /* DViCO FUSION HDTV MCE remote */ | 2252 | /* DViCO FUSION HDTV MCE remote */ |
2095 | IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE] = { | 2253 | static 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 | ||
2153 | EXPORT_SYMBOL_GPL(ir_codes_fusionhdtv_mce); | 2311 | struct ir_scancode_table ir_codes_fusionhdtv_mce_table = { |
2312 | .scan = ir_codes_fusionhdtv_mce, | ||
2313 | .size = ARRAY_SIZE(ir_codes_fusionhdtv_mce), | ||
2314 | }; | ||
2315 | EXPORT_SYMBOL_GPL(ir_codes_fusionhdtv_mce_table); | ||
2154 | 2316 | ||
2155 | /* Pinnacle PCTV HD 800i mini remote */ | 2317 | /* Pinnacle PCTV HD 800i mini remote */ |
2156 | IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE] = { | 2318 | static 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 | }; |
2188 | EXPORT_SYMBOL_GPL(ir_codes_pinnacle_pctv_hd); | 2350 | |
2351 | struct 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 | }; | ||
2355 | EXPORT_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 | */ |
2201 | IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE] = { | 2368 | static 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 | ||
2292 | EXPORT_SYMBOL_GPL(ir_codes_behold); | 2459 | struct ir_scancode_table ir_codes_behold_table = { |
2460 | .scan = ir_codes_behold, | ||
2461 | .size = ARRAY_SIZE(ir_codes_behold), | ||
2462 | }; | ||
2463 | EXPORT_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 | */ |
2302 | IR_KEYTAB_TYPE ir_codes_behold_columbus[IR_KEYTAB_SIZE] = { | 2473 | static 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 | ||
2534 | struct ir_scancode_table ir_codes_behold_columbus_table = { | ||
2535 | .scan = ir_codes_behold_columbus, | ||
2536 | .size = ARRAY_SIZE(ir_codes_behold_columbus), | ||
2361 | }; | 2537 | }; |
2362 | EXPORT_SYMBOL_GPL(ir_codes_behold_columbus); | 2538 | EXPORT_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 | */ |
2368 | IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE] = { | 2544 | static 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 | |||
2585 | struct 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 | }; |
2408 | EXPORT_SYMBOL_GPL(ir_codes_genius_tvgo_a11mce); | 2589 | EXPORT_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 | */ |
2414 | IR_KEYTAB_TYPE ir_codes_powercolor_real_angel[IR_KEYTAB_SIZE] = { | 2595 | static 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 | }; |
2451 | EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel); | 2632 | |
2633 | struct 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 | }; | ||
2637 | EXPORT_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 | */ |
2456 | IR_KEYTAB_TYPE ir_codes_kworld_plus_tv_analog[IR_KEYTAB_SIZE] = { | 2642 | static 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 | }; |
2512 | EXPORT_SYMBOL_GPL(ir_codes_kworld_plus_tv_analog); | 2698 | struct 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 | }; | ||
2702 | EXPORT_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 | */ |
2517 | IR_KEYTAB_TYPE ir_codes_kaiomy[IR_KEYTAB_SIZE] = { | 2707 | static 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 | }; | ||
2561 | EXPORT_SYMBOL_GPL(ir_codes_kaiomy); | ||
2562 | |||
2563 | IR_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 | }; | ||
2599 | EXPORT_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}, |
2604 | IR_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 | }; | ||
2642 | EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_fm53); | ||
2643 | 2716 | ||
2644 | /* Zogis Real Audio 220 - 32 keys IR */ | 2717 | { 0x0f, KEY_4}, |
2645 | IR_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 | }; | ||
2751 | struct ir_scancode_table ir_codes_kaiomy_table = { | ||
2752 | .scan = ir_codes_kaiomy, | ||
2753 | .size = ARRAY_SIZE(ir_codes_kaiomy), | ||
2754 | }; | ||
2755 | EXPORT_SYMBOL_GPL(ir_codes_kaiomy_table); | ||
2756 | |||
2757 | static 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 | }; | ||
2793 | struct ir_scancode_table ir_codes_avermedia_a16d_table = { | ||
2794 | .scan = ir_codes_avermedia_a16d, | ||
2795 | .size = ARRAY_SIZE(ir_codes_avermedia_a16d), | ||
2681 | }; | 2796 | }; |
2682 | EXPORT_SYMBOL_GPL(ir_codes_real_audio_220_32_keys); | 2797 | EXPORT_SYMBOL_GPL(ir_codes_avermedia_a16d_table); |
2798 | |||
2799 | /* Encore ENLTV-FM v5.3 | ||
2800 | Mauro Carvalho Chehab <mchehab@infradead.org> | ||
2801 | */ | ||
2802 | static 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 | }; | ||
2840 | struct 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 | }; | ||
2844 | EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_fm53_table); | ||
2845 | |||
2846 | /* Zogis Real Audio 220 - 32 keys IR */ | ||
2847 | static 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 | }; | ||
2884 | struct 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 | }; | ||
2888 | EXPORT_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 | */ |
2687 | IR_KEYTAB_TYPE ir_codes_ati_tv_wonder_hd_600[IR_KEYTAB_SIZE] = { | 2893 | static 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 | 2919 | struct ir_scancode_table ir_codes_ati_tv_wonder_hd_600_table = { | |
2714 | EXPORT_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 | }; | ||
2923 | EXPORT_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 | */ |
2719 | IR_KEYTAB_TYPE ir_codes_dm1105_nec[IR_KEYTAB_SIZE] = { | 2928 | static 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 | }; |
2752 | EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec); | 2961 | struct ir_scancode_table ir_codes_dm1105_nec_table = { |
2962 | .scan = ir_codes_dm1105_nec, | ||
2963 | .size = ARRAY_SIZE(ir_codes_dm1105_nec), | ||
2964 | }; | ||
2965 | EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec_table); | ||
2966 | |||
2967 | /* Terratec Cinergy Hybrid T USB XS | ||
2968 | Devin Heitmueller <dheitmueller@linuxtv.org> | ||
2969 | */ | ||
2970 | static 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 | }; | ||
3019 | struct 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 | }; | ||
3023 | EXPORT_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 | */ |
2757 | IR_KEYTAB_TYPE ir_codes_evga_indtube[IR_KEYTAB_SIZE] = { | 3028 | static 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 | }; |
2775 | EXPORT_SYMBOL_GPL(ir_codes_evga_indtube); | 3046 | struct ir_scancode_table ir_codes_evga_indtube_table = { |
3047 | .scan = ir_codes_evga_indtube, | ||
3048 | .size = ARRAY_SIZE(ir_codes_evga_indtube), | ||
3049 | }; | ||
3050 | EXPORT_SYMBOL_GPL(ir_codes_evga_indtube_table); | ||
3051 | |||
3052 | static 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 | }; | ||
3098 | struct ir_scancode_table ir_codes_videomate_s350_table = { | ||
3099 | .scan = ir_codes_videomate_s350, | ||
3100 | .size = ARRAY_SIZE(ir_codes_videomate_s350), | ||
3101 | }; | ||
3102 | EXPORT_SYMBOL_GPL(ir_codes_videomate_s350_table); | ||
3103 | |||
3104 | /* GADMEI UTV330+ RM008Z remote | ||
3105 | Shine Liu <shinel@foxmail.com> | ||
3106 | */ | ||
3107 | static 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 | }; | ||
3145 | struct ir_scancode_table ir_codes_gadmei_rm008z_table = { | ||
3146 | .scan = ir_codes_gadmei_rm008z, | ||
3147 | .size = ARRAY_SIZE(ir_codes_gadmei_rm008z), | ||
3148 | }; | ||
3149 | EXPORT_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); | |||
27 | MODULE_PARM_DESC(debug, "set debug level " | 27 | MODULE_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 | ||
30 | static int tda18271_cal_on_startup; | 30 | static int tda18271_cal_on_startup = -1; |
31 | module_param_named(cal, tda18271_cal_on_startup, int, 0644); | 31 | module_param_named(cal, tda18271_cal_on_startup, int, 0644); |
32 | MODULE_PARM_DESC(cal, "perform RF tracking filter calibration on startup"); | 32 | MODULE_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 | |||
1306 | static 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 | |||
1314 | static 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 | ||
1306 | struct tunertype tuners[] = { | 1325 | struct 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 | }; |
1757 | EXPORT_SYMBOL(tuners); | 1782 | EXPORT_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 | ||
5 | config 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 | |||
5 | config DVB_DYNAMIC_MINORS | 18 | config 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) |
70 | static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) | 70 | static 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 | ||
158 | static 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 | |||
183 | static int skystar2_rev23_attach(struct flexcop_device *fc, | 158 | static 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) |
207 | static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe, | 186 | static 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 | ||
235 | static 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 | |||
260 | static u8 samsung_tbmu24112_inittab[] = { | 214 | static 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) |
453 | static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe) | 410 | static 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 | ||
470 | static 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 | |||
496 | static struct mt352_config samsung_tdtc9251dh0_config = { | 427 | static 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) |
584 | static 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 | |||
631 | static u8 alps_tdee4_stv0297_inittab[] = { | 515 | static 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 | |||
613 | fail: | ||
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 | ||
174 | static unsigned int card[] = {[0 ... 3] = UNSET }; | ||
175 | module_param_array(card, int, NULL, 0444); | ||
176 | MODULE_PARM_DESC(card, "card type"); | ||
177 | |||
164 | static int ir_debug; | 178 | static int ir_debug; |
165 | module_param(ir_debug, int, 0644); | 179 | module_param(ir_debug, int, 0644); |
166 | MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); | 180 | MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); |
167 | 181 | ||
182 | static unsigned int dm1105_devcount; | ||
183 | |||
168 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 184 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
169 | 185 | ||
186 | struct dm1105_board { | ||
187 | char *name; | ||
188 | }; | ||
189 | |||
190 | struct dm1105_subid { | ||
191 | u16 subvendor; | ||
192 | u16 subdevice; | ||
193 | u32 card; | ||
194 | }; | ||
195 | |||
196 | static 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 | |||
211 | static 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 | |||
235 | static 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 */ |
171 | struct infrared { | 264 | struct 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) | |||
326 | static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | 420 | static 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) | |||
477 | int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) | 577 | int __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) */ |
431 | static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter) | 431 | static 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 */ |
450 | static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter) | 453 | static 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 | ||
488 | static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter) | 501 | static 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 | ||
539 | static 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 | |||
524 | static inline int dvb_dmxdev_filter_reset(struct dmxdev_filter *dmxdevfilter) | 552 | static 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 | ||
565 | static 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 | |||
534 | static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) | 617 | static 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 | ||
805 | static 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 | |||
832 | static 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 | |||
763 | static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev, | 854 | static 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 | ||
56 | struct dmxdev_feed { | ||
57 | u16 pid; | ||
58 | struct dmx_ts_feed *ts; | ||
59 | struct list_head next; | ||
60 | }; | ||
61 | |||
56 | struct dmxdev_filter { | 62 | struct 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 | |||
357 | static void dvb_frontend_swzigzag(struct dvb_frontend *fe) | 363 | static 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 | ||
255 | config DVB_USB_DW2102 | 255 | config 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 | ||
269 | config DVB_USB_CINERGY_T2 | 271 | config 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 | ||
40 | static struct dvb_usb_rc_key a800_rc_keys[] = { | 40 | static 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 | ||
36 | struct dvb_usb_rc_key af9005_rc_keys[] = { | 36 | struct 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 | ||
77 | int af9005_rc_keys_size = ARRAY_SIZE(af9005_rc_keys); | 77 | int 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 */ |
539 | static int af9015_eeprom_dump(struct dvb_usb_device *d) | 539 | static 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 | }; |
1271 | MODULE_DEVICE_TABLE(usb, af9015_usb_table); | 1270 | MODULE_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 */ |
123 | static struct dvb_usb_rc_key af9015_rc_keys_leadtek[] = { | 123 | static 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 | ||
141 | static u8 af9015_ir_table_leadtek[] = { | 141 | static 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) */ |
195 | static struct dvb_usb_rc_key af9015_rc_keys_twinhan[] = { | 195 | static 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 | ||
252 | static u8 af9015_ir_table_twinhan[] = { | 252 | static 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) */ |
306 | static struct dvb_usb_rc_key af9015_rc_keys_a_link[] = { | 306 | static 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 | ||
327 | static u8 af9015_ir_table_a_link[] = { | 327 | static 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 */ |
349 | static struct dvb_usb_rc_key af9015_rc_keys_msi[] = { | 349 | static 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 | ||
370 | static u8 af9015_ir_table_msi[] = { | 370 | static u8 af9015_ir_table_msi[] = { |
@@ -390,42 +390,42 @@ static u8 af9015_ir_table_msi[] = { | |||
390 | 390 | ||
391 | /* MYGICTV U718 */ | 391 | /* MYGICTV U718 */ |
392 | static struct dvb_usb_rc_key af9015_rc_keys_mygictv[] = { | 392 | static 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 | ||
431 | static u8 af9015_ir_table_mygictv[] = { | 431 | static 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 */ |
518 | static struct dvb_usb_rc_key af9015_rc_keys_avermedia[] = { | 518 | static 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 | ||
556 | static u8 af9015_ir_table_avermedia[] = { | 556 | static 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 */ |
624 | static struct dvb_usb_rc_key af9015_rc_keys_digittrade[] = { | 624 | static 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 | ||
655 | static u8 af9015_ir_table_digittrade[] = { | 655 | static 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 */ |
687 | static struct dvb_usb_rc_key af9015_rc_keys_trekstor[] = { | 687 | static 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 | ||
718 | static u8 af9015_ir_table_trekstor[] = { | 718 | static 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 | ||
402 | static struct dvb_usb_rc_key anysee_rc_keys[] = { | 402 | static 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 | ||
87 | static struct dvb_usb_rc_key cinergyt2_rc_keys[] = { | 87 | static 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 *)¶m, sizeof(param), | 281 | (char *)¶m, 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 */ |
44 | static int dvb_usb_cxusb_debug; | 44 | static 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 | ||
461 | static struct dvb_usb_rc_key dvico_mce_rc_keys[] = { | 461 | static 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 | ||
509 | static struct dvb_usb_rc_key dvico_portable_rc_keys[] = { | 509 | static 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 | ||
548 | static struct dvb_usb_rc_key d680_dmb_rc_keys[] = { | 548 | static 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 | ||
586 | static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) | 586 | static 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 | ||
1097 | static struct lgs8gl5_config lgs8gl5_cfg = { | 1097 | static 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 | ||
1101 | static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap) | 1111 | static 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 | ||
685 | static struct dvb_usb_rc_key dib0700_rc_keys[] = { | 687 | static 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 | }; |
1502 | MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); | 1506 | MODULE_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 | */ |
319 | struct dvb_usb_rc_key dibusb_rc_keys[] = { | 319 | struct 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 | }; |
448 | EXPORT_SYMBOL(dibusb_rc_keys); | 448 | EXPORT_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 | }; |
47 | MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table); | 49 | MODULE_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 | ||
164 | static struct dvb_usb_rc_key digitv_rc_keys[] = { | 164 | static 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 | ||
222 | static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | 222 | static 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) */ |
60 | static struct dvb_usb_rc_key dtt200u_rc_keys[] = { | 60 | static 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 | ||
81 | static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | 81 | static 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 | ||
11 | static 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 | |||
41 | static 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 | */ |
83 | struct dvb_usb_rc_key { | 83 | struct dvb_usb_rc_key { |
84 | u8 custom,data; | 84 | u16 scan; |
85 | u32 event; | 85 | u32 event; |
86 | }; | 86 | }; |
87 | 87 | ||
88 | static inline u8 rc5_custom(struct dvb_usb_rc_key *key) | ||
89 | { | ||
90 | return (key->scan >> 8) & 0xff; | ||
91 | } | ||
92 | |||
93 | static inline u8 rc5_data(struct dvb_usb_rc_key *key) | ||
94 | { | ||
95 | return key->scan & 0xff; | ||
96 | } | ||
97 | |||
98 | static inline u8 rc5_scan(struct dvb_usb_rc_key *key) | ||
99 | { | ||
100 | return key->scan & 0xffff; | ||
101 | } | ||
102 | |||
88 | struct dvb_usb_device; | 103 | struct dvb_usb_device; |
89 | struct dvb_usb_adapter; | 104 | struct dvb_usb_adapter; |
90 | struct usb_data_stream; | 105 | struct 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 | ||
445 | static 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 | |||
439 | static u32 dw210x_i2c_func(struct i2c_adapter *adapter) | 508 | static 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 | ||
538 | static struct i2c_algorithm s630_i2c_algo = { | ||
539 | .master_xfer = s630_i2c_transfer, | ||
540 | .functionality = dw210x_i2c_func, | ||
541 | }; | ||
542 | |||
469 | static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) | 543 | static 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 | ||
567 | static 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 | |||
493 | static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | 598 | static 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 | ||
643 | static struct mt312_config zl313_config = { | ||
644 | .demod_address = 0x0e, | ||
645 | }; | ||
646 | |||
538 | static int dw2104_frontend_attach(struct dvb_usb_adapter *d) | 647 | static 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 | ||
708 | static 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 | |||
599 | static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) | 720 | static 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 | ||
743 | static 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 | |||
622 | static struct dvb_usb_rc_key dw210x_rc_keys[] = { | 751 | static 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 | ||
656 | static struct dvb_usb_rc_key tevii_rc_keys[] = { | 785 | static 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 | ||
706 | static struct dvb_usb_rc_key tbs_rc_keys[] = { | 835 | static 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 | ||
741 | static struct dvb_usb_rc_keys_table keys_tables[] = { | 870 | static 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 | ||
1187 | static 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 | |||
1056 | static int dw2102_probe(struct usb_interface *intf, | 1229 | static 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); | |||
1094 | MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); | 1269 | MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); |
1095 | MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," | 1270 | MODULE_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"); |
1098 | MODULE_VERSION("0.1"); | 1273 | MODULE_VERSION("0.1"); |
1099 | MODULE_LICENSE("GPL"); | 1274 | MODULE_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 */ |
564 | static struct dvb_usb_rc_key megasky_rc_keys [] = { | 564 | static 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 | ||
583 | static struct dvb_usb_rc_key tvwalkertwin_rc_keys [] = { | 583 | static 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 */ |
24 | static struct dvb_usb_rc_key haupp_rc_keys [] = { | 24 | static 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 | ||
334 | static struct dvb_usb_rc_key opera1_rc_keys[] = { | 334 | static 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 */ |
177 | static struct dvb_usb_rc_key vp702x_rc_keys[] = { | 177 | static 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. */ |
102 | static struct dvb_usb_rc_key vp7045_rc_keys[] = { | 102 | static 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 | ||
155 | static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | 155 | static 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 | ||
95 | static int avc_debug; | 104 | static int avc_debug; |
96 | module_param_named(debug, avc_debug, int, 0644); | 105 | module_param_named(debug, avc_debug, int, 0644); |
97 | MODULE_PARM_DESC(debug, "Verbose logging (default = 0" | 106 | MODULE_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 | ||
102 | static const char *debug_fcp_ctype(unsigned int ctype) | 120 | static 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 | ||
145 | static void debug_fcp(const u8 *data, int length) | 177 | static 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) | 198 | static 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 | ||
165 | static int __avc_write(struct firedtv *fdtv, | 205 | static 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 | ||
297 | static 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 | ||
319 | static void avc_tuner_dsd_dvb_c(struct dvb_frontend_parameters *params, | 379 | static 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 | ||
387 | static void avc_tuner_dsd_dvb_t(struct dvb_frontend_parameters *params, | 447 | static 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 = ¶ms->u.ofdm; | 451 | struct dvb_ofdm_parameters *ofdm = ¶ms->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 | ||
490 | int avc_tuner_dsd(struct firedtv *fdtv, | 550 | int 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 | ||
84 | config 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 | |||
84 | config DVB_S5H1420 | 91 | config 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 | |||
31 | obj-$(CONFIG_DVB_NXT6000) += nxt6000.o | 31 | obj-$(CONFIG_DVB_NXT6000) += nxt6000.o |
32 | obj-$(CONFIG_DVB_MT352) += mt352.o | 32 | obj-$(CONFIG_DVB_MT352) += mt352.o |
33 | obj-$(CONFIG_DVB_ZL10036) += zl10036.o | 33 | obj-$(CONFIG_DVB_ZL10036) += zl10036.o |
34 | obj-$(CONFIG_DVB_ZL10039) += zl10039.o | ||
34 | obj-$(CONFIG_DVB_ZL10353) += zl10353.o | 35 | obj-$(CONFIG_DVB_ZL10353) += zl10353.o |
35 | obj-$(CONFIG_DVB_CX22702) += cx22702.o | 36 | obj-$(CONFIG_DVB_CX22702) += cx22702.o |
36 | obj-$(CONFIG_DVB_DRX397XD) += drx397xD.o | 37 | obj-$(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 */ | ||
393 | static 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 */ | ||
407 | static 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 */ | ||
428 | static 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 */ | ||
449 | static 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 | ||
394 | static struct dvb_pll_desc *pll_list[] = { | 465 | static 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); | |||
46 | MODULE_PARM_DESC(fake_signal_str, "fake signal strength for LGS8913." | 46 | MODULE_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 | ||
49 | static 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 | ||
51 | static int lgs8gxx_write_reg(struct lgs8gxx_state *priv, u8 reg, u8 data) | 87 | static 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 | ||
151 | static 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 | |||
115 | static int lgs8gxx_set_ad_mode(struct lgs8gxx_state *priv) | 168 | static 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 | |||
228 | static 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 | ||
168 | static int lgs8gxx_set_mode_auto(struct lgs8gxx_state *priv) | 254 | static 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 */ | ||
366 | static 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 | ||
252 | static int lgs8gxx_autolock_gi(struct lgs8gxx_state *priv, u8 gi, u8 *locked) | 409 | static 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 */ | ||
592 | static 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 | ||
628 | static 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 | |||
420 | static int lgs8gxx_init(struct dvb_frontend *fe) | 656 | static 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, | |||
489 | static int lgs8gxx_get_fe(struct dvb_frontend *fe, | 727 | static 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 | ||
887 | static 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 | |||
661 | static int lgs8gxx_read_signal_strength(struct dvb_frontend *fe, u16 *signal) | 906 | static 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 | ||
943 | static 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 | |||
963 | static 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 | |||
693 | static int lgs8gxx_read_ber(struct dvb_frontend *fe, u32 *ber) | 976 | static 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 | ||
806 | error_out: | 1096 | error_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 | ||
38 | struct lgs8gxx_config { | 39 | struct 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, ®0[1], 8); | 440 | memcpy(&priv->regs, ®0[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 @@ | |||
41 | struct stv6110_config { | 41 | struct 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 | |||
31 | static int debug; | ||
32 | |||
33 | #define dprintk(args...) \ | ||
34 | do { \ | ||
35 | if (debug) \ | ||
36 | printk(KERN_DEBUG args); \ | ||
37 | } while (0) | ||
38 | |||
39 | enum zl10039_model_id { | ||
40 | ID_ZL10039 = 1 | ||
41 | }; | ||
42 | |||
43 | struct zl10039_state { | ||
44 | struct i2c_adapter *i2c; | ||
45 | u8 i2c_addr; | ||
46 | u8 id; | ||
47 | }; | ||
48 | |||
49 | enum 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 | |||
68 | static 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 | |||
97 | static 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 | |||
121 | static 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 | |||
127 | static 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 | |||
134 | static 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 | |||
160 | static 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 | |||
179 | static 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; | ||
233 | error: | ||
234 | dprintk("Error setting tuner\n"); | ||
235 | return ret; | ||
236 | } | ||
237 | |||
238 | static 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 | |||
248 | static 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 | |||
255 | struct 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; | ||
298 | error: | ||
299 | kfree(state); | ||
300 | return NULL; | ||
301 | } | ||
302 | EXPORT_SYMBOL(zl10039_attach); | ||
303 | |||
304 | module_param(debug, int, 0644); | ||
305 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | ||
306 | MODULE_DESCRIPTION("Zarlink ZL10039 DVB-S tuner driver"); | ||
307 | MODULE_AUTHOR("Jan D. Louw <jd.louw@mweb.co.za>"); | ||
308 | MODULE_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)) | ||
27 | struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe, | ||
28 | u8 i2c_addr, | ||
29 | struct i2c_adapter *i2c); | ||
30 | #else | ||
31 | static 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 | ||
43 | static int debug; | 45 | static 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 = ¶m->u.ofdm; | 202 | struct dvb_ofdm_parameters *op = ¶m->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) | |||
542 | static int zl10353_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | 546 | static 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 | ||
291 | config 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 | |||
301 | config RADIO_TYPHOON_PORT | 291 | config 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 | ||
332 | config 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 | |||
342 | config 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 | |||
342 | config USB_DSBR | 355 | config 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 | ||
354 | config USB_SI470X | 367 | config 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 | 371 | source "drivers/media/radio/si470x/Kconfig" |
376 | module will be called radio-si470x. | ||
377 | 372 | ||
378 | config USB_MR800 | 373 | config 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 | |||
15 | obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o | 15 | obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o |
16 | obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o | 16 | obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o |
17 | obj-$(CONFIG_RADIO_TRUST) += radio-trust.o | 17 | obj-$(CONFIG_RADIO_TRUST) += radio-trust.o |
18 | obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o | ||
19 | obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o | ||
18 | obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o | 20 | obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o |
19 | obj-$(CONFIG_USB_DSBR) += dsbr100.o | 21 | obj-$(CONFIG_USB_DSBR) += dsbr100.o |
20 | obj-$(CONFIG_USB_SI470X) += radio-si470x.o | 22 | obj-$(CONFIG_RADIO_SI470X) += si470x/ |
21 | obj-$(CONFIG_USB_MR800) += radio-mr800.o | 23 | obj-$(CONFIG_USB_MR800) += radio-mr800.o |
22 | obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o | 24 | obj-$(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 */ | ||
144 | static 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 | }; | ||
156 | MODULE_DEVICE_TABLE(usb, si470x_usb_driver_id_table); | ||
157 | |||
158 | |||
159 | |||
160 | /************************************************************************** | ||
161 | * Module Parameters | ||
162 | **************************************************************************/ | ||
163 | |||
164 | /* Radio Nr */ | ||
165 | static int radio_nr = -1; | ||
166 | module_param(radio_nr, int, 0444); | ||
167 | MODULE_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 */ | ||
173 | static unsigned short space = 2; | ||
174 | module_param(space, ushort, 0444); | ||
175 | MODULE_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) */ | ||
181 | static unsigned short band = 1; | ||
182 | module_param(band, ushort, 0444); | ||
183 | MODULE_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) */ | ||
188 | static unsigned short de = 1; | ||
189 | module_param(de, ushort, 0444); | ||
190 | MODULE_PARM_DESC(de, "De-emphasis: 0=75us *1=50us*"); | ||
191 | |||
192 | /* USB timeout */ | ||
193 | static unsigned int usb_timeout = 500; | ||
194 | module_param(usb_timeout, uint, 0644); | ||
195 | MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*"); | ||
196 | |||
197 | /* Tune timeout */ | ||
198 | static unsigned int tune_timeout = 3000; | ||
199 | module_param(tune_timeout, uint, 0644); | ||
200 | MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*"); | ||
201 | |||
202 | /* Seek timeout */ | ||
203 | static unsigned int seek_timeout = 5000; | ||
204 | module_param(seek_timeout, uint, 0644); | ||
205 | MODULE_PARM_DESC(seek_timeout, "Seek timeout: *5000*"); | ||
206 | |||
207 | /* RDS buffer blocks */ | ||
208 | static unsigned int rds_buf = 100; | ||
209 | module_param(rds_buf, uint, 0444); | ||
210 | MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*"); | ||
211 | |||
212 | /* RDS maximum block errors */ | ||
213 | static 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 */ | ||
218 | module_param(max_rds_errors, ushort, 0644); | ||
219 | MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*"); | ||
220 | |||
221 | /* RDS poll frequency */ | ||
222 | static 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 */ | ||
227 | module_param(rds_poll_time, uint, 0644); | ||
228 | MODULE_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 | */ | ||
447 | struct 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 | */ | ||
494 | static 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 | */ | ||
517 | static 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 | */ | ||
540 | static 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 | */ | ||
559 | static 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 | */ | ||
576 | static 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 | |||
604 | stop: | ||
605 | /* stop tuning */ | ||
606 | radio->registers[CHANNEL] &= ~CHANNEL_TUNE; | ||
607 | retval = si470x_set_register(radio, CHANNEL); | ||
608 | |||
609 | done: | ||
610 | return retval; | ||
611 | } | ||
612 | |||
613 | |||
614 | /* | ||
615 | * si470x_get_freq - get the frequency | ||
616 | */ | ||
617 | static 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 | */ | ||
663 | static 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 | */ | ||
704 | static 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 | |||
743 | stop: | ||
744 | /* stop seeking */ | ||
745 | radio->registers[POWERCFG] &= ~POWERCFG_SEEK; | ||
746 | retval = si470x_set_register(radio, POWERCFG); | ||
747 | |||
748 | done: | ||
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 | */ | ||
760 | static 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 | |||
791 | done: | ||
792 | return retval; | ||
793 | } | ||
794 | |||
795 | |||
796 | /* | ||
797 | * si470x_stop - switch off radio | ||
798 | */ | ||
799 | static 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 | |||
815 | done: | ||
816 | return retval; | ||
817 | } | ||
818 | |||
819 | |||
820 | /* | ||
821 | * si470x_rds_on - switch on rds reception | ||
822 | */ | ||
823 | static 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 | */ | ||
847 | static 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 | */ | ||
874 | static 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 | */ | ||
911 | static 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 | */ | ||
935 | static 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 | */ | ||
964 | static 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 | */ | ||
1045 | static 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 | */ | ||
1069 | static 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 | |||
1122 | done: | ||
1123 | return retval; | ||
1124 | } | ||
1125 | |||
1126 | |||
1127 | /* | ||
1128 | * si470x_fops_poll - poll RDS data | ||
1129 | */ | ||
1130 | static 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 | */ | ||
1155 | static 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 | |||
1177 | done: | ||
1178 | unlock_kernel(); | ||
1179 | return retval; | ||
1180 | } | ||
1181 | |||
1182 | |||
1183 | /* | ||
1184 | * si470x_fops_release - file release | ||
1185 | */ | ||
1186 | static 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 | } | ||
1217 | unlock: | ||
1218 | mutex_unlock(&radio->disconnect_lock); | ||
1219 | done: | ||
1220 | return retval; | ||
1221 | } | ||
1222 | |||
1223 | |||
1224 | /* | ||
1225 | * si470x_fops - file operations interface | ||
1226 | */ | ||
1227 | static 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 | */ | ||
1245 | static 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 | */ | ||
1270 | static 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 | */ | ||
1289 | static 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 | |||
1315 | done: | ||
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 | */ | ||
1326 | static 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 | |||
1351 | done: | ||
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 | */ | ||
1362 | static 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 | |||
1391 | done: | ||
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 | */ | ||
1402 | static 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 | */ | ||
1418 | static 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 | |||
1484 | done: | ||
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 | */ | ||
1495 | static 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 | |||
1523 | done: | ||
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 | */ | ||
1534 | static 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 | |||
1553 | done: | ||
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 | */ | ||
1564 | static 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 | |||
1582 | done: | ||
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 | */ | ||
1593 | static 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 | |||
1611 | done: | ||
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 | */ | ||
1623 | static 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 | */ | ||
1640 | static 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 | */ | ||
1656 | static 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; | ||
1750 | err_all: | ||
1751 | kfree(radio->buffer); | ||
1752 | err_video: | ||
1753 | video_device_release(radio->videodev); | ||
1754 | err_radio: | ||
1755 | kfree(radio); | ||
1756 | err_initial: | ||
1757 | return retval; | ||
1758 | } | ||
1759 | |||
1760 | |||
1761 | /* | ||
1762 | * si470x_usb_driver_suspend - suspend the device | ||
1763 | */ | ||
1764 | static 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 | */ | ||
1780 | static 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 | */ | ||
1799 | static 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 | */ | ||
1822 | static 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 | */ | ||
1841 | static 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 | */ | ||
1851 | static void __exit si470x_module_exit(void) | ||
1852 | { | ||
1853 | usb_deregister(&si470x_usb_driver); | ||
1854 | } | ||
1855 | |||
1856 | |||
1857 | module_init(si470x_module_init); | ||
1858 | module_exit(si470x_module_exit); | ||
1859 | |||
1860 | MODULE_LICENSE("GPL"); | ||
1861 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
1862 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
1863 | MODULE_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 */ | ||
37 | static int radio_nr = -1; /* radio device minor (-1 ==> auto assign) */ | ||
38 | module_param(radio_nr, int, 0); | ||
39 | MODULE_PARM_DESC(radio_nr, | ||
40 | "Minor number for radio device (-1 ==> auto assign)"); | ||
41 | |||
42 | MODULE_LICENSE("GPL"); | ||
43 | MODULE_AUTHOR("Eduardo Valentin <eduardo.valentin@nokia.com>"); | ||
44 | MODULE_DESCRIPTION("Platform driver for Si4713 FM Radio Transmitter"); | ||
45 | MODULE_VERSION("0.0.1"); | ||
46 | |||
47 | /* Driver state struct */ | ||
48 | struct radio_si4713_device { | ||
49 | struct v4l2_device v4l2_dev; | ||
50 | struct video_device *radio_dev; | ||
51 | }; | ||
52 | |||
53 | /* radio_si4713_fops - file operations interface */ | ||
54 | static const struct v4l2_file_operations radio_si4713_fops = { | ||
55 | .owner = THIS_MODULE, | ||
56 | .ioctl = video_ioctl2, | ||
57 | }; | ||
58 | |||
59 | /* Video4Linux Interface */ | ||
60 | static 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 | |||
68 | static int radio_si4713_enumaudout(struct file *file, void *priv, | ||
69 | struct v4l2_audioout *vao) | ||
70 | { | ||
71 | return radio_si4713_fill_audout(vao); | ||
72 | } | ||
73 | |||
74 | static 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 | |||
84 | static 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 */ | ||
91 | static 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 */ | ||
107 | static 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 | */ | ||
165 | static inline struct v4l2_device *get_v4l2_dev(struct file *file) | ||
166 | { | ||
167 | return &((struct radio_si4713_device *)video_drvdata(file))->v4l2_dev; | ||
168 | } | ||
169 | |||
170 | static 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 | |||
177 | static 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 | |||
184 | static 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 | |||
191 | static 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 | |||
198 | static 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 | |||
205 | static 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 | |||
212 | static 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 | |||
219 | static 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 | |||
226 | static 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 | |||
232 | static 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 */ | ||
250 | static 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 */ | ||
259 | static 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 | |||
321 | free_vdev: | ||
322 | video_device_release(rsdev->radio_dev); | ||
323 | unregister_v4l2_dev: | ||
324 | v4l2_device_unregister(&rsdev->v4l2_dev); | ||
325 | free_rsdev: | ||
326 | kfree(rsdev); | ||
327 | exit: | ||
328 | return rval; | ||
329 | } | ||
330 | |||
331 | /* radio_si4713_pdriver_remove - remove the device */ | ||
332 | static 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 | |||
346 | static 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 */ | ||
355 | static int __init radio_si4713_module_init(void) | ||
356 | { | ||
357 | return platform_driver_register(&radio_si4713_pdriver); | ||
358 | } | ||
359 | |||
360 | static void __exit radio_si4713_module_exit(void) | ||
361 | { | ||
362 | platform_driver_unregister(&radio_si4713_pdriver); | ||
363 | } | ||
364 | |||
365 | module_init(radio_si4713_module_init); | ||
366 | module_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 @@ | |||
1 | config 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 | |||
26 | config 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 | |||
5 | radio-usb-si470x-objs := radio-si470x-usb.o radio-si470x-common.o | ||
6 | radio-i2c-si470x-objs := radio-si470x-i2c.o radio-si470x-common.o | ||
7 | |||
8 | obj-$(CONFIG_USB_SI470X) += radio-usb-si470x.o | ||
9 | obj-$(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 */ | ||
126 | static unsigned short space = 2; | ||
127 | module_param(space, ushort, 0444); | ||
128 | MODULE_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) */ | ||
134 | static unsigned short band = 1; | ||
135 | module_param(band, ushort, 0444); | ||
136 | MODULE_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) */ | ||
141 | static unsigned short de = 1; | ||
142 | module_param(de, ushort, 0444); | ||
143 | MODULE_PARM_DESC(de, "De-emphasis: 0=75us *1=50us*"); | ||
144 | |||
145 | /* Tune timeout */ | ||
146 | static unsigned int tune_timeout = 3000; | ||
147 | module_param(tune_timeout, uint, 0644); | ||
148 | MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*"); | ||
149 | |||
150 | /* Seek timeout */ | ||
151 | static unsigned int seek_timeout = 5000; | ||
152 | module_param(seek_timeout, uint, 0644); | ||
153 | MODULE_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 | */ | ||
164 | static 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 | |||
192 | stop: | ||
193 | /* stop tuning */ | ||
194 | radio->registers[CHANNEL] &= ~CHANNEL_TUNE; | ||
195 | retval = si470x_set_register(radio, CHANNEL); | ||
196 | |||
197 | done: | ||
198 | return retval; | ||
199 | } | ||
200 | |||
201 | |||
202 | /* | ||
203 | * si470x_get_freq - get the frequency | ||
204 | */ | ||
205 | static 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 | */ | ||
251 | int 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 | */ | ||
292 | static 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 | |||
331 | stop: | ||
332 | /* stop seeking */ | ||
333 | radio->registers[POWERCFG] &= ~POWERCFG_SEEK; | ||
334 | retval = si470x_set_register(radio, POWERCFG); | ||
335 | |||
336 | done: | ||
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 | */ | ||
348 | int 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 | |||
379 | done: | ||
380 | return retval; | ||
381 | } | ||
382 | |||
383 | |||
384 | /* | ||
385 | * si470x_stop - switch off radio | ||
386 | */ | ||
387 | int 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 | |||
403 | done: | ||
404 | return retval; | ||
405 | } | ||
406 | |||
407 | |||
408 | /* | ||
409 | * si470x_rds_on - switch on rds reception | ||
410 | */ | ||
411 | int 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 | */ | ||
435 | static 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 | |||
460 | done: | ||
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 | */ | ||
471 | static 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 | |||
495 | done: | ||
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 | */ | ||
506 | static 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 | |||
534 | done: | ||
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 | */ | ||
545 | static 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 | */ | ||
561 | static 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 | |||
638 | done: | ||
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 | */ | ||
649 | static 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 | |||
677 | done: | ||
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 | */ | ||
688 | static 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 | |||
707 | done: | ||
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 | */ | ||
718 | static 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 | |||
736 | done: | ||
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 | */ | ||
747 | static 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 | |||
765 | done: | ||
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 | */ | ||
776 | static 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 | */ | ||
793 | struct 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 */ | ||
46 | static const struct i2c_device_id si470x_i2c_id[] = { | ||
47 | /* Generic Entry */ | ||
48 | { "si470x", 0 }, | ||
49 | /* Terminating entry */ | ||
50 | { } | ||
51 | }; | ||
52 | MODULE_DEVICE_TABLE(i2c, si470x_i2c_id); | ||
53 | |||
54 | |||
55 | |||
56 | /************************************************************************** | ||
57 | * Module Parameters | ||
58 | **************************************************************************/ | ||
59 | |||
60 | /* Radio Nr */ | ||
61 | static int radio_nr = -1; | ||
62 | module_param(radio_nr, int, 0444); | ||
63 | MODULE_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 | */ | ||
88 | int 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 | */ | ||
108 | int 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 | */ | ||
135 | static 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 | */ | ||
162 | int 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 | */ | ||
176 | static 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 | */ | ||
197 | static 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 | */ | ||
221 | const 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 | */ | ||
237 | int 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 | */ | ||
258 | static 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; | ||
332 | err_all: | ||
333 | err_video: | ||
334 | video_device_release(radio->videodev); | ||
335 | err_radio: | ||
336 | kfree(radio); | ||
337 | err_initial: | ||
338 | return retval; | ||
339 | } | ||
340 | |||
341 | |||
342 | /* | ||
343 | * si470x_i2c_remove - remove the device | ||
344 | */ | ||
345 | static __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 | */ | ||
360 | static 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 | */ | ||
379 | static 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 | */ | ||
389 | static void __exit si470x_i2c_exit(void) | ||
390 | { | ||
391 | i2c_del_driver(&si470x_i2c_driver); | ||
392 | } | ||
393 | |||
394 | |||
395 | module_init(si470x_i2c_init); | ||
396 | module_exit(si470x_i2c_exit); | ||
397 | |||
398 | MODULE_LICENSE("GPL"); | ||
399 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
400 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
401 | MODULE_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 */ | ||
45 | static 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 | }; | ||
57 | MODULE_DEVICE_TABLE(usb, si470x_usb_driver_id_table); | ||
58 | |||
59 | |||
60 | |||
61 | /************************************************************************** | ||
62 | * Module Parameters | ||
63 | **************************************************************************/ | ||
64 | |||
65 | /* Radio Nr */ | ||
66 | static int radio_nr = -1; | ||
67 | module_param(radio_nr, int, 0444); | ||
68 | MODULE_PARM_DESC(radio_nr, "Radio Nr"); | ||
69 | |||
70 | /* USB timeout */ | ||
71 | static unsigned int usb_timeout = 500; | ||
72 | module_param(usb_timeout, uint, 0644); | ||
73 | MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*"); | ||
74 | |||
75 | /* RDS buffer blocks */ | ||
76 | static unsigned int rds_buf = 100; | ||
77 | module_param(rds_buf, uint, 0444); | ||
78 | MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*"); | ||
79 | |||
80 | /* RDS maximum block errors */ | ||
81 | static 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 */ | ||
86 | module_param(max_rds_errors, ushort, 0644); | ||
87 | MODULE_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 | */ | ||
209 | static 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 | */ | ||
232 | static 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 | */ | ||
255 | int 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 | */ | ||
274 | int 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 | */ | ||
296 | static 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 | */ | ||
323 | static 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 | */ | ||
347 | static 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 | */ | ||
376 | int 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 | */ | ||
395 | static 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 | |||
493 | resubmit: | ||
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 | */ | ||
514 | static 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 | |||
564 | done: | ||
565 | return retval; | ||
566 | } | ||
567 | |||
568 | |||
569 | /* | ||
570 | * si470x_fops_poll - poll RDS data | ||
571 | */ | ||
572 | static 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 | */ | ||
594 | static 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 | |||
639 | done: | ||
640 | unlock_kernel(); | ||
641 | return retval; | ||
642 | } | ||
643 | |||
644 | |||
645 | /* | ||
646 | * si470x_fops_release - file release | ||
647 | */ | ||
648 | static 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 | } | ||
684 | unlock: | ||
685 | mutex_unlock(&radio->disconnect_lock); | ||
686 | done: | ||
687 | return retval; | ||
688 | } | ||
689 | |||
690 | |||
691 | /* | ||
692 | * si470x_fops - file operations interface | ||
693 | */ | ||
694 | const 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 | */ | ||
712 | int 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 | */ | ||
737 | static 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; | ||
882 | err_all: | ||
883 | kfree(radio->buffer); | ||
884 | err_video: | ||
885 | video_device_release(radio->videodev); | ||
886 | err_intbuffer: | ||
887 | kfree(radio->int_in_buffer); | ||
888 | err_radio: | ||
889 | kfree(radio); | ||
890 | err_initial: | ||
891 | return retval; | ||
892 | } | ||
893 | |||
894 | |||
895 | /* | ||
896 | * si470x_usb_driver_suspend - suspend the device | ||
897 | */ | ||
898 | static 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 | */ | ||
910 | static 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 | */ | ||
921 | static 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 | */ | ||
947 | static 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 | */ | ||
966 | static 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 | */ | ||
976 | static void __exit si470x_module_exit(void) | ||
977 | { | ||
978 | usb_deregister(&si470x_usb_driver); | ||
979 | } | ||
980 | |||
981 | |||
982 | module_init(si470x_module_init); | ||
983 | module_exit(si470x_module_exit); | ||
984 | |||
985 | MODULE_LICENSE("GPL"); | ||
986 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
987 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
988 | MODULE_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 | */ | ||
145 | struct 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 | **************************************************************************/ | ||
215 | extern const struct v4l2_file_operations si470x_fops; | ||
216 | extern struct video_device si470x_viddev_template; | ||
217 | int si470x_get_register(struct si470x_device *radio, int regnr); | ||
218 | int si470x_set_register(struct si470x_device *radio, int regnr); | ||
219 | int si470x_disconnect_check(struct si470x_device *radio); | ||
220 | int si470x_set_freq(struct si470x_device *radio, unsigned int freq); | ||
221 | int si470x_start(struct si470x_device *radio); | ||
222 | int si470x_stop(struct si470x_device *radio); | ||
223 | int si470x_rds_on(struct si470x_device *radio); | ||
224 | int 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 */ | ||
36 | static int debug; | ||
37 | module_param(debug, int, S_IRUGO | S_IWUSR); | ||
38 | MODULE_PARM_DESC(debug, "Debug level (0 - 2)"); | ||
39 | |||
40 | MODULE_LICENSE("GPL"); | ||
41 | MODULE_AUTHOR("Eduardo Valentin <eduardo.valentin@nokia.com>"); | ||
42 | MODULE_DESCRIPTION("I2C driver for Si4713 FM Radio Transmitter"); | ||
43 | MODULE_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 | */ | ||
122 | static 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 | */ | ||
150 | static 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 | */ | ||
163 | static 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 | |||
169 | static 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 | |||
184 | static 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 */ | ||
200 | static 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 | */ | ||
221 | static 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 | */ | ||
273 | static 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 | */ | ||
310 | static 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 | */ | ||
355 | static 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 | */ | ||
396 | static 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 | */ | ||
424 | static 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 | |||
448 | unlock: | ||
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 | */ | ||
459 | static 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 | |||
486 | exit: | ||
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 | */ | ||
497 | static 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 | */ | ||
541 | static 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 | */ | ||
589 | static 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 | */ | ||
640 | static 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 | */ | ||
683 | static 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 | */ | ||
722 | static 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 | |||
748 | static 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 | |||
763 | static 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 | |||
783 | static 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 | |||
824 | unlock: | ||
825 | mutex_unlock(&sdev->mutex); | ||
826 | return rval; | ||
827 | } | ||
828 | |||
829 | static 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 | |||
878 | copy: | ||
879 | strncpy(sdev->rds_info.radio_text, rt, MAX_RDS_RADIO_TEXT); | ||
880 | |||
881 | unlock: | ||
882 | mutex_unlock(&sdev->mutex); | ||
883 | return rval; | ||
884 | } | ||
885 | |||
886 | static 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 | |||
986 | static int si4713_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc); | ||
987 | |||
988 | /* write string property */ | ||
989 | static 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 | |||
1051 | exit: | ||
1052 | return rval; | ||
1053 | } | ||
1054 | |||
1055 | static 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 | |||
1069 | exit: | ||
1070 | return rval; | ||
1071 | } | ||
1072 | |||
1073 | /* properties which use tx_tune_power*/ | ||
1074 | static 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 | |||
1108 | unlock: | ||
1109 | mutex_unlock(&sdev->mutex); | ||
1110 | exit: | ||
1111 | return rval; | ||
1112 | } | ||
1113 | |||
1114 | static 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 | |||
1174 | unlock: | ||
1175 | mutex_unlock(&sdev->mutex); | ||
1176 | exit: | ||
1177 | return rval; | ||
1178 | } | ||
1179 | |||
1180 | static int si4713_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f); | ||
1181 | static 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 | */ | ||
1186 | static 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 | */ | ||
1300 | static 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 | |||
1350 | exit: | ||
1351 | return rval; | ||
1352 | } | ||
1353 | |||
1354 | /* read string property */ | ||
1355 | static 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 | |||
1386 | exit: | ||
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 | */ | ||
1395 | static 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 | |||
1410 | exit: | ||
1411 | return rval; | ||
1412 | } | ||
1413 | |||
1414 | /* properties which use tx_tune_status */ | ||
1415 | static 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 | |||
1439 | unlock: | ||
1440 | mutex_unlock(&sdev->mutex); | ||
1441 | return rval; | ||
1442 | } | ||
1443 | |||
1444 | static 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 | |||
1480 | unlock: | ||
1481 | mutex_unlock(&sdev->mutex); | ||
1482 | exit: | ||
1483 | return rval; | ||
1484 | } | ||
1485 | |||
1486 | /* | ||
1487 | * Video4Linux Subdev Interface | ||
1488 | */ | ||
1489 | /* si4713_s_ext_ctrls - set extended controls value */ | ||
1490 | static 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 */ | ||
1528 | static 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 */ | ||
1566 | static 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 */ | ||
1668 | static 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 | |||
1692 | unlock: | ||
1693 | mutex_unlock(&sdev->mutex); | ||
1694 | return rval; | ||
1695 | } | ||
1696 | |||
1697 | /* si4713_s_ctrl - set the value of a control */ | ||
1698 | static 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 | |||
1728 | exit: | ||
1729 | return rval; | ||
1730 | } | ||
1731 | |||
1732 | /* si4713_ioctl - deal with private ioctls (only rnl for now) */ | ||
1733 | long 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 | |||
1766 | unlock: | ||
1767 | mutex_unlock(&sdev->mutex); | ||
1768 | return rval; | ||
1769 | } | ||
1770 | |||
1771 | static 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 */ | ||
1781 | static 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 | |||
1830 | unlock: | ||
1831 | mutex_unlock(&sdev->mutex); | ||
1832 | exit: | ||
1833 | return rval; | ||
1834 | } | ||
1835 | |||
1836 | /* si4713_s_modulator - set modulator attributes */ | ||
1837 | static 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 | |||
1880 | unlock: | ||
1881 | mutex_unlock(&sdev->mutex); | ||
1882 | return rval; | ||
1883 | } | ||
1884 | |||
1885 | /* si4713_g_frequency - get tuner or modulator radio frequency */ | ||
1886 | static 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 | |||
1908 | unlock: | ||
1909 | mutex_unlock(&sdev->mutex); | ||
1910 | return rval; | ||
1911 | } | ||
1912 | |||
1913 | /* si4713_s_frequency - set tuner or modulator radio frequency */ | ||
1914 | static 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 | |||
1936 | unlock: | ||
1937 | mutex_unlock(&sdev->mutex); | ||
1938 | return rval; | ||
1939 | } | ||
1940 | |||
1941 | static 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 | |||
1948 | static 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 */ | ||
1957 | static 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 | |||
2003 | free_irq: | ||
2004 | if (client->irq) | ||
2005 | free_irq(client->irq, sdev); | ||
2006 | free_sdev: | ||
2007 | kfree(sdev); | ||
2008 | exit: | ||
2009 | return rval; | ||
2010 | } | ||
2011 | |||
2012 | /* si4713_remove - remove the device */ | ||
2013 | static 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 */ | ||
2032 | static const struct i2c_device_id si4713_id[] = { | ||
2033 | { "si4713" , 0 }, | ||
2034 | { }, | ||
2035 | }; | ||
2036 | MODULE_DEVICE_TABLE(i2c, si4713_id); | ||
2037 | |||
2038 | static 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 */ | ||
2048 | static int __init si4713_module_init(void) | ||
2049 | { | ||
2050 | return i2c_add_driver(&si4713_i2c_driver); | ||
2051 | } | ||
2052 | |||
2053 | static void __exit si4713_module_exit(void) | ||
2054 | { | ||
2055 | i2c_del_driver(&si4713_i2c_driver); | ||
2056 | } | ||
2057 | |||
2058 | module_init(si4713_module_init); | ||
2059 | module_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 | |||
163 | struct 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 | |||
185 | struct 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 | |||
193 | struct 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 | |||
201 | struct 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 | */ | ||
217 | struct 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 | ||
205 | config VIDEO_M52790 | 205 | config 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 = { | |||
320 | static struct i2c_adapter au0828_i2c_adap_template = { | 320 | static 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 | ||
4595 | static struct pci_device_id bttv_pci_tbl[] = { | 4597 | static 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) | |||
245 | int bttv_input_init(struct bttv *btv) | 245 | int 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 | ||
271 | static 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 */ |
272 | void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv) | 286 | void 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 | ||
286 | static void cx18_process_eeprom(struct cx18 *cx) | 318 | static 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 */ |
45 | static const u8 hw_addrs[] = { | 48 | static 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 | ||
100 | static 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 | |||
107 | static 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 | |||
89 | int cx18_i2c_register(struct cx18 *cx, unsigned idx) | 128 | int 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 */ |
191 | static struct i2c_adapter cx18_i2c_adap_template = { | 233 | static 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 | ||
62 | enum AV_MODE{ | 62 | enum 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 = { | |||
432 | static struct i2c_adapter cx231xx_adap_template = { | 432 | static 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 | ||
633 | void 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 | |||
643 | void 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 | |||
653 | void 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 | }; |
205 | const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); | 214 | const 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 | }; |
329 | const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); | 346 | const 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 | ||
397 | static struct stv0900_config netup_stv0900_config = { | 397 | static 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 | ||
409 | static struct stv6110_config netup_stv6110_tunerconfig_a = { | 409 | static 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 | ||
415 | static struct stv6110_config netup_stv6110_tunerconfig_b = { | 415 | static 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 | ||
421 | static int tbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | 421 | static 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 | ||
490 | static 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 | |||
505 | static struct xc5000_config magicpro_prohdtve2_xc5000_config = { | ||
506 | .i2c_address = 0x61, | ||
507 | .if_khz = 6500, | ||
508 | }; | ||
509 | |||
490 | static int dvb_register(struct cx23885_tsport *port) | 510 | static 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 = { | |||
283 | static struct i2c_adapter cx23885_i2c_adap_template = { | 283 | static 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); | |||
504 | extern void cx23885_mc417_init(struct cx23885_dev *dev); | 513 | extern void cx23885_mc417_init(struct cx23885_dev *dev); |
505 | extern int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value); | 514 | extern int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value); |
506 | extern int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value); | 515 | extern int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value); |
516 | extern void mc417_gpio_set(struct cx23885_dev *dev, u32 mask); | ||
517 | extern void mc417_gpio_clear(struct cx23885_dev *dev, u32 mask); | ||
518 | extern 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 | ||
43 | static char *firmware = FWFILE; | 39 | static char *firmware = ""; |
44 | 40 | ||
45 | module_param(firmware, charp, 0444); | 41 | module_param(firmware, charp, 0444); |
46 | 42 | ||
47 | MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]"); | 43 | MODULE_PARM_DESC(firmware, "Firmware image to load"); |
48 | 44 | ||
49 | static void start_fw_load(struct i2c_client *client) | 45 | static 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 | ||
64 | static 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 | |||
68 | static int check_fw_load(struct i2c_client *client, int size) | 77 | static 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 | ||
501 | static struct zl10353_config cx88_geniatech_x8000_mt = { | 500 | static 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 | ||
507 | static struct s5h1411_config dvico_fusionhdtv7_config = { | 506 | static 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 | ||
147 | static void cx88_ir_work(struct work_struct *work) | 147 | static 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 | ||
155 | void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir) | 161 | void 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 | ||
241 | enum cx88_itype { | 242 | enum 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 | }; |
1654 | MODULE_DEVICE_TABLE(usb, em28xx_id_table); | 1686 | MODULE_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 | /* ----------------------------------------------------------------------- */ |
2171 | void em28xx_register_i2c_ir(struct em28xx *dev) | 2204 | void 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 | ||
2223 | void em28xx_card_setup(struct em28xx *dev) | 2242 | void 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 = { | |||
459 | static struct i2c_adapter em28xx_adap_template = { | 459 | static 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 */ |
127 | static struct v4l2_queryctrl em28xx_qctrl[] = { | 127 | static 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 | */ |
615 | static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) | 615 | static 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 | */ | ||
634 | static 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 | */ |
633 | static int em28xx_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl) | 653 | static 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 | |||
664 | handle: | ||
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 | ||
650 | static int check_dev(struct em28xx *dev) | 681 | static 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(®->match)) | 1321 | if (!v4l2_chip_match_host(®->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(®->match)) | 1374 | if (!v4l2_chip_match_host(®->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 | ||
414 | struct em28xx_eeprom { | 416 | struct 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 | ||
600 | struct em28xx_ops { | 606 | struct 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 | ||
50 | config 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 | |||
50 | config USB_GSPCA_MARS | 59 | config 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 | ||
105 | config USB_GSPCA_SN9C20X | 114 | config 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 | ||
115 | config USB_GSPCA_SN9C20X_EVDEV | 124 | config 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 | ||
121 | config USB_GSPCA_SONIXB | 130 | config 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 | |||
2 | obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o | 2 | obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o |
3 | obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o | 3 | obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o |
4 | obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o | 4 | obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o |
5 | obj-$(CONFIG_USB_GSPCA_JEILINJ) += gspca_jeilinj.o | ||
5 | obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o | 6 | obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o |
6 | obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o | 7 | obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o |
7 | obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o | 8 | obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o |
@@ -30,6 +31,7 @@ gspca_main-objs := gspca.o | |||
30 | gspca_conex-objs := conex.o | 31 | gspca_conex-objs := conex.o |
31 | gspca_etoms-objs := etoms.o | 32 | gspca_etoms-objs := etoms.o |
32 | gspca_finepix-objs := finepix.o | 33 | gspca_finepix-objs := finepix.o |
34 | gspca_jeilinj-objs := jeilinj.o | ||
33 | gspca_mars-objs := mars.o | 35 | gspca_mars-objs := mars.o |
34 | gspca_mr97310a-objs := mr97310a.o | 36 | gspca_mr97310a-objs := mr97310a.o |
35 | gspca_ov519-objs := ov519.o | 37 | gspca_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>"); | |||
47 | MODULE_DESCRIPTION("GSPCA USB Camera Driver"); | 47 | MODULE_DESCRIPTION("GSPCA USB Camera Driver"); |
48 | MODULE_LICENSE("GPL"); | 48 | MODULE_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 |
53 | int gspca_debug = D_ERR | D_PROBE; | 53 | int 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 | } |
647 | out: | 666 | out: |
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 | ||
1476 | static 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 |
1483 | static int vidiocgmbuf(struct file *file, void *priv, | 1496 | static 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 | ||
183 | int gspca_dev_probe(struct usb_interface *intf, | 186 | int 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 | |||
30 | MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>"); | ||
31 | MODULE_DESCRIPTION("GSPCA/JEILINJ USB Camera Driver"); | ||
32 | MODULE_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 */ | ||
44 | struct 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. */ | ||
61 | static 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 */ | ||
75 | static 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 */ | ||
90 | static 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 | |||
104 | static 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 | |||
151 | static 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 | |||
180 | static 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 | } | ||
257 | quit_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 */ | ||
266 | static 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 */ | ||
288 | static 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 */ | ||
302 | static int sd_init(struct gspca_dev *gspca_dev) | ||
303 | { | ||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | /* Set up for getting frames. */ | ||
308 | static 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 */ | ||
332 | static const __devinitdata struct usb_device_id device_table[] = { | ||
333 | {USB_DEVICE(0x0979, 0x0280)}, | ||
334 | {} | ||
335 | }; | ||
336 | |||
337 | MODULE_DEVICE_TABLE(usb, device_table); | ||
338 | |||
339 | /* sub-driver description */ | ||
340 | static 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 -- */ | ||
349 | static 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 | |||
358 | static 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 -- */ | ||
370 | static 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 | |||
381 | static void __exit sd_mod_exit(void) | ||
382 | { | ||
383 | usb_deregister(&sd_driver); | ||
384 | PDEBUG(D_PROBE, "deregistered"); | ||
385 | } | ||
386 | |||
387 | module_init(sd_mod_init); | ||
388 | module_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 | ||
25 | MODULE_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 | |||
55 | MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>," | ||
56 | "Theodore Kilgore <kilgota@auburn.edu>"); | ||
26 | MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver"); | 57 | MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver"); |
27 | MODULE_LICENSE("GPL"); | 58 | MODULE_LICENSE("GPL"); |
28 | 59 | ||
60 | /* global parameters */ | ||
61 | int force_sensor_type = -1; | ||
62 | module_param(force_sensor_type, int, 0644); | ||
63 | MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)"); | ||
64 | |||
29 | /* specific webcam descriptor */ | 65 | /* specific webcam descriptor */ |
30 | struct sd { | 66 | struct 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 | |||
78 | struct sensor_w_data { | ||
79 | u8 reg; | ||
80 | u8 flags; | ||
81 | u8 data[16]; | ||
82 | int len; | ||
33 | }; | 83 | }; |
34 | 84 | ||
85 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
86 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
87 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); | ||
88 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
89 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); | ||
90 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); | ||
91 | static void setbrightness(struct gspca_dev *gspca_dev); | ||
92 | static void setexposure(struct gspca_dev *gspca_dev); | ||
93 | static void setgain(struct gspca_dev *gspca_dev); | ||
94 | |||
35 | /* V4L2 controls supported by the driver */ | 95 | /* V4L2 controls supported by the driver */ |
36 | static struct ctrl sd_ctrls[] = { | 96 | static 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 | ||
39 | static const struct v4l2_pix_format vga_mode[] = { | 144 | static 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 */ |
68 | static int reg_w(struct gspca_dev *gspca_dev, int len) | 173 | static 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 */ | ||
187 | static 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 | |||
200 | static 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 | |||
211 | static 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 | |||
226 | static 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 | |||
246 | static 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 | |||
260 | static 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 | |||
345 | static 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 */ |
82 | static int sd_config(struct gspca_dev *gspca_dev, | 364 | static 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 | ||
99 | static int sd_start(struct gspca_dev *gspca_dev) | 438 | static 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; | 554 | static 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 | |||
718 | static 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 | ||
267 | static void sd_stopN(struct gspca_dev *gspca_dev) | 740 | static 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 | |||
762 | static 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 | |||
781 | static 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 | |||
828 | static 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 | |||
842 | static 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 | |||
852 | static 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 | |||
860 | static 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 | |||
870 | static 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 | |||
878 | static 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 | |||
888 | static 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 -- */ |
322 | static const __devinitdata struct usb_device_id device_table[] = { | 940 | static 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 | }; |
327 | MODULE_DEVICE_TABLE(usb, device_table); | 946 | MODULE_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 | ||
168 | static const __u8 pac207_sensor_init[][8] = { | 160 | static 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 */ | ||
177 | static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 }; | ||
178 | |||
179 | static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index, | 167 | static 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 -- */ |
1059 | static __devinitdata struct usb_device_id device_table[] = { | 1059 | static __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 | ||
97 | struct i2c_reg_u8 { | ||
98 | u8 reg; | ||
99 | u8 val; | ||
100 | }; | ||
101 | |||
102 | struct i2c_reg_u16 { | ||
103 | u8 reg; | ||
104 | u16 val; | ||
105 | }; | ||
106 | |||
97 | static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val); | 107 | static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val); |
98 | static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val); | 108 | static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val); |
99 | static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val); | 109 | static 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 | ||
406 | static const int hsv_red_x[] = { | 416 | static 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 | ||
454 | static const int hsv_red_y[] = { | 464 | static 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 | ||
502 | static const int hsv_green_x[] = { | 512 | static 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 | ||
550 | static const int hsv_green_y[] = { | 560 | static 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 | ||
598 | static const int hsv_blue_x[] = { | 608 | static 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 | ||
646 | static const int hsv_blue_y[] = { | 656 | static 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 | ||
795 | static u8 soi968_init[][2] = { | 805 | static 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 | ||
809 | static u8 ov7660_init[][2] = { | 819 | static 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 | ||
818 | static u8 ov7670_init[][2] = { | 828 | static 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 | ||
875 | static u8 ov9650_init[][2] = { | 885 | static 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 | ||
905 | static u8 ov9655_init[][2] = { | 915 | static 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 | ||
942 | static u16 mt9v112_init[][2] = { | 952 | static 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 | ||
961 | static u16 mt9v111_init[][2] = { | 971 | static 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 | ||
988 | static u16 mt9v011_init[][2] = { | 998 | static 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 | ||
1015 | static u16 mt9m001_init[][2] = { | 1025 | static 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 | ||
1028 | static u16 mt9m111_init[][2] = { | 1038 | static 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 | ||
1035 | static u8 hv7131r_init[][2] = { | 1045 | static 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 | ||
1046 | int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length) | 1056 | static 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 | ||
1065 | int reg_w(struct gspca_dev *gspca_dev, u16 reg, const u8 *buffer, int length) | 1075 | static 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 | ||
1085 | int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value) | 1096 | static 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 | ||
1091 | int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer) | 1102 | static 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 | ||
1107 | int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) | 1118 | static 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 | ||
1129 | int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val) | 1140 | static 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 | ||
2214 | static void do_autoexposure(struct gspca_dev *gspca_dev) | 2261 | static 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 | ||
2311 | static 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 | |||
2329 | static 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 | |||
2269 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 2344 | static 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 | ||
1625 | static void setinfrared(struct sd *sd) | 1620 | static 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 | }; |
2365 | MODULE_DEVICE_TABLE(usb, device_table); | 2363 | MODULE_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 */ | ||
1308 | static 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 | |||
1347 | out: | ||
1348 | return ret; | ||
1349 | } | ||
1350 | |||
1307 | static int write_vector(struct gspca_dev *gspca_dev, | 1351 | static 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 | ||
137 | int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len) | 137 | int 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"); | |||
32 | struct sd { | 32 | struct 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); | |||
67 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | 68 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); |
68 | 69 | ||
69 | static struct ctrl sd_ctrls[] = { | 70 | static 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 | |||
190 | struct 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 */ |
190 | static const __u16 spca504_pccam600_init_data[][3] = { | 197 | static 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 | */ |
220 | static const __u16 spca504_pccam600_open_data[][3] = { | 226 | static 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 */ |
229 | static const __u16 spca504A_clicksmart420_init_data[][3] = { | 234 | static 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 ? */ |
260 | static const __u16 spca504A_clicksmart420_open_data[][3] = { | 264 | static 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 | ||
407 | static const __u8 qtable_creative_pccam[2][64] = { | 410 | static 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 | */ |
432 | static const __u8 qtable_spca504_default[2][64] = { | 435 | static 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 */ |
455 | static void reg_r(struct gspca_dev *gspca_dev, | 458 | static 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 */ |
477 | static void reg_w(struct gspca_dev *gspca_dev, | 480 | static 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 */ |
499 | static int reg_w_riv(struct usb_device *dev, | 497 | static 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 */ |
517 | static int reg_r_1(struct gspca_dev *gspca_dev, | 515 | static 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 */ |
538 | static int reg_r_12(struct gspca_dev *gspca_dev, | 536 | static 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 | ||
561 | static int write_vector(struct gspca_dev *gspca_dev, | 559 | static 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 | ||
580 | static int spca50x_setup_qtable(struct gspca_dev *gspca_dev, | 578 | static 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 | ||
605 | static void spca504_acknowledged_command(struct gspca_dev *gspca_dev, | 600 | static 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 | ||
622 | static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev, | 617 | static 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 | ||
680 | static void spca50x_GetFirmware(struct gspca_dev *gspca_dev) | 674 | static 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 | ||
768 | static void spca504B_setQtable(struct gspca_dev *gspca_dev) | 755 | static 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 | ||
776 | static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev) | 762 | static 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 | |||
772 | static 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 | |||
782 | static 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 | |||
792 | static 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 | ||
1098 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 1118 | static 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 | ||
1193 | static 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 | |||
1212 | static 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 | |||
1231 | static 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 | |||
1250 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 1213 | static 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 */ |
266 | struct additional_sensor_data { | 266 | struct 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 | ||
279 | static 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 | }; | ||
290 | static 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 | }; | ||
300 | static 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 | |||
275 | static const struct additional_sensor_data sensor_data[] = { | 310 | static 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 | ||
392 | static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07}; | 455 | static 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 */ |
829 | static void poll_sensor(struct gspca_dev *gspca_dev) | 835 | static 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 | ||
856 | static int sd_start(struct gspca_dev *gspca_dev) | 859 | static 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 | ||
432 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | 432 | static 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"); | |||
32 | struct sd { | 32 | struct 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); | |||
65 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | 69 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); |
66 | 70 | ||
67 | static struct ctrl sd_ctrls[] = { | 71 | static 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 | ||
191 | static const __u8 mi0360_matrix[9] = { | 195 | static 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 | ||
195 | static const __u8 mi0360_initVGA_JPG[][4] = { | 199 | static 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 | }; |
304 | static const __u8 mi0360_initQVGA_JPG[][4] = { | 308 | static 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 | ||
424 | static const __u8 mi1310_socinitVGA_JPG[][4] = { | 428 | static 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 | }; | ||
532 | static 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 | }; | ||
580 | static 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 | }; |
650 | static const u8 mi1310_soc_InitSXGA_JPG[][4] = { | 654 | static 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 | ||
758 | static const __u8 mi1320_gamma[17] = { | 848 | static 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 | }; |
762 | static const __u8 mi1320_matrix[9] = { | 852 | static 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 | }; |
765 | static const __u8 mi1320_initVGA_data[][4] = { | 855 | static 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 | }; |
844 | static const __u8 mi1320_initQVGA_data[][4] = { | 934 | static 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 | }; |
1252 | static const __u8 po3130_gamma[17] = { | 1342 | static 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 | }; |
1256 | static const __u8 po3130_matrix[9] = { | 1346 | static 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 | ||
1260 | static const __u8 po3130_initVGA_data[][4] = { | 1350 | static 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 | }; |
1343 | static const __u8 po3130_rundata[][4] = { | 1433 | static 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 | ||
1358 | static const __u8 po3130_initQVGA_data[][4] = { | 1448 | static 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 | ||
1444 | static const __u8 hv7131r_gamma[17] = { | 1534 | static 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 | }; |
1450 | static const __u8 hv7131r_matrix[9] = { | 1538 | static 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 | }; |
1453 | static const __u8 hv7131r_initVGA_data[][4] = { | 1541 | static 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 | ||
1496 | static const __u8 hv7131r_initQVGA_data[][4] = { | 1629 | static 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 | ||
1551 | static const __u8 ov7660_gamma[17] = { | 1727 | static 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 | }; |
1555 | static const __u8 ov7660_matrix[9] = { | 1731 | static 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 | }; |
1558 | static const __u8 ov7660_initVGA_data[][4] = { | 1734 | static 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 | }; |
1616 | static const __u8 ov7660_initQVGA_data[][4] = { | 1792 | static 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 | ||
1685 | static const __u8 ov7660_50HZ[][4] = { | 1861 | static 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 | ||
1692 | static const __u8 ov7660_60HZ[][4] = { | 1868 | static 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 | ||
1699 | static const __u8 ov7660_NoFliker[][4] = { | 1875 | static const u8 ov7660_NoFliker[][4] = { |
1700 | {0x00, 0x13, 0x87, 0xaa}, | 1876 | {0x00, 0x13, 0x87, 0xaa}, |
1701 | {} | 1877 | {} |
1702 | }; | 1878 | }; |
1703 | 1879 | ||
1704 | static const __u8 ov7670_initVGA_JPG[][4] = { | 1880 | static 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 | ||
1834 | static const __u8 ov7670_initQVGA_JPG[][4] = { | 2010 | static 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 */ |
1969 | static const __u8 po1200_gamma[17] = { | 2145 | static 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 | }; |
1973 | static const __u8 po1200_matrix[9] = { | 2149 | static 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 | }; |
1976 | static const __u8 po1200_initVGA_data[][4] = { | 2152 | static 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 */ |
2278 | static void reg_r(struct gspca_dev *gspca_dev, | 2454 | static 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 | ||
2292 | static void reg_w(struct usb_device *dev, | 2468 | static 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 | ||
2343 | static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) | 2519 | static 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 | ||
2408 | static void put_tab_to_reg(struct gspca_dev *gspca_dev, | 2591 | static 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 | ||
2418 | static void usb_exchange(struct gspca_dev *gspca_dev, | 2601 | static 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 */ |
2572 | static void sethvflip(struct gspca_dev *gspca_dev) | 2754 | static 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 | ||
2600 | static void setlightfreq(struct gspca_dev *gspca_dev) | 2793 | static 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) | |||
2612 | static void setsharpness(struct gspca_dev *gspca_dev) | 2805 | static 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) | |||
2625 | static int sd_start(struct gspca_dev *gspca_dev) | 2818 | static 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) | |||
2754 | static void sd_stopN(struct gspca_dev *gspca_dev) | 2960 | static 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) | |||
2764 | static void sd_stop0(struct gspca_dev *gspca_dev) | 2974 | static 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 | ||
2773 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 2988 | static 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) | |||
2872 | static int sd_querymenu(struct gspca_dev *gspca_dev, | 3087 | static 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) | ||
2909 | static const __devinitdata struct usb_device_id device_table[] = { | 3118 | static 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 | }; |
2924 | MODULE_DEVICE_TABLE(usb, device_table); | 3134 | MODULE_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, | |||
7574 | static const struct sd_desc sd_desc = { | 7574 | static 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 | ||
179 | int hdpvr_set_options(struct hdpvr_device *dev) | 179 | int 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; |
194 | error: | 193 | unlock: |
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 | ||
382 | error: | 383 | error: |
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; |
385 | err: | 386 | err: |
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 | ||
125 | static inline int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | 125 | static 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 | ||
130 | static inline int get_key_haup_xvr(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | 130 | static 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 | ||
298 | static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) | 298 | static 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) | |||
454 | static const struct i2c_device_id ir_kbd_id[] = { | 485 | static 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 | ||
982 | static const struct ivtv_card_pci_info ivtv_pci_aver_pvr150[] = { | 982 | static 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 | ||
987 | static const struct ivtv_card ivtv_card_aver_pvr150 = { | 988 | static 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 | |||
1027 | static 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 | |||
1032 | static 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 | ||
1021 | static const struct ivtv_card_pci_info ivtv_pci_aver_ezmaker[] = { | 1070 | static 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"); |
191 | MODULE_PARM_DESC(pal, "Set PAL standard: BGH, DK, I, M, N, Nc, 60"); | 192 | MODULE_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)"); |
219 | MODULE_PARM_DESC(ivtv_yuv_threshold, | 220 | MODULE_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"); |
222 | MODULE_PARM_DESC(enc_mpg_buffers, | 223 | MODULE_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 | ||
239 | static 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 | |||
251 | static int subdev_s_audio_routing(struct v4l2_subdev *sd, | 239 | static 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 | ||
350 | static const struct v4l2_subdev_tuner_ops subdev_tuner_ops = { | 337 | static 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 */ |
510 | static struct i2c_adapter ivtv_i2c_adap_hw_template = { | 510 | static 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 */ |
561 | static struct i2c_adapter ivtv_i2c_adap_template = { | 560 | static 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 | ||
1917 | static struct pci_device_id meye_pci_tbl[] = { | 1917 | static 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 = { | |||
540 | static struct i2c_adapter pvr2_i2c_adap_template = { | 540 | static 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: | |||
1072 | static void pwc_remove_sysfs_files(struct video_device *vdev) | 1073 | static 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 | ||
1864 | err_unreg: | 1856 | err_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); |
1868 | err: | 1860 | pdev->vdev = NULL; /* So we don't try to release it below */ |
1869 | video_device_release(pdev->vdev); /* Drip... drip... drip... */ | 1861 | err_video_release: |
1870 | kfree(pdev); /* Oops, no memory leaks please */ | 1862 | video_device_release(pdev->vdev); |
1863 | err_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... */ |
1875 | static void usb_pwc_disconnect(struct usb_interface *intf) | 1869 | static 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 | ||
1917 | disconnect_out: | 1909 | disconnect_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? :-) */ |
145 | struct pwc_iso_buf | 139 | struct 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 */ |
41 | static unsigned int debug; | 41 | static unsigned int debug; |
42 | static unsigned int xtal; | 42 | static unsigned int xtal; |
43 | static unsigned int rbds; | 43 | static unsigned int mmbs; |
44 | static unsigned int plvl; | 44 | static unsigned int plvl; |
45 | static unsigned int bufblocks = 100; | 45 | static unsigned int bufblocks = 100; |
46 | 46 | ||
@@ -48,8 +48,8 @@ module_param(debug, int, 0644); | |||
48 | MODULE_PARM_DESC(debug, "enable debug messages"); | 48 | MODULE_PARM_DESC(debug, "enable debug messages"); |
49 | module_param(xtal, int, 0); | 49 | module_param(xtal, int, 0); |
50 | MODULE_PARM_DESC(xtal, "select oscillator frequency (0..3), default 0"); | 50 | MODULE_PARM_DESC(xtal, "select oscillator frequency (0..3), default 0"); |
51 | module_param(rbds, int, 0); | 51 | module_param(mmbs, int, 0); |
52 | MODULE_PARM_DESC(rbds, "select mode, 0=RDS, 1=RBDS, default 0"); | 52 | MODULE_PARM_DESC(mmbs, "enable MMBS mode: 0=off (default), 1=on"); |
53 | module_param(plvl, int, 0); | 53 | module_param(plvl, int, 0); |
54 | MODULE_PARM_DESC(plvl, "select pause level (0..3), default 0"); | 54 | MODULE_PARM_DESC(plvl, "select pause level (0..3), default 0"); |
55 | module_param(bufblocks, int, 0); | 55 | module_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 | ||
83 | static inline struct saa6588 *to_saa6588(struct v4l2_subdev *sd) | 84 | static 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 | ||
324 | static int saa6588_configure(struct saa6588 *s) | 336 | static 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 | ||
429 | static 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 | |||
439 | static 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 | |||
419 | static int saa6588_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) | 447 | static 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 | ||
461 | static const struct v4l2_subdev_tuner_ops saa6588_tuner_ops = { | ||
462 | .g_tuner = saa6588_g_tuner, | ||
463 | .s_tuner = saa6588_s_tuner, | ||
464 | }; | ||
465 | |||
433 | static const struct v4l2_subdev_ops saa6588_ops = { | 466 | static 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 | */ | ||
323 | static 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 | ||
440 | static struct snd_pcm_hardware snd_card_saa7134_capture = | 566 | static 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, | |||
846 | static int snd_saa7134_capsrc_put(struct snd_kcontrol * kcontrol, | 977 | static 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 | ||
924 | static struct snd_kcontrol_new snd_saa7134_controls[] = { | 987 | static struct snd_kcontrol_new snd_saa7134_volume_controls[] = { |
925 | SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER), | 988 | SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER), |
926 | SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER), | ||
927 | SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1), | 989 | SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1), |
928 | SAA713x_CAPSRC("Line Capture Switch", 1, MIXER_ADDR_LINE1), | ||
929 | SAA713x_VOLUME("Line Volume", 2, MIXER_ADDR_LINE2), | 990 | SAA713x_VOLUME("Line Volume", 2, MIXER_ADDR_LINE2), |
991 | }; | ||
992 | |||
993 | static struct snd_kcontrol_new snd_saa7134_capture_controls[] = { | ||
994 | SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER), | ||
995 | SAA713x_CAPSRC("Line Capture Switch", 1, MIXER_ADDR_LINE1), | ||
930 | SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2), | 996 | SAA713x_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), | |||
941 | static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip) | 1007 | static 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 */ |
37 | static char name_mute[] = "mute"; | 38 | static 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 | ||
5121 | const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); | 5263 | const 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 | ||
6478 | static 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 | ||
6314 | static int saa7134_tda8290_827x_callback(struct saa7134_dev *dev, | 6505 | static 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 | ||
61 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | 62 | MODULE_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 | ||
972 | static struct mt312_config zl10313_compro_s350_config = { | ||
973 | .demod_address = 0x0e, | ||
974 | }; | ||
975 | |||
971 | static struct lgdt3305_config hcw_lgdt3305_config = { | 976 | static 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 | ||
685 | void saa7134_probe_i2c_ir(struct saa7134_dev *dev) | 692 | void 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 | ||
782 | static int saa7134_rc5_irq(struct saa7134_dev *dev) | 790 | static 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 @@ | |||
34 | static struct uvc_control_info uvc_ctrls[] = { | 34 | static 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] = | |||
675 | static int uvc_entity_match_guid(struct uvc_entity *entity, __u8 guid[16]) | 675 | static 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 | ||
732 | struct uvc_control *uvc_find_control(struct uvc_video_device *video, | 732 | struct 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 | ||
768 | int uvc_query_v4l2_ctrl(struct uvc_video_device *video, | 768 | int 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 | */ |
884 | int uvc_ctrl_begin(struct uvc_video_device *video) | 889 | int 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 | ||
889 | static int uvc_ctrl_commit_entity(struct uvc_device *dev, | 894 | static 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 | ||
936 | int __uvc_ctrl_commit(struct uvc_video_device *video, int rollback) | 941 | int __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 | ||
958 | done: | 963 | done: |
959 | mutex_unlock(&video->ctrl_mutex); | 964 | mutex_unlock(&chain->ctrl_mutex); |
960 | return ret; | 965 | return ret; |
961 | } | 966 | } |
962 | 967 | ||
963 | int uvc_ctrl_get(struct uvc_video_device *video, | 968 | int 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 | ||
1003 | int uvc_ctrl_set(struct uvc_video_device *video, | 1008 | int 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 | ||
1056 | int uvc_xu_ctrl_query(struct uvc_video_device *video, | 1061 | int 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 | ||
279 | static 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 | ||
283 | static int uvc_parse_format(struct uvc_device *dev, | 295 | static 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 | ||
757 | error: | 770 | error: |
@@ -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 | */ | ||
1167 | static 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 | */ |
1193 | static int uvc_scan_chain_entity(struct uvc_video_device *video, | 1204 | static 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 | ||
1278 | static int uvc_scan_chain_forward(struct uvc_video_device *video, | 1282 | static 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 | ||
1319 | static int uvc_scan_chain_backward(struct uvc_video_device *video, | 1346 | static 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 | ||
1372 | static int uvc_scan_chain(struct uvc_video_device *video) | 1399 | static 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; | 1446 | static 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 | |||
1466 | static 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 | */ |
1434 | static int uvc_register_video(struct uvc_device *dev) | 1483 | static 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 | */ | ||
1536 | static 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. */ | 1552 | static 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 | */ | ||
1607 | static 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 | |||
1634 | static 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) | |||
1687 | static int uvc_suspend(struct usb_interface *intf, pm_message_t message) | 1829 | static 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 | ||
1707 | static int __uvc_resume(struct usb_interface *intf, int reset) | 1852 | static 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 | ||
1734 | static int uvc_resume(struct usb_interface *intf) | 1882 | static 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 | ||
102 | void uvc_video_decode_isight(struct urb *urb, struct uvc_video_device *video, | 102 | void 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 | */ |
43 | static int uvc_v4l2_query_menu(struct uvc_video_device *video, | 43 | static 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 | ||
106 | static int uvc_v4l2_try_format(struct uvc_video_device *video, | 106 | static 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 | ||
219 | static int uvc_v4l2_get_format(struct uvc_video_device *video, | 220 | static 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 | ||
243 | static int uvc_v4l2_set_format(struct uvc_video_device *video, | 244 | static 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 | ||
268 | static int uvc_v4l2_get_streamparm(struct uvc_video_device *video, | 269 | static 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 | ||
300 | static int uvc_v4l2_set_streamparm(struct uvc_video_device *video, | 301 | static 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: | |||
398 | static void uvc_dismiss_privileges(struct uvc_fh *handle) | 400 | static 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 | ||
415 | static int uvc_v4l2_open(struct file *file) | 417 | static 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 | ||
457 | done: | 461 | done: |
458 | mutex_unlock(&uvc_driver.open_mutex); | 462 | mutex_unlock(&uvc_driver.open_mutex); |
@@ -461,20 +465,20 @@ done: | |||
461 | 465 | ||
462 | static int uvc_v4l2_release(struct file *file) | 466 | static 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 | ||
493 | static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | 497 | static 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 | ||
1071 | static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | 1077 | static 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 | ||
1119 | done: | 1127 | done: |
1120 | mutex_unlock(&video->queue.mutex); | 1128 | mutex_unlock(&queue->mutex); |
1121 | return ret; | 1129 | return ret; |
1122 | } | 1130 | } |
1123 | 1131 | ||
1124 | static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait) | 1132 | static 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 | ||
1133 | const struct v4l2_file_operations uvc_fops = { | 1142 | const 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 | ||
64 | static void uvc_fixup_video_ctrl(struct uvc_video_device *video, | 64 | static 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 | ||
119 | static int uvc_get_video_ctrl(struct uvc_video_device *video, | 119 | static 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 | ||
198 | out: | 201 | out: |
@@ -200,14 +203,14 @@ out: | |||
200 | return ret; | 203 | return ret; |
201 | } | 204 | } |
202 | 205 | ||
203 | static int uvc_set_video_ctrl(struct uvc_video_device *video, | 206 | static 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 | ||
250 | int uvc_probe_video(struct uvc_video_device *video, | 252 | int 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 | ||
306 | done: | 312 | done: |
307 | mutex_unlock(&video->streaming->mutex); | 313 | mutex_unlock(&stream->mutex); |
308 | return ret; | 314 | return ret; |
309 | } | 315 | } |
310 | 316 | ||
311 | int uvc_commit_video(struct uvc_video_device *video, | 317 | int 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 | */ |
366 | static int uvc_video_decode_start(struct uvc_video_device *video, | 372 | static 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 | ||
445 | static void uvc_video_decode_data(struct uvc_video_device *video, | 451 | static 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 | ||
469 | static void uvc_video_decode_end(struct uvc_video_device *video, | 475 | static 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 | */ |
494 | static int uvc_video_encode_header(struct uvc_video_device *video, | 500 | static 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 | ||
503 | static int uvc_video_encode_data(struct uvc_video_device *video, | 509 | static 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 | */ |
529 | static void uvc_video_decode_isoc(struct urb *urb, | 535 | static 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 | ||
568 | static void uvc_video_decode_bulk(struct urb *urb, | 575 | static 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 | ||
631 | static void uvc_video_encode_bulk(struct urb *urb, | 640 | static 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 | ||
673 | static void uvc_video_complete(struct urb *urb) | 682 | static 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 | */ |
716 | static void uvc_free_urb_buffers(struct uvc_video_device *video) | 725 | static 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 | */ |
742 | static int uvc_alloc_urb_buffers(struct uvc_video_device *video, | 751 | static 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 | */ |
783 | static void uvc_uninit_video(struct uvc_video_device *video, int free_buffers) | 792 | static 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 | */ |
805 | static int uvc_init_video_isoc(struct uvc_video_device *video, | 815 | static 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 | */ |
857 | static int uvc_init_video_bulk(struct uvc_video_device *video, | 867 | static 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 | */ |
907 | static int uvc_init_video(struct uvc_video_device *video, gfp_t gfp_flags) | 917 | static 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 | */ |
990 | int uvc_video_suspend(struct uvc_video_device *video) | 1002 | int 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 | */ |
1009 | int uvc_video_resume(struct uvc_video_device *video) | 1021 | int 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 | */ |
1043 | int uvc_video_init(struct uvc_video_device *video) | 1057 | int 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 | */ |
1136 | int uvc_video_enable(struct uvc_video_device *video, int enable) | 1155 | int 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 | ||
521 | struct 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 | |||
541 | enum uvc_buffer_state { | 366 | enum 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 | ||
582 | struct uvc_video_device { | 407 | struct 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; | 420 | struct 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 | ||
657 | enum uvc_handle_state { | 500 | enum uvc_handle_state { |
@@ -660,7 +503,8 @@ enum uvc_handle_state { | |||
660 | }; | 503 | }; |
661 | 504 | ||
662 | struct uvc_fh { | 505 | struct 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) | |||
757 | extern const struct v4l2_file_operations uvc_fops; | 601 | extern const struct v4l2_file_operations uvc_fops; |
758 | 602 | ||
759 | /* Video */ | 603 | /* Video */ |
760 | extern int uvc_video_init(struct uvc_video_device *video); | 604 | extern int uvc_video_init(struct uvc_streaming *stream); |
761 | extern int uvc_video_suspend(struct uvc_video_device *video); | 605 | extern int uvc_video_suspend(struct uvc_streaming *stream); |
762 | extern int uvc_video_resume(struct uvc_video_device *video); | 606 | extern int uvc_video_resume(struct uvc_streaming *stream); |
763 | extern int uvc_video_enable(struct uvc_video_device *video, int enable); | 607 | extern int uvc_video_enable(struct uvc_streaming *stream, int enable); |
764 | extern int uvc_probe_video(struct uvc_video_device *video, | 608 | extern int uvc_probe_video(struct uvc_streaming *stream, |
765 | struct uvc_streaming_control *probe); | 609 | struct uvc_streaming_control *probe); |
766 | extern int uvc_commit_video(struct uvc_video_device *video, | 610 | extern int uvc_commit_video(struct uvc_streaming *stream, |
767 | struct uvc_streaming_control *ctrl); | 611 | struct uvc_streaming_control *ctrl); |
768 | extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, | 612 | extern 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); | |||
777 | extern int uvc_status_resume(struct uvc_device *dev); | 621 | extern int uvc_status_resume(struct uvc_device *dev); |
778 | 622 | ||
779 | /* Controls */ | 623 | /* Controls */ |
780 | extern struct uvc_control *uvc_find_control(struct uvc_video_device *video, | 624 | extern 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); |
782 | extern int uvc_query_v4l2_ctrl(struct uvc_video_device *video, | 626 | extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, |
783 | struct v4l2_queryctrl *v4l2_ctrl); | 627 | struct v4l2_queryctrl *v4l2_ctrl); |
784 | 628 | ||
785 | extern int uvc_ctrl_add_info(struct uvc_control_info *info); | 629 | extern int uvc_ctrl_add_info(struct uvc_control_info *info); |
@@ -789,23 +633,23 @@ extern void uvc_ctrl_cleanup_device(struct uvc_device *dev); | |||
789 | extern int uvc_ctrl_resume_device(struct uvc_device *dev); | 633 | extern int uvc_ctrl_resume_device(struct uvc_device *dev); |
790 | extern void uvc_ctrl_init(void); | 634 | extern void uvc_ctrl_init(void); |
791 | 635 | ||
792 | extern int uvc_ctrl_begin(struct uvc_video_device *video); | 636 | extern int uvc_ctrl_begin(struct uvc_video_chain *chain); |
793 | extern int __uvc_ctrl_commit(struct uvc_video_device *video, int rollback); | 637 | extern int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback); |
794 | static inline int uvc_ctrl_commit(struct uvc_video_device *video) | 638 | static 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 | } |
798 | static inline int uvc_ctrl_rollback(struct uvc_video_device *video) | 642 | static 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 | ||
803 | extern int uvc_ctrl_get(struct uvc_video_device *video, | 647 | extern int uvc_ctrl_get(struct uvc_video_chain *chain, |
804 | struct v4l2_ext_control *xctrl); | 648 | struct v4l2_ext_control *xctrl); |
805 | extern int uvc_ctrl_set(struct uvc_video_device *video, | 649 | extern int uvc_ctrl_set(struct uvc_video_chain *chain, |
806 | struct v4l2_ext_control *xctrl); | 650 | struct v4l2_ext_control *xctrl); |
807 | 651 | ||
808 | extern int uvc_xu_ctrl_query(struct uvc_video_device *video, | 652 | extern 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 */ |
820 | void uvc_video_decode_isight(struct urb *urb, struct uvc_video_device *video, | 664 | void 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 | ||
603 | struct 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. */ | ||
620 | static 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 | |||
603 | static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up) | 631 | static 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 | ||
644 | static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up) | 674 | static 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 | ||
1777 | static struct i2c_adapter vino_i2c_adapter = { | 1777 | static 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 | ||
102 | MODULE_DEVICE_TABLE(usb, device_table); | 121 | MODULE_DEVICE_TABLE(usb, device_table); |
103 | 122 | ||
123 | struct zr364xx_mode { | ||
124 | u32 color; /* output video color format */ | ||
125 | u32 brightness; /* brightness */ | ||
126 | }; | ||
127 | |||
128 | /* frame structure */ | ||
129 | struct 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 */ | ||
137 | struct zr364xx_bufferi { | ||
138 | unsigned long dwFrames; /* number of frames in buffer */ | ||
139 | struct zr364xx_framei frame[FRAMES]; /* array of FRAME structures */ | ||
140 | }; | ||
141 | |||
142 | struct zr364xx_dmaqueue { | ||
143 | struct list_head active; | ||
144 | struct zr364xx_camera *cam; | ||
145 | }; | ||
146 | |||
147 | struct 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 | |||
157 | struct zr364xx_fmt { | ||
158 | char *name; | ||
159 | u32 fourcc; | ||
160 | int depth; | ||
161 | }; | ||
162 | |||
163 | /* image formats. */ | ||
164 | static 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 */ |
106 | struct zr364xx_camera { | 173 | struct 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 */ | ||
205 | struct 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 */ |
124 | static int send_control_msg(struct usb_device *udev, u8 request, u16 value, | 212 | static int send_control_msg(struct usb_device *udev, u8 request, u16 value, |
@@ -272,139 +360,116 @@ static unsigned char header2[] = { | |||
272 | }; | 360 | }; |
273 | static unsigned char header3; | 361 | static unsigned char header3; |
274 | 362 | ||
363 | /* ------------------------------------------------------------------ | ||
364 | Videobuf operations | ||
365 | ------------------------------------------------------------------*/ | ||
275 | 366 | ||
367 | static 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; |
283 | static 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 */ | 383 | static 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) | 394 | static 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]); | 427 | fail: |
428 | free_buffer(vq, buf); | ||
429 | return rc; | ||
430 | } | ||
431 | |||
432 | static 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 | |||
444 | static 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 | ||
454 | static 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 | /********************/ | ||
464 | static int zr364xx_vidioc_streamon(struct file *file, void *priv, | ||
465 | enum v4l2_buf_type type); | ||
395 | 466 | ||
396 | static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t cnt, | 467 | static 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 | */ | ||
501 | static 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 | |||
542 | static 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); | ||
571 | unlock: | ||
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 | */ | ||
581 | static 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)) | 707 | static 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; | 723 | static inline int res_check(struct zr364xx_camera *cam) |
724 | { | ||
725 | return cam->resources; | ||
422 | } | 726 | } |
423 | 727 | ||
728 | static 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 | ||
425 | static int zr364xx_vidioc_querycap(struct file *file, void *priv, | 736 | static 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, | |||
458 | static int zr364xx_vidioc_queryctrl(struct file *file, void *priv, | 778 | static 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, | |||
484 | static int zr364xx_vidioc_s_ctrl(struct file *file, void *priv, | 803 | static 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 | ||
504 | static int zr364xx_vidioc_g_ctrl(struct file *file, void *priv, | 830 | static 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 | ||
860 | static 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 | |||
535 | static int zr364xx_vidioc_try_fmt_vid_cap(struct file *file, void *priv, | 870 | static 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 | ||
560 | static int zr364xx_vidioc_g_fmt_vid_cap(struct file *file, void *priv, | 902 | static 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, | |||
581 | static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv, | 922 | static 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 | |||
993 | out: | ||
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 | |||
1002 | static 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 | |||
1011 | static 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 | |||
1021 | static 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 | |||
1032 | static 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 | |||
1043 | static 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 | |||
1108 | static 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 | |||
1140 | static 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 */ | ||
1165 | static 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 | |||
1181 | static 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 | ||
607 | static int zr364xx_vidioc_streamon(struct file *file, void *priv, | 1187 | static 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 | ||
613 | static int zr364xx_vidioc_streamoff(struct file *file, void *priv, | 1226 | static 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, | |||
621 | static int zr364xx_open(struct file *file) | 1251 | static 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 | ||
668 | out: | 1297 | out: |
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 | ||
1303 | static 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 */ |
675 | static int zr364xx_release(struct file *file) | 1340 | static 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 | ||
712 | out: | 1383 | out: |
713 | mutex_unlock(&cam->lock); | 1384 | mutex_unlock(&cam->open_lock); |
1385 | |||
714 | return err; | 1386 | return err; |
715 | } | 1387 | } |
716 | 1388 | ||
717 | 1389 | ||
718 | static int zr364xx_mmap(struct file *file, struct vm_area_struct *vma) | 1390 | static 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 | ||
1409 | static 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 | ||
748 | static const struct v4l2_file_operations zr364xx_fops = { | 1422 | static 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 | ||
757 | static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = { | 1432 | static 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 | ||
773 | static struct video_device zr364xx_template = { | 1452 | static 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 | /*******************/ |
1465 | static 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 | ||
787 | static int zr364xx_probe(struct usb_interface *intf, | 1524 | static 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, | |||
876 | static void zr364xx_disconnect(struct usb_interface *intf) | 1643 | static 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 | ||