linux/drivers/media/usb/gspca/benq.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Benq DC E300 subdriver
   4 *
   5 * Copyright (C) 2009 Jean-Francois Moine (http://moinejf.free.fr)
   6 */
   7
   8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   9
  10#define MODULE_NAME "benq"
  11
  12#include "gspca.h"
  13
  14MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
  15MODULE_DESCRIPTION("Benq DC E300 USB Camera Driver");
  16MODULE_LICENSE("GPL");
  17
  18/* specific webcam descriptor */
  19struct sd {
  20        struct gspca_dev gspca_dev;     /* !! must be the first item */
  21};
  22
  23static const struct v4l2_pix_format vga_mode[] = {
  24        {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  25                .bytesperline = 320,
  26                .sizeimage = 320 * 240 * 3 / 8 + 590,
  27                .colorspace = V4L2_COLORSPACE_JPEG},
  28};
  29
  30static void sd_isoc_irq(struct urb *urb);
  31
  32/* -- write a register -- */
  33static void reg_w(struct gspca_dev *gspca_dev,
  34                        u16 value, u16 index)
  35{
  36        struct usb_device *dev = gspca_dev->dev;
  37        int ret;
  38
  39        if (gspca_dev->usb_err < 0)
  40                return;
  41        ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
  42                        0x02,
  43                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  44                        value,
  45                        index,
  46                        NULL,
  47                        0,
  48                        500);
  49        if (ret < 0) {
  50                pr_err("reg_w err %d\n", ret);
  51                gspca_dev->usb_err = ret;
  52        }
  53}
  54
  55/* this function is called at probe time */
  56static int sd_config(struct gspca_dev *gspca_dev,
  57                        const struct usb_device_id *id)
  58{
  59        gspca_dev->cam.cam_mode = vga_mode;
  60        gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
  61        gspca_dev->cam.no_urb_create = 1;
  62        return 0;
  63}
  64
  65/* this function is called at probe and resume time */
  66static int sd_init(struct gspca_dev *gspca_dev)
  67{
  68        return 0;
  69}
  70
  71/* -- start the camera -- */
  72static int sd_start(struct gspca_dev *gspca_dev)
  73{
  74        struct urb *urb;
  75        int i, n;
  76
  77        /* create 4 URBs - 2 on endpoint 0x83 and 2 on 0x082 */
  78#if MAX_NURBS < 4
  79#error "Not enough URBs in the gspca table"
  80#endif
  81#define SD_PKT_SZ 64
  82#define SD_NPKT 32
  83        for (n = 0; n < 4; n++) {
  84                urb = usb_alloc_urb(SD_NPKT, GFP_KERNEL);
  85                if (!urb)
  86                        return -ENOMEM;
  87                gspca_dev->urb[n] = urb;
  88                urb->transfer_buffer = usb_alloc_coherent(gspca_dev->dev,
  89                                                SD_PKT_SZ * SD_NPKT,
  90                                                GFP_KERNEL,
  91                                                &urb->transfer_dma);
  92
  93                if (urb->transfer_buffer == NULL) {
  94                        pr_err("usb_alloc_coherent failed\n");
  95                        return -ENOMEM;
  96                }
  97                urb->dev = gspca_dev->dev;
  98                urb->context = gspca_dev;
  99                urb->transfer_buffer_length = SD_PKT_SZ * SD_NPKT;
 100                urb->pipe = usb_rcvisocpipe(gspca_dev->dev,
 101                                        n & 1 ? 0x82 : 0x83);
 102                urb->transfer_flags = URB_ISO_ASAP
 103                                        | URB_NO_TRANSFER_DMA_MAP;
 104                urb->interval = 1;
 105                urb->complete = sd_isoc_irq;
 106                urb->number_of_packets = SD_NPKT;
 107                for (i = 0; i < SD_NPKT; i++) {
 108                        urb->iso_frame_desc[i].length = SD_PKT_SZ;
 109                        urb->iso_frame_desc[i].offset = SD_PKT_SZ * i;
 110                }
 111        }
 112
 113        return gspca_dev->usb_err;
 114}
 115
 116static void sd_stopN(struct gspca_dev *gspca_dev)
 117{
 118        struct usb_interface *intf;
 119
 120        reg_w(gspca_dev, 0x003c, 0x0003);
 121        reg_w(gspca_dev, 0x003c, 0x0004);
 122        reg_w(gspca_dev, 0x003c, 0x0005);
 123        reg_w(gspca_dev, 0x003c, 0x0006);
 124        reg_w(gspca_dev, 0x003c, 0x0007);
 125
 126        intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
 127        usb_set_interface(gspca_dev->dev, gspca_dev->iface,
 128                                        intf->num_altsetting - 1);
 129}
 130
 131static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 132                        u8 *data,               /* isoc packet */
 133                        int len)                /* iso packet length */
 134{
 135        /* unused */
 136}
 137
 138/* reception of an URB */
 139static void sd_isoc_irq(struct urb *urb)
 140{
 141        struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
 142        struct urb *urb0;
 143        u8 *data;
 144        int i, st;
 145
 146        gspca_dbg(gspca_dev, D_PACK, "sd isoc irq\n");
 147        if (!gspca_dev->streaming)
 148                return;
 149        if (urb->status != 0) {
 150                if (urb->status == -ESHUTDOWN)
 151                        return;         /* disconnection */
 152#ifdef CONFIG_PM
 153                if (gspca_dev->frozen)
 154                        return;
 155#endif
 156                pr_err("urb status: %d\n", urb->status);
 157                return;
 158        }
 159
 160        /* if this is a control URN (ep 0x83), wait */
 161        if (urb == gspca_dev->urb[0] || urb == gspca_dev->urb[2])
 162                return;
 163
 164        /* scan both received URBs */
 165        if (urb == gspca_dev->urb[1])
 166                urb0 = gspca_dev->urb[0];
 167        else
 168                urb0 = gspca_dev->urb[2];
 169        for (i = 0; i < urb->number_of_packets; i++) {
 170
 171                /* check the packet status and length */
 172                if (urb0->iso_frame_desc[i].actual_length != SD_PKT_SZ
 173                    || urb->iso_frame_desc[i].actual_length != SD_PKT_SZ) {
 174                        gspca_err(gspca_dev, "ISOC bad lengths %d / %d\n",
 175                                  urb0->iso_frame_desc[i].actual_length,
 176                                  urb->iso_frame_desc[i].actual_length);
 177                        gspca_dev->last_packet_type = DISCARD_PACKET;
 178                        continue;
 179                }
 180                st = urb0->iso_frame_desc[i].status;
 181                if (st == 0)
 182                        st = urb->iso_frame_desc[i].status;
 183                if (st) {
 184                        pr_err("ISOC data error: [%d] status=%d\n",
 185                                i, st);
 186                        gspca_dev->last_packet_type = DISCARD_PACKET;
 187                        continue;
 188                }
 189
 190                /*
 191                 * The images are received in URBs of different endpoints
 192                 * (0x83 and 0x82).
 193                 * Image pieces in URBs of ep 0x83 are continuated in URBs of
 194                 * ep 0x82 of the same index.
 195                 * The packets in the URBs of endpoint 0x83 start with:
 196                 *      - 80 ba/bb 00 00 = start of image followed by 'ff d8'
 197                 *      - 04 ba/bb oo oo = image piece
 198                 *              where 'oo oo' is the image offset
 199                                                (not checked)
 200                 *      - (other -> bad frame)
 201                 * The images are JPEG encoded with full header and
 202                 * normal ff escape.
 203                 * The end of image ('ff d9') may occur in any URB.
 204                 * (not checked)
 205                 */
 206                data = (u8 *) urb0->transfer_buffer
 207                                        + urb0->iso_frame_desc[i].offset;
 208                if (data[0] == 0x80 && (data[1] & 0xfe) == 0xba) {
 209
 210                        /* new image */
 211                        gspca_frame_add(gspca_dev, LAST_PACKET,
 212                                        NULL, 0);
 213                        gspca_frame_add(gspca_dev, FIRST_PACKET,
 214                                        data + 4, SD_PKT_SZ - 4);
 215                } else if (data[0] == 0x04 && (data[1] & 0xfe) == 0xba) {
 216                        gspca_frame_add(gspca_dev, INTER_PACKET,
 217                                        data + 4, SD_PKT_SZ - 4);
 218                } else {
 219                        gspca_dev->last_packet_type = DISCARD_PACKET;
 220                        continue;
 221                }
 222                data = (u8 *) urb->transfer_buffer
 223                                        + urb->iso_frame_desc[i].offset;
 224                gspca_frame_add(gspca_dev, INTER_PACKET,
 225                                data, SD_PKT_SZ);
 226        }
 227
 228        /* resubmit the URBs */
 229        st = usb_submit_urb(urb0, GFP_ATOMIC);
 230        if (st < 0)
 231                pr_err("usb_submit_urb(0) ret %d\n", st);
 232        st = usb_submit_urb(urb, GFP_ATOMIC);
 233        if (st < 0)
 234                pr_err("usb_submit_urb() ret %d\n", st);
 235}
 236
 237/* sub-driver description */
 238static const struct sd_desc sd_desc = {
 239        .name = MODULE_NAME,
 240        .config = sd_config,
 241        .init = sd_init,
 242        .start = sd_start,
 243        .stopN = sd_stopN,
 244        .pkt_scan = sd_pkt_scan,
 245};
 246
 247/* -- module initialisation -- */
 248static const struct usb_device_id device_table[] = {
 249        {USB_DEVICE(0x04a5, 0x3035)},
 250        {}
 251};
 252MODULE_DEVICE_TABLE(usb, device_table);
 253
 254/* -- device connect -- */
 255static int sd_probe(struct usb_interface *intf,
 256                        const struct usb_device_id *id)
 257{
 258        return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
 259                                THIS_MODULE);
 260}
 261
 262static struct usb_driver sd_driver = {
 263        .name = MODULE_NAME,
 264        .id_table = device_table,
 265        .probe = sd_probe,
 266        .disconnect = gspca_disconnect,
 267#ifdef CONFIG_PM
 268        .suspend = gspca_suspend,
 269        .resume = gspca_resume,
 270        .reset_resume = gspca_resume,
 271#endif
 272};
 273
 274module_usb_driver(sd_driver);
 275