+#include <stdio.h>
+#include <stdlib.h>
+/* According to POSIX.1-2001 */
+#include <sys/select.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <libusb.h>
+#include <getopt.h>
+
+
+#define _GNU_SOURCE
+#include <getopt.h>
+
+
+#define I_VENDOR_NUM 0x0403
+#define I_PRODUCT_NUM 0x6001
+#define BITMODE_CBUS 0x20
+#define BITMODE_RESET 0x00
+
+#define FTDI_SIO_SET_BITMODE 11 /* Set the bitmode */
+#define FTDI_SIO_READ_PINS 12 /* Read pins in bitmode */
+
+#define FTDI_SIO_SET_BITMODE_REQUEST FTDI_SIO_SET_BITMODE
+#define FTDI_SIO_SET_BITMODE_REQUEST_TYPE 0x40
+
+#define FTDI_SIO_READ_PINS_REQUEST FTDI_SIO_READ_PINS
+#define FTDI_SIO_READ_PINS_REQUEST_TYPE 0xC0
+
+int get_device_vid()
+{
+ return I_VENDOR_NUM;
+}
+
+int get_device_pid()
+{
+ return I_PRODUCT_NUM;
+}
+
+/* Get current GPIO register from PL2303 */
+unsigned char gpio_read_reg(libusb_device_handle *h)
+{
+ unsigned char buf;
+ int bytes = libusb_control_transfer(
+ h, // handle obtained with usb_open()
+ FTDI_SIO_READ_PINS_REQUEST_TYPE, // bRequestType
+ FTDI_SIO_READ_PINS_REQUEST, // bRequest
+ 0, // wValue
+ 0, // wIndex
+ &buf, // pointer to destination buffer
+ 1, // wLength
+ 1000
+ );
+ handle_error(bytes);
+ return buf;
+}
+
+void gpio_write_reg(libusb_device_handle *h, unsigned short reg)
+{
+ int bytes = libusb_control_transfer(
+ h, // handle obtained with usb_open()
+ FTDI_SIO_SET_BITMODE_REQUEST_TYPE, //bRequestType
+ FTDI_SIO_SET_BITMODE_REQUEST, // bRequest
+ reg, // wValue
+ 0, // wIndex
+ 0, // pointer to destination buffer
+ 0, // wLength
+ 1000
+ );
+ handle_error(bytes);
+
+}
+
+void gpio_out(libusb_device_handle *h, int gpio, int value)
+{
+ unsigned char cbus_mask;
+
+ if ((gpio < 0) || (gpio > 3))
+ return;
+
+ cbus_mask = gpio_read_reg(h);
+ cbus_mask |= ((1 << gpio) << 4);
+ if (value)
+ cbus_mask |= (1 << gpio);
+ else
+ cbus_mask &= ~(1 << gpio);
+ gpio_write_reg(h, (BITMODE_CBUS << 8) | cbus_mask);
+}
+
+void gpio_in(libusb_device_handle *h, int gpio, int pullup)
+{
+ unsigned char cbus_mask;
+
+ if ((gpio < 0) || (gpio > 3))
+ return;
+
+ cbus_mask = gpio_read_reg(h);
+ cbus_mask &= ~((1 << gpio) << 4);
+ gpio_write_reg(h, (BITMODE_CBUS << 8) | cbus_mask);
+}
+
+int gpio_read(libusb_device_handle *h, int gpio)
+{
+ unsigned char r = gpio_read_reg(h);
+
+ if ((gpio < 0) || (gpio > 3))
+ return 0;
+ return (r & (1 << gpio)) ? 1 : 0;
+}
+