diff options
Diffstat (limited to 'drivers/media/video/gspca/gl860/gl860-ov2640.c')
-rw-r--r-- | drivers/media/video/gspca/gl860/gl860-ov2640.c | 505 |
1 files changed, 505 insertions, 0 deletions
diff --git a/drivers/media/video/gspca/gl860/gl860-ov2640.c b/drivers/media/video/gspca/gl860/gl860-ov2640.c new file mode 100644 index 000000000000..14b9c373f9f7 --- /dev/null +++ b/drivers/media/video/gspca/gl860/gl860-ov2640.c | |||
@@ -0,0 +1,505 @@ | |||
1 | /* @file gl860-ov2640.c | ||
2 | * @author Olivier LORIN, from Malmostoso's logs | ||
3 | * @date 2009-08-27 | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | /* Sensor : OV2640 */ | ||
20 | |||
21 | #include "gl860.h" | ||
22 | |||
23 | static u8 dat_init1[] = "\x00\x41\x07\x6a\x06\x61\x0d\x6a" "\x10\x10\xc1\x01"; | ||
24 | static u8 dat_init2[] = {0x61}; /* expected */ | ||
25 | static u8 dat_init3[] = {0x51}; /* expected */ | ||
26 | |||
27 | static u8 dat_post[] = | ||
28 | "\x00\x41\x07\x6a\x06\xef\x0d\x6a" "\x10\x10\xc1\x01"; | ||
29 | |||
30 | static u8 dat_640[] = "\xd0\x01\xd1\x08\xd2\xe0\xd3\x02\xd4\x10\xd5\x81"; | ||
31 | static u8 dat_800[] = "\xd0\x01\xd1\x10\xd2\x58\xd3\x02\xd4\x18\xd5\x21"; | ||
32 | static u8 dat_1280[] = "\xd0\x01\xd1\x18\xd2\xc0\xd3\x02\xd4\x28\xd5\x01"; | ||
33 | static u8 dat_1600[] = "\xd0\x01\xd1\x20\xd2\xb0\xd3\x02\xd4\x30\xd5\x41"; | ||
34 | |||
35 | static u8 c50[] = {0x50}; /* expected */ | ||
36 | static u8 c28[] = {0x28}; /* expected */ | ||
37 | static u8 ca8[] = {0xa8}; /* expected */ | ||
38 | |||
39 | static struct validx tbl_init_at_startup[] = { | ||
40 | {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1}, | ||
41 | {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d}, | ||
42 | {0x0050, 0x0000}, {0x0041, 0x0000}, {0x006a, 0x0007}, {0x0061, 0x0006}, | ||
43 | {0x006a, 0x000d}, {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1}, | ||
44 | {0x0041, 0x00c2}, {0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058}, | ||
45 | {0x0041, 0x0000}, {0x0061, 0x0000}, | ||
46 | }; | ||
47 | |||
48 | static struct validx tbl_common[] = { | ||
49 | {0x6000, 0x00ff}, {0x60ff, 0x002c}, {0x60df, 0x002e}, {0x6001, 0x00ff}, | ||
50 | {0x6080, 0x0012}, {0x6000, 0x0000}, {0x6000, 0x0045}, {0x6000, 0x0010}, | ||
51 | {0x6035, 0x003c}, {0x6000, 0x0011}, {0x6028, 0x0004}, {0x60e5, 0x0013}, | ||
52 | {0x6088, 0x0014}, {0x600c, 0x002c}, {0x6078, 0x0033}, {0x60f7, 0x003b}, | ||
53 | {0x6000, 0x003e}, {0x6011, 0x0043}, {0x6010, 0x0016}, {0x6082, 0x0039}, | ||
54 | {0x6088, 0x0035}, {0x600a, 0x0022}, {0x6040, 0x0037}, {0x6000, 0x0023}, | ||
55 | {0x60a0, 0x0034}, {0x601a, 0x0036}, {0x6002, 0x0006}, {0x60c0, 0x0007}, | ||
56 | {0x60b7, 0x000d}, {0x6001, 0x000e}, {0x6000, 0x004c}, {0x6081, 0x004a}, | ||
57 | {0x6099, 0x0021}, {0x6002, 0x0009}, {0x603e, 0x0024}, {0x6034, 0x0025}, | ||
58 | {0x6081, 0x0026}, {0x6000, 0x0000}, {0x6000, 0x0045}, {0x6000, 0x0010}, | ||
59 | {0x6000, 0x005c}, {0x6000, 0x0063}, {0x6000, 0x007c}, {0x6070, 0x0061}, | ||
60 | {0x6080, 0x0062}, {0x6080, 0x0020}, {0x6030, 0x0028}, {0x6000, 0x006c}, | ||
61 | {0x6000, 0x006e}, {0x6002, 0x0070}, {0x6094, 0x0071}, {0x60c1, 0x0073}, | ||
62 | {0x6034, 0x003d}, {0x6057, 0x005a}, {0x60bb, 0x004f}, {0x609c, 0x0050}, | ||
63 | {0x6080, 0x006d}, {0x6002, 0x0039}, {0x6033, 0x003a}, {0x60f1, 0x003b}, | ||
64 | {0x6031, 0x003c}, {0x6000, 0x00ff}, {0x6014, 0x00e0}, {0x60ff, 0x0076}, | ||
65 | {0x60a0, 0x0033}, {0x6020, 0x0042}, {0x6018, 0x0043}, {0x6000, 0x004c}, | ||
66 | {0x60d0, 0x0087}, {0x600f, 0x0088}, {0x6003, 0x00d7}, {0x6010, 0x00d9}, | ||
67 | {0x6005, 0x00da}, {0x6082, 0x00d3}, {0x60c0, 0x00f9}, {0x6006, 0x0044}, | ||
68 | {0x6007, 0x00d1}, {0x6002, 0x00d2}, {0x6000, 0x00d2}, {0x6011, 0x00d8}, | ||
69 | {0x6008, 0x00c8}, {0x6080, 0x00c9}, {0x6008, 0x007c}, {0x6020, 0x007d}, | ||
70 | {0x6020, 0x007d}, {0x6000, 0x0090}, {0x600e, 0x0091}, {0x601a, 0x0091}, | ||
71 | {0x6031, 0x0091}, {0x605a, 0x0091}, {0x6069, 0x0091}, {0x6075, 0x0091}, | ||
72 | {0x607e, 0x0091}, {0x6088, 0x0091}, {0x608f, 0x0091}, {0x6096, 0x0091}, | ||
73 | {0x60a3, 0x0091}, {0x60af, 0x0091}, {0x60c4, 0x0091}, {0x60d7, 0x0091}, | ||
74 | {0x60e8, 0x0091}, {0x6020, 0x0091}, {0x6000, 0x0092}, {0x6006, 0x0093}, | ||
75 | {0x60e3, 0x0093}, {0x6005, 0x0093}, {0x6005, 0x0093}, {0x6000, 0x0093}, | ||
76 | {0x6004, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093}, | ||
77 | {0x6000, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093}, | ||
78 | {0x6000, 0x0096}, {0x6008, 0x0097}, {0x6019, 0x0097}, {0x6002, 0x0097}, | ||
79 | {0x600c, 0x0097}, {0x6024, 0x0097}, {0x6030, 0x0097}, {0x6028, 0x0097}, | ||
80 | {0x6026, 0x0097}, {0x6002, 0x0097}, {0x6098, 0x0097}, {0x6080, 0x0097}, | ||
81 | {0x6000, 0x0097}, {0x6000, 0x0097}, {0x60ed, 0x00c3}, {0x609a, 0x00c4}, | ||
82 | {0x6000, 0x00a4}, {0x6011, 0x00c5}, {0x6051, 0x00c6}, {0x6010, 0x00c7}, | ||
83 | {0x6066, 0x00b6}, {0x60a5, 0x00b8}, {0x6064, 0x00b7}, {0x607c, 0x00b9}, | ||
84 | {0x60af, 0x00b3}, {0x6097, 0x00b4}, {0x60ff, 0x00b5}, {0x60c5, 0x00b0}, | ||
85 | {0x6094, 0x00b1}, {0x600f, 0x00b2}, {0x605c, 0x00c4}, {0x6000, 0x00a8}, | ||
86 | {0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x601d, 0x0086}, {0x6000, 0x0050}, | ||
87 | {0x6090, 0x0051}, {0x6018, 0x0052}, {0x6000, 0x0053}, {0x6000, 0x0054}, | ||
88 | {0x6088, 0x0055}, {0x6000, 0x0057}, {0x6090, 0x005a}, {0x6018, 0x005b}, | ||
89 | {0x6005, 0x005c}, {0x60ed, 0x00c3}, {0x6000, 0x007f}, {0x6005, 0x00da}, | ||
90 | {0x601f, 0x00e5}, {0x6067, 0x00e1}, {0x6000, 0x00e0}, {0x60ff, 0x00dd}, | ||
91 | {0x6000, 0x0005}, {0x6001, 0x00ff}, {0x6000, 0x0000}, {0x6000, 0x0045}, | ||
92 | {0x6000, 0x0010}, | ||
93 | }; | ||
94 | |||
95 | static struct validx tbl_sensor_settings_common_a[] = { | ||
96 | {0x0041, 0x0000}, {0x006a, 0x0007}, {0x00ef, 0x0006}, {0x006a, 0x000d}, | ||
97 | {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1}, {0x0041, 0x00c2}, | ||
98 | {0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058}, {0x0041, 0x0000}, | ||
99 | {50, 0xffff}, | ||
100 | {0x0061, 0x0000}, | ||
101 | {0xffff, 0xffff}, | ||
102 | {0x6000, 0x00ff}, {0x6000, 0x007c}, {0x6007, 0x007d}, | ||
103 | {30, 0xffff}, | ||
104 | {0x0040, 0x0000}, | ||
105 | }; | ||
106 | |||
107 | static struct validx tbl_sensor_settings_common_b[] = { | ||
108 | {0x6001, 0x00ff}, {0x6038, 0x000c}, | ||
109 | {10, 0xffff}, | ||
110 | {0x6000, 0x0011}, | ||
111 | /* backlight=31/64 */ | ||
112 | {0x6001, 0x00ff}, {0x603e, 0x0024}, {0x6034, 0x0025}, | ||
113 | /* bright=0/256 */ | ||
114 | {0x6000, 0x00ff}, {0x6009, 0x007c}, {0x6000, 0x007d}, | ||
115 | /* wbal=64/128 */ | ||
116 | {0x6000, 0x00ff}, {0x6003, 0x007c}, {0x6040, 0x007d}, | ||
117 | /* cntr=0/256 */ | ||
118 | {0x6000, 0x00ff}, {0x6007, 0x007c}, {0x6000, 0x007d}, | ||
119 | /* sat=128/256 */ | ||
120 | {0x6000, 0x00ff}, {0x6001, 0x007c}, {0x6080, 0x007d}, | ||
121 | /* sharpness=0/32 */ | ||
122 | {0x6000, 0x00ff}, {0x6001, 0x0092}, {0x60c0, 0x0093}, | ||
123 | /* hue=0/256 */ | ||
124 | {0x6000, 0x00ff}, {0x6002, 0x007c}, {0x6000, 0x007d}, | ||
125 | /* gam=32/64 */ | ||
126 | {0x6000, 0x00ff}, {0x6008, 0x007c}, {0x6020, 0x007d}, | ||
127 | /* image right up */ | ||
128 | {0xffff, 0xffff}, | ||
129 | {15, 0xffff}, | ||
130 | {0x6001, 0x00ff}, {0x6000, 0x8004}, | ||
131 | {0xffff, 0xffff}, | ||
132 | {0x60a8, 0x0004}, | ||
133 | {15, 0xffff}, | ||
134 | {0x6001, 0x00ff}, {0x6000, 0x8004}, | ||
135 | {0xffff, 0xffff}, | ||
136 | {0x60f8, 0x0004}, | ||
137 | /* image right up */ | ||
138 | {0xffff, 0xffff}, | ||
139 | /* backlight=31/64 */ | ||
140 | {0x6001, 0x00ff}, {0x603e, 0x0024}, {0x6034, 0x0025}, | ||
141 | }; | ||
142 | |||
143 | static struct validx tbl_640[] = { | ||
144 | {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, {0x6067, 0x00e1}, | ||
145 | {0x6004, 0x00da}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, | ||
146 | {0x6001, 0x00ff}, {0x6000, 0x0012}, {0x6000, 0x0011}, {0x6011, 0x0017}, | ||
147 | {0x6075, 0x0018}, {0x6001, 0x0019}, {0x6097, 0x001a}, {0x6036, 0x0032}, | ||
148 | {0x60bb, 0x004f}, {0x6057, 0x005a}, {0x609c, 0x0050}, {0x6080, 0x006d}, | ||
149 | {0x6092, 0x0026}, {0x60ff, 0x0020}, {0x6000, 0x0027}, {0x6000, 0x00ff}, | ||
150 | {0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x6000, 0x008c}, {0x603d, 0x0086}, | ||
151 | {0x6089, 0x0050}, {0x6090, 0x0051}, {0x602c, 0x0052}, {0x6000, 0x0053}, | ||
152 | {0x6000, 0x0054}, {0x6088, 0x0055}, {0x6000, 0x0057}, {0x60a0, 0x005a}, | ||
153 | {0x6078, 0x005b}, {0x6000, 0x005c}, {0x6004, 0x00d3}, {0x6000, 0x00e0}, | ||
154 | {0x60ff, 0x00dd}, {0x60a1, 0x005a}, | ||
155 | }; | ||
156 | |||
157 | static struct validx tbl_800[] = { | ||
158 | {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, {0x6067, 0x00e1}, | ||
159 | {0x6004, 0x00da}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, | ||
160 | {0x6001, 0x00ff}, {0x6040, 0x0012}, {0x6000, 0x0011}, {0x6011, 0x0017}, | ||
161 | {0x6043, 0x0018}, {0x6000, 0x0019}, {0x604b, 0x001a}, {0x6009, 0x0032}, | ||
162 | {0x60ca, 0x004f}, {0x60a8, 0x0050}, {0x6000, 0x006d}, {0x6038, 0x003d}, | ||
163 | {0x60c8, 0x0035}, {0x6000, 0x0022}, {0x6092, 0x0026}, {0x60ff, 0x0020}, | ||
164 | {0x6000, 0x0027}, {0x6000, 0x00ff}, {0x6064, 0x00c0}, {0x604b, 0x00c1}, | ||
165 | {0x6000, 0x008c}, {0x601d, 0x0086}, {0x6082, 0x00d3}, {0x6000, 0x00e0}, | ||
166 | {0x60ff, 0x00dd}, {0x6020, 0x008c}, {0x6001, 0x00ff}, {0x6044, 0x0018}, | ||
167 | }; | ||
168 | |||
169 | static struct validx tbl_big_a[] = { | ||
170 | {0x0002, 0x00c1}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, | ||
171 | {0x6001, 0x00ff}, {0x6000, 0x0012}, {0x6000, 0x0000}, {0x6000, 0x0045}, | ||
172 | {0x6000, 0x0010}, {0x6000, 0x0011}, {0x6011, 0x0017}, {0x6075, 0x0018}, | ||
173 | {0x6001, 0x0019}, {0x6097, 0x001a}, {0x6036, 0x0032}, {0x60bb, 0x004f}, | ||
174 | {0x609c, 0x0050}, {0x6057, 0x005a}, {0x6080, 0x006d}, {0x6043, 0x000f}, | ||
175 | {0x608f, 0x0003}, {0x6005, 0x007c}, {0x6081, 0x0026}, {0x6000, 0x00ff}, | ||
176 | {0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x6000, 0x008c}, | ||
177 | }; | ||
178 | |||
179 | static struct validx tbl_big_b[] = { | ||
180 | {0x603d, 0x0086}, {0x6000, 0x0050}, {0x6090, 0x0051}, {0x602c, 0x0052}, | ||
181 | {0x6000, 0x0053}, {0x6000, 0x0054}, {0x6088, 0x0055}, {0x6000, 0x0057}, | ||
182 | {0x6040, 0x005a}, {0x60f0, 0x005b}, {0x6001, 0x005c}, {0x6082, 0x00d3}, | ||
183 | {0x6000, 0x008e}, | ||
184 | }; | ||
185 | |||
186 | static struct validx tbl_big_c[] = { | ||
187 | {0x6004, 0x00da}, {0x6000, 0x00e0}, {0x6067, 0x00e1}, {0x60ff, 0x00dd}, | ||
188 | {0x6001, 0x00ff}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, | ||
189 | {0x6001, 0x00ff}, {0x6000, 0x0011}, {0x6000, 0x00ff}, {0x6010, 0x00c7}, | ||
190 | {0x6000, 0x0092}, {0x6006, 0x0093}, {0x60e3, 0x0093}, {0x6005, 0x0093}, | ||
191 | {0x6005, 0x0093}, {0x60ed, 0x00c3}, {0x6000, 0x00a4}, {0x60d0, 0x0087}, | ||
192 | {0x6003, 0x0096}, {0x600c, 0x0097}, {0x6024, 0x0097}, {0x6030, 0x0097}, | ||
193 | {0x6028, 0x0097}, {0x6026, 0x0097}, {0x6002, 0x0097}, {0x6001, 0x00ff}, | ||
194 | {0x6043, 0x000f}, {0x608f, 0x0003}, {0x6000, 0x002d}, {0x6000, 0x002e}, | ||
195 | {0x600a, 0x0022}, {0x6002, 0x0070}, {0x6008, 0x0014}, {0x6048, 0x0014}, | ||
196 | {0x6000, 0x00ff}, {0x6000, 0x00e0}, {0x60ff, 0x00dd}, | ||
197 | }; | ||
198 | |||
199 | static struct validx tbl_post_unset_alt[] = { | ||
200 | {0x006a, 0x000d}, {0x6001, 0x00ff}, {0x6081, 0x0026}, {0x6000, 0x0000}, | ||
201 | {0x6000, 0x0045}, {0x6000, 0x0010}, {0x6068, 0x000d}, | ||
202 | {50, 0xffff}, | ||
203 | {0x0021, 0x0000}, | ||
204 | }; | ||
205 | |||
206 | static int ov2640_init_at_startup(struct gspca_dev *gspca_dev); | ||
207 | static int ov2640_configure_alt(struct gspca_dev *gspca_dev); | ||
208 | static int ov2640_init_pre_alt(struct gspca_dev *gspca_dev); | ||
209 | static int ov2640_init_post_alt(struct gspca_dev *gspca_dev); | ||
210 | static void ov2640_post_unset_alt(struct gspca_dev *gspca_dev); | ||
211 | static int ov2640_camera_settings(struct gspca_dev *gspca_dev); | ||
212 | /*==========================================================================*/ | ||
213 | |||
214 | void ov2640_init_settings(struct gspca_dev *gspca_dev) | ||
215 | { | ||
216 | struct sd *sd = (struct sd *) gspca_dev; | ||
217 | |||
218 | sd->vcur.backlight = 32; | ||
219 | sd->vcur.brightness = 0; | ||
220 | sd->vcur.sharpness = 6; | ||
221 | sd->vcur.contrast = 0; | ||
222 | sd->vcur.gamma = 32; | ||
223 | sd->vcur.hue = 0; | ||
224 | sd->vcur.saturation = 128; | ||
225 | sd->vcur.whitebal = 64; | ||
226 | |||
227 | sd->vmax.backlight = 64; | ||
228 | sd->vmax.brightness = 255; | ||
229 | sd->vmax.sharpness = 31; | ||
230 | sd->vmax.contrast = 255; | ||
231 | sd->vmax.gamma = 64; | ||
232 | sd->vmax.hue = 255 + 1; | ||
233 | sd->vmax.saturation = 255; | ||
234 | sd->vmax.whitebal = 128; | ||
235 | sd->vmax.mirror = 0; | ||
236 | sd->vmax.flip = 0; | ||
237 | sd->vmax.AC50Hz = 0; | ||
238 | |||
239 | sd->dev_camera_settings = ov2640_camera_settings; | ||
240 | sd->dev_init_at_startup = ov2640_init_at_startup; | ||
241 | sd->dev_configure_alt = ov2640_configure_alt; | ||
242 | sd->dev_init_pre_alt = ov2640_init_pre_alt; | ||
243 | sd->dev_post_unset_alt = ov2640_post_unset_alt; | ||
244 | } | ||
245 | |||
246 | /*==========================================================================*/ | ||
247 | |||
248 | static void common(struct gspca_dev *gspca_dev) | ||
249 | { | ||
250 | fetch_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common)); | ||
251 | } | ||
252 | |||
253 | static int ov2640_init_at_startup(struct gspca_dev *gspca_dev) | ||
254 | { | ||
255 | fetch_validx(gspca_dev, tbl_init_at_startup, | ||
256 | ARRAY_SIZE(tbl_init_at_startup)); | ||
257 | |||
258 | ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_init1); | ||
259 | |||
260 | common(gspca_dev); | ||
261 | |||
262 | ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0006, 1, dat_init2); | ||
263 | |||
264 | ctrl_out(gspca_dev, 0x40, 1, 0x00ef, 0x0006, 0, NULL); | ||
265 | |||
266 | ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, dat_init3); | ||
267 | |||
268 | ctrl_out(gspca_dev, 0x40, 1, 0x0051, 0x0000, 0, NULL); | ||
269 | /* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */ | ||
270 | |||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | static int ov2640_init_pre_alt(struct gspca_dev *gspca_dev) | ||
275 | { | ||
276 | struct sd *sd = (struct sd *) gspca_dev; | ||
277 | |||
278 | sd->vold.backlight = -1; | ||
279 | sd->vold.brightness = -1; | ||
280 | sd->vold.sharpness = -1; | ||
281 | sd->vold.contrast = -1; | ||
282 | sd->vold.saturation = -1; | ||
283 | sd->vold.gamma = -1; | ||
284 | sd->vold.hue = -1; | ||
285 | sd->vold.whitebal = -1; | ||
286 | |||
287 | ov2640_init_post_alt(gspca_dev); | ||
288 | |||
289 | return 0; | ||
290 | } | ||
291 | |||
292 | static int ov2640_init_post_alt(struct gspca_dev *gspca_dev) | ||
293 | { | ||
294 | s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; | ||
295 | s32 n; /* reserved for FETCH macros */ | ||
296 | |||
297 | ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL); | ||
298 | |||
299 | n = fetch_validx(gspca_dev, tbl_sensor_settings_common_a, | ||
300 | ARRAY_SIZE(tbl_sensor_settings_common_a)); | ||
301 | ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_post); | ||
302 | common(gspca_dev); | ||
303 | keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_a, | ||
304 | ARRAY_SIZE(tbl_sensor_settings_common_a), n); | ||
305 | |||
306 | switch (reso) { | ||
307 | case IMAGE_640: | ||
308 | n = fetch_validx(gspca_dev, tbl_640, ARRAY_SIZE(tbl_640)); | ||
309 | ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_640); | ||
310 | break; | ||
311 | |||
312 | case IMAGE_800: | ||
313 | n = fetch_validx(gspca_dev, tbl_800, ARRAY_SIZE(tbl_800)); | ||
314 | ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_800); | ||
315 | break; | ||
316 | |||
317 | case IMAGE_1600: | ||
318 | case IMAGE_1280: | ||
319 | n = fetch_validx(gspca_dev, tbl_big_a, ARRAY_SIZE(tbl_big_a)); | ||
320 | |||
321 | if (reso == IMAGE_1280) { | ||
322 | n = fetch_validx(gspca_dev, tbl_big_b, | ||
323 | ARRAY_SIZE(tbl_big_b)); | ||
324 | } else { | ||
325 | ctrl_out(gspca_dev, 0x40, 1, 0x601d, 0x0086, 0, NULL); | ||
326 | ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00d7, 0, NULL); | ||
327 | ctrl_out(gspca_dev, 0x40, 1, 0x6082, 0x00d3, 0, NULL); | ||
328 | } | ||
329 | |||
330 | n = fetch_validx(gspca_dev, tbl_big_c, ARRAY_SIZE(tbl_big_c)); | ||
331 | |||
332 | if (reso == IMAGE_1280) { | ||
333 | ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL); | ||
334 | ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, | ||
335 | 12, dat_1280); | ||
336 | } else { | ||
337 | ctrl_out(gspca_dev, 0x40, 1, 0x6020, 0x008c, 0, NULL); | ||
338 | ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL); | ||
339 | ctrl_out(gspca_dev, 0x40, 1, 0x6076, 0x0018, 0, NULL); | ||
340 | ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, | ||
341 | 12, dat_1600); | ||
342 | } | ||
343 | break; | ||
344 | } | ||
345 | |||
346 | n = fetch_validx(gspca_dev, tbl_sensor_settings_common_b, | ||
347 | ARRAY_SIZE(tbl_sensor_settings_common_b)); | ||
348 | ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50); | ||
349 | keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b, | ||
350 | ARRAY_SIZE(tbl_sensor_settings_common_b), n); | ||
351 | ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, c28); | ||
352 | keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b, | ||
353 | ARRAY_SIZE(tbl_sensor_settings_common_b), n); | ||
354 | ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, ca8); | ||
355 | keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b, | ||
356 | ARRAY_SIZE(tbl_sensor_settings_common_b), n); | ||
357 | ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50); | ||
358 | keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b, | ||
359 | ARRAY_SIZE(tbl_sensor_settings_common_b), n); | ||
360 | |||
361 | ov2640_camera_settings(gspca_dev); | ||
362 | |||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | static int ov2640_configure_alt(struct gspca_dev *gspca_dev) | ||
367 | { | ||
368 | s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; | ||
369 | |||
370 | switch (reso) { | ||
371 | case IMAGE_640: | ||
372 | gspca_dev->alt = 3 + 1; | ||
373 | break; | ||
374 | |||
375 | case IMAGE_800: | ||
376 | case IMAGE_1280: | ||
377 | case IMAGE_1600: | ||
378 | gspca_dev->alt = 1 + 1; | ||
379 | break; | ||
380 | } | ||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | static int ov2640_camera_settings(struct gspca_dev *gspca_dev) | ||
385 | { | ||
386 | struct sd *sd = (struct sd *) gspca_dev; | ||
387 | |||
388 | s32 backlight = sd->vcur.backlight; | ||
389 | s32 bright = sd->vcur.brightness; | ||
390 | s32 sharp = sd->vcur.sharpness; | ||
391 | s32 gam = sd->vcur.gamma; | ||
392 | s32 cntr = sd->vcur.contrast; | ||
393 | s32 sat = sd->vcur.saturation; | ||
394 | s32 hue = sd->vcur.hue; | ||
395 | s32 wbal = sd->vcur.whitebal; | ||
396 | |||
397 | if (backlight != sd->vold.backlight) { | ||
398 | if (backlight < 0 || backlight > sd->vmax.backlight) | ||
399 | backlight = 0; | ||
400 | |||
401 | ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff, | ||
402 | 0, NULL); | ||
403 | ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight , 0x0024, | ||
404 | 0, NULL); | ||
405 | ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight - 10, 0x0025, | ||
406 | 0, NULL); | ||
407 | /* No sd->vold.backlight=backlight; (to be done again later) */ | ||
408 | } | ||
409 | |||
410 | if (bright != sd->vold.brightness) { | ||
411 | sd->vold.brightness = bright; | ||
412 | if (bright < 0 || bright > sd->vmax.brightness) | ||
413 | bright = 0; | ||
414 | |||
415 | ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL); | ||
416 | ctrl_out(gspca_dev, 0x40, 1, 0x6009 , 0x007c, 0, NULL); | ||
417 | ctrl_out(gspca_dev, 0x40, 1, 0x6000 + bright, 0x007d, 0, NULL); | ||
418 | } | ||
419 | |||
420 | if (wbal != sd->vold.whitebal) { | ||
421 | sd->vold.whitebal = wbal; | ||
422 | if (wbal < 0 || wbal > sd->vmax.whitebal) | ||
423 | wbal = 0; | ||
424 | |||
425 | ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL); | ||
426 | ctrl_out(gspca_dev, 0x40, 1, 0x6003 , 0x007c, 0, NULL); | ||
427 | ctrl_out(gspca_dev, 0x40, 1, 0x6000 + wbal, 0x007d, 0, NULL); | ||
428 | } | ||
429 | |||
430 | if (cntr != sd->vold.contrast) { | ||
431 | sd->vold.contrast = cntr; | ||
432 | if (cntr < 0 || cntr > sd->vmax.contrast) | ||
433 | cntr = 0; | ||
434 | |||
435 | ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL); | ||
436 | ctrl_out(gspca_dev, 0x40, 1, 0x6007 , 0x007c, 0, NULL); | ||
437 | ctrl_out(gspca_dev, 0x40, 1, 0x6000 + cntr, 0x007d, 0, NULL); | ||
438 | } | ||
439 | |||
440 | if (sat != sd->vold.saturation) { | ||
441 | sd->vold.saturation = sat; | ||
442 | if (sat < 0 || sat > sd->vmax.saturation) | ||
443 | sat = 0; | ||
444 | |||
445 | ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL); | ||
446 | ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x007c, 0, NULL); | ||
447 | ctrl_out(gspca_dev, 0x40, 1, 0x6000 + sat, 0x007d, 0, NULL); | ||
448 | } | ||
449 | |||
450 | if (sharp != sd->vold.sharpness) { | ||
451 | sd->vold.sharpness = sharp; | ||
452 | if (sharp < 0 || sharp > sd->vmax.sharpness) | ||
453 | sharp = 0; | ||
454 | |||
455 | ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL); | ||
456 | ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x0092, 0, NULL); | ||
457 | ctrl_out(gspca_dev, 0x40, 1, 0x60c0 + sharp, 0x0093, 0, NULL); | ||
458 | } | ||
459 | |||
460 | if (hue != sd->vold.hue) { | ||
461 | sd->vold.hue = hue; | ||
462 | if (hue < 0 || hue > sd->vmax.hue) | ||
463 | hue = 0; | ||
464 | |||
465 | ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL); | ||
466 | ctrl_out(gspca_dev, 0x40, 1, 0x6002 , 0x007c, 0, NULL); | ||
467 | ctrl_out(gspca_dev, 0x40, 1, 0x6000 + hue * (hue < 255), 0x007d, | ||
468 | 0, NULL); | ||
469 | if (hue >= sd->vmax.hue) | ||
470 | sd->swapRB = 1; | ||
471 | else | ||
472 | sd->swapRB = 0; | ||
473 | } | ||
474 | |||
475 | if (gam != sd->vold.gamma) { | ||
476 | sd->vold.gamma = gam; | ||
477 | if (gam < 0 || gam > sd->vmax.gamma) | ||
478 | gam = 0; | ||
479 | |||
480 | ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL); | ||
481 | ctrl_out(gspca_dev, 0x40, 1, 0x6008 , 0x007c, 0, NULL); | ||
482 | ctrl_out(gspca_dev, 0x40, 1, 0x6000 + gam, 0x007d, 0, NULL); | ||
483 | } | ||
484 | |||
485 | if (backlight != sd->vold.backlight) { | ||
486 | sd->vold.backlight = backlight; | ||
487 | |||
488 | ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff, | ||
489 | 0, NULL); | ||
490 | ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight , 0x0024, | ||
491 | 0, NULL); | ||
492 | ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight - 10, 0x0025, | ||
493 | 0, NULL); | ||
494 | } | ||
495 | |||
496 | return 0; | ||
497 | } | ||
498 | |||
499 | static void ov2640_post_unset_alt(struct gspca_dev *gspca_dev) | ||
500 | { | ||
501 | ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL); | ||
502 | msleep(20); | ||
503 | fetch_validx(gspca_dev, tbl_post_unset_alt, | ||
504 | ARRAY_SIZE(tbl_post_unset_alt)); | ||
505 | } | ||