Version:  2.0.40 2.2.26 2.4.37 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16

Linux/drivers/media/usb/gspca/t613.c

  1 /*
  2  * T613 subdriver
  3  *
  4  * Copyright (C) 2010 Jean-Francois Moine (http://moinejf.free.fr)
  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, write to the Free Software
 18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 19  *
 20  *Notes: * t613  + tas5130A
 21  *      * Focus to light do not balance well as in win.
 22  *        Quality in win is not good, but its kinda better.
 23  *       * Fix some "extraneous bytes", most of apps will show the image anyway
 24  *       * Gamma table, is there, but its really doing something?
 25  *       * 7~8 Fps, its ok, max on win its 10.
 26  *                      Costantino Leandro
 27  */
 28 
 29 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 30 
 31 #define MODULE_NAME "t613"
 32 
 33 #include <linux/input.h>
 34 #include <linux/slab.h>
 35 #include "gspca.h"
 36 
 37 MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
 38 MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
 39 MODULE_LICENSE("GPL");
 40 
 41 struct sd {
 42         struct gspca_dev gspca_dev;     /* !! must be the first item */
 43         struct v4l2_ctrl *freq;
 44         struct { /* awb / color gains control cluster */
 45                 struct v4l2_ctrl *awb;
 46                 struct v4l2_ctrl *gain;
 47                 struct v4l2_ctrl *red_balance;
 48                 struct v4l2_ctrl *blue_balance;
 49         };
 50 
 51         u8 sensor;
 52         u8 button_pressed;
 53 };
 54 enum sensors {
 55         SENSOR_OM6802,
 56         SENSOR_OTHER,
 57         SENSOR_TAS5130A,
 58         SENSOR_LT168G,          /* must verify if this is the actual model */
 59 };
 60 
 61 static const struct v4l2_pix_format vga_mode_t16[] = {
 62         {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 63                 .bytesperline = 160,
 64                 .sizeimage = 160 * 120 * 4 / 8 + 590,
 65                 .colorspace = V4L2_COLORSPACE_JPEG,
 66                 .priv = 4},
 67 #if 0 /* HDG: broken with my test cam, so lets disable it */
 68         {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 69                 .bytesperline = 176,
 70                 .sizeimage = 176 * 144 * 3 / 8 + 590,
 71                 .colorspace = V4L2_COLORSPACE_JPEG,
 72                 .priv = 3},
 73 #endif
 74         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 75                 .bytesperline = 320,
 76                 .sizeimage = 320 * 240 * 3 / 8 + 590,
 77                 .colorspace = V4L2_COLORSPACE_JPEG,
 78                 .priv = 2},
 79 #if 0 /* HDG: broken with my test cam, so lets disable it */
 80         {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 81                 .bytesperline = 352,
 82                 .sizeimage = 352 * 288 * 3 / 8 + 590,
 83                 .colorspace = V4L2_COLORSPACE_JPEG,
 84                 .priv = 1},
 85 #endif
 86         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 87                 .bytesperline = 640,
 88                 .sizeimage = 640 * 480 * 3 / 8 + 590,
 89                 .colorspace = V4L2_COLORSPACE_JPEG,
 90                 .priv = 0},
 91 };
 92 
 93 /* sensor specific data */
 94 struct additional_sensor_data {
 95         const u8 n3[6];
 96         const u8 *n4, n4sz;
 97         const u8 reg80, reg8e;
 98         const u8 nset8[6];
 99         const u8 data1[10];
100         const u8 data2[9];
101         const u8 data3[9];
102         const u8 data5[6];
103         const u8 stream[4];
104 };
105 
106 static const u8 n4_om6802[] = {
107         0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
108         0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
109         0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
110         0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
111         0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
112         0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
113         0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
114         0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
115         0xac, 0x84, 0xad, 0x86, 0xaf, 0x46
116 };
117 static const u8 n4_other[] = {
118         0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69,
119         0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68,
120         0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8,
121         0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8,
122         0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56,
123         0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5,
124         0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0,
125         0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00
126 };
127 static const u8 n4_tas5130a[] = {
128         0x80, 0x3c, 0x81, 0x68, 0x83, 0xa0, 0x84, 0x20,
129         0x8a, 0x68, 0x8b, 0x58, 0x8c, 0x88, 0x8e, 0xb4,
130         0x8f, 0x24, 0xa1, 0xb1, 0xa2, 0x30, 0xa5, 0x10,
131         0xa6, 0x4a, 0xae, 0x03, 0xb1, 0x44, 0xb2, 0x08,
132         0xb7, 0x06, 0xb9, 0xe7, 0xbb, 0xc4, 0xbc, 0x4a,
133         0xbe, 0x36, 0xbf, 0xff, 0xc2, 0x88, 0xc5, 0xc8,
134         0xc6, 0xda
135 };
136 static const u8 n4_lt168g[] = {
137         0x66, 0x01, 0x7f, 0x00, 0x80, 0x7c, 0x81, 0x28,
138         0x83, 0x44, 0x84, 0x20, 0x86, 0x20, 0x8a, 0x70,
139         0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xa0, 0x8e, 0xb3,
140         0x8f, 0x24, 0xa1, 0xb0, 0xa2, 0x38, 0xa5, 0x20,
141         0xa6, 0x4a, 0xa8, 0xe8, 0xaf, 0x38, 0xb0, 0x68,
142         0xb1, 0x44, 0xb2, 0x88, 0xbb, 0x86, 0xbd, 0x40,
143         0xbe, 0x26, 0xc1, 0x05, 0xc2, 0x88, 0xc5, 0xc0,
144         0xda, 0x8e, 0xdb, 0xca, 0xdc, 0xa8, 0xdd, 0x8c,
145         0xde, 0x44, 0xdf, 0x0c, 0xe9, 0x80
146 };
147 
148 static const struct additional_sensor_data sensor_data[] = {
149 [SENSOR_OM6802] = {
150         .n3 =
151                 {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04},
152         .n4 = n4_om6802,
153         .n4sz = sizeof n4_om6802,
154         .reg80 = 0x3c,
155         .reg8e = 0x33,
156         .nset8 = {0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00},
157         .data1 =
158                 {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
159                  0xb3, 0xfc},
160         .data2 =
161                 {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
162                  0xff},
163         .data3 =
164                 {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
165                  0xff},
166         .data5 =        /* this could be removed later */
167                 {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
168         .stream =
169                 {0x0b, 0x04, 0x0a, 0x78},
170     },
171 [SENSOR_OTHER] = {
172         .n3 =
173                 {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00},
174         .n4 = n4_other,
175         .n4sz = sizeof n4_other,
176         .reg80 = 0xac,
177         .reg8e = 0xb8,
178         .nset8 = {0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00},
179         .data1 =
180                 {0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a,
181                  0xe8, 0xfc},
182         .data2 =
183                 {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
184                  0xd9},
185         .data3 =
186                 {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
187                  0xd9},
188         .data5 =
189                 {0x0c, 0x03, 0xab, 0x29, 0x81, 0x69},
190         .stream =
191                 {0x0b, 0x04, 0x0a, 0x00},
192     },
193 [SENSOR_TAS5130A] = {
194         .n3 =
195                 {0x61, 0xc2, 0x65, 0x0d, 0x60, 0x08},
196         .n4 = n4_tas5130a,
197         .n4sz = sizeof n4_tas5130a,
198         .reg80 = 0x3c,
199         .reg8e = 0xb4,
200         .nset8 = {0xa8, 0xf0, 0xc6, 0xda, 0xc0, 0x00},
201         .data1 =
202                 {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
203                  0xc8, 0xfc},
204         .data2 =
205                 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
206                  0xe0},
207         .data3 =
208                 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
209                  0xe0},
210         .data5 =
211                 {0x0c, 0x03, 0xab, 0x10, 0x81, 0x20},
212         .stream =
213                 {0x0b, 0x04, 0x0a, 0x40},
214     },
215 [SENSOR_LT168G] = {
216         .n3 = {0x61, 0xc2, 0x65, 0x68, 0x60, 0x00},
217         .n4 = n4_lt168g,
218         .n4sz = sizeof n4_lt168g,
219         .reg80 = 0x7c,
220         .reg8e = 0xb3,
221         .nset8 = {0xa8, 0xf0, 0xc6, 0xba, 0xc0, 0x00},
222         .data1 = {0xc0, 0x38, 0x08, 0x10, 0xc0, 0x30, 0x10, 0x40,
223                  0xb0, 0xf4},
224         .data2 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
225                  0xff},
226         .data3 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
227                  0xff},
228         .data5 = {0x0c, 0x03, 0xab, 0x4b, 0x81, 0x2b},
229         .stream = {0x0b, 0x04, 0x0a, 0x28},
230     },
231 };
232 
233 #define MAX_EFFECTS 7
234 static const u8 effects_table[MAX_EFFECTS][6] = {
235         {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00},   /* Normal */
236         {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04},   /* Repujar */
237         {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20},   /* Monochrome */
238         {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80},   /* Sepia */
239         {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02},   /* Croquis */
240         {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10},   /* Sun Effect */
241         {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40},   /* Negative */
242 };
243 
244 #define GAMMA_MAX (15)
245 static const u8 gamma_table[GAMMA_MAX+1][17] = {
246 /* gamma table from cam1690.ini */
247         {0x00, 0x00, 0x01, 0x04, 0x08, 0x0e, 0x16, 0x21,        /* 0 */
248          0x2e, 0x3d, 0x50, 0x65, 0x7d, 0x99, 0xb8, 0xdb,
249          0xff},
250         {0x00, 0x01, 0x03, 0x08, 0x0e, 0x16, 0x21, 0x2d,        /* 1 */
251          0x3c, 0x4d, 0x60, 0x75, 0x8d, 0xa6, 0xc2, 0xe1,
252          0xff},
253         {0x00, 0x01, 0x05, 0x0b, 0x12, 0x1c, 0x28, 0x35,        /* 2 */
254          0x45, 0x56, 0x69, 0x7e, 0x95, 0xad, 0xc7, 0xe3,
255          0xff},
256         {0x00, 0x02, 0x07, 0x0f, 0x18, 0x24, 0x30, 0x3f,        /* 3 */
257          0x4f, 0x61, 0x73, 0x88, 0x9d, 0xb4, 0xcd, 0xe6,
258          0xff},
259         {0x00, 0x04, 0x0b, 0x15, 0x20, 0x2d, 0x3b, 0x4a,        /* 4 */
260          0x5b, 0x6c, 0x7f, 0x92, 0xa7, 0xbc, 0xd2, 0xe9,
261          0xff},
262         {0x00, 0x07, 0x11, 0x15, 0x20, 0x2d, 0x48, 0x58,        /* 5 */
263          0x68, 0x79, 0x8b, 0x9d, 0xb0, 0xc4, 0xd7, 0xec,
264          0xff},
265         {0x00, 0x0c, 0x1a, 0x29, 0x38, 0x47, 0x57, 0x67,        /* 6 */
266          0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
267          0xff},
268         {0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,        /* 7 */
269          0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
270          0xff},
271         {0x00, 0x15, 0x27, 0x38, 0x49, 0x59, 0x69, 0x79,        /* 8 */
272          0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe2, 0xf0,
273          0xff},
274         {0x00, 0x1c, 0x30, 0x43, 0x54, 0x65, 0x75, 0x84,        /* 9 */
275          0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd8, 0xe5, 0xf2,
276          0xff},
277         {0x00, 0x24, 0x3b, 0x4f, 0x60, 0x70, 0x80, 0x8e,        /* 10 */
278          0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xdc, 0xe8, 0xf3,
279          0xff},
280         {0x00, 0x2a, 0x3c, 0x5d, 0x6e, 0x7e, 0x8d, 0x9b,        /* 11 */
281          0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
282          0xff},
283         {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8,        /* 12 */
284          0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6,
285          0xff},
286         {0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7,        /* 13 */
287          0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9,
288          0xff},
289         {0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6,        /* 14 */
290          0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa,
291          0xff},
292         {0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8,        /* 15 */
293          0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc,
294          0xff}
295 };
296 
297 static const u8 tas5130a_sensor_init[][8] = {
298         {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
299         {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
300         {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
301 };
302 
303 static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
304 
305 /* read 1 byte */
306 static u8 reg_r(struct gspca_dev *gspca_dev,
307                    u16 index)
308 {
309         usb_control_msg(gspca_dev->dev,
310                         usb_rcvctrlpipe(gspca_dev->dev, 0),
311                         0,              /* request */
312                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
313                         0,              /* value */
314                         index,
315                         gspca_dev->usb_buf, 1, 500);
316         return gspca_dev->usb_buf[0];
317 }
318 
319 static void reg_w(struct gspca_dev *gspca_dev,
320                   u16 index)
321 {
322         usb_control_msg(gspca_dev->dev,
323                         usb_sndctrlpipe(gspca_dev->dev, 0),
324                         0,
325                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
326                         0, index,
327                         NULL, 0, 500);
328 }
329 
330 static void reg_w_buf(struct gspca_dev *gspca_dev,
331                   const u8 *buffer, u16 len)
332 {
333         if (len <= USB_BUF_SZ) {
334                 memcpy(gspca_dev->usb_buf, buffer, len);
335                 usb_control_msg(gspca_dev->dev,
336                                 usb_sndctrlpipe(gspca_dev->dev, 0),
337                                 0,
338                            USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
339                                 0x01, 0,
340                                 gspca_dev->usb_buf, len, 500);
341         } else {
342                 u8 *tmpbuf;
343 
344                 tmpbuf = kmemdup(buffer, len, GFP_KERNEL);
345                 if (!tmpbuf) {
346                         pr_err("Out of memory\n");
347                         return;
348                 }
349                 usb_control_msg(gspca_dev->dev,
350                                 usb_sndctrlpipe(gspca_dev->dev, 0),
351                                 0,
352                            USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
353                                 0x01, 0,
354                                 tmpbuf, len, 500);
355                 kfree(tmpbuf);
356         }
357 }
358 
359 /* write values to consecutive registers */
360 static void reg_w_ixbuf(struct gspca_dev *gspca_dev,
361                         u8 reg,
362                         const u8 *buffer, u16 len)
363 {
364         int i;
365         u8 *p, *tmpbuf;
366 
367         if (len * 2 <= USB_BUF_SZ) {
368                 p = tmpbuf = gspca_dev->usb_buf;
369         } else {
370                 p = tmpbuf = kmalloc(len * 2, GFP_KERNEL);
371                 if (!tmpbuf) {
372                         pr_err("Out of memory\n");
373                         return;
374                 }
375         }
376         i = len;
377         while (--i >= 0) {
378                 *p++ = reg++;
379                 *p++ = *buffer++;
380         }
381         usb_control_msg(gspca_dev->dev,
382                         usb_sndctrlpipe(gspca_dev->dev, 0),
383                         0,
384                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
385                         0x01, 0,
386                         tmpbuf, len * 2, 500);
387         if (len * 2 > USB_BUF_SZ)
388                 kfree(tmpbuf);
389 }
390 
391 static void om6802_sensor_init(struct gspca_dev *gspca_dev)
392 {
393         int i;
394         const u8 *p;
395         u8 byte;
396         u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
397         static const u8 sensor_init[] = {
398                 0xdf, 0x6d,
399                 0xdd, 0x18,
400                 0x5a, 0xe0,
401                 0x5c, 0x07,
402                 0x5d, 0xb0,
403                 0x5e, 0x1e,
404                 0x60, 0x71,
405                 0xef, 0x00,
406                 0xe9, 0x00,
407                 0xea, 0x00,
408                 0x90, 0x24,
409                 0x91, 0xb2,
410                 0x82, 0x32,
411                 0xfd, 0x41,
412                 0x00                    /* table end */
413         };
414 
415         reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
416         msleep(100);
417         i = 4;
418         while (--i > 0) {
419                 byte = reg_r(gspca_dev, 0x0060);
420                 if (!(byte & 0x01))
421                         break;
422                 msleep(100);
423         }
424         byte = reg_r(gspca_dev, 0x0063);
425         if (byte != 0x17) {
426                 pr_err("Bad sensor reset %02x\n", byte);
427                 /* continue? */
428         }
429 
430         p = sensor_init;
431         while (*p != 0) {
432                 val[1] = *p++;
433                 val[3] = *p++;
434                 if (*p == 0)
435                         reg_w(gspca_dev, 0x3c80);
436                 reg_w_buf(gspca_dev, val, sizeof val);
437                 i = 4;
438                 while (--i >= 0) {
439                         msleep(15);
440                         byte = reg_r(gspca_dev, 0x60);
441                         if (!(byte & 0x01))
442                                 break;
443                 }
444         }
445         msleep(15);
446         reg_w(gspca_dev, 0x3c80);
447 }
448 
449 /* this function is called at probe time */
450 static int sd_config(struct gspca_dev *gspca_dev,
451                      const struct usb_device_id *id)
452 {
453         struct cam *cam  = &gspca_dev->cam;
454 
455         cam->cam_mode = vga_mode_t16;
456         cam->nmodes = ARRAY_SIZE(vga_mode_t16);
457 
458         return 0;
459 }
460 
461 static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness)
462 {
463         u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
464 
465         if (brightness < 7) {
466                 set6[1] = 0x26;
467                 set6[3] = 0x70 - brightness * 0x10;
468         } else {
469                 set6[3] = 0x00 + ((brightness - 7) * 0x10);
470         }
471 
472         reg_w_buf(gspca_dev, set6, sizeof set6);
473 }
474 
475 static void setcontrast(struct gspca_dev *gspca_dev, s32 contrast)
476 {
477         u16 reg_to_write;
478 
479         if (contrast < 7)
480                 reg_to_write = 0x8ea9 - contrast * 0x200;
481         else
482                 reg_to_write = 0x00a9 + (contrast - 7) * 0x200;
483 
484         reg_w(gspca_dev, reg_to_write);
485 }
486 
487 static void setcolors(struct gspca_dev *gspca_dev, s32 val)
488 {
489         u16 reg_to_write;
490 
491         reg_to_write = 0x80bb + val * 0x100;    /* was 0xc0 */
492         reg_w(gspca_dev, reg_to_write);
493 }
494 
495 static void setgamma(struct gspca_dev *gspca_dev, s32 val)
496 {
497         PDEBUG(D_CONF, "Gamma: %d", val);
498         reg_w_ixbuf(gspca_dev, 0x90,
499                 gamma_table[val], sizeof gamma_table[0]);
500 }
501 
502 static void setawb_n_RGB(struct gspca_dev *gspca_dev)
503 {
504         struct sd *sd = (struct sd *) gspca_dev;
505         u8 all_gain_reg[8] = {
506                 0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x80, 0x00 };
507         s32 red_gain, blue_gain, green_gain;
508 
509         green_gain = sd->gain->val;
510 
511         red_gain = green_gain + sd->red_balance->val;
512         if (red_gain > 0x40)
513                 red_gain = 0x40;
514         else if (red_gain < 0x10)
515                 red_gain = 0x10;
516 
517         blue_gain = green_gain + sd->blue_balance->val;
518         if (blue_gain > 0x40)
519                 blue_gain = 0x40;
520         else if (blue_gain < 0x10)
521                 blue_gain = 0x10;
522 
523         all_gain_reg[1] = red_gain;
524         all_gain_reg[3] = blue_gain;
525         all_gain_reg[5] = green_gain;
526         all_gain_reg[7] = sensor_data[sd->sensor].reg80;
527         if (!sd->awb->val)
528                 all_gain_reg[7] &= ~0x04; /* AWB off */
529 
530         reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg);
531 }
532 
533 static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
534 {
535         u16 reg_to_write;
536 
537         reg_to_write = 0x0aa6 + 0x1000 * val;
538 
539         reg_w(gspca_dev, reg_to_write);
540 }
541 
542 static void setfreq(struct gspca_dev *gspca_dev, s32 val)
543 {
544         struct sd *sd = (struct sd *) gspca_dev;
545         u8 reg66;
546         u8 freq[4] = { 0x66, 0x00, 0xa8, 0xe8 };
547 
548         switch (sd->sensor) {
549         case SENSOR_LT168G:
550                 if (val != 0)
551                         freq[3] = 0xa8;
552                 reg66 = 0x41;
553                 break;
554         case SENSOR_OM6802:
555                 reg66 = 0xca;
556                 break;
557         default:
558                 reg66 = 0x40;
559                 break;
560         }
561         switch (val) {
562         case 0:                         /* no flicker */
563                 freq[3] = 0xf0;
564                 break;
565         case 2:                         /* 60Hz */
566                 reg66 &= ~0x40;
567                 break;
568         }
569         freq[1] = reg66;
570 
571         reg_w_buf(gspca_dev, freq, sizeof freq);
572 }
573 
574 /* this function is called at probe and resume time */
575 static int sd_init(struct gspca_dev *gspca_dev)
576 {
577         /* some of this registers are not really neded, because
578          * they are overriden by setbrigthness, setcontrast, etc,
579          * but wont hurt anyway, and can help someone with similar webcam
580          * to see the initial parameters.*/
581         struct sd *sd = (struct sd *) gspca_dev;
582         const struct additional_sensor_data *sensor;
583         int i;
584         u16 sensor_id;
585         u8 test_byte = 0;
586 
587         static const u8 read_indexs[] =
588                 { 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
589                   0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 };
590         static const u8 n1[] =
591                         {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
592         static const u8 n2[] =
593                         {0x08, 0x00};
594 
595         sensor_id = (reg_r(gspca_dev, 0x06) << 8)
596                         | reg_r(gspca_dev, 0x07);
597         switch (sensor_id & 0xff0f) {
598         case 0x0801:
599                 PDEBUG(D_PROBE, "sensor tas5130a");
600                 sd->sensor = SENSOR_TAS5130A;
601                 break;
602         case 0x0802:
603                 PDEBUG(D_PROBE, "sensor lt168g");
604                 sd->sensor = SENSOR_LT168G;
605                 break;
606         case 0x0803:
607                 PDEBUG(D_PROBE, "sensor 'other'");
608                 sd->sensor = SENSOR_OTHER;
609                 break;
610         case 0x0807:
611                 PDEBUG(D_PROBE, "sensor om6802");
612                 sd->sensor = SENSOR_OM6802;
613                 break;
614         default:
615                 pr_err("unknown sensor %04x\n", sensor_id);
616                 return -EINVAL;
617         }
618 
619         if (sd->sensor == SENSOR_OM6802) {
620                 reg_w_buf(gspca_dev, n1, sizeof n1);
621                 i = 5;
622                 while (--i >= 0) {
623                         reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
624                         test_byte = reg_r(gspca_dev, 0x0063);
625                         msleep(100);
626                         if (test_byte == 0x17)
627                                 break;          /* OK */
628                 }
629                 if (i < 0) {
630                         pr_err("Bad sensor reset %02x\n", test_byte);
631                         return -EIO;
632                 }
633                 reg_w_buf(gspca_dev, n2, sizeof n2);
634         }
635 
636         i = 0;
637         while (read_indexs[i] != 0x00) {
638                 test_byte = reg_r(gspca_dev, read_indexs[i]);
639                 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i],
640                        test_byte);
641                 i++;
642         }
643 
644         sensor = &sensor_data[sd->sensor];
645         reg_w_buf(gspca_dev, sensor->n3, sizeof sensor->n3);
646         reg_w_buf(gspca_dev, sensor->n4, sensor->n4sz);
647 
648         if (sd->sensor == SENSOR_LT168G) {
649                 test_byte = reg_r(gspca_dev, 0x80);
650                 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
651                        test_byte);
652                 reg_w(gspca_dev, 0x6c80);
653         }
654 
655         reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
656         reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
657         reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
658 
659         reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
660         reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
661         reg_w(gspca_dev, (sensor->reg8e << 8) + 0x8e);
662         reg_w(gspca_dev, (0x20 << 8) + 0x87);
663         reg_w(gspca_dev, (0x20 << 8) + 0x88);
664         reg_w(gspca_dev, (0x20 << 8) + 0x89);
665 
666         reg_w_buf(gspca_dev, sensor->data5, sizeof sensor->data5);
667         reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8);
668         reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
669 
670         if (sd->sensor == SENSOR_LT168G) {
671                 test_byte = reg_r(gspca_dev, 0x80);
672                 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
673                        test_byte);
674                 reg_w(gspca_dev, 0x6c80);
675         }
676 
677         reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
678         reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
679         reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
680 
681         return 0;
682 }
683 
684 static void setmirror(struct gspca_dev *gspca_dev, s32 val)
685 {
686         u8 hflipcmd[8] =
687                 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
688 
689         if (val)
690                 hflipcmd[3] = 0x01;
691 
692         reg_w_buf(gspca_dev, hflipcmd, sizeof hflipcmd);
693 }
694 
695 static void seteffect(struct gspca_dev *gspca_dev, s32 val)
696 {
697         int idx = 0;
698 
699         switch (val) {
700         case V4L2_COLORFX_NONE:
701                 break;
702         case V4L2_COLORFX_BW:
703                 idx = 2;
704                 break;
705         case V4L2_COLORFX_SEPIA:
706                 idx = 3;
707                 break;
708         case V4L2_COLORFX_SKETCH:
709                 idx = 4;
710                 break;
711         case V4L2_COLORFX_NEGATIVE:
712                 idx = 6;
713                 break;
714         default:
715                 break;
716         }
717 
718         reg_w_buf(gspca_dev, effects_table[idx],
719                                 sizeof effects_table[0]);
720 
721         if (val == V4L2_COLORFX_SKETCH)
722                 reg_w(gspca_dev, 0x4aa6);
723         else
724                 reg_w(gspca_dev, 0xfaa6);
725 }
726 
727 /* Is this really needed?
728  * i added some module parameters for test with some users */
729 static void poll_sensor(struct gspca_dev *gspca_dev)
730 {
731         static const u8 poll1[] =
732                 {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
733                  0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
734                  0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
735                  0x60, 0x14};
736         static const u8 poll2[] =
737                 {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
738                  0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
739         static const u8 noise03[] =     /* (some differences / ms-drv) */
740                 {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
741                  0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
742                  0xc2, 0x80, 0xc3, 0x10};
743 
744         PDEBUG(D_STREAM, "[Sensor requires polling]");
745         reg_w_buf(gspca_dev, poll1, sizeof poll1);
746         reg_w_buf(gspca_dev, poll2, sizeof poll2);
747         reg_w_buf(gspca_dev, noise03, sizeof noise03);
748 }
749 
750 static int sd_start(struct gspca_dev *gspca_dev)
751 {
752         struct sd *sd = (struct sd *) gspca_dev;
753         const struct additional_sensor_data *sensor;
754         int i, mode;
755         u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
756         static const u8 t3[] =
757                 { 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 };
758 
759         mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
760         switch (mode) {
761         case 0:         /* 640x480 (0x00) */
762                 break;
763         case 1:         /* 352x288 */
764                 t2[1] = 0x40;
765                 break;
766         case 2:         /* 320x240 */
767                 t2[1] = 0x10;
768                 break;
769         case 3:         /* 176x144 */
770                 t2[1] = 0x50;
771                 break;
772         default:
773 /*      case 4:          * 160x120 */
774                 t2[1] = 0x20;
775                 break;
776         }
777 
778         switch (sd->sensor) {
779         case SENSOR_OM6802:
780                 om6802_sensor_init(gspca_dev);
781                 break;
782         case SENSOR_TAS5130A:
783                 i = 0;
784                 for (;;) {
785                         reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
786                                          sizeof tas5130a_sensor_init[0]);
787                         if (i >= ARRAY_SIZE(tas5130a_sensor_init) - 1)
788                                 break;
789                         i++;
790                 }
791                 reg_w(gspca_dev, 0x3c80);
792                 /* just in case and to keep sync with logs (for mine) */
793                 reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
794                                  sizeof tas5130a_sensor_init[0]);
795                 reg_w(gspca_dev, 0x3c80);
796                 break;
797         }
798         sensor = &sensor_data[sd->sensor];
799         setfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->freq));
800         reg_r(gspca_dev, 0x0012);
801         reg_w_buf(gspca_dev, t2, sizeof t2);
802         reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3);
803         reg_w(gspca_dev, 0x0013);
804         msleep(15);
805         reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
806         reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
807 
808         if (sd->sensor == SENSOR_OM6802)
809                 poll_sensor(gspca_dev);
810 
811         return 0;
812 }
813 
814 static void sd_stopN(struct gspca_dev *gspca_dev)
815 {
816         struct sd *sd = (struct sd *) gspca_dev;
817 
818         reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
819                         sizeof sensor_data[sd->sensor].stream);
820         reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
821                         sizeof sensor_data[sd->sensor].stream);
822         if (sd->sensor == SENSOR_OM6802) {
823                 msleep(20);
824                 reg_w(gspca_dev, 0x0309);
825         }
826 #if IS_ENABLED(CONFIG_INPUT)
827         /* If the last button state is pressed, release it now! */
828         if (sd->button_pressed) {
829                 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
830                 input_sync(gspca_dev->input_dev);
831                 sd->button_pressed = 0;
832         }
833 #endif
834 }
835 
836 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
837                         u8 *data,                       /* isoc packet */
838                         int len)                        /* iso packet length */
839 {
840         struct sd *sd = (struct sd *) gspca_dev;
841         int pkt_type;
842 
843         if (data[0] == 0x5a) {
844 #if IS_ENABLED(CONFIG_INPUT)
845                 if (len > 20) {
846                         u8 state = (data[20] & 0x80) ? 1 : 0;
847                         if (sd->button_pressed != state) {
848                                 input_report_key(gspca_dev->input_dev,
849                                                  KEY_CAMERA, state);
850                                 input_sync(gspca_dev->input_dev);
851                                 sd->button_pressed = state;
852                         }
853                 }
854 #endif
855                 /* Control Packet, after this came the header again,
856                  * but extra bytes came in the packet before this,
857                  * sometimes an EOF arrives, sometimes not... */
858                 return;
859         }
860         data += 2;
861         len -= 2;
862         if (data[0] == 0xff && data[1] == 0xd8)
863                 pkt_type = FIRST_PACKET;
864         else if (data[len - 2] == 0xff && data[len - 1] == 0xd9)
865                 pkt_type = LAST_PACKET;
866         else
867                 pkt_type = INTER_PACKET;
868         gspca_frame_add(gspca_dev, pkt_type, data, len);
869 }
870 
871 static int sd_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
872 {
873         struct gspca_dev *gspca_dev =
874                 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
875         struct sd *sd = (struct sd *)gspca_dev;
876         s32 red_gain, blue_gain, green_gain;
877 
878         gspca_dev->usb_err = 0;
879 
880         switch (ctrl->id) {
881         case V4L2_CID_AUTO_WHITE_BALANCE:
882                 red_gain = reg_r(gspca_dev, 0x0087);
883                 if (red_gain > 0x40)
884                         red_gain = 0x40;
885                 else if (red_gain < 0x10)
886                         red_gain = 0x10;
887 
888                 blue_gain = reg_r(gspca_dev, 0x0088);
889                 if (blue_gain > 0x40)
890                         blue_gain = 0x40;
891                 else if (blue_gain < 0x10)
892                         blue_gain = 0x10;
893 
894                 green_gain = reg_r(gspca_dev, 0x0089);
895                 if (green_gain > 0x40)
896                         green_gain = 0x40;
897                 else if (green_gain < 0x10)
898                         green_gain = 0x10;
899 
900                 sd->gain->val = green_gain;
901                 sd->red_balance->val = red_gain - green_gain;
902                 sd->blue_balance->val = blue_gain - green_gain;
903                 break;
904         }
905         return 0;
906 }
907 
908 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
909 {
910         struct gspca_dev *gspca_dev =
911                 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
912 
913         gspca_dev->usb_err = 0;
914 
915         if (!gspca_dev->streaming)
916                 return 0;
917 
918         switch (ctrl->id) {
919         case V4L2_CID_BRIGHTNESS:
920                 setbrightness(gspca_dev, ctrl->val);
921                 break;
922         case V4L2_CID_CONTRAST:
923                 setcontrast(gspca_dev, ctrl->val);
924                 break;
925         case V4L2_CID_SATURATION:
926                 setcolors(gspca_dev, ctrl->val);
927                 break;
928         case V4L2_CID_GAMMA:
929                 setgamma(gspca_dev, ctrl->val);
930                 break;
931         case V4L2_CID_HFLIP:
932                 setmirror(gspca_dev, ctrl->val);
933                 break;
934         case V4L2_CID_SHARPNESS:
935                 setsharpness(gspca_dev, ctrl->val);
936                 break;
937         case V4L2_CID_POWER_LINE_FREQUENCY:
938                 setfreq(gspca_dev, ctrl->val);
939                 break;
940         case V4L2_CID_BACKLIGHT_COMPENSATION:
941                 reg_w(gspca_dev, ctrl->val ? 0xf48e : 0xb48e);
942                 break;
943         case V4L2_CID_AUTO_WHITE_BALANCE:
944                 setawb_n_RGB(gspca_dev);
945                 break;
946         case V4L2_CID_COLORFX:
947                 seteffect(gspca_dev, ctrl->val);
948                 break;
949         }
950         return gspca_dev->usb_err;
951 }
952 
953 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
954         .g_volatile_ctrl = sd_g_volatile_ctrl,
955         .s_ctrl = sd_s_ctrl,
956 };
957 
958 static int sd_init_controls(struct gspca_dev *gspca_dev)
959 {
960         struct sd *sd = (struct sd *)gspca_dev;
961         struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
962 
963         gspca_dev->vdev.ctrl_handler = hdl;
964         v4l2_ctrl_handler_init(hdl, 12);
965         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
966                         V4L2_CID_BRIGHTNESS, 0, 14, 1, 8);
967         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
968                         V4L2_CID_CONTRAST, 0, 0x0d, 1, 7);
969         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
970                         V4L2_CID_SATURATION, 0, 0xf, 1, 5);
971         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
972                         V4L2_CID_GAMMA, 0, GAMMA_MAX, 1, 10);
973         /* Activate lowlight, some apps dont bring up the
974            backlight_compensation control) */
975         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
976                         V4L2_CID_BACKLIGHT_COMPENSATION, 0, 1, 1, 1);
977         if (sd->sensor == SENSOR_TAS5130A)
978                 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
979                                 V4L2_CID_HFLIP, 0, 1, 1, 0);
980         sd->awb = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
981                         V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
982         sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
983                         V4L2_CID_GAIN, 0x10, 0x40, 1, 0x20);
984         sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
985                         V4L2_CID_BLUE_BALANCE, -0x30, 0x30, 1, 0);
986         sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
987                         V4L2_CID_RED_BALANCE, -0x30, 0x30, 1, 0);
988         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
989                         V4L2_CID_SHARPNESS, 0, 15, 1, 6);
990         v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
991                         V4L2_CID_COLORFX, V4L2_COLORFX_SKETCH,
992                         ~((1 << V4L2_COLORFX_NONE) |
993                           (1 << V4L2_COLORFX_BW) |
994                           (1 << V4L2_COLORFX_SEPIA) |
995                           (1 << V4L2_COLORFX_SKETCH) |
996                           (1 << V4L2_COLORFX_NEGATIVE)),
997                         V4L2_COLORFX_NONE);
998         sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
999                         V4L2_CID_POWER_LINE_FREQUENCY,
1000                         V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1,
1001                         V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
1002 
1003         if (hdl->error) {
1004                 pr_err("Could not initialize controls\n");
1005                 return hdl->error;
1006         }
1007 
1008         v4l2_ctrl_auto_cluster(4, &sd->awb, 0, true);
1009 
1010         return 0;
1011 }
1012 
1013 /* sub-driver description */
1014 static const struct sd_desc sd_desc = {
1015         .name = MODULE_NAME,
1016         .config = sd_config,
1017         .init = sd_init,
1018         .init_controls = sd_init_controls,
1019         .start = sd_start,
1020         .stopN = sd_stopN,
1021         .pkt_scan = sd_pkt_scan,
1022 #if IS_ENABLED(CONFIG_INPUT)
1023         .other_input = 1,
1024 #endif
1025 };
1026 
1027 /* -- module initialisation -- */
1028 static const struct usb_device_id device_table[] = {
1029         {USB_DEVICE(0x17a1, 0x0128)},
1030         {}
1031 };
1032 MODULE_DEVICE_TABLE(usb, device_table);
1033 
1034 /* -- device connect -- */
1035 static int sd_probe(struct usb_interface *intf,
1036                     const struct usb_device_id *id)
1037 {
1038         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1039                                THIS_MODULE);
1040 }
1041 
1042 static struct usb_driver sd_driver = {
1043         .name = MODULE_NAME,
1044         .id_table = device_table,
1045         .probe = sd_probe,
1046         .disconnect = gspca_disconnect,
1047 #ifdef CONFIG_PM
1048         .suspend = gspca_suspend,
1049         .resume = gspca_resume,
1050         .reset_resume = gspca_resume,
1051 #endif
1052 };
1053 
1054 module_usb_driver(sd_driver);
1055 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us