Linux-libre 5.4.47-gnu
[librecmc/linux-libre.git] / drivers / media / usb / gspca / spca1528.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * spca1528 subdriver
4  *
5  * Copyright (C) 2010-2011 Jean-Francois Moine (http://moinejf.free.fr)
6  */
7
8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9
10 #define MODULE_NAME "spca1528"
11
12 #include "gspca.h"
13 #include "jpeg.h"
14
15 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
16 MODULE_DESCRIPTION("SPCA1528 USB Camera Driver");
17 MODULE_LICENSE("GPL");
18
19 /* specific webcam descriptor */
20 struct sd {
21         struct gspca_dev gspca_dev;     /* !! must be the first item */
22
23         u8 pkt_seq;
24
25         u8 jpeg_hdr[JPEG_HDR_SZ];
26 };
27
28 static const struct v4l2_pix_format vga_mode[] = {
29 /*              (does not work correctly)
30         {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
31                 .bytesperline = 176,
32                 .sizeimage = 176 * 144 * 5 / 8 + 590,
33                 .colorspace = V4L2_COLORSPACE_JPEG,
34                 .priv = 3},
35 */
36         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
37                 .bytesperline = 320,
38                 .sizeimage = 320 * 240 * 4 / 8 + 590,
39                 .colorspace = V4L2_COLORSPACE_JPEG,
40                 .priv = 2},
41         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
42                 .bytesperline = 640,
43                 .sizeimage = 640 * 480 * 3 / 8 + 590,
44                 .colorspace = V4L2_COLORSPACE_JPEG,
45                 .priv = 1},
46 };
47
48 /* read <len> bytes to gspca usb_buf */
49 static void reg_r(struct gspca_dev *gspca_dev,
50                         u8 req,
51                         u16 index,
52                         int len)
53 {
54 #if USB_BUF_SZ < 64
55 #error "USB buffer too small"
56 #endif
57         struct usb_device *dev = gspca_dev->dev;
58         int ret;
59
60         if (gspca_dev->usb_err < 0)
61                 return;
62         ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
63                         req,
64                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
65                         0x0000,                 /* value */
66                         index,
67                         gspca_dev->usb_buf, len,
68                         500);
69         gspca_dbg(gspca_dev, D_USBI, "GET %02x 0000 %04x %02x\n", req, index,
70                   gspca_dev->usb_buf[0]);
71         if (ret < 0) {
72                 pr_err("reg_r err %d\n", ret);
73                 gspca_dev->usb_err = ret;
74                 /*
75                  * Make sure the buffer is zeroed to avoid uninitialized
76                  * values.
77                  */
78                 memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
79         }
80 }
81
82 static void reg_w(struct gspca_dev *gspca_dev,
83                         u8 req,
84                         u16 value,
85                         u16 index)
86 {
87         struct usb_device *dev = gspca_dev->dev;
88         int ret;
89
90         if (gspca_dev->usb_err < 0)
91                 return;
92         gspca_dbg(gspca_dev, D_USBO, "SET %02x %04x %04x\n", req, value, index);
93         ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
94                         req,
95                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
96                         value, index,
97                         NULL, 0, 500);
98         if (ret < 0) {
99                 pr_err("reg_w err %d\n", ret);
100                 gspca_dev->usb_err = ret;
101         }
102 }
103
104 static void reg_wb(struct gspca_dev *gspca_dev,
105                         u8 req,
106                         u16 value,
107                         u16 index,
108                         u8 byte)
109 {
110         struct usb_device *dev = gspca_dev->dev;
111         int ret;
112
113         if (gspca_dev->usb_err < 0)
114                 return;
115         gspca_dbg(gspca_dev, D_USBO, "SET %02x %04x %04x %02x\n",
116                   req, value, index, byte);
117         gspca_dev->usb_buf[0] = byte;
118         ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
119                         req,
120                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
121                         value, index,
122                         gspca_dev->usb_buf, 1, 500);
123         if (ret < 0) {
124                 pr_err("reg_w err %d\n", ret);
125                 gspca_dev->usb_err = ret;
126         }
127 }
128
129 static void wait_status_0(struct gspca_dev *gspca_dev)
130 {
131         int i, w;
132
133         i = 16;
134         w = 0;
135         do {
136                 reg_r(gspca_dev, 0x21, 0x0000, 1);
137                 if (gspca_dev->usb_buf[0] == 0)
138                         return;
139                 w += 15;
140                 msleep(w);
141         } while (--i > 0);
142         gspca_err(gspca_dev, "wait_status_0 timeout\n");
143         gspca_dev->usb_err = -ETIME;
144 }
145
146 static void wait_status_1(struct gspca_dev *gspca_dev)
147 {
148         int i;
149
150         i = 10;
151         do {
152                 reg_r(gspca_dev, 0x21, 0x0001, 1);
153                 msleep(10);
154                 if (gspca_dev->usb_buf[0] == 1) {
155                         reg_wb(gspca_dev, 0x21, 0x0000, 0x0001, 0x00);
156                         reg_r(gspca_dev, 0x21, 0x0001, 1);
157                         return;
158                 }
159         } while (--i > 0);
160         gspca_err(gspca_dev, "wait_status_1 timeout\n");
161         gspca_dev->usb_err = -ETIME;
162 }
163
164 static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
165 {
166         reg_wb(gspca_dev, 0xc0, 0x0000, 0x00c0, val);
167 }
168
169 static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
170 {
171         reg_wb(gspca_dev, 0xc1, 0x0000, 0x00c1, val);
172 }
173
174 static void sethue(struct gspca_dev *gspca_dev, s32 val)
175 {
176         reg_wb(gspca_dev, 0xc2, 0x0000, 0x0000, val);
177 }
178
179 static void setcolor(struct gspca_dev *gspca_dev, s32 val)
180 {
181         reg_wb(gspca_dev, 0xc3, 0x0000, 0x00c3, val);
182 }
183
184 static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
185 {
186         reg_wb(gspca_dev, 0xc4, 0x0000, 0x00c4, val);
187 }
188
189 /* this function is called at probe time */
190 static int sd_config(struct gspca_dev *gspca_dev,
191                         const struct usb_device_id *id)
192 {
193         gspca_dev->cam.cam_mode = vga_mode;
194         gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
195         gspca_dev->cam.npkt = 128; /* number of packets per ISOC message */
196                         /*fixme: 256 in ms-win traces*/
197
198         return 0;
199 }
200
201 /* this function is called at probe and resume time */
202 static int sd_init(struct gspca_dev *gspca_dev)
203 {
204         reg_w(gspca_dev, 0x00, 0x0001, 0x2067);
205         reg_w(gspca_dev, 0x00, 0x00d0, 0x206b);
206         reg_w(gspca_dev, 0x00, 0x0000, 0x206c);
207         reg_w(gspca_dev, 0x00, 0x0001, 0x2069);
208         msleep(8);
209         reg_w(gspca_dev, 0x00, 0x00c0, 0x206b);
210         reg_w(gspca_dev, 0x00, 0x0000, 0x206c);
211         reg_w(gspca_dev, 0x00, 0x0001, 0x2069);
212
213         reg_r(gspca_dev, 0x20, 0x0000, 1);
214         reg_r(gspca_dev, 0x20, 0x0000, 5);
215         reg_r(gspca_dev, 0x23, 0x0000, 64);
216         gspca_dbg(gspca_dev, D_PROBE, "%s%s\n", &gspca_dev->usb_buf[0x1c],
217                   &gspca_dev->usb_buf[0x30]);
218         reg_r(gspca_dev, 0x23, 0x0001, 64);
219         return gspca_dev->usb_err;
220 }
221
222 /* function called at start time before URB creation */
223 static int sd_isoc_init(struct gspca_dev *gspca_dev)
224 {
225         u8 mode;
226
227         reg_r(gspca_dev, 0x00, 0x2520, 1);
228         wait_status_0(gspca_dev);
229         reg_w(gspca_dev, 0xc5, 0x0003, 0x0000);
230         wait_status_1(gspca_dev);
231
232         wait_status_0(gspca_dev);
233         mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
234         reg_wb(gspca_dev, 0x25, 0x0000, 0x0004, mode);
235         reg_r(gspca_dev, 0x25, 0x0004, 1);
236         reg_wb(gspca_dev, 0x27, 0x0000, 0x0000, 0x06);  /* 420 */
237         reg_r(gspca_dev, 0x27, 0x0000, 1);
238
239 /* not useful..
240         gspca_dev->alt = 4;             * use alternate setting 3 */
241
242         return gspca_dev->usb_err;
243 }
244
245 /* -- start the camera -- */
246 static int sd_start(struct gspca_dev *gspca_dev)
247 {
248         struct sd *sd = (struct sd *) gspca_dev;
249
250         /* initialize the JPEG header */
251         jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
252                         gspca_dev->pixfmt.width,
253                         0x22);          /* JPEG 411 */
254
255         /* the JPEG quality shall be 85% */
256         jpeg_set_qual(sd->jpeg_hdr, 85);
257
258         reg_r(gspca_dev, 0x00, 0x2520, 1);
259         msleep(8);
260
261         /* start the capture */
262         wait_status_0(gspca_dev);
263         reg_w(gspca_dev, 0x31, 0x0000, 0x0004); /* start request */
264         wait_status_1(gspca_dev);
265         wait_status_0(gspca_dev);
266         msleep(200);
267
268         sd->pkt_seq = 0;
269         return gspca_dev->usb_err;
270 }
271
272 static void sd_stopN(struct gspca_dev *gspca_dev)
273 {
274         /* stop the capture */
275         wait_status_0(gspca_dev);
276         reg_w(gspca_dev, 0x31, 0x0000, 0x0000); /* stop request */
277         wait_status_1(gspca_dev);
278         wait_status_0(gspca_dev);
279 }
280
281 /* move a packet adding 0x00 after 0xff */
282 static void add_packet(struct gspca_dev *gspca_dev,
283                         u8 *data,
284                         int len)
285 {
286         int i;
287
288         i = 0;
289         do {
290                 if (data[i] == 0xff) {
291                         gspca_frame_add(gspca_dev, INTER_PACKET,
292                                         data, i + 1);
293                         len -= i;
294                         data += i;
295                         *data = 0x00;
296                         i = 0;
297                 }
298         } while (++i < len);
299         gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
300 }
301
302 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
303                         u8 *data,                       /* isoc packet */
304                         int len)                        /* iso packet length */
305 {
306         struct sd *sd = (struct sd *) gspca_dev;
307         static const u8 ffd9[] = {0xff, 0xd9};
308
309         /* image packets start with:
310          *      02 8n
311          * with <n> bit:
312          *      0x01: even (0) / odd (1) image
313          *      0x02: end of image when set
314          */
315         if (len < 3)
316                 return;                         /* empty packet */
317         if (*data == 0x02) {
318                 if (data[1] & 0x02) {
319                         sd->pkt_seq = !(data[1] & 1);
320                         add_packet(gspca_dev, data + 2, len - 2);
321                         gspca_frame_add(gspca_dev, LAST_PACKET,
322                                         ffd9, 2);
323                         return;
324                 }
325                 if ((data[1] & 1) != sd->pkt_seq)
326                         goto err;
327                 if (gspca_dev->last_packet_type == LAST_PACKET)
328                         gspca_frame_add(gspca_dev, FIRST_PACKET,
329                                         sd->jpeg_hdr, JPEG_HDR_SZ);
330                 add_packet(gspca_dev, data + 2, len - 2);
331                 return;
332         }
333 err:
334         gspca_dev->last_packet_type = DISCARD_PACKET;
335 }
336
337 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
338 {
339         struct gspca_dev *gspca_dev =
340                 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
341
342         gspca_dev->usb_err = 0;
343
344         if (!gspca_dev->streaming)
345                 return 0;
346
347         switch (ctrl->id) {
348         case V4L2_CID_BRIGHTNESS:
349                 setbrightness(gspca_dev, ctrl->val);
350                 break;
351         case V4L2_CID_CONTRAST:
352                 setcontrast(gspca_dev, ctrl->val);
353                 break;
354         case V4L2_CID_HUE:
355                 sethue(gspca_dev, ctrl->val);
356                 break;
357         case V4L2_CID_SATURATION:
358                 setcolor(gspca_dev, ctrl->val);
359                 break;
360         case V4L2_CID_SHARPNESS:
361                 setsharpness(gspca_dev, ctrl->val);
362                 break;
363         }
364         return gspca_dev->usb_err;
365 }
366
367 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
368         .s_ctrl = sd_s_ctrl,
369 };
370
371 static int sd_init_controls(struct gspca_dev *gspca_dev)
372 {
373         struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
374
375         gspca_dev->vdev.ctrl_handler = hdl;
376         v4l2_ctrl_handler_init(hdl, 5);
377         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
378                         V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
379         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
380                         V4L2_CID_CONTRAST, 0, 8, 1, 1);
381         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
382                         V4L2_CID_HUE, 0, 255, 1, 0);
383         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
384                         V4L2_CID_SATURATION, 0, 8, 1, 1);
385         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
386                         V4L2_CID_SHARPNESS, 0, 255, 1, 0);
387
388         if (hdl->error) {
389                 pr_err("Could not initialize controls\n");
390                 return hdl->error;
391         }
392         return 0;
393 }
394
395 /* sub-driver description */
396 static const struct sd_desc sd_desc = {
397         .name = MODULE_NAME,
398         .config = sd_config,
399         .init = sd_init,
400         .init_controls = sd_init_controls,
401         .isoc_init = sd_isoc_init,
402         .start = sd_start,
403         .stopN = sd_stopN,
404         .pkt_scan = sd_pkt_scan,
405 };
406
407 /* -- module initialisation -- */
408 static const struct usb_device_id device_table[] = {
409         {USB_DEVICE(0x04fc, 0x1528)},
410         {}
411 };
412 MODULE_DEVICE_TABLE(usb, device_table);
413
414 /* -- device connect -- */
415 static int sd_probe(struct usb_interface *intf,
416                         const struct usb_device_id *id)
417 {
418         /* the video interface for isochronous transfer is 1 */
419         if (intf->cur_altsetting->desc.bInterfaceNumber != 1)
420                 return -ENODEV;
421
422         return gspca_dev_probe2(intf, id, &sd_desc, sizeof(struct sd),
423                                 THIS_MODULE);
424 }
425
426 static struct usb_driver sd_driver = {
427         .name = MODULE_NAME,
428         .id_table = device_table,
429         .probe = sd_probe,
430         .disconnect = gspca_disconnect,
431 #ifdef CONFIG_PM
432         .suspend = gspca_suspend,
433         .resume = gspca_resume,
434         .reset_resume = gspca_resume,
435 #endif
436 };
437
438 module_usb_driver(sd_driver);