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