]> oss.titaniummirror.com Git - cp210x.git/commitdiff
Move userspace/kernel shared defs to cp210x.h; no new typedefs; other cleanups.
authorR. Steve McKown <rsmckown@gmail.com>
Mon, 17 May 2010 15:55:48 +0000 (09:55 -0600)
committerR. Steve McKown <rsmckown@gmail.com>
Thu, 20 May 2010 01:21:16 +0000 (19:21 -0600)
src/cp210x.c
src/cp210x.c.karmic
src/cp210x.h [new file with mode: 0644]

index e89ed3cccd2b507227ca3a036cebcc9c3c2901a8..af0302c1ba61613fd0563427ce4f47c1e659b70f 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/usb.h>
 #include <asm/uaccess.h>
 #include <linux/usb/serial.h>
+#include "cp210x.h"
 
 /*
  * Version Information
@@ -200,96 +201,44 @@ static struct usb_serial_driver cp210x_device = {
 #define CONTROL_WRITE_DTR      0x0100
 #define CONTROL_WRITE_RTS      0x0200
 
-/* 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)
-
-/* GetDeviceVersion() return codes */
-#define CP210x_CP2101_VERSION  0x01
-#define        CP210x_CP2102_VERSION   0x02
-#define        CP210x_CP2103_VERSION   0x03
-
-/* Return codes */
-#define        CP210x_SUCCESS                  0x00
-#define        CP210x_DEVICE_NOT_FOUND         0xFF
-#define        CP210x_INVALID_HANDLE           0x01
-#define        CP210x_INVALID_PARAMETER        0x02
-#define        CP210x_DEVICE_IO_FAILED         0x03
-#define        CP210x_FUNCTION_NOT_SUPPORTED   0x04
-#define        CP210x_GLOBAL_DATA_ERROR        0x05
-#define        CP210x_FILE_ERROR               0x06
-#define        CP210x_COMMAND_FAILED           0x08
-#define        CP210x_INVALID_ACCESS_TYPE      0x09
-
-/* USB descriptor sizes */
-#define        CP210x_MAX_DEVICE_STRLEN        256
-#define        CP210x_MAX_PRODUCT_STRLEN       126
-#define        CP210x_MAX_SERIAL_STRLEN        63
-#define        CP210x_MAX_MAXPOWER             250
-
-/* Used to pass variable sized buffers between user and kernel space (ioctls) */
-typedef struct {
-       char *buf;
-       size_t len;
-} cp210x_buffer_t;
-
-/* 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 */
-} cp210x_port_state_t;
-
-typedef struct {
-       cp210x_port_state_t reset;
-       cp210x_port_state_t suspend;
-       uint8_t enhancedFxn;
-} cp210x_port_config_t;
-
-#define PORT_CONFIG_LEN        13      /* Because sizeof() will pad to full words */
+/* cp210x_get_partnum() return codes */
+#define CP210x_PART_UNKNOWN    0x00
+#define CP210x_PART_CP2101     0x01
+#define CP210x_PART_CP2102     0x02
+#define CP210x_PART_CP2103     0x03
 
 /*
  * cp210x_buf_from_user
  * Copy a buffer from user space, returning the number of bytes copied
  * from ubuf.buf into kbuf.  klen is the size of the buffer at kbuf.
  */
-static size_t copy_buf_from_user(char *kbuf, unsigned long ubuf, size_t klen)
+static size_t cp210x_buf_from_user(char *kbuf, unsigned long ubuf, size_t klen)
 {
-       cp210x_buffer_t t;
+       struct cp210x_buffer t;
 
        if (!kbuf || !ubuf || !klen ||
-                       copy_from_user(&t, (cp210x_buffer_t __user *)ubuf,
+                       copy_from_user(&t, (struct cp210x_buffer __user *)ubuf,
                        sizeof(t)))
                return 0;
        if (t.len < klen)
                klen = t.len;
        if (!t.buf || !t.len ||
-                       copy_from_user(kbuf, (char __user *)t.buf, klen))
+                       copy_from_user(kbuf, (u8 __user *)t.buf, klen))
                return 0;
        return klen;
 }
 
+/* cp210x_has_setmfg
+ * Returns 1 if the CP210X part includes firmware that allows setting the
+ * USB MFG descriptor, else 0.  As of this writing, no CP210X firmware allows
+ * this.  SiLabs has suggested this may change in future firmware versions or
+ * parts.
+ */
+static inline int cp210x_has_setmfg(void)
+{
+       return 0;
+}
+
 /*
  * cp210x_ctlmsg
  * A generic usb control message interface.
@@ -329,7 +278,7 @@ static int cp210x_reset(struct usb_serial_port *port)
        dbg("%s", __FUNCTION__);
 
 #if 1
-    /* Is this better than usb_device_reset?  It may be.  Once a client issues
+       /* Is this better than usb_device_reset?  It may be.  Once a client issues
         * the reset ioctl, it must disconnect and reconnect, since the USB
         * connections are torn down.  We also ignore the error return, since
         * the part resets and doesn't send one...
@@ -343,25 +292,24 @@ static int cp210x_reset(struct usb_serial_port *port)
 
 static int cp210x_get_partnum(struct usb_serial_port *port)
 {
-       static u8 _partnum = 0;
-       int ret = CP210x_SUCCESS;
-       if (!_partnum) {
+       static u8 _partnum = CP210x_PART_UNKNOWN;
+
+       if (_partnum == CP210x_PART_UNKNOWN) {
                u8 addr = port->serial->dev->actconfig->interface[0]->
                        cur_altsetting->endpoint[0].desc.bEndpointAddress &
                        USB_ENDPOINT_NUMBER_MASK;
 
-               if (addr == 0x03 || addr == 0x02) /* The part is a cp2101 */
-                       _partnum = 0x01;
+               if (addr == 0x03 || addr == 0x02)
+                       _partnum = CP210x_PART_CP2101;
                else if (addr == 0x01) {
                        /* Must query part to determine part number */
                        if (cp210x_ctlmsg(port, 0xff, 0xc0, 0x370b, 0x00,
                                        &_partnum, 1) != 1)
-                               ret = CP210x_DEVICE_IO_FAILED;
-               } else
-                       ret = CP210x_DEVICE_IO_FAILED;
+                               _partnum = CP210x_PART_UNKNOWN;
+               }
        }
-       dbg("%s - partnum %u err %d", __FUNCTION__, _partnum, ret);
-       return (ret == CP210x_SUCCESS) ? _partnum : 0;
+       dbg("%s - partnum %u", __FUNCTION__, _partnum);
+       return _partnum;
 }
 
 static inline int cp210x_setu16(struct usb_serial_port *port, int cmd,
@@ -387,9 +335,8 @@ static int make_usb_string(char *usbstr, size_t usblen, char *src,
        if (usbstr && usblen >= 2 && src && *src && srclen) {
                char *p;
 
-               /* The usb string format uses first byte as length */
-               if (usblen > 256)
-                       usblen = 256;
+               if (usblen > 255)
+                       usblen = 255;
 
                p = usbstr + 1;
                *p++ = 0x03;
@@ -473,30 +420,31 @@ static int cp210x_gpioget(struct usb_serial_port *port, u8 *gpio)
 }
 
 static int cp210x_portconfset(struct usb_serial_port *port,
-               cp210x_port_config_t *config)
+               struct cp210x_port_config *config)
 {
-       cp210x_port_config_t lconfig;
+       struct cp210x_port_config lconfig;
        int ret;
 
        dbg("%s", __FUNCTION__);
 
        memcpy(&lconfig, config, sizeof(lconfig));
 
-       /* apparently not implemented yet */
-       lconfig.suspend.lowPower = 0;
-       lconfig.reset.lowPower = 0;
-
        /* Words from cp2103 are MSB */
        lconfig.reset.mode = cpu_to_be16(config->reset.mode);
-       /* lconfig.reset.lowPower = cpu_to_be16(config->reset.lowPower); */
        lconfig.reset.latch = cpu_to_be16(config->reset.latch);
        lconfig.suspend.mode = cpu_to_be16(config->suspend.mode);
-       /* lconfig.suspend.lowPower = cpu_to_be16(config->suspend.lowPower); */
        lconfig.suspend.latch = cpu_to_be16(config->suspend.latch);
+#if 0 /* apparently not implemented by CP210X firmware */
+       lconfig.reset.lowPower = cpu_to_be16(config->reset.lowPower);
+       lconfig.suspend.lowPower = cpu_to_be16(config->suspend.lowPower);
+#else
+       lconfig.suspend.lowPower = 0;
+       lconfig.reset.lowPower = 0;
+#endif
 
        ret = cp210x_ctlmsg(port, 0xff, 0x40, 0x370c, 0, &lconfig,
-                       PORT_CONFIG_LEN);
-       if (ret == PORT_CONFIG_LEN)
+                       sizeof(struct cp210x_port_config));
+       if (ret == sizeof(struct cp210x_port_config))
                return 0;
        else if (ret >= 0)
                return -1;
@@ -505,15 +453,15 @@ static int cp210x_portconfset(struct usb_serial_port *port,
 }
 
 static int cp210x_portconfget(struct usb_serial_port *port,
-               cp210x_port_config_t *config)
+               struct cp210x_port_config *config)
 {
        int ret;
 
        dbg("%s", __FUNCTION__);
 
        ret = cp210x_ctlmsg(port, 0xff, 0xc0, 0x370c, 0, config,
-                       PORT_CONFIG_LEN);
-       if (ret == PORT_CONFIG_LEN) {
+                       sizeof(struct cp210x_port_config));
+       if (ret == sizeof(struct cp210x_port_config)) {
                /* Words from cp2103 are MSB */
                config->reset.mode = be16_to_cpu(config->reset.mode);
                config->reset.lowPower = be16_to_cpu(config->reset.lowPower);
@@ -742,7 +690,7 @@ static int cp210x_ioctl(struct usb_serial_port *port, struct file *file,
        break;
 
        case IOCTL_GPIOGET:
-       if (cp210x_get_partnum(port) == CP210x_CP2103_VERSION) {
+       if (cp210x_get_partnum(port) == CP210x_PART_CP2103) {
                u8 gpio = 0;
                if (!cp210x_gpioget(port, &gpio) && !copy_to_user(
                                        (u8 __user *)arg, &gpio, sizeof(gpio)))
@@ -752,7 +700,7 @@ static int cp210x_ioctl(struct usb_serial_port *port, struct file *file,
        break;
 
        case IOCTL_GPIOSET:
-       if (cp210x_get_partnum(port) == CP210x_CP2103_VERSION &&
+       if (cp210x_get_partnum(port) == CP210x_PART_CP2103 &&
                        !cp210x_gpioset(port, arg))
                return 0;
        return -EFAULT;
@@ -760,7 +708,7 @@ static int cp210x_ioctl(struct usb_serial_port *port, struct file *file,
 
        case IOCTL_GPIOBIC:
        case IOCTL_GPIOBIS:
-       if (cp210x_get_partnum(port) == CP210x_CP2103_VERSION &&
+       if (cp210x_get_partnum(port) == CP210x_PART_CP2103 &&
                        !cp210x_gpiosetb(port, (cmd==IOCTL_GPIOBIC) ?  0 : arg,
                        (cmd==IOCTL_GPIOBIC) ? arg : 0))
                return 0;
@@ -773,9 +721,9 @@ static int cp210x_ioctl(struct usb_serial_port *port, struct file *file,
 
        case IOCTL_PORTCONFGET:
        {
-               cp210x_port_config_t config;
+               struct cp210x_port_config config;
                if (!cp210x_portconfget(port, &config) && !copy_to_user(
-                                       (cp210x_port_config_t __user *)arg,
+                                       (struct cp210x_port_config __user *)arg,
                                        &config, sizeof(config)))
                        return 0;
        }
@@ -784,8 +732,8 @@ static int cp210x_ioctl(struct usb_serial_port *port, struct file *file,
 
        case IOCTL_PORTCONFSET:
        {
-       cp210x_port_config_t config;
-       if (!copy_from_user(&config, (cp210x_port_config_t __user *)arg,
+       struct cp210x_port_config config;
+       if (!copy_from_user(&config, (struct cp210x_port_config __user *)arg,
                        sizeof(config)) &&
                        !cp210x_portconfset(port, &config))
                return 0;
@@ -816,25 +764,23 @@ static int cp210x_ioctl(struct usb_serial_port *port, struct file *file,
        break;
 
        case IOCTL_SETMFG:
-#if 0 /* Silicon Labs apparently doesn't provide for setting of mfg desc */
-       {
+       if (cp210x_has_setmfg()) {
                char usbstr[CP210x_MAX_MFG_STRLEN * 2 + 2];
-               size_t len = copy_buf_from_user(usbstr + sizeof(usbstr) -
-                               CP210x_MAX_MFG_STRLEN, arg,
+               char *str = usbstr + sizeof(usbstr) - CP210x_MAX_MFG_STRLEN;
+               size_t len = cp210x_buf_from_user(str, arg,
                                CP210x_MAX_MFG_STRLEN);
                len = make_usb_string(usbstr, sizeof(usbstr), str, len);
                if (len && cp210x_setstr(port, 0x00, usbstr) == len)
                        return 0;
-               return -EFAULT;
        }
-#endif
+       return -EFAULT;
        break;
 
        case IOCTL_SETPRODUCT:
        {
                char usbstr[CP210x_MAX_PRODUCT_STRLEN * 2 + 2];
                char *str = usbstr + sizeof(usbstr) - CP210x_MAX_PRODUCT_STRLEN;
-               size_t len = copy_buf_from_user(str, arg,
+               size_t len = cp210x_buf_from_user(str, arg,
                                CP210x_MAX_PRODUCT_STRLEN);
                len = make_usb_string(usbstr, sizeof(usbstr), str, len);
                if (len && cp210x_setstr(port, 0x03, usbstr) == len)
@@ -847,7 +793,7 @@ static int cp210x_ioctl(struct usb_serial_port *port, struct file *file,
        {
                char usbstr[CP210x_MAX_SERIAL_STRLEN * 2 + 2];
                char *str = usbstr + sizeof(usbstr) - CP210x_MAX_SERIAL_STRLEN;
-               size_t len = copy_buf_from_user(str, arg,
+               size_t len = cp210x_buf_from_user(str, arg,
                                CP210x_MAX_SERIAL_STRLEN);
                len = make_usb_string(usbstr, sizeof(usbstr), str, len);
                if (len && cp210x_setstr(port, 0x04, usbstr) == len)
index 831a0f4321c49512f4402c1f132d7bda9cf99a9d..78d6b62c1e0e1a84c0bae56825dd909ad6766224 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/usb.h>
 #include <linux/uaccess.h>
 #include <linux/usb/serial.h>
+#include "cp210x.h"
 
 /*
  * Version Information
@@ -221,96 +222,44 @@ static struct usb_serial_driver cp210x_device = {
 #define CONTROL_WRITE_DTR      0x0100
 #define CONTROL_WRITE_RTS      0x0200
 
-/* 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)
-
-/* GetDeviceVersion() return codes */
-#define CP210x_CP2101_VERSION  0x01
-#define        CP210x_CP2102_VERSION   0x02
-#define        CP210x_CP2103_VERSION   0x03
-
-/* Return codes */
-#define        CP210x_SUCCESS                  0x00
-#define        CP210x_DEVICE_NOT_FOUND         0xFF
-#define        CP210x_INVALID_HANDLE           0x01
-#define        CP210x_INVALID_PARAMETER        0x02
-#define        CP210x_DEVICE_IO_FAILED         0x03
-#define        CP210x_FUNCTION_NOT_SUPPORTED   0x04
-#define        CP210x_GLOBAL_DATA_ERROR        0x05
-#define        CP210x_FILE_ERROR               0x06
-#define        CP210x_COMMAND_FAILED           0x08
-#define        CP210x_INVALID_ACCESS_TYPE      0x09
-
-/* USB descriptor sizes */
-#define        CP210x_MAX_DEVICE_STRLEN        256
-#define        CP210x_MAX_PRODUCT_STRLEN       126
-#define        CP210x_MAX_SERIAL_STRLEN        63
-#define        CP210x_MAX_MAXPOWER             250
-
-/* Used to pass variable sized buffers between user and kernel space (ioctls) */
-typedef struct {
-       char *buf;
-       size_t len;
-} cp210x_buffer_t;
-
-/* 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 */
-} cp210x_port_state_t;
-
-typedef struct {
-       cp210x_port_state_t reset;
-       cp210x_port_state_t suspend;
-       uint8_t enhancedFxn;
-} cp210x_port_config_t;
-
-#define PORT_CONFIG_LEN        13      /* Because sizeof() will pad to full words */
+/* cp210x_get_partnum() return codes */
+#define CP210x_PART_UNKNOWN    0x00
+#define CP210x_PART_CP2101     0x01
+#define CP210x_PART_CP2102     0x02
+#define CP210x_PART_CP2103     0x03
 
 /*
  * cp210x_buf_from_user
  * Copy a buffer from user space, returning the number of bytes copied
  * from ubuf.buf into kbuf.  klen is the size of the buffer at kbuf.
  */
-static size_t copy_buf_from_user(char *kbuf, unsigned long ubuf, size_t klen)
+static size_t cp210x_buf_from_user(char *kbuf, unsigned long ubuf, size_t klen)
 {
-       cp210x_buffer_t t;
+       struct cp210x_buffer t;
 
        if (!kbuf || !ubuf || !klen ||
-                       copy_from_user(&t, (cp210x_buffer_t __user *)ubuf,
+                       copy_from_user(&t, (struct cp210x_buffer __user *)ubuf,
                        sizeof(t)))
                return 0;
        if (t.len < klen)
                klen = t.len;
        if (!t.buf || !t.len ||
-                       copy_from_user(kbuf, (char __user *)t.buf, klen))
+                       copy_from_user(kbuf, (u8 __user *)t.buf, klen))
                return 0;
        return klen;
 }
 
+/* cp210x_has_setmfg
+ * Returns 1 if the CP210X part includes firmware that allows setting the
+ * USB MFG descriptor, else 0.  As of this writing, no CP210X firmware allows
+ * this.  SiLabs has suggested this may change in future firmware versions or
+ * parts.
+ */
+static inline int cp210x_has_setmfg(void)
+{
+       return 0;
+}
+
 /*
  * cp210x_ctlmsg
  * A generic usb control message interface.
@@ -347,10 +296,10 @@ static int cp210x_ctlmsg(struct usb_serial_port *port, u8 request,
 
 static int cp210x_reset(struct usb_serial_port *port)
 {
-       dbg("%s", __FUNCTION__);
+       dbg("%s", __func__);
 
 #if 1
-    /* Is this better than usb_device_reset?  It may be.  Once a client issues
+       /* Is this better than usb_device_reset?  It may be.  Once a client issues
         * the reset ioctl, it must disconnect and reconnect, since the USB
         * connections are torn down.  We also ignore the error return, since
         * the part resets and doesn't send one...
@@ -364,25 +313,24 @@ static int cp210x_reset(struct usb_serial_port *port)
 
 static int cp210x_get_partnum(struct usb_serial_port *port)
 {
-       static u8 _partnum = 0;
-       int ret = CP210x_SUCCESS;
-       if (!_partnum) {
+       static u8 _partnum = CP210x_PART_UNKNOWN;
+
+       if (_partnum == CP210x_PART_UNKNOWN) {
                u8 addr = port->serial->dev->actconfig->interface[0]->
                        cur_altsetting->endpoint[0].desc.bEndpointAddress &
                        USB_ENDPOINT_NUMBER_MASK;
 
-               if (addr == 0x03 || addr == 0x02) /* The part is a cp2101 */
-                       _partnum = 0x01;
+               if (addr == 0x03 || addr == 0x02)
+                       _partnum = CP210x_PART_CP2101;
                else if (addr == 0x01) {
                        /* Must query part to determine part number */
                        if (cp210x_ctlmsg(port, 0xff, 0xc0, 0x370b, 0x00,
                                        &_partnum, 1) != 1)
-                               ret = CP210x_DEVICE_IO_FAILED;
-               } else
-                       ret = CP210x_DEVICE_IO_FAILED;
+                               _partnum = CP210x_PART_UNKNOWN;
+               }
        }
-       dbg("%s - partnum %u err %d", __FUNCTION__, _partnum, ret);
-       return (ret == CP210x_SUCCESS) ? _partnum : 0;
+       dbg("%s - partnum %u", __func__, _partnum);
+       return _partnum;
 }
 
 static inline int cp210x_setu16(struct usb_serial_port *port, int cmd,
@@ -408,9 +356,8 @@ static int make_usb_string(char *usbstr, size_t usblen, char *src,
        if (usbstr && usblen >= 2 && src && *src && srclen) {
                char *p;
 
-               /* The usb string format uses first byte as length */
-               if (usblen > 256)
-                       usblen = 256;
+               if (usblen > 255)
+                       usblen = 255;
 
                p = usbstr + 1;
                *p++ = 0x03;
@@ -437,14 +384,14 @@ static int cp210x_setstr(struct usb_serial_port *port, int cmd, char *usbstr)
        unsigned len = usbstr[0];
        int ret = cp210x_ctlmsg(port, 0xff, 0x40, 0x3700 | (cmd & 0xff), 0,
                        usbstr, len);
-       dbg("%s - cmd 0x%02x len %d ret %d", __FUNCTION__, cmd, len, ret);
+       dbg("%s - cmd 0x%02x len %d ret %d", __func__, cmd, len, ret);
        return ret;
 }
 
 /* Set all gpio simultaneously */
 static int cp210x_gpioset(struct usb_serial_port *port, u8 gpio)
 {
-       dbg("%s - port %d, gpio = 0x%.2x", __FUNCTION__, port->number, gpio);
+       dbg("%s - port %d, gpio = 0x%.2x", __func__, port->number, gpio);
 
        return cp210x_ctlmsg(port, 0xff, 0x40, 0x37e1,
                        ((uint16_t)gpio << 8) | GPIO_MASK, NULL, 0);
@@ -473,7 +420,7 @@ static int cp210x_gpiosetb(struct usb_serial_port *port, u8 set, u8 clear)
        if (clear & GPIO_3)
                gpio = (gpio & ~(GPIO_3 << 8))|GPIO_3;
 
-       dbg("%s - port %d, gpiob = 0x%.4x", __FUNCTION__, port->number, gpio);
+       dbg("%s - port %d, gpiob = 0x%.4x", __func__, port->number, gpio);
 
        /* FIXME: how about REQTYPE_HOST_TO_DEVICE instead of 0x40? */
        return cp210x_ctlmsg(port, 0xff, 0x40, 0x37e1, gpio, NULL, 0);
@@ -483,41 +430,42 @@ static int cp210x_gpioget(struct usb_serial_port *port, u8 *gpio)
 {
        int ret;
 
-       dbg("%s - port %d", __FUNCTION__, port->number);
+       dbg("%s - port %d", __func__, port->number);
 
        /* FIXME: how about REQTYPE_DEVICE_TO_HOST instead of 0xc0? */
        ret = cp210x_ctlmsg(port, 0xff, 0xc0, 0x00c2, 0, gpio, 1);
 
-       dbg("%s - gpio = 0x%.2x (%d)", __FUNCTION__, *gpio, ret);
+       dbg("%s - gpio = 0x%.2x (%d)", __func__, *gpio, ret);
 
        return (ret == 1) ? 0 : -1;
 }
 
 static int cp210x_portconfset(struct usb_serial_port *port,
-               cp210x_port_config_t *config)
+               struct cp210x_port_config *config)
 {
-       cp210x_port_config_t lconfig;
+       struct cp210x_port_config lconfig;
        int ret;
 
-       dbg("%s", __FUNCTION__);
+       dbg("%s", __func__);
 
        memcpy(&lconfig, config, sizeof(lconfig));
 
-       /* apparently not implemented yet */
-       lconfig.suspend.lowPower = 0;
-       lconfig.reset.lowPower = 0;
-
        /* Words from cp2103 are MSB */
        lconfig.reset.mode = cpu_to_be16(config->reset.mode);
-       /* lconfig.reset.lowPower = cpu_to_be16(config->reset.lowPower); */
        lconfig.reset.latch = cpu_to_be16(config->reset.latch);
        lconfig.suspend.mode = cpu_to_be16(config->suspend.mode);
-       /* lconfig.suspend.lowPower = cpu_to_be16(config->suspend.lowPower); */
        lconfig.suspend.latch = cpu_to_be16(config->suspend.latch);
+#if 0 /* apparently not implemented by CP210X firmware */
+       lconfig.reset.lowPower = cpu_to_be16(config->reset.lowPower);
+       lconfig.suspend.lowPower = cpu_to_be16(config->suspend.lowPower);
+#else
+       lconfig.suspend.lowPower = 0;
+       lconfig.reset.lowPower = 0;
+#endif
 
        ret = cp210x_ctlmsg(port, 0xff, 0x40, 0x370c, 0, &lconfig,
-                       PORT_CONFIG_LEN);
-       if (ret == PORT_CONFIG_LEN)
+                       sizeof(struct cp210x_port_config));
+       if (ret == sizeof(struct cp210x_port_config))
                return 0;
        else if (ret >= 0)
                return -1;
@@ -526,15 +474,15 @@ static int cp210x_portconfset(struct usb_serial_port *port,
 }
 
 static int cp210x_portconfget(struct usb_serial_port *port,
-               cp210x_port_config_t *config)
+               struct cp210x_port_config *config)
 {
        int ret;
 
-       dbg("%s", __FUNCTION__);
+       dbg("%s", __func__);
 
        ret = cp210x_ctlmsg(port, 0xff, 0xc0, 0x370c, 0, config,
-                       PORT_CONFIG_LEN);
-       if (ret == PORT_CONFIG_LEN) {
+                       sizeof(struct cp210x_port_config));
+       if (ret == sizeof(struct cp210x_port_config)) {
                /* Words from cp2103 are MSB */
                config->reset.mode = be16_to_cpu(config->reset.mode);
                config->reset.lowPower = be16_to_cpu(config->reset.lowPower);
@@ -778,7 +726,7 @@ static int cp210x_ioctl(struct tty_struct *tty, struct file *file,
 {
        struct usb_serial_port *port = tty->driver_data;
 
-       dbg("%s (%d) cmd = 0x%04x", __FUNCTION__, port->number, cmd);
+       dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd);
 
        switch (cmd) {
 
@@ -809,7 +757,7 @@ static int cp210x_ioctl(struct tty_struct *tty, struct file *file,
        break;
 
        case IOCTL_GPIOGET:
-       if (cp210x_get_partnum(port) == CP210x_CP2103_VERSION) {
+       if (cp210x_get_partnum(port) == CP210x_PART_CP2103) {
                u8 gpio = 0;
                if (!cp210x_gpioget(port, &gpio) && !copy_to_user(
                                        (u8 __user *)arg, &gpio, sizeof(gpio)))
@@ -819,7 +767,7 @@ static int cp210x_ioctl(struct tty_struct *tty, struct file *file,
        break;
 
        case IOCTL_GPIOSET:
-       if (cp210x_get_partnum(port) == CP210x_CP2103_VERSION &&
+       if (cp210x_get_partnum(port) == CP210x_PART_CP2103 &&
                        !cp210x_gpioset(port, arg))
                return 0;
        return -EFAULT;
@@ -827,7 +775,7 @@ static int cp210x_ioctl(struct tty_struct *tty, struct file *file,
 
        case IOCTL_GPIOBIC:
        case IOCTL_GPIOBIS:
-       if (cp210x_get_partnum(port) == CP210x_CP2103_VERSION &&
+       if (cp210x_get_partnum(port) == CP210x_PART_CP2103 &&
                        !cp210x_gpiosetb(port, (cmd==IOCTL_GPIOBIC) ?  0 : arg,
                        (cmd==IOCTL_GPIOBIC) ? arg : 0))
                return 0;
@@ -840,9 +788,9 @@ static int cp210x_ioctl(struct tty_struct *tty, struct file *file,
 
        case IOCTL_PORTCONFGET:
        {
-               cp210x_port_config_t config;
+               struct cp210x_port_config config;
                if (!cp210x_portconfget(port, &config) && !copy_to_user(
-                                       (cp210x_port_config_t __user *)arg,
+                                       (struct cp210x_port_config __user *)arg,
                                        &config, sizeof(config)))
                        return 0;
        }
@@ -851,8 +799,8 @@ static int cp210x_ioctl(struct tty_struct *tty, struct file *file,
 
        case IOCTL_PORTCONFSET:
        {
-       cp210x_port_config_t config;
-       if (!copy_from_user(&config, (cp210x_port_config_t __user *)arg,
+       struct cp210x_port_config config;
+       if (!copy_from_user(&config, (struct cp210x_port_config __user *)arg,
                        sizeof(config)) &&
                        !cp210x_portconfset(port, &config))
                return 0;
@@ -883,25 +831,23 @@ static int cp210x_ioctl(struct tty_struct *tty, struct file *file,
        break;
 
        case IOCTL_SETMFG:
-#if 0 /* Silicon Labs apparently doesn't provide for setting of mfg desc */
-       {
+       if (cp210x_has_setmfg()) {
                char usbstr[CP210x_MAX_MFG_STRLEN * 2 + 2];
-               size_t len = copy_buf_from_user(usbstr + sizeof(usbstr) -
-                               CP210x_MAX_MFG_STRLEN, arg,
+               char *str = usbstr + sizeof(usbstr) - CP210x_MAX_MFG_STRLEN;
+               size_t len = cp210x_buf_from_user(str, arg,
                                CP210x_MAX_MFG_STRLEN);
                len = make_usb_string(usbstr, sizeof(usbstr), str, len);
                if (len && cp210x_setstr(port, 0x00, usbstr) == len)
                        return 0;
-               return -EFAULT;
        }
-#endif
+       return -EFAULT;
        break;
 
        case IOCTL_SETPRODUCT:
        {
                char usbstr[CP210x_MAX_PRODUCT_STRLEN * 2 + 2];
                char *str = usbstr + sizeof(usbstr) - CP210x_MAX_PRODUCT_STRLEN;
-               size_t len = copy_buf_from_user(str, arg,
+               size_t len = cp210x_buf_from_user(str, arg,
                                CP210x_MAX_PRODUCT_STRLEN);
                len = make_usb_string(usbstr, sizeof(usbstr), str, len);
                if (len && cp210x_setstr(port, 0x03, usbstr) == len)
@@ -914,7 +860,7 @@ static int cp210x_ioctl(struct tty_struct *tty, struct file *file,
        {
                char usbstr[CP210x_MAX_SERIAL_STRLEN * 2 + 2];
                char *str = usbstr + sizeof(usbstr) - CP210x_MAX_SERIAL_STRLEN;
-               size_t len = copy_buf_from_user(str, arg,
+               size_t len = cp210x_buf_from_user(str, arg,
                                CP210x_MAX_SERIAL_STRLEN);
                len = make_usb_string(usbstr, sizeof(usbstr), str, len);
                if (len && cp210x_setstr(port, 0x04, usbstr) == len)
@@ -935,7 +881,7 @@ static int cp210x_ioctl(struct tty_struct *tty, struct file *file,
        break;
 
        default:
-       dbg("%s not supported = 0x%04x", __FUNCTION__, cmd);
+       dbg("%s not supported = 0x%04x", __func__, cmd);
        break;
        }
 
diff --git a/src/cp210x.h b/src/cp210x.h
new file mode 100644 (file)
index 0000000..9892464
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Silicon Laboratories CP210x USB to RS232 serial adaptor driver
+ *
+ * Copyright (C) 2005 Craig Shelley (craig@microtron.org.uk)
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License version
+ *     2 as published by the Free Software Foundation.
+ *
+ * Definitions usable by both the cp210x kernel module and userspace.
+ *
+ */
+
+#if !defined(CP210X_H)
+#define CP210X_H
+
+/* CP2103 GPIO 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 */
+
+/* CP2103 GPIO bit positions */
+#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)
+
+/* USB descriptor sizes */
+#define        CP210x_MAX_MFG_STRLEN           255
+#define        CP210x_MAX_PRODUCT_STRLEN       126
+#define        CP210x_MAX_SERIAL_STRLEN        63
+
+/* Used to pass variable sized buffers between user and kernel space (ioctls) */
+struct cp210x_buffer {
+       __u8 *buf;
+       __s32 len;
+} __attribute__((packed));
+
+/* Port config definitions */
+struct cp210x_port_state {
+       __u16 mode;             /* Push-pull = 1, Open-drain = 0 */
+       __u16 lowPower;
+       __u16 latch;            /* Logic high = 1, Logic low = 0 */
+} __attribute__((packed));
+
+struct cp210x_port_config {
+       struct cp210x_port_state reset;
+       struct cp210x_port_state suspend;
+       __u8 enhancedFxn;
+} __attribute__((packed));
+
+#endif /* CP210X_H */