^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * kinect sensor device camera, gspca driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2011 Antonio Ospite <ospite@studenti.unina.it>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Based on the OpenKinect project and libfreenect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * http://openkinect.org/wiki/Init_Analysis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Special thanks to Steven Toth and kernellabs.com for sponsoring a Kinect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * sensor device which I tested the driver on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define MODULE_NAME "kinect"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "gspca.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define CTRL_TIMEOUT 500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) MODULE_DESCRIPTION("GSPCA/Kinect Sensor Device USB Camera Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static bool depth_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct pkt_hdr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) uint8_t magic[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) uint8_t pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) uint8_t flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) uint8_t unk1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) uint8_t seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) uint8_t unk2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) uint8_t unk3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) uint32_t timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct cam_hdr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) uint8_t magic[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) __le16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) __le16 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) __le16 tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* specific webcam descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct sd {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct gspca_dev gspca_dev; /* !! must be the first item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) uint16_t cam_tag; /* a sequence number for packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) uint8_t stream_flag; /* to identify different stream types */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) uint8_t obuf[0x400]; /* output buffer for control commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) uint8_t ibuf[0x200]; /* input buffer for control commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define MODE_640x480 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define MODE_640x488 0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define MODE_1280x1024 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define FORMAT_BAYER 0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define FORMAT_UYVY 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define FORMAT_Y10B 0x0040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define FPS_HIGH 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static const struct v4l2_pix_format depth_camera_mode[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {640, 480, V4L2_PIX_FMT_Y10BPACK, V4L2_FIELD_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .bytesperline = 640 * 10 / 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .sizeimage = 640 * 480 * 10 / 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .colorspace = V4L2_COLORSPACE_SRGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .priv = MODE_640x488 | FORMAT_Y10B},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static const struct v4l2_pix_format video_camera_mode[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {640, 480, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .bytesperline = 640,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) .sizeimage = 640 * 480,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .colorspace = V4L2_COLORSPACE_SRGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .priv = MODE_640x480 | FORMAT_BAYER | FPS_HIGH},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .bytesperline = 640 * 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .sizeimage = 640 * 480 * 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .colorspace = V4L2_COLORSPACE_SRGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .priv = MODE_640x480 | FORMAT_UYVY},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {1280, 1024, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .bytesperline = 1280,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) .sizeimage = 1280 * 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) .colorspace = V4L2_COLORSPACE_SRGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .priv = MODE_1280x1024 | FORMAT_BAYER},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {640, 488, V4L2_PIX_FMT_Y10BPACK, V4L2_FIELD_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) .bytesperline = 640 * 10 / 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) .sizeimage = 640 * 488 * 10 / 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) .colorspace = V4L2_COLORSPACE_SRGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) .priv = MODE_640x488 | FORMAT_Y10B | FPS_HIGH},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {1280, 1024, V4L2_PIX_FMT_Y10BPACK, V4L2_FIELD_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) .bytesperline = 1280 * 10 / 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .sizeimage = 1280 * 1024 * 10 / 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .colorspace = V4L2_COLORSPACE_SRGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .priv = MODE_1280x1024 | FORMAT_Y10B},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static int kinect_write(struct usb_device *udev, uint8_t *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) uint16_t wLength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return usb_control_msg(udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) usb_sndctrlpipe(udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 0, 0, data, wLength, CTRL_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static int kinect_read(struct usb_device *udev, uint8_t *data, uint16_t wLength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return usb_control_msg(udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) usb_rcvctrlpipe(udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 0, 0, data, wLength, CTRL_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static int send_cmd(struct gspca_dev *gspca_dev, uint16_t cmd, void *cmdbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) unsigned int cmd_len, void *replybuf, unsigned int reply_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct usb_device *udev = gspca_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int res, actual_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) uint8_t *obuf = sd->obuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) uint8_t *ibuf = sd->ibuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct cam_hdr *chdr = (void *)obuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct cam_hdr *rhdr = (void *)ibuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (cmd_len & 1 || cmd_len > (0x400 - sizeof(*chdr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) pr_err("send_cmd: Invalid command length (0x%x)\n", cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) chdr->magic[0] = 0x47;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) chdr->magic[1] = 0x4d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) chdr->cmd = cpu_to_le16(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) chdr->tag = cpu_to_le16(sd->cam_tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) chdr->len = cpu_to_le16(cmd_len / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) memcpy(obuf+sizeof(*chdr), cmdbuf, cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) res = kinect_write(udev, obuf, cmd_len + sizeof(*chdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) gspca_dbg(gspca_dev, D_USBO, "Control cmd=%04x tag=%04x len=%04x: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) sd->cam_tag, cmd_len, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (res < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) pr_err("send_cmd: Output control transfer failed (%d)\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) actual_len = kinect_read(udev, ibuf, 0x200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) } while (actual_len == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) gspca_dbg(gspca_dev, D_USBO, "Control reply: %d\n", actual_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (actual_len < (int)sizeof(*rhdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) pr_err("send_cmd: Input control transfer failed (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) actual_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return actual_len < 0 ? actual_len : -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) actual_len -= sizeof(*rhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (rhdr->magic[0] != 0x52 || rhdr->magic[1] != 0x42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) pr_err("send_cmd: Bad magic %02x %02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) rhdr->magic[0], rhdr->magic[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (rhdr->cmd != chdr->cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) pr_err("send_cmd: Bad cmd %02x != %02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) rhdr->cmd, chdr->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (rhdr->tag != chdr->tag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) pr_err("send_cmd: Bad tag %04x != %04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) rhdr->tag, chdr->tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (le16_to_cpu(rhdr->len) != (actual_len/2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) pr_err("send_cmd: Bad len %04x != %04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) le16_to_cpu(rhdr->len), (int)(actual_len/2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (actual_len > reply_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) pr_warn("send_cmd: Data buffer is %d bytes long, but got %d bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) reply_len, actual_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) memcpy(replybuf, ibuf+sizeof(*rhdr), reply_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) memcpy(replybuf, ibuf+sizeof(*rhdr), actual_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) sd->cam_tag++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return actual_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static int write_register(struct gspca_dev *gspca_dev, uint16_t reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) uint16_t data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) uint16_t reply[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) __le16 cmd[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) cmd[0] = cpu_to_le16(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) cmd[1] = cpu_to_le16(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) gspca_dbg(gspca_dev, D_USBO, "Write Reg 0x%04x <= 0x%02x\n", reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) res = send_cmd(gspca_dev, 0x03, cmd, 4, reply, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (res < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (res != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) pr_warn("send_cmd returned %d [%04x %04x], 0000 expected\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) res, reply[0], reply[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /* this function is called at probe time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static int sd_config_video(struct gspca_dev *gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) struct cam *cam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) sd->cam_tag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) sd->stream_flag = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) cam = &gspca_dev->cam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) cam->cam_mode = video_camera_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) cam->nmodes = ARRAY_SIZE(video_camera_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) gspca_dev->xfer_ep = 0x81;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /* Setting those values is not needed for video stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) cam->npkt = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) gspca_dev->pkt_size = 960 * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static int sd_config_depth(struct gspca_dev *gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct cam *cam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) sd->cam_tag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) sd->stream_flag = 0x70;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) cam = &gspca_dev->cam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) cam->cam_mode = depth_camera_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) cam->nmodes = ARRAY_SIZE(depth_camera_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) gspca_dev->xfer_ep = 0x82;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /* this function is called at probe and resume time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static int sd_init(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) gspca_dbg(gspca_dev, D_PROBE, "Kinect Camera device.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static int sd_start_video(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) int mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) uint8_t fmt_reg, fmt_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) uint8_t res_reg, res_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) uint8_t fps_reg, fps_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) uint8_t mode_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (mode & FORMAT_Y10B) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) fmt_reg = 0x19;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) res_reg = 0x1a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) fps_reg = 0x1b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) mode_val = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) fmt_reg = 0x0c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) res_reg = 0x0d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) fps_reg = 0x0e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) mode_val = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (mode & FORMAT_UYVY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) fmt_val = 0x05;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) fmt_val = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (mode & MODE_1280x1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) res_val = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) res_val = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (mode & FPS_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) fps_val = 0x1e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) fps_val = 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /* turn off IR-reset function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) write_register(gspca_dev, 0x105, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) /* Reset video stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) write_register(gspca_dev, 0x05, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* Due to some ridiculous condition in the firmware, we have to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * and stop the depth stream before the camera will hand us 1280x1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * IR. This is a stupid workaround, but we've yet to find a better
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * solution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * Thanks to Drew Fisher for figuring this out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (mode & (FORMAT_Y10B | MODE_1280x1024)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) write_register(gspca_dev, 0x13, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) write_register(gspca_dev, 0x14, 0x1e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) write_register(gspca_dev, 0x06, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) write_register(gspca_dev, 0x06, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) write_register(gspca_dev, fmt_reg, fmt_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) write_register(gspca_dev, res_reg, res_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) write_register(gspca_dev, fps_reg, fps_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* Start video stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) write_register(gspca_dev, 0x05, mode_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) /* disable Hflip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) write_register(gspca_dev, 0x47, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static int sd_start_depth(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /* turn off IR-reset function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) write_register(gspca_dev, 0x105, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /* reset depth stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) write_register(gspca_dev, 0x06, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /* Depth Stream Format 0x03: 11 bit stream | 0x02: 10 bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) write_register(gspca_dev, 0x12, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* Depth Stream Resolution 1: standard (640x480) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) write_register(gspca_dev, 0x13, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) /* Depth Framerate / 0x1e (30): 30 fps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) write_register(gspca_dev, 0x14, 0x1e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /* Depth Stream Control / 2: Open Depth Stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) write_register(gspca_dev, 0x06, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /* disable depth hflip / LSB = 0: Smoothing Disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) write_register(gspca_dev, 0x17, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) static void sd_stopN_video(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /* reset video stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) write_register(gspca_dev, 0x05, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static void sd_stopN_depth(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) /* reset depth stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) write_register(gspca_dev, 0x06, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static void sd_pkt_scan(struct gspca_dev *gspca_dev, u8 *__data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct pkt_hdr *hdr = (void *)__data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) uint8_t *data = __data + sizeof(*hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) int datalen = len - sizeof(*hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) uint8_t sof = sd->stream_flag | 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) uint8_t mof = sd->stream_flag | 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) uint8_t eof = sd->stream_flag | 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (len < 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (hdr->magic[0] != 'R' || hdr->magic[1] != 'B') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) pr_warn("[Stream %02x] Invalid magic %02x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) sd->stream_flag, hdr->magic[0], hdr->magic[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (hdr->flag == sof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) gspca_frame_add(gspca_dev, FIRST_PACKET, data, datalen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) else if (hdr->flag == mof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) gspca_frame_add(gspca_dev, INTER_PACKET, data, datalen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) else if (hdr->flag == eof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) gspca_frame_add(gspca_dev, LAST_PACKET, data, datalen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) pr_warn("Packet type not recognized...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /* sub-driver description */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static const struct sd_desc sd_desc_video = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) .name = MODULE_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) .config = sd_config_video,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) .init = sd_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) .start = sd_start_video,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) .stopN = sd_stopN_video,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) .pkt_scan = sd_pkt_scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) .get_streamparm = sd_get_streamparm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) .set_streamparm = sd_set_streamparm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static const struct sd_desc sd_desc_depth = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) .name = MODULE_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) .config = sd_config_depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) .init = sd_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) .start = sd_start_depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) .stopN = sd_stopN_depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) .pkt_scan = sd_pkt_scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) .get_streamparm = sd_get_streamparm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) .set_streamparm = sd_set_streamparm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) /* -- module initialisation -- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) static const struct usb_device_id device_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {USB_DEVICE(0x045e, 0x02ae)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) {USB_DEVICE(0x045e, 0x02bf)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) MODULE_DEVICE_TABLE(usb, device_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /* -- device connect -- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (depth_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) return gspca_dev_probe(intf, id, &sd_desc_depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) sizeof(struct sd), THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return gspca_dev_probe(intf, id, &sd_desc_video,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) sizeof(struct sd), THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static struct usb_driver sd_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) .name = MODULE_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) .id_table = device_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) .probe = sd_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) .disconnect = gspca_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) .suspend = gspca_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) .resume = gspca_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) .reset_resume = gspca_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) module_usb_driver(sd_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) module_param(depth_mode, bool, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) MODULE_PARM_DESC(depth_mode, "0=video 1=depth");