📄 fps200usb.c
字号:
break; } if (s->readptr == 0) { /* start the acquisition process */ if (fps200_usb_StartImageAcquisition(s->usbdev, s->x, s->y, s->width, s->height) < 0){ ret = -EIO; break; } /* set up our urb */#if (LINUX_VERSION_CODE < USB_SUPPORT_KERNEL) /* the old way */ FILL_BULK_URB(s->read_urb, s->usbdev, usb_rcvbulkpipe(s->usbdev, FPS200_USB_ENDPOINT_READDATA), s->bulk_in_buffer, s->bulk_in_size, (usb_complete_t)fps200_read_bulk_callback, s);#else /* the new recommendation */ usb_fill_bulk_urb(s->read_urb, s->usbdev, usb_rcvbulkpipe(s->usbdev, FPS200_USB_ENDPOINT_READDATA), s->bulk_in_buffer, s->bulk_in_size, (usb_complete_t)fps200_read_bulk_callback, s);#endif /* starts the read of the bulk port */ codret = usb_submit_urb(s->read_urb); if (codret) { ferr("failed submitting write urb, error %d", codret); ret = -EIO; break; } else { /* waits for the data */ interruptible_sleep_on (&s->waitReadCompletion); if (!s->statusDataReceived){ ret = -EIO; break; } rem = s->header_size+s->image_size; } } /* if it is in the start of the file gets the image from the sensor */ else { rem = (s->header_size+s->image_size)-s->readptr; } /* if it is not at the start of the file the image was read already */ if (rem == 0){ /* reach the end of the file */ break; } if (count >= rem) cnt = rem; else cnt = count; if (s->readptr < s->header_size){ /*fdbg("transfering the header. cnt=%d count=%d new cnt=%d", cnt, count, min(cnt, s->header_size));*/ cnt = min(cnt, s->header_size); } if (s->readptr < s->header_size){ if (copy_to_user (buf, s->file_header + s->readptr, cnt)) { err("read: copy_to_user failed"); if (!ret) ret = -EFAULT; break; } } else { if (copy_to_user (buf, s->bulk_in_buffer + s->readptr - s->header_size, cnt)) { err("read: copy_to_user failed"); if (!ret) ret = -EFAULT; break; } } s->readptr += cnt; *ppos += cnt; count -= cnt; buf += cnt; ret += cnt; } if (s->readptr >= (s->header_size+s->image_size)){ *ppos = 0; s->readptr = 0; } up(&s->mutex); return ret;}/*----------------------------------------------------------------*//* \brief implements the open operation on the driver * \param inode parameter passed by the kernel * \param file pointer to the file struct * \return return values conforming to the open function. */static int fps200usb_open (struct inode *inode, struct file *file){ int devnum = MINOR (inode->i_rdev); pfps200usb_t s; int ret; if (devnum < minor || devnum >= (minor + NRSENSORS)){ fdbg("error getting devnum"); return -EIO; } s = &fsusb[devnum - minor]; fdbg("s=%p devnum=%d", s, devnum); down (&s->mutex); while (!s->usbdev || s->opened) { up (&s->mutex); if (file->f_flags & O_NONBLOCK) { return -EBUSY; } schedule_timeout (HZ / 2); if (signal_pending (current)) { return -EAGAIN; } down (&s->mutex); } s->opened = 1; s->state = _started; up (&s->mutex); file->f_pos = 0; file->private_data = s; s->readptr = 0; /* initializes the sensor */ ret=fps200_usb_sensorInitialization(s); if (ret < 0){ s->opened = 0; return -ENODEV; }#ifdef INTERRUPT_HANDLING /* start interrupt handling */ fdbg("submitting irq_urb"); fps200usb_configInterrupt(s); if (usb_submit_urb(&s->irq_urb)){ s->opened = 0; err("Could not submit the irq_urb"); return -ENODEV; }#endif return 0;}/* ---------------------------------------------------------------- *//* \brief called when the file is closed by the user program * \param inode parameter passed by the kernel * \param file pointer to the file struct * \return return values conforming to the release function. */static int fps200usb_release (struct inode *inode, struct file *file){ pfps200usb_t s = (pfps200usb_t) file->private_data; fdbg("s=%p", s); lock_kernel(); down (&s->mutex); /* stop usb here */ /* restore the defaults for the next open process */ fps200usb_configureImage(s, FPS200_FILEFORMAT_DEFAULT, 0, 0, FPS200_WIDTH, FPS200_HEIGHT);#ifdef INTERRUPT_HANDLING /* stop handling interrupts */ fdbg("unlinking irq_urb"); usb_unlink_urb (&s->irq_urb);#endif /* disable the sensor */ fps200_usb_sensorDisable(s->usbdev); up (&s->mutex); if (!s->remove_pending) { s->state = _stopped; } else { wake_up (&s->remove_ok); } /* shutdown any bulk writes that might be going on */ if (s->read_urb) usb_unlink_urb (s->read_urb); s->opened = 0; unlock_kernel(); return 0;}/* ---------------------------------------------------------------- *//* \brief IO control function * \param inode parameter passed by the kernel * \param file pointer to the file struct * \param cmd the command to be passed to the driver * \param arg the argument to the command * \return return values depending of the solicited cmd. */static int fps200usb_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ struct fps200_dimension *rect; unsigned char readValue; unsigned int regindex; pfps200usb_t s = (pfps200usb_t) file->private_data; int ret = 0; fdbg("fps200usb_ioctl cmd=%u arg=%lu", cmd, arg); if (s->remove_pending) return -EIO; down (&s->mutex); if (!s->usbdev) { up (&s->mutex); return -EIO; } ret = -1; /* default to indicate error */ switch (cmd) { /* write operations */ case FPS200_IOCTL_VERSION: ret=VERSION_NUMBER; break; case FPS200_IOCTL_ENABLE: if (arg == 0) ret=fps200_usb_sensorDisable(s->usbdev); else ret=fps200_usb_sensorInitialization(s); break; case FPS200_IOCTL_SETRECT: rect = (struct fps200_dimension *)arg; if (rect != NULL) { if ((rect->width > 0) && (rect->width <= FPS200_WIDTH) && (rect->height > 0) && (rect->height <= FPS200_HEIGHT) && (rect->x >= 0) && ((rect->x+rect->width) <= FPS200_WIDTH) && (rect->y >= 0) && ((rect->y+rect->height) <= FPS200_HEIGHT)){ /* ok - it's safe to change */ if (fps200usb_configureImage(s, s->file_format, rect->x, rect->y, rect->width, rect->height) == 0){ ret = 0; } } else { ferr("you specified parameters out of the sensor area"); } } break; case FPS200_IOCTL_SETFORMAT: ret=fps200usb_configureImage(s, arg, s->x, s->y, s->width, s->height); break; case FPS200_IOCTL_SETDTR: if ((unsigned char)arg != dtr){ dtr = (unsigned char)arg; ret=fps200_usb_writeRegister(s->usbdev, FPS200_DTR, dtr); } else ret = 0; break; case FPS200_IOCTL_SETDCR: if ((unsigned char)arg != dcr){ dcr = (unsigned char)arg; ret=fps200_usb_writeRegister(s->usbdev, FPS200_DCR, dcr); } else ret = 0; break; case FPS200_IOCTL_SETPGC: if ((unsigned char)arg != pgc){ pgc = (unsigned char)arg; ret=fps200_usb_writeRegister(s->usbdev, FPS200_PGC, pgc); } else ret = 0; break; case FPS200_IOCTL_SETTHR: if ((unsigned char)arg != thr){ thr = (unsigned char)arg; ret=fps200_usb_writeRegister(s->usbdev, FPS200_THR, thr); } else ret = 0; break; case FPS200_IOCTL_RESET_PARAMETERS: dtr = parcopy.dtr; dcr = parcopy.dcr; pgc = parcopy.pgc; thr = parcopy.pgc; if (fps200_usb_writeRegister(s->usbdev, FPS200_DTR, dtr) < 0) break; if (fps200_usb_writeRegister(s->usbdev, FPS200_DCR, dcr) < 0) break; if (fps200_usb_writeRegister(s->usbdev, FPS200_PGC, pgc) < 0) break; if (fps200_usb_writeRegister(s->usbdev, FPS200_THR, thr) < 0) break; ret = 0; break;#ifdef ENABLEDIRECTACCESS case FPS200_IOCTL_WRITEREG: regindex = (unsigned int)arg; if (fps200_usb_writeRegister(s->usbdev, regindex >> 8, regindex) == 0) ret = 0; break;#endif case FPS200_IOCTL_CONTROLOUTPUTPINS: if (fps200_usb_writeRegister(s->usbdev, FPS200_CTRLC, (unsigned char)arg) == 0) ret = 0; break; /* read operations */ case FPS200_IOCTL_GETENABLESTATE: if (fps200_usb_readRegister(s->usbdev, FPS200_CTRLB, &readValue) >= 0) ret = (readValue & FPS200_CTRLB_ENABLE)?1:0; break; case FPS200_IOCTL_GETDTR: if (fps200_usb_readRegister(s->usbdev, FPS200_DTR, &readValue) >= 0) ret = readValue; break; case FPS200_IOCTL_GETDCR: if (fps200_usb_readRegister(s->usbdev, FPS200_DCR, &readValue) >= 0) ret = readValue; break; case FPS200_IOCTL_GETPGC: if (fps200_usb_readRegister(s->usbdev, FPS200_PGC, &readValue) >= 0) ret = readValue; break; case FPS200_IOCTL_GETTHR: if (fps200_usb_readRegister(s->usbdev, FPS200_THR, &readValue) >= 0) ret = readValue; break; case FPS200_IOCTL_GETFILEFORMAT: ret = s->file_format; case FPS200_IOCTL_GETRECT: rect = (struct fps200_dimension *)arg; rect->x = s->x; rect->y = s->y; rect->width = s->width; rect->height = s->height; break; case FPS200_IOCTL_READREG: regindex = (unsigned int)arg; if (fps200_usb_readRegister(s->usbdev, regindex >> 8, &readValue) >= 0) ret = readValue; break; case FPS200_IOCTL_READAIN: /* starts the acquisition */ if (fps200_usb_writeRegister(s->usbdev, FPS200_CTRLA, FPS200_CTRLA_AINSEL | FPS200_CTRLA_GETROW) == 0) { if (fps200_usb_readRegister(s->usbdev, FPS200_CTRLA, &readValue) >= 0) ret = readValue; } break; default: ret = -ENOIOCTLCMD; break; } up (&s->mutex); return ret;}/* ---------------------------------------------------------------- */static struct file_operations fps200usb_fops = { owner: THIS_MODULE, read: fps200usb_read, ioctl: fps200usb_ioctl, open: fps200usb_open, release: fps200usb_release,};/* ---------------------------------------------------------------- */static int fps200usb_find_struct (void){ int u; for (u = 0; u < NRSENSORS; u++) { pfps200usb_t s = &fsusb[u]; if (!s->usbdev) return u; } return -1;}/* --------------------------------------------------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -