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