diff options
Diffstat (limited to 'camlibs/stv0680/stv0680.c')
-rw-r--r-- | camlibs/stv0680/stv0680.c | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/camlibs/stv0680/stv0680.c b/camlibs/stv0680/stv0680.c new file mode 100644 index 000000000..c24a2fb9a --- /dev/null +++ b/camlibs/stv0680/stv0680.c @@ -0,0 +1,331 @@ +/* + * STV0680 Vision Camera Chipset Driver + * Copyright © 2000 Adam Harrison <adam@antispin.org> + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <gphoto2/gphoto2.h> +#include <gphoto2/gphoto2-port.h> +#include <gphoto2/gphoto2-library.h> + +#ifdef ENABLE_NLS +# include <libintl.h> +# undef _ +# define _(String) dgettext (GETTEXT_PACKAGE, String) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#else +# define _(String) (String) +# define N_(String) (String) +#endif + +#include "stv0680.h" +#include "library.h" + +#define GP_MODULE "stv0680" + +static const struct camera_to_usb { + char *name; + unsigned short idVendor; + unsigned short idProduct; + int serial; +} camera_to_usb[] = { + /* http://www.vvl.co.uk/products/co-processors/680/680.htm */ + { "STM:USB Dual-mode camera", 0x0553, 0x0202, 1 }, + { "STV0680", 0x0553, 0x0202, 1 }, + + /* You can search in google for them, using either: + * AAA 80 CIF + * or + * AAA 26 VGA + * It has been rebranded and rereleased dozens of times. + */ + + /* According to: http://www.bazelet.com/generic74.html */ + { "SpyPen:Axys", 0x0553, 0x0202, 0 }, + { "SpyPen:Cleo", 0x0553, 0x0202, 0 }, + { "SpyPen:Xion", 0x0553, 0x0202, 0 }, + { "SpyPen:Memo", 0x0553, 0x0202, 0 }, + + /* Tested by Priit Laes <amd@tt.ee> */ + { "SpyPen:Luxo", 0x0553, 0x0202, 0 }, + + /* http://www.iomagic.com/support/digitalcameras/magicimage400/magicimage400manual.htm */ + { "IOMagic:MagicImage 400", 0x0553, 0x0202, 0 }, + /* http://www.pctekonline.com/phoebsmardig.html */ + { "Phoebe:Smartcam", 0x0553, 0x0202, 0 }, + { "QuickPix:QP1", 0x0553, 0x0202, 0 }, + { "Hawking:DC120 Pocketcam", 0x0553, 0x0202, 0 }, + { "Aiptek:PenCam Trio", 0x0553, 0x0202, 0 }, + /* reported by Klaus-M. Klingsporn */ + { "Aiptek:PalmCam Trio", 0x0553, 0x0202, 0 }, + /* Made by Medion (ALDI hw reseller). Their homepage is broken, so + * no URL. This is the camera I have -Marcus. CIF */ + { "Micromaxx:Digital Camera", 0x0553, 0x0202, 0 }, + + /* http://www.digitaldreamco.com/shop/elegante.htm, VGA */ + { "DigitalDream:l'elegante", 0x0553, 0x0202, 0 }, + /* http://www.digitaldreamco.com/shop/espion.htm, CIF */ + { "DigitalDream:l'espion", 0x0553, 0x0202, 0 }, + /* http://www.digitaldreamco.com/shop/lesprit.html, CIF */ + { "DigitalDream:l'esprit", 0x0553, 0x0202, 0 }, + /* http://www.digitaldreamco.com/shop/laronde.htm, VGA */ + { "DigitalDream:la ronde", 0x0553, 0x0202, 0 }, + /* https://sf.net/tracker/index.php?func=detail&aid=1000498&group_id=8874&atid=358874 */ + { "DigitalDream:l'espion XS", 0x1183, 0x0001, 0 }, + + + /* reported by jerry white */ + { "Argus:DC-1500", 0x0553, 0x0202, 1 }, + /* reported by Philippe Libat <philippe@mandrakesoft.com>, + * serial only. */ + { "Yahoo!Cam", 0x0 , 0x0 , 1 }, + + { "AEG:Snap 300", 0x0553, 0x0202, 0 }, + + /* ALDI (german discounter) version */ + { "Pencam:TEVION MD 9456", 0x0553, 0x0202, 0 }, + + /* http://www.umax.de/digicam/AstraPen_SL.htm. + * There is an additional 100K (CIF), 300K (VGA) tag after the name. */ + { "UMAX:AstraPen", 0x0553, 0x0202, 0 }, /* SV and SL */ + + { "Fuji:IX-1", 0x0553, 0x0202, 0 }, /* Unconfirmed */ + /* Added for the konica e-mini by Roland Marcus Rutschmann<Rutschmann@gmx.de>*/ + { "Konica:e-mini", 0x04c8, 0x0722, 0 }, + + { "Che-ez!:Babe", 0x0553, 0x0202, 0 }, + { "Che-ez!:SPYZ", 0x0553, 0x0202, 0 }, + + /* According to Sonic Tsunami <mmcburn86@earthlink.net> */ + /* http://www.timlex.com/cif.html */ + { "Timlex:CP075", 0x0553, 0x0202, 1 }, + + { "Creative:Go Mini", 0x041e, 0x4007, 1 } +}; + +int camera_id (CameraText *id) +{ + strcpy(id->text, "STV0680"); + + return (GP_OK); +} + +int camera_abilities (CameraAbilitiesList *list) +{ + CameraAbilities a; + unsigned int i; + + /* 10/11/01/cw rewritten to add cameras via array */ + + for (i = 0; i < sizeof(camera_to_usb) / sizeof(struct camera_to_usb); i++) { + + memset(&a, 0, sizeof(a)); + strcpy(a.model, camera_to_usb[i].name); + + a.port = 0; + /* serial status is experimental, usb status is testing */ + a.status = GP_DRIVER_STATUS_EXPERIMENTAL; + a.operations = GP_OPERATION_CAPTURE_IMAGE; + a.file_operations = GP_FILE_OPERATION_PREVIEW; + a.folder_operations = GP_FOLDER_OPERATION_DELETE_ALL; + + if (camera_to_usb[i].idVendor) { + a.status = GP_DRIVER_STATUS_PRODUCTION; + a.port |= GP_PORT_USB; + a.operations |= GP_OPERATION_CAPTURE_PREVIEW; + a.usb_vendor = camera_to_usb[i].idVendor; + a.usb_product = camera_to_usb[i].idProduct; + } + if (camera_to_usb[i].serial) { + a.port |= GP_PORT_SERIAL; + a.speed[0] = 115200; + a.speed[1] = 0; + } + gp_abilities_list_append(list, a); + } + + return (GP_OK); +} + +static int file_list_func (CameraFilesystem *fs, const char *folder, + CameraList *list, void *data, GPContext *context) +{ + Camera *camera = data; + int count, result; + + result = stv0680_file_count(camera->port, &count); + if (result != GP_OK) + return result; + + gp_list_populate(list, "image%03i.pnm", count); + + return (GP_OK); +} + + + +static int get_file_func (CameraFilesystem *fs, const char *folder, + const char *filename, CameraFileType type, + CameraFile *file, void *user_data, GPContext *context) +{ + Camera *camera = user_data; + int image_no, result; + + image_no = gp_filesystem_number(camera->fs, folder, filename, context); + if(image_no < 0) + return image_no; + + gp_file_set_name (file, filename); + gp_file_set_mime_type (file, GP_MIME_PNM); + switch (type) { + case GP_FILE_TYPE_NORMAL: + result = stv0680_get_image (camera->port, image_no, file); + break; + case GP_FILE_TYPE_RAW: + result = stv0680_get_image_raw (camera->port, image_no, file); + break; + case GP_FILE_TYPE_PREVIEW: + result = stv0680_get_image_preview (camera->port, image_no, file); + break; + default: + return (GP_ERROR_NOT_SUPPORTED); + } + return result; +} + +static int camera_capture (Camera *camera, CameraCaptureType type, CameraFilePath *path, GPContext *context) +{ + int result; + int count,oldcount; + + if (type != GP_CAPTURE_IMAGE) + return (GP_ERROR_NOT_SUPPORTED); + result = stv0680_file_count(camera->port,&oldcount); + + result = stv0680_capture(camera->port); + if (result < 0) + return result; + + /* Just added a new picture... */ + result = stv0680_file_count(camera->port,&count); + if (count == oldcount) + return GP_ERROR; /* unclear what went wrong ... hmm */ + strcpy(path->folder,"/"); + sprintf(path->name,"image%03i.pnm",count); + + /* Tell the filesystem about it */ + result = gp_filesystem_append (camera->fs, path->folder, path->name, + context); + if (result < 0) + return (result); + + return (GP_OK); +} + +static int camera_capture_preview (Camera *camera, CameraFile *file, GPContext *context) +{ + char *data; + int size, result; + + result = stv0680_capture_preview (camera->port, &data, &size); + if (result < 0) + return result; + + gp_file_set_name (file, "capture.pnm"); + gp_file_set_mime_type (file, GP_MIME_PNM); + gp_file_set_data_and_size (file, data, size); + + return (GP_OK); +} + +static int camera_summary (Camera *camera, CameraText *summary, GPContext *context) +{ + stv0680_summary(camera->port,summary->text); + return (GP_OK); +} + +static int camera_about (Camera *camera, CameraText *about, GPContext *context) +{ + strcpy (about->text, + _("STV0680\n" + "Adam Harrison <adam@antispin.org>\n" + "Driver for cameras using the STV0680 processor ASIC.\n" + "Protocol reverse engineered using CommLite Beta 5\n" + "Carsten Weinholz <c.weinholz@netcologne.de>\n" + "Extended for Aiptek PenCam and other STM USB Dual-mode cameras.")); + + return (GP_OK); +} + +static int +delete_all_func (CameraFilesystem *fs, const char* folder, void *data, + GPContext *context) +{ + Camera *camera = data; + if (strcmp (folder, "/")) + return (GP_ERROR_DIRECTORY_NOT_FOUND); + return stv0680_delete_all(camera->port); +} + +static CameraFilesystemFuncs fsfuncs = { + .file_list_func = file_list_func, + .get_file_func = get_file_func, + .delete_all_func = delete_all_func, +}; + +int camera_init (Camera *camera, GPContext *context) +{ + GPPortSettings settings; + + /* First, set up all the function pointers */ + camera->functions->summary = camera_summary; + camera->functions->about = camera_about; + camera->functions->capture_preview = camera_capture_preview; + camera->functions->capture = camera_capture; + + gp_port_get_settings(camera->port, &settings); + switch(camera->port->type) { + case GP_PORT_SERIAL: + gp_port_set_timeout(camera->port, 1000); + settings.serial.speed = 115200; + settings.serial.bits = 8; + settings.serial.parity = 0; + settings.serial.stopbits = 1; + break; + case GP_PORT_USB: + /* Use the defaults the core parsed */ + break; + default: + return (GP_ERROR_UNKNOWN_PORT); + break; + } + gp_port_set_settings(camera->port, settings); + + /* Set up the filesystem */ + gp_filesystem_set_funcs (camera->fs, &fsfuncs, camera); + + /* test camera */ + return stv0680_ping(camera->port); +} |