/* specific webcam descriptor */ struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ struct urb *last_data_urb;
u8 snapshot_pressed;
};
/* this function is called at probe time */ staticint sd_config(struct gspca_dev *gspca_dev, conststruct usb_device_id *id)
{
gspca_dev->cam.cam_mode = vga_mode;
gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
gspca_dev->cam.no_urb_create = 1;
return0;
}
/* this function is called at probe and resume time */ staticint sd_init(struct gspca_dev *gspca_dev)
{ int i;
/* *Thekonicaneedsafreakinglargetimeto"boot"(approx6.5sec.), *anddoesnotwanttobebotheredwhiledoingso:| *Register0x10countsfrom1-3,with3being"ready"
*/
msleep(6000); for (i = 0; i < 20; i++) {
reg_r(gspca_dev, 0, 0x10); if (gspca_dev->usb_buf[0] == 3) break;
msleep(100);
}
reg_w(gspca_dev, 0, 0x0d);
return gspca_dev->usb_err;
}
staticint sd_start(struct gspca_dev *gspca_dev)
{ struct sd *sd = (struct sd *) gspca_dev; struct urb *urb; int i, n, packet_size; struct usb_host_interface *alt; struct usb_interface *intf;
intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); if (!alt) {
pr_err("Couldn't get altsetting\n"); return -EIO;
}
konica_stream_off(gspca_dev); #if IS_ENABLED(CONFIG_INPUT) /* Don't keep the button in the pressed state "forever" if it was
pressed when streaming is stopped */ if (sd->snapshot_pressed) {
input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
input_sync(gspca_dev->input_dev);
sd->snapshot_pressed = 0;
} #endif
}
/* reception of an URB */ staticvoid sd_isoc_irq(struct urb *urb)
{ struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; struct sd *sd = (struct sd *) gspca_dev; struct urb *data_urb, *status_urb;
u8 *data; int i, st;
gspca_dbg(gspca_dev, D_PACK, "sd isoc irq\n"); if (!gspca_dev->streaming) return;
if (urb->status != 0) { if (urb->status == -ESHUTDOWN) return; /* disconnection */ #ifdef CONFIG_PM if (gspca_dev->frozen) return; #endif
gspca_err(gspca_dev, "urb status: %d\n", urb->status);
st = usb_submit_urb(urb, GFP_ATOMIC); if (st < 0)
pr_err("resubmit urb error %d\n", st); return;
}
/* if this is a data URB (ep 0x82), wait */ if (urb->transfer_buffer_length > 32) {
sd->last_data_urb = urb; return;
}
if (!data_urb || data_urb->start_frame != status_urb->start_frame) {
gspca_err(gspca_dev, "lost sync on frames\n"); goto resubmit;
}
if (data_urb->number_of_packets != status_urb->number_of_packets) {
gspca_err(gspca_dev, "no packets does not match, data: %d, status: %d\n",
data_urb->number_of_packets,
status_urb->number_of_packets); goto resubmit;
}
for (i = 0; i < status_urb->number_of_packets; i++) { if (data_urb->iso_frame_desc[i].status ||
status_urb->iso_frame_desc[i].status) {
gspca_err(gspca_dev, "pkt %d data-status %d, status-status %d\n",
i,
data_urb->iso_frame_desc[i].status,
status_urb->iso_frame_desc[i].status);
gspca_dev->last_packet_type = DISCARD_PACKET; continue;
}
if (status_urb->iso_frame_desc[i].actual_length != 1) {
gspca_err(gspca_dev, "bad status packet length %d\n",
status_urb->iso_frame_desc[i].actual_length);
gspca_dev->last_packet_type = DISCARD_PACKET; continue;
}
st = *((u8 *)status_urb->transfer_buffer
+ status_urb->iso_frame_desc[i].offset);
data = (u8 *)data_urb->transfer_buffer
+ data_urb->iso_frame_desc[i].offset;
resubmit: if (data_urb) {
st = usb_submit_urb(data_urb, GFP_ATOMIC); if (st < 0)
gspca_err(gspca_dev, "usb_submit_urb(data_urb) ret %d\n",
st);
}
st = usb_submit_urb(status_urb, GFP_ATOMIC); if (st < 0)
gspca_err(gspca_dev, "usb_submit_urb(status_urb) ret %d\n", st);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.