Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
[pandora-kernel.git] / drivers / media / video / gspca / gl860 / gl860-mi2020.c
1 /* @file gl860-mi2020.c
2  * @author Olivier LORIN, from Ice/Soro2005's logs(A), Fret_saw/Hulkie's
3  * logs(B) and Tricid"s logs(C). With the help of Kytrix/BUGabundo/Blazercist.
4  * @date 2009-08-27
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  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 /* Sensor : MI2020 */
21
22 #include "gl860.h"
23
24 static u8 dat_bright1[] = {0x8c, 0xa2, 0x06};
25 static u8 dat_bright3[] = {0x8c, 0xa1, 0x02};
26 static u8 dat_bright4[] = {0x90, 0x00, 0x0f};
27 static u8 dat_bright5[] = {0x8c, 0xa1, 0x03};
28 static u8 dat_bright6[] = {0x90, 0x00, 0x05};
29
30 static u8 dat_dummy1[] = {0x90, 0x00, 0x06};
31 /*static u8 dummy2[] = {0x8c, 0xa1, 0x02};*/
32 /*static u8 dummy3[] = {0x90, 0x00, 0x1f};*/
33
34 static u8 dat_hvflip1[] = {0x8c, 0x27, 0x19};
35 static u8 dat_hvflip3[] = {0x8c, 0x27, 0x3b};
36 static u8 dat_hvflip5[] = {0x8c, 0xa1, 0x03};
37 static u8 dat_hvflip6[] = {0x90, 0x00, 0x06};
38
39 static u8 dat_freq1[] = { 0x8c, 0xa4, 0x04 };
40
41 static u8 dat_multi5[] = { 0x8c, 0xa1, 0x03 };
42 static u8 dat_multi6[] = { 0x90, 0x00, 0x05 };
43
44 static struct validx tbl_common_a[] = {
45         {0x0000, 0x0000},
46         {1, 0xffff}, /* msleep(35); */
47         {0x006a, 0x0007}, {0x0063, 0x0006}, {0x006a, 0x000d}, {0x0000, 0x00c0},
48         {0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042, 0x00c2}, {0x0004, 0x00d8},
49         {0x0000, 0x0058}, {0x0002, 0x0004}, {0x0041, 0x0000},
50 };
51
52 static struct validx tbl_common_b[] = {
53         {0x006a, 0x0007},
54         {35, 0xffff},
55         {0x00ef, 0x0006},
56         {35, 0xffff},
57         {0x006a, 0x000d},
58         {35, 0xffff},
59         {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042, 0x00c2},
60         {0x0004, 0x00d8}, {0x0000, 0x0058}, {0x0041, 0x0000},
61 };
62
63 static struct idxdata tbl_common_c[] = {
64         {0x32, "\x02\x00\x08"}, {0x33, "\xf4\x03\x1d"},
65         {6, "\xff\xff\xff"}, /* 12 */
66         {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
67         {2, "\xff\xff\xff"}, /* - */
68         {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\x22\x23"},
69         {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa2\x0f"}, {0x33, "\x90\x00\x0d"},
70         {0x33, "\x8c\xa2\x10"}, {0x33, "\x90\x00\x0b"}, {0x33, "\x8c\xa2\x11"},
71         {0x33, "\x90\x00\x07"}, {0x33, "\xf4\x03\x1d"}, {0x35, "\xa2\x00\xe2"},
72         {0x33, "\x8c\xab\x05"}, {0x33, "\x90\x00\x01"}, {0x32, "\x6e\x00\x86"},
73         {0x32, "\x70\x0f\xaa"}, {0x32, "\x72\x0f\xe4"}, {0x33, "\x8c\xa3\x4a"},
74         {0x33, "\x90\x00\x5a"}, {0x33, "\x8c\xa3\x4b"}, {0x33, "\x90\x00\xa6"},
75         {0x33, "\x8c\xa3\x61"}, {0x33, "\x90\x00\xc8"}, {0x33, "\x8c\xa3\x62"},
76         {0x33, "\x90\x00\xe1"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
77         {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
78         {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
79         {0x34, "\xde\x01\x5b"}, {0x34, "\xe6\x01\x13"}, {0x34, "\xee\x0b\xf0"},
80         {0x34, "\xf6\x0b\xa4"}, {0x35, "\x00\xf6\xe7"}, {0x35, "\x08\x0d\xfd"},
81         {0x35, "\x10\x25\x63"}, {0x35, "\x18\x35\x6c"}, {0x35, "\x20\x42\x7e"},
82         {0x35, "\x28\x19\x44"}, {0x35, "\x30\x39\xd4"}, {0x35, "\x38\xf5\xa8"},
83         {0x35, "\x4c\x07\x90"}, {0x35, "\x44\x07\xb8"}, {0x35, "\x5c\x06\x88"},
84         {0x35, "\x54\x07\xff"}, {0x34, "\xe0\x01\x52"}, {0x34, "\xe8\x00\xcc"},
85         {0x34, "\xf0\x0d\x83"}, {0x34, "\xf8\x0c\xb3"}, {0x35, "\x02\xfe\xba"},
86         {0x35, "\x0a\x04\xe0"}, {0x35, "\x12\x1c\x63"}, {0x35, "\x1a\x2b\x5a"},
87         {0x35, "\x22\x32\x5e"}, {0x35, "\x2a\x0d\x28"}, {0x35, "\x32\x2c\x02"},
88         {0x35, "\x3a\xf4\xfa"}, {0x35, "\x4e\x07\xef"}, {0x35, "\x46\x07\x88"},
89         {0x35, "\x5e\x07\xc1"}, {0x35, "\x56\x04\x64"}, {0x34, "\xe4\x01\x15"},
90         {0x34, "\xec\x00\x82"}, {0x34, "\xf4\x0c\xce"}, {0x34, "\xfc\x0c\xba"},
91         {0x35, "\x06\x1f\x02"}, {0x35, "\x0e\x02\xe3"}, {0x35, "\x16\x1a\x50"},
92         {0x35, "\x1e\x24\x39"}, {0x35, "\x26\x23\x4c"}, {0x35, "\x2e\xf9\x1b"},
93         {0x35, "\x36\x23\x19"}, {0x35, "\x3e\x12\x08"}, {0x35, "\x52\x07\x22"},
94         {0x35, "\x4a\x03\xd3"}, {0x35, "\x62\x06\x54"}, {0x35, "\x5a\x04\x5d"},
95         {0x34, "\xe2\x01\x04"}, {0x34, "\xea\x00\xa0"}, {0x34, "\xf2\x0c\xbc"},
96         {0x34, "\xfa\x0c\x5b"}, {0x35, "\x04\x17\xf2"}, {0x35, "\x0c\x02\x08"},
97         {0x35, "\x14\x28\x43"}, {0x35, "\x1c\x28\x62"}, {0x35, "\x24\x2b\x60"},
98         {0x35, "\x2c\x07\x33"}, {0x35, "\x34\x1f\xb0"}, {0x35, "\x3c\xed\xcd"},
99         {0x35, "\x50\x00\x06"}, {0x35, "\x48\x07\xff"}, {0x35, "\x60\x05\x89"},
100         {0x35, "\x58\x07\xff"}, {0x35, "\x40\x00\xa0"}, {0x35, "\x42\x00\x00"},
101         {0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"},
102         {1, "\xff\xff\xff"},
103         {0x33, "\x78\x00\x00"},
104         {1, "\xff\xff\xff"},
105         {0x35, "\xb8\x1f\x20"}, {0x33, "\x8c\xa2\x06"}, {0x33, "\x90\x00\x10"},
106         {0x33, "\x8c\xa2\x07"}, {0x33, "\x90\x00\x08"}, {0x33, "\x8c\xa2\x42"},
107         {0x33, "\x90\x00\x0b"}, {0x33, "\x8c\xa2\x4a"}, {0x33, "\x90\x00\x8c"},
108         {0x35, "\xba\xfa\x08"}, {0x33, "\x8c\xa2\x02"}, {0x33, "\x90\x00\x22"},
109         {0x33, "\x8c\xa2\x03"}, {0x33, "\x90\x00\xbb"},
110 };
111
112 static struct idxdata tbl_common_d[] = {
113         {0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\xa0"}, {0x33, "\x8c\xa4\x08"},
114         {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x21"},
115         {0x33, "\x8c\xa4\x0a"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\xa4\x0b"},
116         {0x33, "\x90\x00\x27"}, {0x33, "\x8c\x24\x11"}, {0x33, "\x90\x00\xa0"},
117         {0x33, "\x8c\x24\x13"}, {0x33, "\x90\x00\xc0"}, {0x33, "\x8c\x24\x15"},
118         {0x33, "\x90\x00\xa0"}, {0x33, "\x8c\x24\x17"}, {0x33, "\x90\x00\xc0"},
119 };
120
121 static struct idxdata tbl_common_e[] = {
122         {0x33, "\x8c\xa4\x04"}, {0x33, "\x90\x00\x80"}, {0x33, "\x8c\xa7\x9d"},
123         {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa7\x9e"}, {0x33, "\x90\x00\x00"},
124         {0x33, "\x8c\xa2\x0c"}, {0x33, "\x90\x00\x17"}, {0x33, "\x8c\xa2\x15"},
125         {0x33, "\x90\x00\x04"}, {0x33, "\x8c\xa2\x14"}, {0x33, "\x90\x00\x20"},
126         {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x17"},
127         /* msleep(53); */
128         {0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x1b"}, {0x33, "\x90\x02\x4f"},
129         {0x33, "\x8c\x27\x25"}, {0x33, "\x90\x06\x0f"}, {0x33, "\x8c\x27\x39"},
130         {0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x3d"}, {0x33, "\x90\x01\x20"},
131         {0x33, "\x8c\x27\x47"}, {0x33, "\x90\x09\x4c"}, {0x33, "\x8c\x27\x03"},
132         {0x33, "\x90\x02\x84"}, {0x33, "\x8c\x27\x05"}, {0x33, "\x90\x01\xe2"},
133         {0x33, "\x8c\x27\x07"}, {0x33, "\x90\x06\x40"}, {0x33, "\x8c\x27\x09"},
134         {0x33, "\x90\x04\xb0"}, {0x33, "\x8c\x27\x0d"}, {0x33, "\x90\x00\x00"},
135         {0x33, "\x8c\x27\x0f"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x11"},
136         {0x33, "\x90\x04\xbd"}, {0x33, "\x8c\x27\x13"}, {0x33, "\x90\x06\x4d"},
137         {0x33, "\x8c\x27\x15"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x17"},
138         {0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x19"}, {0x33, "\x90\x04\x6c"},
139         {0x33, "\x8c\x27\x1b"}, {0x33, "\x90\x02\x4f"}, {0x33, "\x8c\x27\x1d"},
140         {0x33, "\x90\x01\x02"}, {0x33, "\x8c\x27\x1f"}, {0x33, "\x90\x02\x79"},
141         {0x33, "\x8c\x27\x21"}, {0x33, "\x90\x01\x55"}, {0x33, "\x8c\x27\x23"},
142         {0x33, "\x90\x02\x85"}, {0x33, "\x8c\x27\x25"}, {0x33, "\x90\x06\x0f"},
143         {0x33, "\x8c\x27\x27"}, {0x33, "\x90\x20\x20"}, {0x33, "\x8c\x27\x29"},
144         {0x33, "\x90\x20\x20"}, {0x33, "\x8c\x27\x2b"}, {0x33, "\x90\x10\x20"},
145         {0x33, "\x8c\x27\x2d"}, {0x33, "\x90\x20\x07"}, {0x33, "\x8c\x27\x2f"},
146         {0x33, "\x90\x00\x04"}, {0x33, "\x8c\x27\x31"}, {0x33, "\x90\x00\x04"},
147         {0x33, "\x8c\x27\x33"}, {0x33, "\x90\x04\xbb"}, {0x33, "\x8c\x27\x35"},
148         {0x33, "\x90\x06\x4b"}, {0x33, "\x8c\x27\x37"}, {0x33, "\x90\x00\x00"},
149         {0x33, "\x8c\x27\x39"}, {0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x3b"},
150         {0x33, "\x90\x00\x24"}, {0x33, "\x8c\x27\x3d"}, {0x33, "\x90\x01\x20"},
151         {0x33, "\x8c\x27\x41"}, {0x33, "\x90\x01\x69"}, {0x33, "\x8c\x27\x45"},
152         {0x33, "\x90\x04\xed"}, {0x33, "\x8c\x27\x47"}, {0x33, "\x90\x09\x4c"},
153         {0x33, "\x8c\x27\x51"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x53"},
154         {0x33, "\x90\x03\x20"}, {0x33, "\x8c\x27\x55"}, {0x33, "\x90\x00\x00"},
155         {0x33, "\x8c\x27\x57"}, {0x33, "\x90\x02\x58"}, {0x33, "\x8c\x27\x5f"},
156         {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x61"}, {0x33, "\x90\x06\x40"},
157         {0x33, "\x8c\x27\x63"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x65"},
158         {0x33, "\x90\x04\xb0"}, {0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\xa1"},
159         {0x33, "\x8c\xa4\x08"}, {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa4\x09"},
160         {0x33, "\x90\x00\x21"}, {0x33, "\x8c\xa4\x0a"}, {0x33, "\x90\x00\x25"},
161         {0x33, "\x8c\xa4\x0b"}, {0x33, "\x90\x00\x27"}, {0x33, "\x8c\x24\x11"},
162         {0x33, "\x90\x00\xa1"}, {0x33, "\x8c\x24\x13"}, {0x33, "\x90\x00\xc1"},
163         {0x33, "\x8c\x24\x15"},
164 };
165
166 static struct validx tbl_init_at_startup[] = {
167         {0x0000, 0x0000},
168         {53, 0xffff},
169         {0x0010, 0x0010},
170         {53, 0xffff},
171         {0x0008, 0x00c0},
172         {53, 0xffff},
173         {0x0001, 0x00c1},
174         {53, 0xffff},
175         {0x0001, 0x00c2},
176         {53, 0xffff},
177         {0x0020, 0x0006},
178         {53, 0xffff},
179         {0x006a, 0x000d},
180         {53, 0xffff},
181 };
182
183 static struct idxdata tbl_init_post_alt_low_a[] = {
184         {0x33, "\x8c\x27\x15"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\x22\x2e"},
185         {0x33, "\x90\x00\x81"}, {0x33, "\x8c\xa4\x08"}, {0x33, "\x90\x00\x17"},
186         {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x1a"}, {0x33, "\x8c\xa4\x0a"},
187         {0x33, "\x90\x00\x1d"}, {0x33, "\x8c\xa4\x0b"}, {0x33, "\x90\x00\x20"},
188         {0x33, "\x8c\x24\x11"}, {0x33, "\x90\x00\x81"}, {0x33, "\x8c\x24\x13"},
189         {0x33, "\x90\x00\x9b"},
190 };
191
192 static struct idxdata tbl_init_post_alt_low_b[] = {
193         {0x33, "\x8c\x27\x03"}, {0x33, "\x90\x03\x24"}, {0x33, "\x8c\x27\x05"},
194         {0x33, "\x90\x02\x58"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
195         {2, "\xff\xff\xff"},
196         {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
197         {2, "\xff\xff\xff"},
198 };
199
200 static struct idxdata tbl_init_post_alt_low_c[] = {
201         {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
202         {2, "\xff\xff\xff"},
203         {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x20"},
204         {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x01"},
205         {0x33, "\x2e\x01\x00"}, {0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"},
206         {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x95"}, {0x33, "\x90\x01\x00"},
207         {2, "\xff\xff\xff"},
208         {0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa1\x03"},
209         {0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"},
210         {2, "\xff\xff\xff"},
211         {0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa1\x03"},
212         {0x33, "\x90\x00\x01"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x00"},
213         {2, "\xff\xff\xff"}, /* - * */
214         {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
215         {2, "\xff\xff\xff"},
216         {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
217         {2, "\xff\xff\xff"},
218         {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
219         {2, "\xff\xff\xff"},
220         {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
221         {1, "\xff\xff\xff"},
222 };
223
224 static struct idxdata tbl_init_post_alt_low_d[] = {
225         {0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
226         {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
227         {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
228         {0x34, "\xde\x01\x5b"}, {0x34, "\xe6\x01\x13"}, {0x34, "\xee\x0b\xf0"},
229         {0x34, "\xf6\x0b\xa4"}, {0x35, "\x00\xf6\xe7"}, {0x35, "\x08\x0d\xfd"},
230         {0x35, "\x10\x25\x63"}, {0x35, "\x18\x35\x6c"}, {0x35, "\x20\x42\x7e"},
231         {0x35, "\x28\x19\x44"}, {0x35, "\x30\x39\xd4"}, {0x35, "\x38\xf5\xa8"},
232         {0x35, "\x4c\x07\x90"}, {0x35, "\x44\x07\xb8"}, {0x35, "\x5c\x06\x88"},
233         {0x35, "\x54\x07\xff"}, {0x34, "\xe0\x01\x52"}, {0x34, "\xe8\x00\xcc"},
234         {0x34, "\xf0\x0d\x83"}, {0x34, "\xf8\x0c\xb3"}, {0x35, "\x02\xfe\xba"},
235         {0x35, "\x0a\x04\xe0"}, {0x35, "\x12\x1c\x63"}, {0x35, "\x1a\x2b\x5a"},
236         {0x35, "\x22\x32\x5e"}, {0x35, "\x2a\x0d\x28"}, {0x35, "\x32\x2c\x02"},
237         {0x35, "\x3a\xf4\xfa"}, {0x35, "\x4e\x07\xef"}, {0x35, "\x46\x07\x88"},
238         {0x35, "\x5e\x07\xc1"}, {0x35, "\x56\x04\x64"}, {0x34, "\xe4\x01\x15"},
239         {0x34, "\xec\x00\x82"}, {0x34, "\xf4\x0c\xce"}, {0x34, "\xfc\x0c\xba"},
240         {0x35, "\x06\x1f\x02"}, {0x35, "\x0e\x02\xe3"}, {0x35, "\x16\x1a\x50"},
241         {0x35, "\x1e\x24\x39"}, {0x35, "\x26\x23\x4c"}, {0x35, "\x2e\xf9\x1b"},
242         {0x35, "\x36\x23\x19"}, {0x35, "\x3e\x12\x08"}, {0x35, "\x52\x07\x22"},
243         {0x35, "\x4a\x03\xd3"}, {0x35, "\x62\x06\x54"}, {0x35, "\x5a\x04\x5d"},
244         {0x34, "\xe2\x01\x04"}, {0x34, "\xea\x00\xa0"}, {0x34, "\xf2\x0c\xbc"},
245         {0x34, "\xfa\x0c\x5b"}, {0x35, "\x04\x17\xf2"}, {0x35, "\x0c\x02\x08"},
246         {0x35, "\x14\x28\x43"}, {0x35, "\x1c\x28\x62"}, {0x35, "\x24\x2b\x60"},
247         {0x35, "\x2c\x07\x33"}, {0x35, "\x34\x1f\xb0"}, {0x35, "\x3c\xed\xcd"},
248         {0x35, "\x50\x00\x06"}, {0x35, "\x48\x07\xff"}, {0x35, "\x60\x05\x89"},
249         {0x35, "\x58\x07\xff"}, {0x35, "\x40\x00\xa0"}, {0x35, "\x42\x00\x00"},
250         {0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"},
251         /* Flip/Mirror h/v=1 */
252         {0x33, "\x90\x00\x3c"}, {0x33, "\x8c\x27\x19"}, {0x33, "\x90\x04\x6c"},
253         {0x33, "\x8c\x27\x3b"}, {0x33, "\x90\x00\x24"}, {0x33, "\x8c\xa1\x03"},
254         {0x33, "\x90\x00\x06"},
255         {130, "\xff\xff\xff"},
256         {0x33, "\x90\x00\x06"}, {0x33, "\x90\x00\x06"}, {0x33, "\x90\x00\x06"},
257         {0x33, "\x90\x00\x06"}, {0x33, "\x90\x00\x06"}, {0x33, "\x90\x00\x06"},
258         {100, "\xff\xff\xff"},
259         /* ?? */
260         {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa1\x02"},
261         {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"},
262         {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"},
263         /* Brigthness=70 */
264         {0x33, "\x8c\xa2\x06"}, {0x33, "\x90\x00\x46"}, {0x33, "\x8c\xa1\x02"},
265         {0x33, "\x90\x00\x0f"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
266         /* Sharpness=20 */
267         {0x32, "\x6c\x14\x08"},
268 };
269
270 static struct idxdata tbl_init_post_alt_big_a[] = {
271         {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
272         {2, "\xff\xff\xff"},
273         {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
274         {2, "\xff\xff\xff"},
275         {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
276         {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x03"},
277         {0x33, "\x90\x00\x05"},
278         {2, "\xff\xff\xff"},
279         {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
280         {2, "\xff\xff\xff"},
281         {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
282         {2, "\xff\xff\xff"},
283         {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, {0x33, "\x8c\xa1\x20"},
284         {0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa1\x30"}, {0x33, "\x90\x00\x03"},
285         {0x33, "\x8c\xa1\x31"}, {0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa1\x32"},
286         {0x33, "\x90\x00\x03"}, {0x33, "\x8c\xa1\x34"}, {0x33, "\x90\x00\x03"},
287         {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x02"}, {0x33, "\x2e\x01\x00"},
288         {0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"},
289 };
290
291 static struct idxdata tbl_init_post_alt_big_b[] = {
292         {0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
293         {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
294         {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
295         {0x34, "\xde\x01\x5b"}, {0x34, "\xe6\x01\x13"}, {0x34, "\xee\x0b\xf0"},
296         {0x34, "\xf6\x0b\xa4"}, {0x35, "\x00\xf6\xe7"}, {0x35, "\x08\x0d\xfd"},
297         {0x35, "\x10\x25\x63"}, {0x35, "\x18\x35\x6c"}, {0x35, "\x20\x42\x7e"},
298         {0x35, "\x28\x19\x44"}, {0x35, "\x30\x39\xd4"}, {0x35, "\x38\xf5\xa8"},
299         {0x35, "\x4c\x07\x90"}, {0x35, "\x44\x07\xb8"}, {0x35, "\x5c\x06\x88"},
300         {0x35, "\x54\x07\xff"}, {0x34, "\xe0\x01\x52"}, {0x34, "\xe8\x00\xcc"},
301         {0x34, "\xf0\x0d\x83"}, {0x34, "\xf8\x0c\xb3"}, {0x35, "\x02\xfe\xba"},
302         {0x35, "\x0a\x04\xe0"}, {0x35, "\x12\x1c\x63"}, {0x35, "\x1a\x2b\x5a"},
303         {0x35, "\x22\x32\x5e"}, {0x35, "\x2a\x0d\x28"}, {0x35, "\x32\x2c\x02"},
304         {0x35, "\x3a\xf4\xfa"}, {0x35, "\x4e\x07\xef"}, {0x35, "\x46\x07\x88"},
305         {0x35, "\x5e\x07\xc1"}, {0x35, "\x56\x04\x64"}, {0x34, "\xe4\x01\x15"},
306         {0x34, "\xec\x00\x82"}, {0x34, "\xf4\x0c\xce"}, {0x34, "\xfc\x0c\xba"},
307         {0x35, "\x06\x1f\x02"}, {0x35, "\x0e\x02\xe3"}, {0x35, "\x16\x1a\x50"},
308         {0x35, "\x1e\x24\x39"}, {0x35, "\x26\x23\x4c"}, {0x35, "\x2e\xf9\x1b"},
309         {0x35, "\x36\x23\x19"}, {0x35, "\x3e\x12\x08"}, {0x35, "\x52\x07\x22"},
310         {0x35, "\x4a\x03\xd3"}, {0x35, "\x62\x06\x54"}, {0x35, "\x5a\x04\x5d"},
311         {0x34, "\xe2\x01\x04"}, {0x34, "\xea\x00\xa0"}, {0x34, "\xf2\x0c\xbc"},
312         {0x34, "\xfa\x0c\x5b"}, {0x35, "\x04\x17\xf2"}, {0x35, "\x0c\x02\x08"},
313         {0x35, "\x14\x28\x43"}, {0x35, "\x1c\x28\x62"}, {0x35, "\x24\x2b\x60"},
314         {0x35, "\x2c\x07\x33"}, {0x35, "\x34\x1f\xb0"}, {0x35, "\x3c\xed\xcd"},
315         {0x35, "\x50\x00\x06"}, {0x35, "\x48\x07\xff"}, {0x35, "\x60\x05\x89"},
316         {0x35, "\x58\x07\xff"}, {0x35, "\x40\x00\xa0"}, {0x35, "\x42\x00\x00"},
317         {0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"},
318 };
319
320 static struct idxdata tbl_init_post_alt_big_c[] = {
321         {0x33, "\x8c\xa1\x02"},
322         {0x33, "\x90\x00\x1f"},
323         {0x33, "\x8c\xa1\x02"},
324         {0x33, "\x90\x00\x1f"},
325         {0x33, "\x8c\xa1\x02"},
326         {0x33, "\x90\x00\x1f"},
327         {0x33, "\x8c\xa1\x02"},
328         {0x33, "\x90\x00\x1f"},
329 };
330
331 static u8 *dat_640  = "\xd0\x02\xd1\x08\xd2\xe1\xd3\x02\xd4\x10\xd5\x81";
332 static u8 *dat_800  = "\xd0\x02\xd1\x10\xd2\x57\xd3\x02\xd4\x18\xd5\x21";
333 static u8 *dat_1280 = "\xd0\x02\xd1\x20\xd2\x01\xd3\x02\xd4\x28\xd5\x01";
334 static u8 *dat_1600 = "\xd0\x02\xd1\x20\xd2\xaf\xd3\x02\xd4\x30\xd5\x41";
335
336 static int  mi2020_init_at_startup(struct gspca_dev *gspca_dev);
337 static int  mi2020_configure_alt(struct gspca_dev *gspca_dev);
338 static int  mi2020_init_pre_alt(struct gspca_dev *gspca_dev);
339 static int  mi2020_init_post_alt(struct gspca_dev *gspca_dev);
340 static void mi2020_post_unset_alt(struct gspca_dev *gspca_dev);
341 static int  mi2020_camera_settings(struct gspca_dev *gspca_dev);
342 /*==========================================================================*/
343
344 void mi2020_init_settings(struct gspca_dev *gspca_dev)
345 {
346         struct sd *sd = (struct sd *) gspca_dev;
347
348         sd->vcur.backlight  =  0;
349         sd->vcur.brightness = 70;
350         sd->vcur.sharpness  = 20;
351         sd->vcur.contrast   =  0;
352         sd->vcur.gamma      =  0;
353         sd->vcur.hue        =  0;
354         sd->vcur.saturation = 60;
355         sd->vcur.whitebal   = 50;
356         sd->vcur.mirror = 0;
357         sd->vcur.flip   = 0;
358         sd->vcur.AC50Hz = 1;
359
360         sd->vmax.backlight  =  64;
361         sd->vmax.brightness = 128;
362         sd->vmax.sharpness  =  40;
363         sd->vmax.contrast   =   3;
364         sd->vmax.gamma      =   2;
365         sd->vmax.hue        =   0 + 1; /* 200 */
366         sd->vmax.saturation =   0;     /* 100 */
367         sd->vmax.whitebal   =   0;     /* 100 */
368         sd->vmax.mirror = 1;
369         sd->vmax.flip   = 1;
370         sd->vmax.AC50Hz = 1;
371         if (_MI2020b_) {
372                 sd->vmax.contrast  = 0;
373                 sd->vmax.gamma     = 0;
374                 sd->vmax.backlight = 0;
375         }
376
377         sd->dev_camera_settings = mi2020_camera_settings;
378         sd->dev_init_at_startup = mi2020_init_at_startup;
379         sd->dev_configure_alt   = mi2020_configure_alt;
380         sd->dev_init_pre_alt    = mi2020_init_pre_alt;
381         sd->dev_post_unset_alt  = mi2020_post_unset_alt;
382 }
383
384 /*==========================================================================*/
385
386 static void common(struct gspca_dev *gspca_dev)
387 {
388         s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
389
390         if (_MI2020b_) {
391                 fetch_validx(gspca_dev, tbl_common_a, ARRAY_SIZE(tbl_common_a));
392         } else {
393                 if (_MI2020_)
394                         ctrl_out(gspca_dev, 0x40,  1, 0x0008, 0x0004,  0, NULL);
395                 else
396                         ctrl_out(gspca_dev, 0x40,  1, 0x0002, 0x0004,  0, NULL);
397                 msleep(35);
398                 fetch_validx(gspca_dev, tbl_common_b, ARRAY_SIZE(tbl_common_b));
399         }
400         ctrl_out(gspca_dev, 0x40,  3, 0x7a00, 0x0033,  3, "\x86\x25\x01");
401         ctrl_out(gspca_dev, 0x40,  3, 0x7a00, 0x0033,  3, "\x86\x25\x00");
402         msleep(2); /* - * */
403         ctrl_out(gspca_dev, 0x40,  3, 0x7a00, 0x0030,  3, "\x1a\x0a\xcc");
404         if (reso == IMAGE_1600)
405                 msleep(2); /* 1600 */
406         fetch_idxdata(gspca_dev, tbl_common_c, ARRAY_SIZE(tbl_common_c));
407
408         if (_MI2020b_ || _MI2020_)
409                 fetch_idxdata(gspca_dev, tbl_common_d,
410                                 ARRAY_SIZE(tbl_common_d));
411
412         fetch_idxdata(gspca_dev, tbl_common_e, ARRAY_SIZE(tbl_common_e));
413         if (_MI2020b_ || _MI2020_) {
414                 /* Different from fret */
415                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x78");
416                 /* Same as fret */
417                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\x24\x17");
418                 /* Different from fret */
419                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x90");
420         } else {
421                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x6a");
422                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\x24\x17");
423                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x80");
424         }
425         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
426         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x05");
427         msleep(2);
428         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
429         if (reso == IMAGE_1600)
430                 msleep(14); /* 1600 */
431         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x06");
432         msleep(2);
433 }
434
435 static int mi2020_init_at_startup(struct gspca_dev *gspca_dev)
436 {
437         u8 c;
438
439         ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &c);
440         ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &c);
441
442         fetch_validx(gspca_dev, tbl_init_at_startup,
443                         ARRAY_SIZE(tbl_init_at_startup));
444
445         common(gspca_dev);
446
447         return 0;
448 }
449
450 static int mi2020_init_pre_alt(struct gspca_dev *gspca_dev)
451 {
452         struct sd *sd = (struct sd *) gspca_dev;
453
454         sd->mirrorMask = 0;
455
456         sd->vold.backlight  = -1;
457         sd->vold.brightness = -1;
458         sd->vold.sharpness  = -1;
459         sd->vold.contrast   = -1;
460         sd->vold.gamma  = -1;
461         sd->vold.hue    = -1;
462         sd->vold.mirror = -1;
463         sd->vold.flip   = -1;
464         sd->vold.AC50Hz = -1;
465
466         mi2020_init_post_alt(gspca_dev);
467
468         return 0;
469 }
470
471 static int mi2020_init_post_alt(struct gspca_dev *gspca_dev)
472 {
473         struct sd *sd = (struct sd *) gspca_dev;
474         s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
475
476         s32 backlight = sd->vcur.backlight;
477         s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0);
478         s32 flip   = (((sd->vcur.flip   > 0) ^ sd->mirrorMask) > 0);
479         s32 freq   = (sd->vcur.AC50Hz  > 0);
480
481         u8 dat_freq2[] = {0x90, 0x00, 0x80};
482         u8 dat_multi1[] = {0x8c, 0xa7, 0x00};
483         u8 dat_multi2[] = {0x90, 0x00, 0x00};
484         u8 dat_multi3[] = {0x8c, 0xa7, 0x00};
485         u8 dat_multi4[] = {0x90, 0x00, 0x00};
486         u8 dat_hvflip2[] = {0x90, 0x04, 0x6c};
487         u8 dat_hvflip4[] = {0x90, 0x00, 0x24};
488         u8 c;
489
490         sd->nbIm = -1;
491
492         dat_freq2[2] = freq ? 0xc0 : 0x80;
493         dat_multi1[2] = 0x9d;
494         dat_multi3[2] = dat_multi1[2] + 1;
495         dat_multi4[2] = dat_multi2[2] = backlight;
496         dat_hvflip2[2] = 0x6c + 2 * (1 - flip) + (1 - mirror);
497         dat_hvflip4[2] = 0x24 + 2 * (1 - flip) + (1 - mirror);
498
499         msleep(200);
500
501         ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
502         msleep(3); /* 35 * */
503
504         common(gspca_dev);
505
506         ctrl_out(gspca_dev, 0x40,  1, 0x0041, 0x0000,  0, NULL);
507         msleep(70);
508
509         if (_MI2020b_)
510                 ctrl_out(gspca_dev, 0x40,  1, 0x0040, 0x0000,  0, NULL);
511
512         ctrl_out(gspca_dev, 0x40,  1, 0x0010, 0x0010,  0, NULL);
513         ctrl_out(gspca_dev, 0x40,  1, 0x0003, 0x00c1,  0, NULL);
514         ctrl_out(gspca_dev, 0x40,  1, 0x0042, 0x00c2,  0, NULL);
515         ctrl_out(gspca_dev, 0x40,  1, 0x006a, 0x000d,  0, NULL);
516
517         switch (reso) {
518         case IMAGE_640:
519         case IMAGE_800:
520                 if (reso != IMAGE_800)
521                         ctrl_out(gspca_dev, 0x40,  3, 0x0000, 0x0200,
522                                 12, dat_640);
523                 else
524                         ctrl_out(gspca_dev, 0x40,  3, 0x0000, 0x0200,
525                                 12, dat_800);
526
527                 if (_MI2020c_)
528                         fetch_idxdata(gspca_dev, tbl_init_post_alt_low_a,
529                                         ARRAY_SIZE(tbl_init_post_alt_low_a));
530
531                 if (reso == IMAGE_800)
532                         fetch_idxdata(gspca_dev, tbl_init_post_alt_low_b,
533                                         ARRAY_SIZE(tbl_init_post_alt_low_b));
534
535                 fetch_idxdata(gspca_dev, tbl_init_post_alt_low_c,
536                                 ARRAY_SIZE(tbl_init_post_alt_low_c));
537
538                 if (_MI2020b_) {
539                         ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
540                         ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
541                         ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
542                         msleep(150);
543                 } else if (_MI2020c_) {
544                         ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL);
545                         ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
546                         ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
547                         msleep(120);
548                         ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
549                         msleep(30);
550                 } else if (_MI2020_) {
551                         ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
552                         ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
553                         ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
554                         msleep(120);
555                         ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
556                         msleep(30);
557                 }
558
559                 /* AC power frequency */
560                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq1);
561                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq2);
562                 msleep(20);
563                 /* backlight */
564                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
565                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
566                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
567                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
568                 /* at init time but not after */
569                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa2\x0c");
570                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x17");
571                 /* finish the backlight */
572                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
573                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
574                 msleep(5);/* " */
575
576                 if (_MI2020c_) {
577                         fetch_idxdata(gspca_dev, tbl_init_post_alt_low_d,
578                                         ARRAY_SIZE(tbl_init_post_alt_low_d));
579                 } else {
580                         ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, &c);
581                         msleep(14); /* 0xd8 */
582
583                         /* flip/mirror */
584                         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
585                                         3, dat_hvflip1);
586                         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
587                                         3, dat_hvflip2);
588                         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
589                                         3, dat_hvflip3);
590                         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
591                                         3, dat_hvflip4);
592                         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
593                                         3, dat_hvflip5);
594                         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
595                                         3, dat_hvflip6);
596                         msleep(21);
597                         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
598                                         3, dat_dummy1);
599                         msleep(5);
600                         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
601                                         3, dat_dummy1);
602                         msleep(5);
603                         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
604                                         3, dat_dummy1);
605                         msleep(5);
606                         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
607                                         3, dat_dummy1);
608                         msleep(5);
609                         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
610                                         3, dat_dummy1);
611                         msleep(5);
612                         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
613                                         3, dat_dummy1);
614                         /* end of flip/mirror main part */
615                         msleep(246); /* 146 */
616
617                         sd->nbIm = 0;
618                 }
619                 break;
620
621         case IMAGE_1280:
622         case IMAGE_1600:
623                 if (reso == IMAGE_1280) {
624                         ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
625                                         12, dat_1280);
626                         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
627                                         3, "\x8c\x27\x07");
628                         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
629                                         3, "\x90\x05\x04");
630                         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
631                                         3, "\x8c\x27\x09");
632                         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
633                                         3, "\x90\x04\x02");
634                 } else {
635                         ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
636                                         12, dat_1600);
637                         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
638                                         3, "\x8c\x27\x07");
639                         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
640                                         3, "\x90\x06\x40");
641                         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
642                                         3, "\x8c\x27\x09");
643                         ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
644                                         3, "\x90\x04\xb0");
645                 }
646
647                 fetch_idxdata(gspca_dev, tbl_init_post_alt_big_a,
648                                 ARRAY_SIZE(tbl_init_post_alt_big_a));
649
650                 if (reso == IMAGE_1600)
651                         msleep(13); /* 1600 */
652                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\x27\x97");
653                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x01\x00");
654                 msleep(53);
655                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x20");
656                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x00");
657                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
658                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x01");
659                 if (reso == IMAGE_1600)
660                         msleep(13); /* 1600 */
661                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa7\x02");
662                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x00");
663                 msleep(53);
664                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x20");
665                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x72");
666                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
667                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x02");
668                 if (reso == IMAGE_1600)
669                         msleep(13); /* 1600 */
670                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa7\x02");
671                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x01");
672                 msleep(53);
673
674                 if (_MI2020b_) {
675                         ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
676                         if (reso == IMAGE_1600)
677                                 msleep(500); /* 1600 */
678                         ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
679                         ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
680                         msleep(1850);
681                 } else if (_MI2020c_ || _MI2020_) {
682                         ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
683                         ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
684                         ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
685                         msleep(1850);
686                         ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
687                         msleep(30);
688                 }
689
690                 /* AC power frequency */
691                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq1);
692                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq2);
693                 msleep(20);
694                 /* backlight */
695                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
696                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
697                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
698                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
699                 /* at init time but not after */
700                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa2\x0c");
701                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x17");
702                 /* finish the backlight */
703                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
704                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
705                 msleep(6); /* " */
706
707                 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, &c);
708                 msleep(14);
709
710                 if (_MI2020c_)
711                         fetch_idxdata(gspca_dev, tbl_init_post_alt_big_b,
712                                         ARRAY_SIZE(tbl_init_post_alt_big_b));
713
714                 /* flip/mirror */
715                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1);
716                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip2);
717                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip3);
718                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip4);
719                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip5);
720                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip6);
721                 /* end of flip/mirror main part */
722                 msleep(16);
723                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
724                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x01");
725                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x20");
726                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x00");
727                 if (reso == IMAGE_1600)
728                         msleep(25); /* 1600 */
729                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa7\x02");
730                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x00");
731                 msleep(103);
732                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
733                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x02");
734                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x20");
735                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x72");
736                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa7\x02");
737                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x01");
738                 sd->nbIm = 0;
739
740                 if (_MI2020c_)
741                         fetch_idxdata(gspca_dev, tbl_init_post_alt_big_c,
742                                         ARRAY_SIZE(tbl_init_post_alt_big_c));
743         }
744
745         sd->vold.mirror    = mirror;
746         sd->vold.flip      = flip;
747         sd->vold.AC50Hz    = freq;
748         sd->vold.backlight = backlight;
749
750         mi2020_camera_settings(gspca_dev);
751
752         return 0;
753 }
754
755 static int mi2020_configure_alt(struct gspca_dev *gspca_dev)
756 {
757         s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
758
759         switch (reso) {
760         case IMAGE_640:
761                 gspca_dev->alt = 3 + 1;
762                 break;
763
764         case IMAGE_800:
765         case IMAGE_1280:
766         case IMAGE_1600:
767                 gspca_dev->alt = 1 + 1;
768                 break;
769         }
770         return 0;
771 }
772
773 int mi2020_camera_settings(struct gspca_dev *gspca_dev)
774 {
775         struct sd *sd = (struct sd *) gspca_dev;
776
777         s32 backlight = sd->vcur.backlight;
778         s32 bright =  sd->vcur.brightness;
779         s32 sharp  =  sd->vcur.sharpness;
780         s32 cntr   =  sd->vcur.contrast;
781         s32 gam    =  sd->vcur.gamma;
782         s32 hue    = (sd->vcur.hue > 0);
783         s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0);
784         s32 flip   = (((sd->vcur.flip   > 0) ^ sd->mirrorMask) > 0);
785         s32 freq   = (sd->vcur.AC50Hz > 0);
786
787         u8 dat_sharp[] = {0x6c, 0x00, 0x08};
788         u8 dat_bright2[] = {0x90, 0x00, 0x00};
789         u8 dat_freq2[] = {0x90, 0x00, 0x80};
790         u8 dat_multi1[] = {0x8c, 0xa7, 0x00};
791         u8 dat_multi2[] = {0x90, 0x00, 0x00};
792         u8 dat_multi3[] = {0x8c, 0xa7, 0x00};
793         u8 dat_multi4[] = {0x90, 0x00, 0x00};
794         u8 dat_hvflip2[] = {0x90, 0x04, 0x6c};
795         u8 dat_hvflip4[] = {0x90, 0x00, 0x24};
796
797         /* Less than 4 images received -> too early to set the settings */
798         if (sd->nbIm < 4) {
799                 sd->waitSet = 1;
800                 return 0;
801         }
802         sd->waitSet = 0;
803
804         if (freq != sd->vold.AC50Hz) {
805                 sd->vold.AC50Hz = freq;
806
807                 dat_freq2[2] = freq ? 0xc0 : 0x80;
808                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq1);
809                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq2);
810                 msleep(20);
811         }
812
813         if (mirror != sd->vold.mirror || flip != sd->vold.flip) {
814                 sd->vold.mirror = mirror;
815                 sd->vold.flip   = flip;
816
817                 dat_hvflip2[2] = 0x6c + 2 * (1 - flip) + (1 - mirror);
818                 dat_hvflip4[2] = 0x24 + 2 * (1 - flip) + (1 - mirror);
819                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1);
820                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip2);
821                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip3);
822                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip4);
823                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip5);
824                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip6);
825                 msleep(130);
826                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
827                 msleep(6);
828                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
829                 msleep(6);
830                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
831                 msleep(6);
832                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
833                 msleep(6);
834                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
835                 msleep(6);
836                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
837                 msleep(6);
838
839                 /* Sometimes present, sometimes not, useful? */
840                 /* ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy2);
841                  * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy3);
842                  * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy2);
843                  * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy3);
844                  * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy2);
845                  * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy3);
846                  * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy2);
847                  * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy3);*/
848         }
849
850         if (backlight != sd->vold.backlight) {
851                 sd->vold.backlight = backlight;
852                 if (backlight < 0 || backlight > sd->vmax.backlight)
853                         backlight = 0;
854
855                 dat_multi1[2] = 0x9d;
856                 dat_multi3[2] = dat_multi1[2] + 1;
857                 dat_multi4[2] = dat_multi2[2] = backlight;
858                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
859                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
860                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
861                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
862                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
863                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
864         }
865
866         if (gam != sd->vold.gamma) {
867                 sd->vold.gamma = gam;
868                 if (gam < 0 || gam > sd->vmax.gamma)
869                         gam = 0;
870
871                 dat_multi1[2] = 0x6d;
872                 dat_multi3[2] = dat_multi1[2] + 1;
873                 dat_multi4[2] = dat_multi2[2] = 0x40 + gam;
874                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
875                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
876                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
877                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
878                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
879                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
880         }
881
882         if (cntr != sd->vold.contrast) {
883                 sd->vold.contrast = cntr;
884                 if (cntr < 0 || cntr > sd->vmax.contrast)
885                         cntr = 0;
886
887                 dat_multi1[2] = 0x6d;
888                 dat_multi3[2] = dat_multi1[2] + 1;
889                 dat_multi4[2] = dat_multi2[2] = 0x12 + 16 * cntr;
890                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
891                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
892                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
893                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
894                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
895                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
896         }
897
898         if (bright != sd->vold.brightness) {
899                 sd->vold.brightness = bright;
900                 if (bright < 0 || bright > sd->vmax.brightness)
901                         bright = 0;
902
903                 dat_bright2[2] = bright;
904                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright1);
905                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright2);
906                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright3);
907                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright4);
908                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright5);
909                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright6);
910         }
911
912         if (sharp != sd->vold.sharpness) {
913                 sd->vold.sharpness = sharp;
914                 if (sharp < 0 || sharp > sd->vmax.sharpness)
915                         sharp = 0;
916
917                 dat_sharp[1] = sharp;
918                 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0032, 3, dat_sharp);
919         }
920
921         if (hue != sd->vold.hue) {
922                 sd->swapRB = hue;
923                 sd->vold.hue = hue;
924         }
925
926         return 0;
927 }
928
929 static void mi2020_post_unset_alt(struct gspca_dev *gspca_dev)
930 {
931         ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL);
932         msleep(20);
933         if (_MI2020c_ || _MI2020_)
934                 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0000, 0, NULL);
935         else
936                 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL);
937 }