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