--- /dev/null
+/**
+ * cpcfg.c
+ *
+ * Read the configuration of a cp2103-equipped device.
+ */
+
+#include <netinet/in.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define VID 0x10c4
+#define PID 0xea60
+
+/* CP2103 ioctls */
+#define IOCTL_GPIOGET 0x8000 /* Get gpio bits */
+#define IOCTL_GPIOSET 0x8001 /* Set gpio bits */
+#define IOCTL_GPIOBIC 0x8002 /* Clear specific gpio bit(s) */
+#define IOCTL_GPIOBIS 0x8003 /* Set specific gpio bit(s) */
+
+/* CP210x ioctls principally used during initial device configuration */
+#define IOCTL_DEVICERESET 0x8004 /* Reset the cp210x */
+#define IOCTL_PORTCONFGET 0x8005 /* Get port configuration */
+#define IOCTL_PORTCONFSET 0x8006 /* Set port configuration */
+#define IOCTL_SETVID 0x8007 /* Set vendor id */
+#define IOCTL_SETPID 0x8008 /* Set product id */
+#define IOCTL_SETMFG 0x8009 /* Set manufacturer string */
+#define IOCTL_SETPRODUCT 0x800a /* Set product string */
+#define IOCTL_SETSERIAL 0x800b /* Set serial number string */
+#define IOCTL_SETDEVVER 0x800c /* set device version id */
+/* FIXME: where is IOCTL_SETMFG? */
+
+/* CP2103 GPIO */
+#define GPIO_0 0x01
+#define GPIO_1 0x02
+#define GPIO_2 0x04
+#define GPIO_3 0x08
+#define GPIO_MASK (GPIO_0|GPIO_1|GPIO_2|GPIO_3)
+
+/* Port config definitions */
+typedef struct {
+ uint16_t mode; /* Push-pull = 1, Open-drain = 0 */
+ uint16_t lowPower;
+ uint16_t latch; /* Logic high = 1, Logic low = 0 */
+} cp2101_port_state_t;
+
+typedef struct {
+ cp2101_port_state_t reset;
+ cp2101_port_state_t suspend;
+ uint8_t enhancedFxn;
+} cp2101_port_config_t;
+
+#define PORT_CONFIG_LEN 13 /* Because sizeof() will pad to full words */
+
+/* Used to pass variable sized buffers between user and kernel space (ioctls) */
+typedef struct {
+ char* buf;
+ size_t len;
+} cp210x_buffer_t;
+
+void exit(int);
+
+int cpConnect(char* device)
+{
+ int ret, ioval;
+ int fd = open(device, O_RDWR);
+ if (fd < 0) {
+ fprintf(stderr, "cannot open %s\n", device);
+ exit(1);
+ }
+ printf("%s opened\n", device);
+ return fd;
+}
+
+void cpDisconnect(int fd)
+{
+ if (fd >= 0)
+ close(fd);
+}
+
+void printState(cp2101_port_state_t* state)
+{
+ printf("m:0x%02x lp:0x%02x l:0x%02x", state->mode, state->lowPower,
+ state->latch);
+}
+
+void printConfig(cp2101_port_config_t* config)
+{
+ printf("config: reset: "); printState(&config->reset);
+ printf("\nconfig: suspend: "); printState(&config->reset);
+ printf("\nenhancedFxn: 0x%02x\n", config->enhancedFxn);
+}
+
+void cpReset(int fd)
+{
+ int ret;
+
+ /* Reset the part */
+ if ((ret = ioctl(fd, IOCTL_DEVICERESET, 0))) {
+ fprintf(stderr, "device reset ioctl %d\n", ret);
+ exit(1);
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ cp2101_port_config_t config;
+ uint8_t gpio = 0xff;
+ int ret;
+ int fd;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s <tty>\n", argv[0]);
+ exit(1);
+ }
+
+ fd = cpConnect(argv[1]);
+
+ /* Read the current port configuration */
+ if ((ret = ioctl(fd, IOCTL_PORTCONFGET, &config))) {
+ fprintf(stderr, "portconfget ioctl failed %d\n", ret);
+ return 1;
+ }
+
+ /* Read the current gpio latches */
+ if ((ret = ioctl(fd, IOCTL_GPIOGET, &gpio))) {
+ fprintf(stderr, "gpioget ioctl failed %d\n", ret);
+ return 1;
+ }
+
+ printConfig(&config);
+ printf("gpio = 0x%0x\n", gpio);
+
+ cpDisconnect(fd);
+ return 0;
+}