blob: 08c7485b537dd0ffdeac731f28b1a227615c1220 [file] [log] [blame]
/*
* Copyright (C) 1999-2000 by David Brownell <dbrownell@users.sourceforge.net>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* USB driver for Kodak DC-2XX series digital still cameras
*
* The protocol here is the same as the one going over a serial line, but
* it uses USB for speed. Set up /dev/kodak, get gphoto (www.gphoto.org),
* and have fun!
*
* This should also work for a number of other digital (non-Kodak) cameras,
* by adding the vendor and product IDs to the table below. They'll need
* to be the sort using USB just as a fast bulk data channel.
*/
/*
* HISTORY
*
* 26 August, 1999 -- first release (0.1), works with my DC-240.
* The DC-280 (2Mpixel) should also work, but isn't tested.
* If you use gphoto, make sure you have the USB updates.
* Lives in a 2.3.14 or so Linux kernel, in drivers/usb.
* 31 August, 1999 -- minor update to recognize DC-260 and handle
* its endpoints being in a different order. Note that as
* of gPhoto 0.36pre, the USB updates are integrated.
* 12 Oct, 1999 -- handle DC-280 interface class (0xff not 0x0);
* added timeouts to bulk_msg calls. Minor updates, docs.
* 03 Nov, 1999 -- update for 2.3.25 kernel API changes.
* 08 Jan, 2000 .. multiple camera support
* 12 Aug, 2000 .. add some real locking, remove an Oops
* 10 Oct, 2000 .. usb_device_id table created.
* 01 Nov, 2000 .. usb_device_id support added by Adam J. Richter
* 08 Apr, 2001 .. Identify version on module load. gb
*
* Thanks to: the folk who've provided USB product IDs, sent in
* patches, and shared their successes!
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/random.h>
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/devfs_fs_kernel.h>
#ifdef CONFIG_USB_DEBUG
#define DEBUG
#else
#undef DEBUG
#endif
#include <linux/usb.h>
/* /dev/usb dir. */
extern devfs_handle_t usb_devfs_handle;
/*
* Version Information
*/
#define DRIVER_VERSION "v1.0.0"
#define DRIVER_AUTHOR "David Brownell, <dbrownell@users.sourceforge.net>"
#define DRIVER_DESC "USB Camera Driver for Kodak DC-2xx series cameras"
/* current USB framework handles max of 16 USB devices per driver */
#define MAX_CAMERAS 16
/* USB char devs use USB_MAJOR and from USB_CAMERA_MINOR_BASE up */
#define USB_CAMERA_MINOR_BASE 80
// XXX remove packet size limit, now that bulk transfers seem fixed
/* Application protocol limit is 0x8002; USB has disliked that limit! */
#define MAX_PACKET_SIZE 0x2000 /* e.g. image downloading */
#define MAX_READ_RETRY 5 /* times to retry reads */
#define MAX_WRITE_RETRY 5 /* times to retry writes */
#define RETRY_TIMEOUT (HZ) /* sleep between retries */
/* table of cameras that work through this driver */
static struct usb_device_id camera_table [] = {
/* These have the same application level protocol */
{ USB_DEVICE(0x040a, 0x0120) }, // Kodak DC-240
{ USB_DEVICE(0x040a, 0x0130) }, // Kodak DC-280
{ USB_DEVICE(0x040a, 0x0131) }, // Kodak DC-5000
{ USB_DEVICE(0x040a, 0x0132) }, // Kodak DC-3400
/* These have a different application level protocol which
* is part of the Flashpoint "DigitaOS". That supports some
* non-camera devices, and some non-Kodak cameras.
* Use this driver to get USB and "OpenDis" to talk.
*/
{ USB_DEVICE(0x040a, 0x0100) }, // Kodak DC-220
{ USB_DEVICE(0x040a, 0x0110) }, // Kodak DC-260
{ USB_DEVICE(0x040a, 0x0111) }, // Kodak DC-265
{ USB_DEVICE(0x040a, 0x0112) }, // Kodak DC-290
{ USB_DEVICE(0xf003, 0x6002) }, // HP PhotoSmart C500
{ USB_DEVICE(0x03f0, 0x4102) }, // HP PhotoSmart C618
{ USB_DEVICE(0x0a17, 0x1001) }, // Pentax EI-200
/* Other USB devices may well work here too, so long as they
* just stick to half duplex bulk packet exchanges. That
* means, among other things, no iso or interrupt endpoints.
*/
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, camera_table);
struct camera_state {
struct usb_device *dev; /* USB device handle */
int inEP; /* read endpoint */
int outEP; /* write endpoint */
const struct usb_device_id *info; /* DC-240, etc */
int subminor; /* which minor dev #? */
struct semaphore sem; /* locks this struct */
/* this is non-null iff the device is open */
char *buf; /* buffer for I/O */
devfs_handle_t devfs; /* devfs device */
/* always valid */
wait_queue_head_t wait; /* for timed waits */
};
/* Support multiple cameras, possibly of different types. */
static struct camera_state *minor_data [MAX_CAMERAS];
/* make this an rwlock if contention becomes an issue */
static DECLARE_MUTEX (state_table_mutex);
static ssize_t camera_read (struct file *file,
char *buf, size_t len, loff_t *ppos)
{
struct camera_state *camera;
int retries;
int retval = 0;
if (len > MAX_PACKET_SIZE)
return -EINVAL;
camera = (struct camera_state *) file->private_data;
down (&camera->sem);
if (!camera->dev) {
up (&camera->sem);
return -ENODEV;
}
/* Big reads are common, for image downloading. Smaller ones
* are also common (even "directory listing" commands don't
* send very much data). We preserve packet boundaries here,
* they matter in the application protocol.
*/
for (retries = 0; retries < MAX_READ_RETRY; retries++) {
int count;
if (signal_pending (current)) {
retval = -EINTR;
break;
}
retval = usb_bulk_msg (camera->dev,
usb_rcvbulkpipe (camera->dev, camera->inEP),
camera->buf, len, &count, HZ*10);
dbg ("read (%Zd) - 0x%x %d", len, retval, count);
if (!retval) {
if (copy_to_user (buf, camera->buf, count))
retval = -EFAULT;
else
retval = count;
break;
}
if (retval != -ETIMEDOUT)
break;
interruptible_sleep_on_timeout (&camera->wait, RETRY_TIMEOUT);
dbg ("read (%Zd) - retry", len);
}
up (&camera->sem);
return retval;
}
static ssize_t camera_write (struct file *file,
const char *buf, size_t len, loff_t *ppos)
{
struct camera_state *camera;
ssize_t bytes_written = 0;
if (len > MAX_PACKET_SIZE)
return -EINVAL;
camera = (struct camera_state *) file->private_data;
down (&camera->sem);
if (!camera->dev) {
up (&camera->sem);
return -ENODEV;
}
/* most writes will be small: simple commands, sometimes with
* parameters. putting images (like borders) into the camera
* would be the main use of big writes.
*/
while (len > 0) {
char *obuf = camera->buf;
int maxretry = MAX_WRITE_RETRY;
unsigned long copy_size, thistime;
/* it's not clear that retrying can do any good ... or that
* fragmenting application packets into N writes is correct.
*/
thistime = copy_size = len;
if (copy_from_user (obuf, buf, copy_size)) {
bytes_written = -EFAULT;
break;
}
while (thistime) {
int result;
int count;
if (signal_pending (current)) {
if (!bytes_written)
bytes_written = -EINTR;
goto done;
}
result = usb_bulk_msg (camera->dev,
usb_sndbulkpipe (camera->dev, camera->outEP),
obuf, thistime, &count, HZ*10);
if (result)
dbg ("write USB err - %d", result);
if (count) {
obuf += count;
thistime -= count;
maxretry = MAX_WRITE_RETRY;
continue;
} else if (!result)
break;
if (result == -ETIMEDOUT) { /* NAK - delay a bit */
if (!maxretry--) {
if (!bytes_written)
bytes_written = -ETIME;
goto done;
}
interruptible_sleep_on_timeout (&camera->wait,
RETRY_TIMEOUT);
continue;
}
if (!bytes_written)
bytes_written = -EIO;
goto done;
}
bytes_written += copy_size;
len -= copy_size;
buf += copy_size;
}
done:
up (&camera->sem);
dbg ("wrote %Zd", bytes_written);
return bytes_written;
}
static int camera_open (struct inode *inode, struct file *file)
{
struct camera_state *camera = NULL;
int subminor;
int value = 0;
down (&state_table_mutex);
subminor = minor (inode->i_rdev) - USB_CAMERA_MINOR_BASE;
if (subminor < 0 || subminor >= MAX_CAMERAS
|| !(camera = minor_data [subminor])) {
up (&state_table_mutex);
return -ENODEV;
}
down (&camera->sem);
up (&state_table_mutex);
if (camera->buf) {
value = -EBUSY;
goto done;
}
if (!(camera->buf = (char *) kmalloc (MAX_PACKET_SIZE, GFP_KERNEL))) {
value = -ENOMEM;
goto done;
}
dbg ("open #%d", subminor);
file->private_data = camera;
done:
up (&camera->sem);
return value;
}
static int camera_release (struct inode *inode, struct file *file)
{
struct camera_state *camera;
int subminor;
camera = (struct camera_state *) file->private_data;
down (&state_table_mutex);
down (&camera->sem);
if (camera->buf) {
kfree (camera->buf);
camera->buf = 0;
}
subminor = camera->subminor;
/* If camera was unplugged with open file ... */
if (!camera->dev) {
minor_data [subminor] = NULL;
kfree (camera);
} else
up (&camera->sem);
up (&state_table_mutex);
dbg ("close #%d", subminor);
return 0;
}
/* XXX should define some ioctls to expose camera type
* to applications ... what USB exposes should suffice.
* apps should be able to see the camera type.
*/
static /* const */ struct file_operations usb_camera_fops = {
/* Uses GCC initializer extension; simpler to maintain */
owner: THIS_MODULE,
read: camera_read,
write: camera_write,
open: camera_open,
release: camera_release,
};
static void *
camera_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *camera_info)
{
int i;
struct usb_interface_descriptor *interface;
struct usb_endpoint_descriptor *endpoint;
int direction, ep;
char name[8];
struct camera_state *camera = NULL;
/* these have one config, one interface */
if (dev->descriptor.bNumConfigurations != 1
|| dev->config[0].bNumInterfaces != 1) {
dbg ("Bogus camera config info");
return NULL;
}
/* models differ in how they report themselves */
interface = &dev->actconfig->interface[ifnum].altsetting[0];
if ((interface->bInterfaceClass != USB_CLASS_PER_INTERFACE
&& interface->bInterfaceClass != USB_CLASS_VENDOR_SPEC)
|| interface->bInterfaceSubClass != 0
|| interface->bInterfaceProtocol != 0
|| interface->bNumEndpoints != 2
) {
dbg ("Bogus camera interface info");
return NULL;
}
/* select "subminor" number (part of a minor number) */
down (&state_table_mutex);
for (i = 0; i < MAX_CAMERAS; i++) {
if (!minor_data [i])
break;
}
if (i >= MAX_CAMERAS) {
info ("Ignoring additional USB Camera");
goto bye;
}
/* allocate & init camera state */
camera = minor_data [i] = kmalloc (sizeof *camera, GFP_KERNEL);
if (!camera) {
err ("no memory!");
goto bye;
}
init_MUTEX (&camera->sem);
camera->info = camera_info;
camera->subminor = i;
camera->buf = NULL;
init_waitqueue_head (&camera->wait);
/* get input and output endpoints (either order) */
endpoint = interface->endpoint;
camera->outEP = camera->inEP = -1;
ep = endpoint [0].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
direction = endpoint [0].bEndpointAddress & USB_ENDPOINT_DIR_MASK;
if (direction == USB_DIR_IN)
camera->inEP = ep;
else
camera->outEP = ep;
ep = endpoint [1].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
direction = endpoint [1].bEndpointAddress & USB_ENDPOINT_DIR_MASK;
if (direction == USB_DIR_IN)
camera->inEP = ep;
else
camera->outEP = ep;
if (camera->outEP == -1 || camera->inEP == -1
|| endpoint [0].bmAttributes != USB_ENDPOINT_XFER_BULK
|| endpoint [1].bmAttributes != USB_ENDPOINT_XFER_BULK
) {
dbg ("Bogus endpoints");
goto error;
}
info ("USB Camera #%d connected, major/minor %d/%d", camera->subminor,
USB_MAJOR, USB_CAMERA_MINOR_BASE + camera->subminor);
camera->dev = dev;
usb_inc_dev_use (dev);
/* If we have devfs, register the device */
sprintf(name, "dc2xx%d", camera->subminor);
camera->devfs = devfs_register(usb_devfs_handle, name,
DEVFS_FL_DEFAULT, USB_MAJOR,
USB_CAMERA_MINOR_BASE + camera->subminor,
S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP |
S_IWGRP, &usb_camera_fops, NULL);
goto bye;
error:
minor_data [camera->subminor] = NULL;
kfree (camera);
camera = NULL;
bye:
up (&state_table_mutex);
return camera;
}
static void camera_disconnect(struct usb_device *dev, void *ptr)
{
struct camera_state *camera = (struct camera_state *) ptr;
int subminor = camera->subminor;
down (&state_table_mutex);
down (&camera->sem);
devfs_unregister(camera->devfs);
/* If camera's not opened, we can clean up right away.
* Else apps see a disconnect on next I/O; the release cleans.
*/
if (!camera->buf) {
minor_data [subminor] = NULL;
kfree (camera);
camera = NULL;
} else
camera->dev = NULL;
info ("USB Camera #%d disconnected", subminor);
usb_dec_dev_use (dev);
if (camera != NULL)
up (&camera->sem);
up (&state_table_mutex);
}
static /* const */ struct usb_driver camera_driver = {
name: "dc2xx",
id_table: camera_table,
probe: camera_probe,
disconnect: camera_disconnect,
fops: &usb_camera_fops,
minor: USB_CAMERA_MINOR_BASE
};
int __init usb_dc2xx_init(void)
{
if (usb_register (&camera_driver) < 0)
return -1;
info(DRIVER_VERSION ":" DRIVER_DESC);
return 0;
}
void __exit usb_dc2xx_cleanup(void)
{
usb_deregister (&camera_driver);
}
module_init (usb_dc2xx_init);
module_exit (usb_dc2xx_cleanup);
MODULE_AUTHOR( DRIVER_AUTHOR );
MODULE_DESCRIPTION( DRIVER_DESC );
MODULE_LICENSE("GPL");