aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2009-01-08 14:29:38 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:42:30 -0400
commita0306bfa011d86899f3e88d35b6ffe525271bafc (patch)
tree05bca5b4a322b844028e7b2b58f51ee82c79f464
parent3ab67baf36c1f5356afb6424aca77866d91a6b5b (diff)
V4L/DVB (10347): gspca - mars: Optimize, rewrite initialization and add controls.
Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/gspca/mars.c435
1 files changed, 243 insertions, 192 deletions
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index 54c68ea7e546..e85ba1aa8bd3 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -32,16 +32,86 @@ MODULE_LICENSE("GPL");
32/* specific webcam descriptor */ 32/* specific webcam descriptor */
33struct sd { 33struct sd {
34 struct gspca_dev gspca_dev; /* !! must be the first item */ 34 struct gspca_dev gspca_dev; /* !! must be the first item */
35
36 u8 brightness;
37 u8 colors;
38 u8 gamma;
39 u8 sharpness;
35}; 40};
36 41
37/* V4L2 controls supported by the driver */ 42/* V4L2 controls supported by the driver */
43static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
44static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
45static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
46static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
47static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
48static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
49static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
50static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
51
38static struct ctrl sd_ctrls[] = { 52static struct ctrl sd_ctrls[] = {
53 {
54 {
55 .id = V4L2_CID_BRIGHTNESS,
56 .type = V4L2_CTRL_TYPE_INTEGER,
57 .name = "Brightness",
58 .minimum = 0,
59 .maximum = 30,
60 .step = 1,
61#define BRIGHTNESS_DEF 15
62 .default_value = BRIGHTNESS_DEF,
63 },
64 .set = sd_setbrightness,
65 .get = sd_getbrightness,
66 },
67 {
68 {
69 .id = V4L2_CID_SATURATION,
70 .type = V4L2_CTRL_TYPE_INTEGER,
71 .name = "Color",
72 .minimum = 0,
73 .maximum = 220,
74 .step = 1,
75#define COLOR_DEF 190
76 .default_value = COLOR_DEF,
77 },
78 .set = sd_setcolors,
79 .get = sd_getcolors,
80 },
81 {
82 {
83 .id = V4L2_CID_GAMMA,
84 .type = V4L2_CTRL_TYPE_INTEGER,
85 .name = "Gamma",
86 .minimum = 0,
87 .maximum = 3,
88 .step = 1,
89#define GAMMA_DEF 1
90 .default_value = GAMMA_DEF,
91 },
92 .set = sd_setgamma,
93 .get = sd_getgamma,
94 },
95 {
96 {
97 .id = V4L2_CID_SHARPNESS,
98 .type = V4L2_CTRL_TYPE_INTEGER,
99 .name = "Sharpness",
100 .minimum = 0,
101 .maximum = 2,
102 .step = 1,
103#define SHARPNESS_DEF 1
104 .default_value = SHARPNESS_DEF,
105 },
106 .set = sd_setsharpness,
107 .get = sd_getsharpness,
108 },
39}; 109};
40 110
41static const struct v4l2_pix_format vga_mode[] = { 111static const struct v4l2_pix_format vga_mode[] = {
42 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 112 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
43 .bytesperline = 320, 113 .bytesperline = 320,
44 .sizeimage = 320 * 240 * 3 / 8 + 589, 114 .sizeimage = 320 * 240 * 3 / 8 + 590,
45 .colorspace = V4L2_COLORSPACE_JPEG, 115 .colorspace = V4L2_COLORSPACE_JPEG,
46 .priv = 2}, 116 .priv = 2},
47 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 117 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
@@ -51,76 +121,62 @@ static const struct v4l2_pix_format vga_mode[] = {
51 .priv = 1}, 121 .priv = 1},
52}; 122};
53 123
54/* MI Register table //elvis */ 124static const __u8 mi_data[0x20] = {
55enum { 125/* 01 02 03 04 05 06 07 08 */
56 REG_HW_MI_0, 126 0x48, 0x22, 0x01, 0x47, 0x10, 0x00, 0x00, 0x00,
57 REG_HW_MI_1, 127/* 09 0a 0b 0c 0d 0e 0f 10 */
58 REG_HW_MI_2, 128 0x00, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01,
59 REG_HW_MI_3, 129/* 11 12 13 14 15 16 17 18 */
60 REG_HW_MI_4, 130 0x30, 0x00, 0x04, 0x00, 0x06, 0x01, 0xe2, 0x02,
61 REG_HW_MI_5, 131/* 19 1a 1b 1c 1d 1e 1f 20 */
62 REG_HW_MI_6, 132 0x82, 0x00, 0x20, 0x17, 0x80, 0x08, 0x0c, 0x00
63 REG_HW_MI_7,
64 REG_HW_MI_9 = 0x09,
65 REG_HW_MI_B = 0x0B,
66 REG_HW_MI_C,
67 REG_HW_MI_D,
68 REG_HW_MI_1E = 0x1E,
69 REG_HW_MI_20 = 0x20,
70 REG_HW_MI_2B = 0x2B,
71 REG_HW_MI_2C,
72 REG_HW_MI_2D,
73 REG_HW_MI_2E,
74 REG_HW_MI_35 = 0x35,
75 REG_HW_MI_5F = 0x5f,
76 REG_HW_MI_60,
77 REG_HW_MI_61,
78 REG_HW_MI_62,
79 REG_HW_MI_63,
80 REG_HW_MI_64,
81 REG_HW_MI_F1 = 0xf1,
82 ATTR_TOTAL_MI_REG = 0xf2
83}; 133};
84 134
85/* the bytes to write are in gspca_dev->usb_buf */ 135/* write <len> bytes from gspca_dev->usb_buf */
86static int reg_w(struct gspca_dev *gspca_dev, 136static int reg_w(struct gspca_dev *gspca_dev,
87 __u16 index, int len) 137 int len)
88{ 138{
89 int rc; 139 int alen, ret;
90 140
91 rc = usb_control_msg(gspca_dev->dev, 141 ret = usb_bulk_msg(gspca_dev->dev,
92 usb_sndbulkpipe(gspca_dev->dev, 4), 142 usb_sndbulkpipe(gspca_dev->dev, 4),
93 0x12, 143 gspca_dev->usb_buf,
94 0xc8, /* ?? */ 144 len,
95 0, /* value */ 145 &alen,
96 index, gspca_dev->usb_buf, len, 500); 146 500); /* timeout in milliseconds */
97 if (rc < 0) 147 if (ret < 0)
98 PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc); 148 PDEBUG(D_ERR, "reg write [%02x] error %d",
99 return rc; 149 gspca_dev->usb_buf[0], ret);
150 return ret;
100} 151}
101 152
102static void bulk_w(struct gspca_dev *gspca_dev, 153static void mi_w(struct gspca_dev *gspca_dev,
103 __u16 *pch, 154 u8 addr,
104 __u16 Address) 155 u8 value)
105{ 156{
106 gspca_dev->usb_buf[0] = 0x1f; 157 gspca_dev->usb_buf[0] = 0x1f;
107 gspca_dev->usb_buf[1] = 0; /* control byte */ 158 gspca_dev->usb_buf[1] = 0; /* control byte */
108 gspca_dev->usb_buf[2] = Address; 159 gspca_dev->usb_buf[2] = addr;
109 gspca_dev->usb_buf[3] = *pch >> 8; /* high byte */ 160 gspca_dev->usb_buf[3] = value;
110 gspca_dev->usb_buf[4] = *pch; /* low byte */
111 161
112 reg_w(gspca_dev, Address, 5); 162 reg_w(gspca_dev, 4);
113} 163}
114 164
115/* this function is called at probe time */ 165/* this function is called at probe time */
116static int sd_config(struct gspca_dev *gspca_dev, 166static int sd_config(struct gspca_dev *gspca_dev,
117 const struct usb_device_id *id) 167 const struct usb_device_id *id)
118{ 168{
169 struct sd *sd = (struct sd *) gspca_dev;
119 struct cam *cam; 170 struct cam *cam;
120 171
121 cam = &gspca_dev->cam; 172 cam = &gspca_dev->cam;
122 cam->cam_mode = vga_mode; 173 cam->cam_mode = vga_mode;
123 cam->nmodes = ARRAY_SIZE(vga_mode); 174 cam->nmodes = ARRAY_SIZE(vga_mode);
175 sd->brightness = BRIGHTNESS_DEF;
176 sd->colors = COLOR_DEF;
177 sd->gamma = GAMMA_DEF;
178 sd->sharpness = SHARPNESS_DEF;
179 gspca_dev->iface = 9; /* use the altsetting 08 */
124 return 0; 180 return 0;
125} 181}
126 182
@@ -132,24 +188,16 @@ static int sd_init(struct gspca_dev *gspca_dev)
132 188
133static int sd_start(struct gspca_dev *gspca_dev) 189static int sd_start(struct gspca_dev *gspca_dev)
134{ 190{
191 struct sd *sd = (struct sd *) gspca_dev;
135 int err_code; 192 int err_code;
136 __u8 *data; 193 u8 *data;
137 __u16 *MI_buf; 194 int i, val;
138 int h_size, v_size;
139 int intpipe;
140
141 PDEBUG(D_STREAM, "camera start, iface %d, alt 8", gspca_dev->iface);
142 err_code = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 8);
143 if (err_code < 0) {
144 PDEBUG(D_ERR|D_STREAM, "Set packet size: set interface error");
145 return err_code;
146 }
147 195
148 data = gspca_dev->usb_buf; 196 data = gspca_dev->usb_buf;
197
149 data[0] = 0x01; /* address */ 198 data[0] = 0x01; /* address */
150 data[1] = 0x01; 199 data[1] = 0x01;
151 200 err_code = reg_w(gspca_dev, 2);
152 err_code = reg_w(gspca_dev, data[0], 2);
153 if (err_code < 0) 201 if (err_code < 0)
154 return err_code; 202 return err_code;
155 203
@@ -159,30 +207,28 @@ static int sd_start(struct gspca_dev *gspca_dev)
159 data[0] = 0x00; /* address */ 207 data[0] = 0x00; /* address */
160 data[1] = 0x0c | 0x01; /* reg 0 */ 208 data[1] = 0x0c | 0x01; /* reg 0 */
161 data[2] = 0x01; /* reg 1 */ 209 data[2] = 0x01; /* reg 1 */
162 h_size = gspca_dev->width; 210 data[3] = gspca_dev->width / 8; /* h_size , reg 2 */
163 v_size = gspca_dev->height; 211 data[4] = gspca_dev->height / 8; /* v_size , reg 3 */
164 data[3] = h_size / 8; /* h_size , reg 2 */
165 data[4] = v_size / 8; /* v_size , reg 3 */
166 data[5] = 0x30; /* reg 4, MI, PAS5101 : 212 data[5] = 0x30; /* reg 4, MI, PAS5101 :
167 * 0x30 for 24mhz , 0x28 for 12mhz */ 213 * 0x30 for 24mhz , 0x28 for 12mhz */
168 data[6] = 4; /* reg 5, H start */ 214 data[6] = 0x02; /* reg 5, H start - was 0x04 */
169 data[7] = 0xc0; /* reg 6, gamma 1.5 */ 215 data[7] = sd->gamma * 0x40; /* reg 0x06: gamma */
170 data[8] = 3; /* reg 7, V start */ 216 data[8] = 0x01; /* reg 7, V start - was 0x03 */
171/* if (h_size == 320 ) */ 217/* if (h_size == 320 ) */
172/* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */ 218/* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */
173/* else */ 219/* else */
174 data[9] = 0x52; /* reg 8, 24MHz, no scale down */ 220 data[9] = 0x52; /* reg 8, 24MHz, no scale down */
175 data[10] = 0x5d; /* reg 9, I2C device address 221/*jfm: from win trace*/
176 * [for PAS5101 (0x40)] [for MI (0x5d)] */ 222 data[10] = 0x18;
177 223
178 err_code = reg_w(gspca_dev, data[0], 11); 224 err_code = reg_w(gspca_dev, 11);
179 if (err_code < 0) 225 if (err_code < 0)
180 return err_code; 226 return err_code;
181 227
182 data[0] = 0x23; /* address */ 228 data[0] = 0x23; /* address */
183 data[1] = 0x09; /* reg 35, append frame header */ 229 data[1] = 0x09; /* reg 35, append frame header */
184 230
185 err_code = reg_w(gspca_dev, data[0], 2); 231 err_code = reg_w(gspca_dev, 2);
186 if (err_code < 0) 232 if (err_code < 0)
187 return err_code; 233 return err_code;
188 234
@@ -193,137 +239,55 @@ static int sd_start(struct gspca_dev *gspca_dev)
193/* else */ 239/* else */
194 data[1] = 50; /* 50 reg 60, pc-cam frame size 240 data[1] = 50; /* 50 reg 60, pc-cam frame size
195 * (unit: 4KB) 200KB */ 241 * (unit: 4KB) 200KB */
196 err_code = reg_w(gspca_dev, data[0], 2); 242 err_code = reg_w(gspca_dev, 2);
197 if (err_code < 0) 243 if (err_code < 0)
198 return err_code; 244 return err_code;
199 245
200 if (0) { /* fixed dark-gain */
201 data[1] = 0; /* reg 94, Y Gain (1.75) */
202 data[2] = 0; /* reg 95, UV Gain (1.75) */
203 data[3] = 0x3f; /* reg 96, Y Gain/UV Gain/disable
204 * auto dark-gain */
205 data[4] = 0; /* reg 97, set fixed dark level */
206 data[5] = 0; /* reg 98, don't care */
207 } else { /* auto dark-gain */
208 data[1] = 0; /* reg 94, Y Gain (auto) */
209 data[2] = 0; /* reg 95, UV Gain (1.75) */
210 data[3] = 0x78; /* reg 96, Y Gain/UV Gain/disable
211 * auto dark-gain */
212 switch (gspca_dev->width) {
213/* case 1280: */
214/* data[4] = 154;
215 * reg 97, %3 shadow point (unit: 256 pixel) */
216/* data[5] = 51;
217 * reg 98, %1 highlight point
218 * (uint: 256 pixel) */
219/* break; */
220 default:
221/* case 640: */
222 data[4] = 36; /* reg 97, %3 shadow point
223 * (unit: 256 pixel) */
224 data[5] = 12; /* reg 98, %1 highlight point
225 * (uint: 256 pixel) */
226 break;
227 case 320:
228 data[4] = 9; /* reg 97, %3 shadow point
229 * (unit: 256 pixel) */
230 data[5] = 3; /* reg 98, %1 highlight point
231 * (uint: 256 pixel) */
232 break;
233 }
234 }
235 /* auto dark-gain */ 246 /* auto dark-gain */
236 data[0] = 0x5e; /* address */ 247 data[0] = 0x5e; /* address */
237 248 data[1] = 0; /* reg 94, Y Gain (auto) */
238 err_code = reg_w(gspca_dev, data[0], 6); 249/*jfm: from win trace*/
250 val = sd->colors * 0x40 + 0x400;
251 data[2] = val; /* reg 0x5f/0x60 (LE) = saturation */
252 data[3] = val >> 8;
253 data[4] = sd->brightness; /* reg 0x61 = brightness */
254 data[5] = 0x00;
255
256 err_code = reg_w(gspca_dev, 6);
239 if (err_code < 0) 257 if (err_code < 0)
240 return err_code; 258 return err_code;
241 259
242 data[0] = 0x67; 260 data[0] = 0x67;
243 data[1] = 0x13; /* reg 103, first pixel B, disable sharpness */ 261/*jfm: from win trace*/
244 err_code = reg_w(gspca_dev, data[0], 2); 262 data[1] = sd->sharpness * 4 + 3;
263 data[2] = 0x14;
264 err_code = reg_w(gspca_dev, 3);
245 if (err_code < 0) 265 if (err_code < 0)
246 return err_code; 266 return err_code;
247 267
248 /* 268 data[0] = 0x69;
249 * initialize the value of MI sensor... 269 data[1] = 0x2f;
250 */ 270 data[2] = 0x28;
251 MI_buf = kzalloc(ATTR_TOTAL_MI_REG * sizeof *MI_buf, GFP_KERNEL); 271 data[3] = 0x42;
252 MI_buf[REG_HW_MI_1] = 0x000a; 272 err_code = reg_w(gspca_dev, 4);
253 MI_buf[REG_HW_MI_2] = 0x000c; 273 if (err_code < 0)
254 MI_buf[REG_HW_MI_3] = 0x0405; 274 return err_code;
255 MI_buf[REG_HW_MI_4] = 0x0507; 275
256 /* mi_Attr_Reg_[REG_HW_MI_5] = 0x01ff;//13 */ 276 data[0] = 0x63;
257 MI_buf[REG_HW_MI_5] = 0x0013; /* 13 */ 277 data[1] = 0x07;
258 MI_buf[REG_HW_MI_6] = 0x001f; /* vertical blanking */ 278 err_code = reg_w(gspca_dev, 2);
259 /* mi_Attr_Reg_[REG_HW_MI_6] = 0x0400; // vertical blanking */ 279/*jfm: win trace - many writes here to reg 0x64*/
260 MI_buf[REG_HW_MI_7] = 0x0002; 280 if (err_code < 0)
261 /* mi_Attr_Reg_[REG_HW_MI_9] = 0x015f; */ 281 return err_code;
262 /* mi_Attr_Reg_[REG_HW_MI_9] = 0x030f; */ 282
263 MI_buf[REG_HW_MI_9] = 0x0374; 283 /* initialize the MI sensor */
264 MI_buf[REG_HW_MI_B] = 0x0000; 284 for (i = 0; i < sizeof mi_data; i++)
265 MI_buf[REG_HW_MI_C] = 0x0000; 285 mi_w(gspca_dev, i + 1, mi_data[i]);
266 MI_buf[REG_HW_MI_D] = 0x0000;
267 MI_buf[REG_HW_MI_1E] = 0x8000;
268/* mi_Attr_Reg_[REG_HW_MI_20] = 0x1104; */
269 MI_buf[REG_HW_MI_20] = 0x1104; /* 0x111c; */
270 MI_buf[REG_HW_MI_2B] = 0x0008;
271/* mi_Attr_Reg_[REG_HW_MI_2C] = 0x000f; */
272 MI_buf[REG_HW_MI_2C] = 0x001f; /* lita suggest */
273 MI_buf[REG_HW_MI_2D] = 0x0008;
274 MI_buf[REG_HW_MI_2E] = 0x0008;
275 MI_buf[REG_HW_MI_35] = 0x0051;
276 MI_buf[REG_HW_MI_5F] = 0x0904; /* fail to write */
277 MI_buf[REG_HW_MI_60] = 0x0000;
278 MI_buf[REG_HW_MI_61] = 0x0000;
279 MI_buf[REG_HW_MI_62] = 0x0498;
280 MI_buf[REG_HW_MI_63] = 0x0000;
281 MI_buf[REG_HW_MI_64] = 0x0000;
282 MI_buf[REG_HW_MI_F1] = 0x0001;
283 /* changing while setting up the different value of dx/dy */
284
285 if (gspca_dev->width != 1280) {
286 MI_buf[0x01] = 0x010a;
287 MI_buf[0x02] = 0x014c;
288 MI_buf[0x03] = 0x01e5;
289 MI_buf[0x04] = 0x0287;
290 }
291 MI_buf[0x20] = 0x1104;
292
293 bulk_w(gspca_dev, MI_buf + 1, 1);
294 bulk_w(gspca_dev, MI_buf + 2, 2);
295 bulk_w(gspca_dev, MI_buf + 3, 3);
296 bulk_w(gspca_dev, MI_buf + 4, 4);
297 bulk_w(gspca_dev, MI_buf + 5, 5);
298 bulk_w(gspca_dev, MI_buf + 6, 6);
299 bulk_w(gspca_dev, MI_buf + 7, 7);
300 bulk_w(gspca_dev, MI_buf + 9, 9);
301 bulk_w(gspca_dev, MI_buf + 0x0b, 0x0b);
302 bulk_w(gspca_dev, MI_buf + 0x0c, 0x0c);
303 bulk_w(gspca_dev, MI_buf + 0x0d, 0x0d);
304 bulk_w(gspca_dev, MI_buf + 0x1e, 0x1e);
305 bulk_w(gspca_dev, MI_buf + 0x20, 0x20);
306 bulk_w(gspca_dev, MI_buf + 0x2b, 0x2b);
307 bulk_w(gspca_dev, MI_buf + 0x2c, 0x2c);
308 bulk_w(gspca_dev, MI_buf + 0x2d, 0x2d);
309 bulk_w(gspca_dev, MI_buf + 0x2e, 0x2e);
310 bulk_w(gspca_dev, MI_buf + 0x35, 0x35);
311 bulk_w(gspca_dev, MI_buf + 0x5f, 0x5f);
312 bulk_w(gspca_dev, MI_buf + 0x60, 0x60);
313 bulk_w(gspca_dev, MI_buf + 0x61, 0x61);
314 bulk_w(gspca_dev, MI_buf + 0x62, 0x62);
315 bulk_w(gspca_dev, MI_buf + 0x63, 0x63);
316 bulk_w(gspca_dev, MI_buf + 0x64, 0x64);
317 bulk_w(gspca_dev, MI_buf + 0xf1, 0xf1);
318 kfree(MI_buf);
319
320 intpipe = usb_sndintpipe(gspca_dev->dev, 0);
321 err_code = usb_clear_halt(gspca_dev->dev, intpipe);
322 286
323 data[0] = 0x00; 287 data[0] = 0x00;
324 data[1] = 0x4d; /* ISOC transfering enable... */ 288 data[1] = 0x4d; /* ISOC transfering enable... */
325 reg_w(gspca_dev, data[0], 2); 289 reg_w(gspca_dev, 2);
326 return err_code; 290 return 0;
327} 291}
328 292
329static void sd_stopN(struct gspca_dev *gspca_dev) 293static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -332,7 +296,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
332 296
333 gspca_dev->usb_buf[0] = 1; 297 gspca_dev->usb_buf[0] = 1;
334 gspca_dev->usb_buf[1] = 0; 298 gspca_dev->usb_buf[1] = 0;
335 result = reg_w(gspca_dev, gspca_dev->usb_buf[0], 2); 299 result = reg_w(gspca_dev, 2);
336 if (result < 0) 300 if (result < 0)
337 PDEBUG(D_ERR, "Camera Stop failed"); 301 PDEBUG(D_ERR, "Camera Stop failed");
338} 302}
@@ -358,7 +322,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
358 || data[5 + p] == 0x65 322 || data[5 + p] == 0x65
359 || data[5 + p] == 0x66 323 || data[5 + p] == 0x66
360 || data[5 + p] == 0x67) { 324 || data[5 + p] == 0x67) {
361 PDEBUG(D_PACK, "sof offset: %d leng: %d", 325 PDEBUG(D_PACK, "sof offset: %d len: %d",
362 p, len); 326 p, len);
363 frame = gspca_frame_add(gspca_dev, LAST_PACKET, 327 frame = gspca_frame_add(gspca_dev, LAST_PACKET,
364 frame, data, 0); 328 frame, data, 0);
@@ -374,6 +338,92 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
374 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); 338 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
375} 339}
376 340
341static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
342{
343 struct sd *sd = (struct sd *) gspca_dev;
344
345 sd->brightness = val;
346 if (gspca_dev->streaming) {
347 gspca_dev->usb_buf[0] = 0x61;
348 gspca_dev->usb_buf[1] = val;
349 reg_w(gspca_dev, 2);
350 }
351 return 0;
352}
353
354static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
355{
356 struct sd *sd = (struct sd *) gspca_dev;
357
358 *val = sd->brightness;
359 return 0;
360}
361
362static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
363{
364 struct sd *sd = (struct sd *) gspca_dev;
365
366 sd->colors = val;
367 if (gspca_dev->streaming) {
368 val = val * 0x40 + 0x400;
369 gspca_dev->usb_buf[0] = 0x5f;
370 gspca_dev->usb_buf[1] = val;
371 gspca_dev->usb_buf[2] = val >> 8;
372 reg_w(gspca_dev, 3);
373 }
374 return 0;
375}
376
377static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
378{
379 struct sd *sd = (struct sd *) gspca_dev;
380
381 *val = sd->colors;
382 return 0;
383}
384
385static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
386{
387 struct sd *sd = (struct sd *) gspca_dev;
388
389 sd->gamma = val;
390 if (gspca_dev->streaming) {
391 gspca_dev->usb_buf[0] = 0x06;
392 gspca_dev->usb_buf[1] = val * 0x40;
393 reg_w(gspca_dev, 2);
394 }
395 return 0;
396}
397
398static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
399{
400 struct sd *sd = (struct sd *) gspca_dev;
401
402 *val = sd->gamma;
403 return 0;
404}
405
406static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
407{
408 struct sd *sd = (struct sd *) gspca_dev;
409
410 sd->sharpness = val;
411 if (gspca_dev->streaming) {
412 gspca_dev->usb_buf[0] = 0x67;
413 gspca_dev->usb_buf[1] = val * 4 + 3;
414 reg_w(gspca_dev, 2);
415 }
416 return 0;
417}
418
419static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
420{
421 struct sd *sd = (struct sd *) gspca_dev;
422
423 *val = sd->sharpness;
424 return 0;
425}
426
377/* sub-driver description */ 427/* sub-driver description */
378static const struct sd_desc sd_desc = { 428static const struct sd_desc sd_desc = {
379 .name = MODULE_NAME, 429 .name = MODULE_NAME,
@@ -416,6 +466,7 @@ static struct usb_driver sd_driver = {
416static int __init sd_mod_init(void) 466static int __init sd_mod_init(void)
417{ 467{
418 int ret; 468 int ret;
469
419 ret = usb_register(&sd_driver); 470 ret = usb_register(&sd_driver);
420 if (ret < 0) 471 if (ret < 0)
421 return ret; 472 return ret;