X-Git-Url: https://git.ao2.it/libam7xxx.git/blobdiff_plain/759559da7fb9c03e5f42eab12acbc01ebe763186..25f3a9107b11f84ad5b94335bc15beabaaac8d4b:/src/am7xxx.c diff --git a/src/am7xxx.c b/src/am7xxx.c index 76b997c..ffdd59c 100644 --- a/src/am7xxx.c +++ b/src/am7xxx.c @@ -26,6 +26,7 @@ #include "am7xxx.h" #include "serialize.h" +#include "tools.h" #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) @@ -79,7 +80,9 @@ struct am7xxx_usb_device_descriptor { }; static int default_set_power_mode(am7xxx_device *dev, am7xxx_power_mode power); +static int picopix_set_power_mode(am7xxx_device *dev, am7xxx_power_mode power); static int default_set_zoom_mode(am7xxx_device *dev, am7xxx_zoom_mode zoom); +static int picopix_set_zoom_mode(am7xxx_device *dev, am7xxx_zoom_mode zoom); #define DEFAULT_OPS { \ .set_power_mode = default_set_power_mode, \ @@ -125,6 +128,10 @@ static const struct am7xxx_usb_device_descriptor supported_devices[] = { .product_id = 0x0016, .configuration = 2, .interface_number = 0, + .ops = { + .set_power_mode = picopix_set_power_mode, + .set_zoom_mode = picopix_set_zoom_mode, + }, }, { .name = "Philips/Sagemcom PicoPix 2330", @@ -163,6 +170,11 @@ typedef enum { AM7XXX_PACKET_TYPE_IMAGE = 0x02, AM7XXX_PACKET_TYPE_POWER = 0x04, AM7XXX_PACKET_TYPE_ZOOM = 0x05, + AM7XXX_PACKET_TYPE_PICOPIX_POWER_LOW = 0x15, + AM7XXX_PACKET_TYPE_PICOPIX_POWER_MEDIUM = 0x16, + AM7XXX_PACKET_TYPE_PICOPIX_POWER_HIGH = 0x17, + AM7XXX_PACKET_TYPE_PICOPIX_ENABLE_TI = 0x18, + AM7XXX_PACKET_TYPE_PICOPIX_DISABLE_TI = 0x19, } am7xxx_packet_type; struct am7xxx_generic_header { @@ -890,6 +902,26 @@ static int default_set_power_mode(am7xxx_device *dev, am7xxx_power_mode power) return 0; } +static int picopix_set_power_mode(am7xxx_device *dev, am7xxx_power_mode power) +{ + switch(power) { + case AM7XXX_POWER_LOW: + return send_command(dev, AM7XXX_PACKET_TYPE_PICOPIX_POWER_LOW); + + case AM7XXX_POWER_MIDDLE: + return send_command(dev, AM7XXX_PACKET_TYPE_PICOPIX_POWER_MEDIUM); + + case AM7XXX_POWER_HIGH: + return send_command(dev, AM7XXX_PACKET_TYPE_PICOPIX_POWER_HIGH); + + case AM7XXX_POWER_OFF: + case AM7XXX_POWER_TURBO: + default: + error(dev->ctx, "Unsupported power mode.\n"); + return -EINVAL; + }; +} + static int default_set_zoom_mode(am7xxx_device *dev, am7xxx_zoom_mode zoom) { int ret; @@ -922,6 +954,7 @@ static int default_set_zoom_mode(am7xxx_device *dev, am7xxx_zoom_mode zoom) h.header_data.zoom.bit0 = 1; break; + case AM7XXX_ZOOM_TELE: default: error(dev->ctx, "Unsupported zoom mode.\n"); return -EINVAL; @@ -934,6 +967,41 @@ static int default_set_zoom_mode(am7xxx_device *dev, am7xxx_zoom_mode zoom) return 0; } +static int picopix_set_zoom_mode(am7xxx_device *dev, am7xxx_zoom_mode zoom) +{ + int ret; + am7xxx_packet_type packet_type; + + switch(zoom) { + case AM7XXX_ZOOM_ORIGINAL: + packet_type = AM7XXX_PACKET_TYPE_PICOPIX_DISABLE_TI; + break; + + case AM7XXX_ZOOM_TELE: + packet_type = AM7XXX_PACKET_TYPE_PICOPIX_ENABLE_TI; + break; + + case AM7XXX_ZOOM_H: + case AM7XXX_ZOOM_H_V: + case AM7XXX_ZOOM_TEST: + default: + error(dev->ctx, "Unsupported zoom mode.\n"); + return -EINVAL; + }; + + ret = send_command(dev, packet_type); + if (ret < 0) + return ret; + + /* The Windows drivers wait for 100ms and send the same command again, + * probably to overcome a firmware deficiency */ + ret = msleep(100); + if (ret < 0) + return ret; + + return send_command(dev, packet_type); +} + /* Public API */ AM7XXX_PUBLIC int am7xxx_init(am7xxx_context **ctx)