* Re: [PATCH] usb: cp210x: Added support for GPIO (CP2103/4/5)
From: Alan Cox @ 2012-04-28 21:08 UTC (permalink / raw)
To: Preston Fick
Cc: Preston Fick, gregkh@linuxfoundation.org,
linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-serial@vger.kernel.org
In-Reply-To: <00374F755A5C474884D69FBCA77349D105219FB334@EXCAUS002.silabs.com>
> I understand that this change is all over the place in this code, so I'm willing to change it back, and just use raw usb functions contained in the ones I modified. This should make it simpler and eliminate this problem.
I would suggest you split this into two patches then. The first patch
which changes the submission handling but nothing else, and a second
patch which adds the GPIO functions.
> Is there a better way to get this type of support for our devices? The reason I'm adding this here is because our customers need and use this functionality. The way we do this on Windows and Mac is through custom ioctl calls, so I assumed this would be the appropriate way to do this here as well.
I've Cc'd the linux-serial list as well to see what people think. I'd
like to avoid chip specific custom ioctls in favour of a standardised
way of doing it, but I'm not entirely sure how that should look.
That is really a minor detail but an important one so I'd like to see
what other feedback appears over the next few days (including some
weekdays).
> >>We could also the agree how that maps onto the extra gpio lines used with
> >>SIM card readers and the like so we can standardise that.
>
> I'm open to suggestions on how to properly get this implemented, so if there is some more feedback you can give to point me in the right direction I'd be glad to consider it and resubmit.
For what sort of things are the GPIO lines generally used by customers ?
Alan
^ permalink raw reply
* RE: [PATCH] usb: cp210x: Added support for GPIO (CP2103/4/5)
From: Preston Fick @ 2012-04-28 21:44 UTC (permalink / raw)
To: Alan Cox
Cc: Preston Fick,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org,
linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-serial-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <20120428220808.4674a8df-38n7/U1jhRXW96NNrWNlrekiAK3p4hvP@public.gmane.org>
Hi Alan -
More in line:
Kind Regards -
Preston
________________________________________
From: Alan Cox [alan-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org]
Sent: Saturday, April 28, 2012 4:08 PM
To: Preston Fick
Cc: Preston Fick; gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org; linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-serial-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH] usb: cp210x: Added support for GPIO (CP2103/4/5)
> I understand that this change is all over the place in this code, so I'm willing to change it back, and just use raw usb functions contained in the ones I modified. This should make it simpler and eliminate this problem.
>>I would suggest you split this into two patches then. The first patch
>>which changes the submission handling but nothing else, and a second
>>patch which adds the GPIO functions.
For the time being I'm going add in the GPIO support using the raw usb_control_msg function, this should make the patch much simpler. Then if needed I can roll everything into a new calling mechanism later. I'll need to test with our devices then I'll resubmit tomorrow or Monday.
> Is there a better way to get this type of support for our devices? The reason I'm adding this here is because our customers need and use this functionality. The way we do this on Windows and Mac is through custom ioctl calls, so I assumed this would be the appropriate way to do this here as well.
>>I've Cc'd the linux-serial list as well to see what people think. I'd
>>like to avoid chip specific custom ioctls in favour of a standardised
>>way of doing it, but I'm not entirely sure how that should look.
>>That is really a minor detail but an important one so I'd like to see
>>what other feedback appears over the next few days (including some
>>weekdays).
Yes - I can see how something like this could be standardized, but my knowledge of the kernel outside of this driver is limited.
Hopefully this patch can get accepted with my modifications, but if a more generic access to this type of feature is available at some point I'd be glad to help get the driver using that feature instead of something so part specific, as it is now.
> >>We could also the agree how that maps onto the extra gpio lines used with
> >>SIM card readers and the like so we can standardise that.
>
> I'm open to suggestions on how to properly get this implemented, so if there is some more feedback you can give to point me in the right direction I'd be glad to consider it and resubmit.
>>For what sort of things are the GPIO lines generally used by customers ?
I would say they are mostly these would be tied to an LED of some sort, but since these are GPIO they could go to anything. I've seen some customers use them to set states from the host as well to notify whatever MCU may be attached to the RS232 side of the device. They are really just raw pins that can be set low or high for whatever is listening on the other side.
Unfortunately the number of pins and way we access them differs from device to device, and some of the CP210x's don't have GPIO at all. This patch supports our complete portfolio of this type of adapter, so this shouldn't need to be modified often, only if we decide to create a new flavor.
>>Alan
Thanks for the feedback, I agree it will be interesting to see if this sparks a more generic discussion on how the GPIO functionality could be added for multiple devices and drivers in the kernel.
This message (including any attachments) is intended only for the use of the individual or entity to which it is addressed and may contain information that is non-public, proprietary, privileged, confidential, and exempt from disclosure under applicable law or may constitute as attorney work product. If you are not the intended recipient, you are hereby notified that any use, dissemination, distribution, or copying of this communication is strictly prohibited. If you have received this communication in error, notify us immediately by telephone and (i) destroy this message if a facsimile or (ii) delete this message immediately if this is an electronic communication.
Thank you.
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] usb: cp210x: Added support for GPIO (CP2103/4/5)
From: Uwe Bonnes @ 2012-04-29 13:02 UTC (permalink / raw)
To: Alan Cox; +Cc: linux-usb, linux-kernel, linux-serial
In-Reply-To: <20120428203322.7680594f@pyramind.ukuu.org.uk>
>>>>> "Alan" == Alan Cox <alan@lxorguk.ukuu.org.uk> writes:
Alan> On Sat, 28 Apr 2012 20:17:07 +0200 Uwe Bonnes
Alan> <bon@elektron.ikp.physik.tu-darmstadt.de> wrote:
>> >>>>> "Alan" == Alan Cox <alan@lxorguk.ukuu.org.uk> writes:
>>
>> ...
Alan> The other question is whether having some custom gpio poking
Alan> interface is actually a good idea. I suspect probably not. The
Alan> kernel gpio layer can help a bit but doesn't really solve the
Alan> problem as there is no way to tie a gpio to a port. Given how many
Alan> devices seem to have gpios these days I wonder if we need a gpio
Alan> setting interface via termiox.
>> Is this really kernel stuff or better handled in libusb(x)
Alan> Tricky to do it that way when the kernel driver owns the
Alan> interface. Also it's looking increasingly like we'll need to
Alan> support a variety of "serial and a couple of extra magic lines"
Alan> type interfaces for things like SIM readers.
Well,
most RS232/USB Adapter don't supply and most applications working with these
adapters don't need hard realtime. So even writing and reading the serial
lines can be handled with libusb, like libftdi does.
But as soon as higher level protocols based on the serial line get involved,
a kernel driver is needed...
So when thinking some termiox, some thoughts for the FTDI special modes,
like MPSSE or synchronous FIFO should be spent. It would come handy if I
could open /dev/ttyUSBx, set som termiox and could use the kernel driver for
sending and receiving MPSSE commands. MPSSE is e.g. used in OpenOCD and
xc3sprog to talk e.g. JTAG to external devices.
Bye
--
Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de
Institut fuer Kernphysik Schlossgartenstrasse 9 64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
^ permalink raw reply
* Re: [PATCH] usb: cp210x: Added support for GPIO (CP2103/4/5)
From: Xiaofan Chen @ 2012-04-29 14:35 UTC (permalink / raw)
To: Uwe Bonnes; +Cc: Alan Cox, linux-usb, linux-kernel, linux-serial
In-Reply-To: <20381.15336.604590.461744@elektron.ikp.physik.tu-darmstadt.de>
On Sun, Apr 29, 2012 at 9:02 PM, Uwe Bonnes
<bon@elektron.ikp.physik.tu-darmstadt.de> wrote:
> most RS232/USB Adapter don't supply and most applications working with these
> adapters don't need hard realtime. So even writing and reading the serial
> lines can be handled with libusb, like libftdi does.
>
> But as soon as higher level protocols based on the serial line get involved,
> a kernel driver is needed...
>
> So when thinking some termiox, some thoughts for the FTDI special modes,
> like MPSSE or synchronous FIFO should be spent. It would come handy if I
> could open /dev/ttyUSBx, set som termiox and could use the kernel driver for
> sending and receiving MPSSE commands. MPSSE is e.g. used in OpenOCD and
> xc3sprog to talk e.g. JTAG to external devices.
On the other hand, OpenOCD and your xc3sprog will probably remain
to be cross-plattform and in that case libusb/libftdi is a good option
to go. There is a patch under review in OpenOCD where libusb-1.0
is used for the MPSSE engine instead of libftdi/ftd2xx and the
performance seems to be better.
--
Xiaofan
^ permalink raw reply
* Re: [PATCH] 8250.c: less than 2400 baud fix.
From: gregkh @ 2012-04-30 2:07 UTC (permalink / raw)
To: Christian Melki; +Cc: linux-serial@vger.kernel.org
In-Reply-To: <1346E68D3A5B2043907CF4BF466383411A07E00DBB@ESESSCMS0353.eemea.ericsson.se>
On Thu, Apr 26, 2012 at 08:59:50AM +0200, Christian Melki wrote:
> From: Christian Melki <christian.melki@ericsson.se>
>
> We noticed that we were loosing data at speed less than 2400 baud.
> It turned out our (TI16750 compatible) uart with 64 byte outgoing fifo
> was truncated to 16 byte (bit 5 sets fifo len) when modifying the fcr
> reg.
> The input code still fills the buffer with 64 bytes if I remember
> correctly and thus data is lost.
> Our fix was to remove whiping of the fcr content and just add the
> TRIGGER_1 which we want for latency.
> I can't see why this would not work on less than 2400 always, for all
> uarts ...
> Otherwise one would have to make sure the filling of the fifo re-checks
> the current state of available fifo size (urrk).
>
> Signed-off-by: Christian Melki <christian.melki@ericsson.se>
> ---
>
> diff -urpN linux-3.3.2.orig//drivers/tty/serial/8250/8250.c linux-3.3.2/drivers/tty/serial/8250/8250.c
> --- linux-3.3.2.orig//drivers/tty/serial/8250/8250.c 2012-04-25 10:31:29.000000000 +0200
> +++ linux-3.3.2/drivers/tty/serial/8250/8250.c 2012-04-26 08:46:29.000000000 +0200
> @@ -2299,10 +2299,11 @@ serial8250_do_set_termios(struct uart_po
> quot++;
>
> if (up->capabilities & UART_CAP_FIFO && up->port.fifosize > 1) {
> - if (baud < 2400)
> - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
> - else
> - fcr = uart_config[up->port.type].fcr;
> + fcr = uart_config[up->port.type].fcr;
> + if (baud < 2400) {
> + fcr &= ~UART_FCR_TRIGGER_MASK;
> + fcr |= UART_FCR_TRIGGER_1;
> + }
> }
This patch doesn't apply at all to my tree, and I can't see why with a
quick glance :(
Can you redo this against the linux-next tree and resend it please?
thanks,
greg k-h
^ permalink raw reply
* RE: 8250.c: Generic support for RTS disabling once shiftreg and fifo is empty. (low latency RS485 etc).
From: Christian Melki @ 2012-04-30 7:05 UTC (permalink / raw)
To: Alan Cox; +Cc: linux-serial@vger.kernel.org
In-Reply-To: <20120427100207.48c04654@pyramind.ukuu.org.uk>
> On Fri, 27 Apr 2012 08:23:23 +0200
> Christian Melki <christian.melki@ericsson.com> wrote:
>
> > Hi.
> >
> > I have written a patch for 8250.c that introduces a new
> > ioctl to tell the uart driver to shift disable RTS when uart
> > has been completely emptied.
> > This idea is to set the ioctl once the master is finished
> > and wants to shift the bus.
> > We needed this to be in the kernel since we have very
> > little time to shift RTS according to the implemented
> > protocol on top of RS485.
> >
> > Is there any interest in the community for such a behavior?
>
> We have a set of RS485 ioctls that provide a standard
> interface for assisting RS485 handling. The interface should
> probably use those if possible.
Ok, didn't see that ioctl. Don't like the naming though.
I know I have used RS485 as a reference, but this can be used for
any half duplex protocol control. Maybe something like RTSCTL
would be more appropriate. (I was looking for ioctls with RTS names).
Anyway, no more whining :). I'll redo it with that ioctl instead.
> > The patch is a little ugly right now. It busywaits a
> > maximum amount of time for the shift register to become
> > empty. I don't know how to do it without introducing a
> > latency that is more than our max RTS time shift requirement
> > (50us). I think it could be useful with a generic 8250.c
> > support for this.
>
> We've hit the same hardware limit in a couple of other places
> where you end up having to spin on the last byte. I don't
> think it's a problem providing it is only triggered when
> trying to do the RS485 bits with that feature.
It will be exactly like that in the tx-path. So it won't disturb
"normal" users beside one more feature check.
> Alan
>
^ permalink raw reply
* RE: [PATCH] 8250.c: less than 2400 baud fix.
From: Christian Melki @ 2012-04-30 9:21 UTC (permalink / raw)
To: gregkh@linuxfoundation.org; +Cc: linux-serial@vger.kernel.org
In-Reply-To: <20120430020710.GA18098@kroah.com>
Sorry about that.
Diff should have handled that simple line offset. Now it applies cleanly to my linux-next atleast.
Signed-off-by: Christian Melki <christian.melki@ericsson.se>
---
diff -urpN linux-next.orig/drivers/tty/serial/8250/8250.c linux-next/drivers/tty/serial/8250/8250.c
--- linux-next.orig/drivers/tty/serial/8250/8250.c 2012-04-30 10:58:13.000000000 +0200
+++ linux-next/drivers/tty/serial/8250/8250.c 2012-04-30 11:03:12.000000000 +0200
@@ -2259,10 +2259,11 @@ serial8250_do_set_termios(struct uart_po
quot++;
if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) {
- if (baud < 2400)
- fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
- else
- fcr = uart_config[port->type].fcr;
+ fcr = uart_config[port->type].fcr;
+ if (baud < 2400) {
+ fcr &= ~UART_FCR_TRIGGER_MASK;
+ fcr |= UART_FCR_TRIGGER_1;
+ }
}
/*
^ permalink raw reply
* [PATCH] usb: cp210x: Added support for GPIO (CP2103/4/5)
From: Preston Fick @ 2012-04-30 20:27 UTC (permalink / raw)
To: gregkh, linux-usb, linux-kernel, linux-serial; +Cc: preston.fick
This fix contains several changes that allow toggling of GPIO on CP210x
devices that support it. Changes include:
* Added in part number support, necessary to see if the connected device
supports the GPIO functionality
* Added two IOCTLs and ioctl function to allow GET/SET of GPIO
* Added in new #defines for partnum support, new USB requests
* Changed "Config request types" section to contain more correct definitions
for request recipient
Signed-off-by: Preston Fick <preston.fick@silabs.com>
---
drivers/usb/serial/cp210x.c | 134 +++++++++++++++++++++++++++++++++++++++++--
1 files changed, 129 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index ec30f95..9d1e542 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -35,6 +35,8 @@
*/
static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *);
static void cp210x_close(struct usb_serial_port *);
+static int cp210x_ioctl(struct tty_struct *tty,
+ unsigned int cmd, unsigned long arg);
static void cp210x_get_termios(struct tty_struct *,
struct usb_serial_port *port);
static void cp210x_get_termios_port(struct usb_serial_port *port,
@@ -154,6 +156,7 @@ MODULE_DEVICE_TABLE(usb, id_table);
struct cp210x_port_private {
__u8 bInterfaceNumber;
+ __u8 bPartNumber;
};
static struct usb_driver cp210x_driver = {
@@ -174,6 +177,7 @@ static struct usb_serial_driver cp210x_device = {
.bulk_out_size = 256,
.open = cp210x_open,
.close = cp210x_close,
+ .ioctl = cp210x_ioctl,
.break_ctl = cp210x_break_ctl,
.set_termios = cp210x_set_termios,
.tiocmget = cp210x_tiocmget,
@@ -187,9 +191,22 @@ static struct usb_serial_driver * const serial_drivers[] = {
&cp210x_device, NULL
};
+/* Part number definitions */
+#define CP2101_PARTNUM 0x01
+#define CP2102_PARTNUM 0x02
+#define CP2103_PARTNUM 0x03
+#define CP2104_PARTNUM 0x04
+#define CP2105_PARTNUM 0x05
+
+/* IOCTLs */
+#define IOCTL_GPIOGET 0x8000
+#define IOCTL_GPIOSET 0x8001
+
/* Config request types */
-#define REQTYPE_HOST_TO_DEVICE 0x41
-#define REQTYPE_DEVICE_TO_HOST 0xc1
+#define REQTYPE_HOST_TO_INTERFACE 0x41
+#define REQTYPE_INTERFACE_TO_HOST 0xc1
+#define REQTYPE_HOST_TO_DEVICE 0x40
+#define REQTYPE_DEVICE_TO_HOST 0xc0
/* Config request codes */
#define CP210X_IFC_ENABLE 0x00
@@ -218,11 +235,17 @@ static struct usb_serial_driver * const serial_drivers[] = {
#define CP210X_SET_CHARS 0x19
#define CP210X_GET_BAUDRATE 0x1D
#define CP210X_SET_BAUDRATE 0x1E
+#define CP210X_VENDOR_SPECIFIC 0xFF
/* CP210X_IFC_ENABLE */
#define UART_ENABLE 0x0001
#define UART_DISABLE 0x0000
+/* CP210X_VENDOR_SPECIFIC */
+#define CP210X_WRITE_LATCH 0x37E1
+#define CP210X_READ_LATCH 0x00C2
+#define CP210X_GET_PARTNUM 0x370B
+
/* CP210X_(SET|GET)_BAUDDIV */
#define BAUD_RATE_GEN_FREQ 0x384000
@@ -286,7 +309,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request,
/* Issue the request, attempting to read 'size' bytes */
result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
- request, REQTYPE_DEVICE_TO_HOST, 0x0000,
+ request, REQTYPE_INTERFACE_TO_HOST, 0x0000,
port_priv->bInterfaceNumber, buf, size,
USB_CTRL_GET_TIMEOUT);
@@ -340,13 +363,13 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,
if (size > 2) {
result = usb_control_msg(serial->dev,
usb_sndctrlpipe(serial->dev, 0),
- request, REQTYPE_HOST_TO_DEVICE, 0x0000,
+ request, REQTYPE_HOST_TO_INTERFACE, 0x0000,
port_priv->bInterfaceNumber, buf, size,
USB_CTRL_SET_TIMEOUT);
} else {
result = usb_control_msg(serial->dev,
usb_sndctrlpipe(serial->dev, 0),
- request, REQTYPE_HOST_TO_DEVICE, data[0],
+ request, REQTYPE_HOST_TO_INTERFACE, data[0],
port_priv->bInterfaceNumber, NULL, 0,
USB_CTRL_SET_TIMEOUT);
}
@@ -453,6 +476,95 @@ static void cp210x_close(struct usb_serial_port *port)
mutex_unlock(&port->serial->disc_mutex);
}
+static int cp210x_ioctl(struct tty_struct *tty,
+ unsigned int cmd, unsigned long arg)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
+ int result = 0;
+ unsigned int latch_setting = 0;
+
+ switch (cmd) {
+
+ case IOCTL_GPIOGET:
+ if ((port_priv->bPartNumber == CP2103_PARTNUM) ||
+ (port_priv->bPartNumber == CP2104_PARTNUM)) {
+ result = usb_control_msg(port->serial->dev,
+ usb_rcvctrlpipe(port->serial->dev, 0),
+ CP210X_VENDOR_SPECIFIC,
+ REQTYPE_DEVICE_TO_HOST,
+ CP210X_READ_LATCH,
+ port_priv->bInterfaceNumber,
+ &latch_setting, 1,
+ USB_CTRL_GET_TIMEOUT);
+ if (result != 1)
+ return -EPROTO;
+ *(unsigned long *)arg = (unsigned long)latch_setting;
+ return 0;
+ } else if (port_priv->bPartNumber == CP2105_PARTNUM) {
+ result = usb_control_msg(port->serial->dev,
+ usb_rcvctrlpipe(port->serial->dev, 0),
+ CP210X_VENDOR_SPECIFIC,
+ REQTYPE_INTERFACE_TO_HOST,
+ CP210X_READ_LATCH,
+ port_priv->bInterfaceNumber,
+ &latch_setting, 1,
+ USB_CTRL_GET_TIMEOUT);
+ if (result != 1)
+ return -EPROTO;
+ *(unsigned long *)arg = (unsigned long)latch_setting;
+ return 0;
+ } else {
+ return -ENOTSUPP;
+ }
+ break;
+
+ case IOCTL_GPIOSET:
+ if ((port_priv->bPartNumber == CP2103_PARTNUM) ||
+ (port_priv->bPartNumber == CP2104_PARTNUM)) {
+ latch_setting =
+ *(unsigned int *)arg & 0x000000FF;
+ latch_setting |=
+ (*(unsigned int *)arg & 0x00FF0000) >> 8;
+ result = usb_control_msg(port->serial->dev,
+ usb_sndctrlpipe(port->serial->dev, 0),
+ CP210X_VENDOR_SPECIFIC,
+ REQTYPE_HOST_TO_DEVICE,
+ CP210X_WRITE_LATCH,
+ latch_setting,
+ NULL, 0,
+ USB_CTRL_SET_TIMEOUT);
+ if (result != 0)
+ return -EPROTO;
+ return 0;
+ } else if (port_priv->bPartNumber == CP2105_PARTNUM) {
+ latch_setting =
+ *(unsigned int *)arg & 0x000000FF;
+ latch_setting |=
+ (*(unsigned int *)arg & 0x00FF0000) >> 8;
+ result = usb_control_msg(port->serial->dev,
+ usb_sndctrlpipe(port->serial->dev, 0),
+ CP210X_VENDOR_SPECIFIC,
+ REQTYPE_HOST_TO_INTERFACE,
+ CP210X_WRITE_LATCH,
+ port_priv->bInterfaceNumber,
+ &latch_setting, 2,
+ USB_CTRL_SET_TIMEOUT);
+ if (result != 2)
+ return -EPROTO;
+ return 0;
+ } else {
+ return -ENOTSUPP;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return -ENOIOCTLCMD;
+}
+
/*
* cp210x_get_termios
* Reads the baud rate, data bits, parity, stop bits and flow control mode
@@ -860,6 +972,7 @@ static int cp210x_startup(struct usb_serial *serial)
{
struct cp210x_port_private *port_priv;
int i;
+ unsigned int partNum;
/* cp210x buffers behave strangely unless device is reset */
usb_reset_device(serial->dev);
@@ -874,6 +987,17 @@ static int cp210x_startup(struct usb_serial *serial)
serial->interface->cur_altsetting->desc.bInterfaceNumber;
usb_set_serial_port_data(serial->port[i], port_priv);
+
+ /* Get the 1-byte part number of the cp210x device */
+ usb_control_msg(serial->dev,
+ usb_rcvctrlpipe(serial->dev, 0),
+ CP210X_VENDOR_SPECIFIC,
+ REQTYPE_DEVICE_TO_HOST,
+ CP210X_GET_PARTNUM,
+ port_priv->bInterfaceNumber,
+ &partNum, 1,
+ USB_CTRL_GET_TIMEOUT);
+ port_priv->bPartNumber = partNum & 0xFF;
}
return 0;
--
1.7.5.4
^ permalink raw reply related
* Re: [PATCH] usb: cp210x: Added support for GPIO (CP2103/4/5)
From: Greg KH @ 2012-04-30 20:32 UTC (permalink / raw)
To: Preston Fick
Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA,
preston.fick-S6d6foEdJf7QT0dZR+AlfA
In-Reply-To: <1335817637-2862-1-git-send-email-preston.fick-S6d6foEdJf7QT0dZR+AlfA@public.gmane.org>
On Mon, Apr 30, 2012 at 03:27:17PM -0500, Preston Fick wrote:
> This fix contains several changes that allow toggling of GPIO on CP210x
> devices that support it. Changes include:
> * Added in part number support, necessary to see if the connected device
> supports the GPIO functionality
> * Added two IOCTLs and ioctl function to allow GET/SET of GPIO
> * Added in new #defines for partnum support, new USB requests
> * Changed "Config request types" section to contain more correct definitions
> for request recipient
No, please break this out into one-patch-per-change, don't bundle all of
this together into one, as I can't take it as-is, sorry.
Especially with those new ioctls...
thanks,
greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Question: How to power-manage UART-attached devices.
From: NeilBrown @ 2012-04-30 22:22 UTC (permalink / raw)
To: linux-serial, linux-pm; +Cc: lkml
[-- Attachment #1: Type: text/plain, Size: 2029 bytes --]
Greetings.
I have a conundrum that I am hoping someone could help me with.
I have a mobile device (Openmoko successor: GTA04) which has two devices
that are attached by UARTs - bluetooth and GPS.
Each of these can usefully be power-managed: The bluetooth shares a
regulator with WIFI and if both are inactive the regulator can be turned off.
GPS has a powered antenna which and be powered down when inactive, and also
has an 'on/off' pin which, when pulsed, toggles the GPS between 'on' and
'off.
The question is how can user-space tell the kernel that these devices are
'inactive'?
I would like to integrate this into Linux in the most "natural" way that I
can but am having trouble. My current approach involves using "rfkill" but
that doesn't work very well for reasons that are probably not very relevant
here. It probably does make sense for powering the GPS antenna, but not
much else.
What I would really like is to integrate it closely with the state of the
UART. i.e. if the /dev/ttyO1 device is open, then the GPS is "on". If not
then it is "off". Similarly if /dev/tty/O0 is open, bluetooth is "on", else
"off".
However I cannot find any way to "plug in" to the tty or serial drivers to
perform an arbitrary action on first-open or last-close. Is something like
that possible?
If not, is it a reasonable thing to ask?
Any suggests about where to put such a hook?
It would be particularly useful if the hooked-in code could also find out
about received characters when the device is thought to be "off". This is
because the only way to find out if the GPS is "on" is to see if it is
sending data, so to turn it off you check if it is sending data and if it
does, toggle the 'on/off' line. I could manage this a different way by
reprogramming the RX pin on the OMAP3 to be a GPIO and then taking a falling
interrupt as an indication that the device is 'on', but I would rather
something more integrated.
Thanks,
NeilBrown
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply
* Re: Question: How to power-manage UART-attached devices.
From: Mark Brown @ 2012-04-30 22:33 UTC (permalink / raw)
To: NeilBrown; +Cc: linux-serial, linux-pm, lkml
In-Reply-To: <20120501082209.0b560708@notabene.brown>
On Tue, May 01, 2012 at 08:22:09AM +1000, NeilBrown wrote:
> The question is how can user-space tell the kernel that these devices are
> 'inactive'?
> I would like to integrate this into Linux in the most "natural" way that I
> can but am having trouble. My current approach involves using "rfkill" but
> that doesn't work very well for reasons that are probably not very relevant
> here. It probably does make sense for powering the GPS antenna, but not
> much else.
The userspace consumer was added for users like this that live entirely
in userspace.
^ permalink raw reply
* Re: Question: How to power-manage UART-attached devices.
From: H. Peter Anvin @ 2012-04-30 22:51 UTC (permalink / raw)
To: NeilBrown, Alan Cox; +Cc: linux-serial, linux-pm, lkml
In-Reply-To: <20120501082209.0b560708@notabene.brown>
On 04/30/2012 03:22 PM, NeilBrown wrote:
>
> What I would really like is to integrate it closely with the state
> of the UART. i.e. if the /dev/ttyO1 device is open, then the GPS
> is "on". If not then it is "off". Similarly if /dev/tty/O0 is
> open, bluetooth is "on", else "off". However I cannot find any way
> to "plug in" to the tty or serial drivers to perform an arbitrary
> action on first-open or last-close. Is something like that
> possible? If not, is it a reasonable thing to ask? Any suggests
> about where to put such a hook?
>
I don't think that's the right interface. Just because the port is
currently open doesn't mean the device is active, nor vice versa. ALL
it means is that someone currently has an access handle to it.
Since a serial port models, well, a *port*, it is logical to think of
a (hypothetical) socket containing an RS-232 connector as well as a
power outlet. Given that, it would be logical to drive the "power
connector" using the same type of interface used for the other parts
of an RS-232 control, meaning either with termios flags or via a
dedicated control ioctl (TIOCPOWER?).
-hpa
^ permalink raw reply
* Re: Question: How to power-manage UART-attached devices.
From: Alan Cox @ 2012-04-30 23:34 UTC (permalink / raw)
To: H. Peter Anvin; +Cc: NeilBrown, linux-serial, linux-pm, lkml
In-Reply-To: <4F9F178F.3030408@zytor.com>
On Mon, 30 Apr 2012 15:51:59 -0700
"H. Peter Anvin" <hpa@zytor.com> wrote:
> On 04/30/2012 03:22 PM, NeilBrown wrote:
> >
> > What I would really like is to integrate it closely with the state
> > of the UART. i.e. if the /dev/ttyO1 device is open, then the GPS
> > is "on". If not then it is "off". Similarly if /dev/tty/O0 is
> > open, bluetooth is "on", else "off". However I cannot find any way
> > to "plug in" to the tty or serial drivers to perform an arbitrary
> > action on first-open or last-close. Is something like that
> > possible? If not, is it a reasonable thing to ask? Any suggests
> > about where to put such a hook?
> >
>
> I don't think that's the right interface. Just because the port is
> currently open doesn't mean the device is active, nor vice versa. ALL
> it means is that someone currently has an access handle to it.
>
> Since a serial port models, well, a *port*, it is logical to think of
> a (hypothetical) socket containing an RS-232 connector as well as a
> power outlet. Given that, it would be logical to drive the "power
> connector" using the same type of interface used for the other parts
> of an RS-232 control, meaning either with termios flags or via a
> dedicated control ioctl (TIOCPOWER?).
Actually several of our virtual tty interfaces treat open as meaning
powered up. It's a fairly logical power management model. A lot of our
real tty ports do the same as well and kill power on the last close.
At the tty layer the tty_port helper callbacks port->activate() and
port->shutdown() provide the needed functionality.
You don't however want to be "hooking" this - your platform needs to
provide its own versions of the relevant operations in the OMAP serial
driver.
Alan
^ permalink raw reply
* Re: Question: How to power-manage UART-attached devices.
From: NeilBrown @ 2012-04-30 23:35 UTC (permalink / raw)
To: Mark Brown; +Cc: linux-serial, linux-pm, lkml
In-Reply-To: <20120430223322.GA3951@sirena.org.uk>
[-- Attachment #1: Type: text/plain, Size: 1539 bytes --]
On Mon, 30 Apr 2012 23:33:22 +0100 Mark Brown
<broonie@opensource.wolfsonmicro.com> wrote:
> On Tue, May 01, 2012 at 08:22:09AM +1000, NeilBrown wrote:
>
> > The question is how can user-space tell the kernel that these devices are
> > 'inactive'?
>
> > I would like to integrate this into Linux in the most "natural" way that I
> > can but am having trouble. My current approach involves using "rfkill" but
> > that doesn't work very well for reasons that are probably not very relevant
> > here. It probably does make sense for powering the GPS antenna, but not
> > much else.
>
> The userspace consumer was added for users like this that live entirely
> in userspace.
Hi Mark,
thanks for the reply.
I assume you mean REGULATOR_VIRTUAL_CONSUMER (drivers/regulator/virtual.c)?
The one where the Kconfig entry says:
This is mainly useful for test purposes.
That certainly was useful for test purposes but I want to move beyond
testing.
One of the purposes of an operating system is to provide useful abstractions
and hide irrelevant details, so I don't want user-space to have to
explicitly enable a regulator.
I could cope with an 'on/off switch' abstraction. It might then enable a
regulator. In the case of the GPS device it would need to both enable a
regulator and toggle a GPIO line. I really don't want user-space to "know"
that it has to turn on a regulator and toggle a gpio line...
So I'm still hoping for something more abstract.
Thanks,
NeilBrown
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply
* Re: Question: How to power-manage UART-attached devices.
From: NeilBrown @ 2012-04-30 23:47 UTC (permalink / raw)
To: H. Peter Anvin; +Cc: Alan Cox, linux-serial, linux-pm, lkml
In-Reply-To: <4F9F178F.3030408@zytor.com>
[-- Attachment #1: Type: text/plain, Size: 2364 bytes --]
On Mon, 30 Apr 2012 15:51:59 -0700 "H. Peter Anvin" <hpa@zytor.com> wrote:
> On 04/30/2012 03:22 PM, NeilBrown wrote:
> >
> > What I would really like is to integrate it closely with the state
> > of the UART. i.e. if the /dev/ttyO1 device is open, then the GPS
> > is "on". If not then it is "off". Similarly if /dev/tty/O0 is
> > open, bluetooth is "on", else "off". However I cannot find any way
> > to "plug in" to the tty or serial drivers to perform an arbitrary
> > action on first-open or last-close. Is something like that
> > possible? If not, is it a reasonable thing to ask? Any suggests
> > about where to put such a hook?
> >
>
> I don't think that's the right interface. Just because the port is
> currently open doesn't mean the device is active, nor vice versa. ALL
> it means is that someone currently has an access handle to it.
>
> Since a serial port models, well, a *port*, it is logical to think of
> a (hypothetical) socket containing an RS-232 connector as well as a
> power outlet. Given that, it would be logical to drive the "power
> connector" using the same type of interface used for the other parts
> of an RS-232 control, meaning either with termios flags or via a
> dedicated control ioctl (TIOCPOWER?).
>
> -hpa
Hi Peter,
I agree that in general there is not necessarily a 1-1 correspondence between
"device file is open" and "device is powered", however I think that in a lot
of real cases it is a very natural correspondence.
In my bluetooth case, there is nothing useful that the device can do if
hciattach isn't running and listening to the device, so it may as well be
off.
For GPS it is less clear as the GPS could maintain state (current almanac
and ephemeris) and could even periodically tune in to the satellites and
update this state (though as mine cannot power on/off the antenna that
second case might not be very useful). This particular GPS device does not
lose state when I toggle the 'on/off' line. It just stops sending
information (and maybe stops doing calculations, I don't know). And that is
exactly what I want to happen when the tty device is closed.
I imagine this proposal as being like a virtual DTR line. It may not always
be appropriate to connect DTR to the power switch, but sometimes it is.
Thanks,
NeilBrown
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply
* Re: Question: How to power-manage UART-attached devices.
From: H. Peter Anvin @ 2012-04-30 23:50 UTC (permalink / raw)
To: NeilBrown; +Cc: Alan Cox, linux-serial, linux-pm, lkml
In-Reply-To: <20120501094752.2ea16f23@notabene.brown>
On 04/30/2012 04:47 PM, NeilBrown wrote:
>
> I imagine this proposal as being like a virtual DTR line. It may
> not always be appropriate to connect DTR to the power switch, but
> sometimes it is.
>
Yeah, that's pretty much what I'm suggesting.
-hpa
^ permalink raw reply
* Re: Question: How to power-manage UART-attached devices.
From: NeilBrown @ 2012-05-01 0:12 UTC (permalink / raw)
To: Alan Cox; +Cc: H. Peter Anvin, linux-serial, linux-pm, lkml
In-Reply-To: <20120501003420.028b57ec@pyramind.ukuu.org.uk>
[-- Attachment #1: Type: text/plain, Size: 2868 bytes --]
On Tue, 1 May 2012 00:34:20 +0100 Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:
> On Mon, 30 Apr 2012 15:51:59 -0700
> "H. Peter Anvin" <hpa@zytor.com> wrote:
>
> > On 04/30/2012 03:22 PM, NeilBrown wrote:
> > >
> > > What I would really like is to integrate it closely with the state
> > > of the UART. i.e. if the /dev/ttyO1 device is open, then the GPS
> > > is "on". If not then it is "off". Similarly if /dev/tty/O0 is
> > > open, bluetooth is "on", else "off". However I cannot find any way
> > > to "plug in" to the tty or serial drivers to perform an arbitrary
> > > action on first-open or last-close. Is something like that
> > > possible? If not, is it a reasonable thing to ask? Any suggests
> > > about where to put such a hook?
> > >
> >
> > I don't think that's the right interface. Just because the port is
> > currently open doesn't mean the device is active, nor vice versa. ALL
> > it means is that someone currently has an access handle to it.
> >
> > Since a serial port models, well, a *port*, it is logical to think of
> > a (hypothetical) socket containing an RS-232 connector as well as a
> > power outlet. Given that, it would be logical to drive the "power
> > connector" using the same type of interface used for the other parts
> > of an RS-232 control, meaning either with termios flags or via a
> > dedicated control ioctl (TIOCPOWER?).
>
> Actually several of our virtual tty interfaces treat open as meaning
> powered up. It's a fairly logical power management model. A lot of our
> real tty ports do the same as well and kill power on the last close.
>
> At the tty layer the tty_port helper callbacks port->activate() and
> port->shutdown() provide the needed functionality.
>
> You don't however want to be "hooking" this - your platform needs to
> provide its own versions of the relevant operations in the OMAP serial
> driver.
Hi Alan,
thanks for the pointers.
Looking at serial_core.c, which appears the be the gateway between tty_port
and the OMAP serial driver, the activate() function it provides is a no-op,
and the shutdown() function calls uport->ops->shutdown() (and a couple of
other things).
However there is a uart_port_startup() which claims to be called
once-per-open even though activate() doesn't call it (tty_operations.open()
does). And it calls uport->ops->startup().
The omap-serial handlers for these are serial_omap_startup() and
serial_omap_shutdown(). I think you are suggesting that I should plug in
there somehow. I wonder how.
Maybe I could teach it to use a given GPIO as a 'DTR', and then write a
separate driver which registers with gpiolib as providing an output GPIO and
which responds to changes on that GPIO by turning the device 'on' or 'off'.
Does that sound reasonably sane?
Thanks,
NeilBrown
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply
* Re: Question: How to power-manage UART-attached devices.
From: NeilBrown @ 2012-05-01 0:27 UTC (permalink / raw)
To: H. Peter Anvin; +Cc: Alan Cox, linux-serial, linux-pm, lkml
In-Reply-To: <4F9F2538.4080407@zytor.com>
[-- Attachment #1: Type: text/plain, Size: 1752 bytes --]
On Mon, 30 Apr 2012 16:50:16 -0700 "H. Peter Anvin" <hpa@zytor.com> wrote:
> On 04/30/2012 04:47 PM, NeilBrown wrote:
> >
> > I imagine this proposal as being like a virtual DTR line. It may
> > not always be appropriate to connect DTR to the power switch, but
> > sometimes it is.
> >
>
> Yeah, that's pretty much what I'm suggesting.
>
> -hpa
Yes, so you are :-)
I was distracted by the TIOCPOWER suggestion, and I really didn't want any
new action by user-space, I would much prefer it all "just works".
But you also mentioned "termios flags" but by that I suspect you are
referring to HUPCL which is documented as:
HUPCL Lower modem control lines after last process closes the device
(hang up).
without really saying which modem control lines. Looking at the code it
seems to be talking about DTR and RTS. It only says "lower on last close"
but doesn't say "raise on first open" but maybe that is assumed.
So as long as HUPCL is the default, defining a virtual DTR line might be just
what I want, and HUPCL could be disabled of someone want to keep the device
powered on while it is closed.
So I think I want to:
1/ teach omap-serial to drive a given GPIO as a DTR line
2/ write a 'gpio-regulator' driver which provides a single GPIO and
turns a given regulator 'on' or 'off' depending on the state of the GPIO
3/ write a special-purpose GPIO driver which provides a single GPIO
and toggles another GPIO whenever the state of the first changes, and also
monitors the serial RX pin when the device should be 'off', and toggles
again if it sees RX activity.
4/ Keeping using rfkill to power the GPS antenna.
Sounds like a plan.
Thanks,
NeilBrown
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply
* [PATCH 2/3] usb: cp210x: Added in support to get and store part number
From: Preston Fick @ 2012-05-01 4:06 UTC (permalink / raw)
To: gregkh, linux-usb, linux-kernel, linux-serial; +Cc: preston.fick
In-Reply-To: <1335845210-5147-1-git-send-email-preston.fick@silabs.com>
This change gets the part number of the device when the driver is loaded and
stores it in the private portion of the port structure. This addition will
allow for part specific functionality to be added to the driver if needed.
Signed-off-by: Preston Fick <preston.fick@silabs.com>
---
drivers/usb/serial/cp210x.c | 24 ++++++++++++++++++++++++
1 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index e67ccf3..b3646b8 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -154,6 +154,7 @@ MODULE_DEVICE_TABLE(usb, id_table);
struct cp210x_port_private {
__u8 bInterfaceNumber;
+ __u8 bPartNumber;
};
static struct usb_driver cp210x_driver = {
@@ -187,6 +188,13 @@ static struct usb_serial_driver * const serial_drivers[] = {
&cp210x_device, NULL
};
+/* Part number definitions */
+#define CP2101_PARTNUM 0x01
+#define CP2102_PARTNUM 0x02
+#define CP2103_PARTNUM 0x03
+#define CP2104_PARTNUM 0x04
+#define CP2105_PARTNUM 0x05
+
/* Config request types */
#define REQTYPE_HOST_TO_INTERFACE 0x41
#define REQTYPE_INTERFACE_TO_HOST 0xc1
@@ -220,11 +228,15 @@ static struct usb_serial_driver * const serial_drivers[] = {
#define CP210X_SET_CHARS 0x19
#define CP210X_GET_BAUDRATE 0x1D
#define CP210X_SET_BAUDRATE 0x1E
+#define CP210X_VENDOR_SPECIFIC 0xFF
/* CP210X_IFC_ENABLE */
#define UART_ENABLE 0x0001
#define UART_DISABLE 0x0000
+/* CP210X_VENDOR_SPECIFIC */
+#define CP210X_GET_PARTNUM 0x370B
+
/* CP210X_(SET|GET)_BAUDDIV */
#define BAUD_RATE_GEN_FREQ 0x384000
@@ -862,6 +874,7 @@ static int cp210x_startup(struct usb_serial *serial)
{
struct cp210x_port_private *port_priv;
int i;
+ unsigned int partNum;
/* cp210x buffers behave strangely unless device is reset */
usb_reset_device(serial->dev);
@@ -876,6 +889,17 @@ static int cp210x_startup(struct usb_serial *serial)
serial->interface->cur_altsetting->desc.bInterfaceNumber;
usb_set_serial_port_data(serial->port[i], port_priv);
+
+ /* Get the 1-byte part number of the cp210x device */
+ usb_control_msg(serial->dev,
+ usb_rcvctrlpipe(serial->dev, 0),
+ CP210X_VENDOR_SPECIFIC,
+ REQTYPE_DEVICE_TO_HOST,
+ CP210X_GET_PARTNUM,
+ port_priv->bInterfaceNumber,
+ &partNum, 1,
+ USB_CTRL_GET_TIMEOUT);
+ port_priv->bPartNumber = partNum & 0xFF;
}
return 0;
--
1.7.5.4
^ permalink raw reply related
* [PATCH 3/3] usb: cp210x: Add ioctl for GPIO support
From: Preston Fick @ 2012-05-01 4:06 UTC (permalink / raw)
To: gregkh, linux-usb, linux-kernel, linux-serial; +Cc: preston.fick
In-Reply-To: <1335845210-5147-1-git-send-email-preston.fick@silabs.com>
This patch adds support for GPIO for CP210x devices that support it through two
IOCTLs to get or set the GPIO latch on a CP210x device. The specification for
this can be found in Silicon Labs AN571 document on section 5.27.1-4.
Signed-off-by: Preston Fick <preston.fick@silabs.com>
---
drivers/usb/serial/cp210x.c | 98 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 98 insertions(+), 0 deletions(-)
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index b3646b8..9d1e542 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -35,6 +35,8 @@
*/
static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *);
static void cp210x_close(struct usb_serial_port *);
+static int cp210x_ioctl(struct tty_struct *tty,
+ unsigned int cmd, unsigned long arg);
static void cp210x_get_termios(struct tty_struct *,
struct usb_serial_port *port);
static void cp210x_get_termios_port(struct usb_serial_port *port,
@@ -175,6 +177,7 @@ static struct usb_serial_driver cp210x_device = {
.bulk_out_size = 256,
.open = cp210x_open,
.close = cp210x_close,
+ .ioctl = cp210x_ioctl,
.break_ctl = cp210x_break_ctl,
.set_termios = cp210x_set_termios,
.tiocmget = cp210x_tiocmget,
@@ -195,6 +198,10 @@ static struct usb_serial_driver * const serial_drivers[] = {
#define CP2104_PARTNUM 0x04
#define CP2105_PARTNUM 0x05
+/* IOCTLs */
+#define IOCTL_GPIOGET 0x8000
+#define IOCTL_GPIOSET 0x8001
+
/* Config request types */
#define REQTYPE_HOST_TO_INTERFACE 0x41
#define REQTYPE_INTERFACE_TO_HOST 0xc1
@@ -235,6 +242,8 @@ static struct usb_serial_driver * const serial_drivers[] = {
#define UART_DISABLE 0x0000
/* CP210X_VENDOR_SPECIFIC */
+#define CP210X_WRITE_LATCH 0x37E1
+#define CP210X_READ_LATCH 0x00C2
#define CP210X_GET_PARTNUM 0x370B
/* CP210X_(SET|GET)_BAUDDIV */
@@ -467,6 +476,95 @@ static void cp210x_close(struct usb_serial_port *port)
mutex_unlock(&port->serial->disc_mutex);
}
+static int cp210x_ioctl(struct tty_struct *tty,
+ unsigned int cmd, unsigned long arg)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
+ int result = 0;
+ unsigned int latch_setting = 0;
+
+ switch (cmd) {
+
+ case IOCTL_GPIOGET:
+ if ((port_priv->bPartNumber == CP2103_PARTNUM) ||
+ (port_priv->bPartNumber == CP2104_PARTNUM)) {
+ result = usb_control_msg(port->serial->dev,
+ usb_rcvctrlpipe(port->serial->dev, 0),
+ CP210X_VENDOR_SPECIFIC,
+ REQTYPE_DEVICE_TO_HOST,
+ CP210X_READ_LATCH,
+ port_priv->bInterfaceNumber,
+ &latch_setting, 1,
+ USB_CTRL_GET_TIMEOUT);
+ if (result != 1)
+ return -EPROTO;
+ *(unsigned long *)arg = (unsigned long)latch_setting;
+ return 0;
+ } else if (port_priv->bPartNumber == CP2105_PARTNUM) {
+ result = usb_control_msg(port->serial->dev,
+ usb_rcvctrlpipe(port->serial->dev, 0),
+ CP210X_VENDOR_SPECIFIC,
+ REQTYPE_INTERFACE_TO_HOST,
+ CP210X_READ_LATCH,
+ port_priv->bInterfaceNumber,
+ &latch_setting, 1,
+ USB_CTRL_GET_TIMEOUT);
+ if (result != 1)
+ return -EPROTO;
+ *(unsigned long *)arg = (unsigned long)latch_setting;
+ return 0;
+ } else {
+ return -ENOTSUPP;
+ }
+ break;
+
+ case IOCTL_GPIOSET:
+ if ((port_priv->bPartNumber == CP2103_PARTNUM) ||
+ (port_priv->bPartNumber == CP2104_PARTNUM)) {
+ latch_setting =
+ *(unsigned int *)arg & 0x000000FF;
+ latch_setting |=
+ (*(unsigned int *)arg & 0x00FF0000) >> 8;
+ result = usb_control_msg(port->serial->dev,
+ usb_sndctrlpipe(port->serial->dev, 0),
+ CP210X_VENDOR_SPECIFIC,
+ REQTYPE_HOST_TO_DEVICE,
+ CP210X_WRITE_LATCH,
+ latch_setting,
+ NULL, 0,
+ USB_CTRL_SET_TIMEOUT);
+ if (result != 0)
+ return -EPROTO;
+ return 0;
+ } else if (port_priv->bPartNumber == CP2105_PARTNUM) {
+ latch_setting =
+ *(unsigned int *)arg & 0x000000FF;
+ latch_setting |=
+ (*(unsigned int *)arg & 0x00FF0000) >> 8;
+ result = usb_control_msg(port->serial->dev,
+ usb_sndctrlpipe(port->serial->dev, 0),
+ CP210X_VENDOR_SPECIFIC,
+ REQTYPE_HOST_TO_INTERFACE,
+ CP210X_WRITE_LATCH,
+ port_priv->bInterfaceNumber,
+ &latch_setting, 2,
+ USB_CTRL_SET_TIMEOUT);
+ if (result != 2)
+ return -EPROTO;
+ return 0;
+ } else {
+ return -ENOTSUPP;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return -ENOIOCTLCMD;
+}
+
/*
* cp210x_get_termios
* Reads the baud rate, data bits, parity, stop bits and flow control mode
--
1.7.5.4
^ permalink raw reply related
* [PATCH 1/3] usb: cp210x: Corrected USB request type definitions
From: Preston Fick @ 2012-05-01 4:06 UTC (permalink / raw)
To: gregkh, linux-usb, linux-kernel, linux-serial; +Cc: preston.fick
The original request types in the cp210x driver are labled as "DEVICE_TO_HOST" and
"HOST_TO_DEVICE" but the actual bit definition corresponds to a request to the
interface. This has been corrected, and the actual definition for the device
requests have been added.
Signed-off-by: Preston Fick <preston.fick@silabs.com>
---
drivers/usb/serial/cp210x.c | 12 +++++++-----
1 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index ec30f95..e67ccf3 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -188,8 +188,10 @@ static struct usb_serial_driver * const serial_drivers[] = {
};
/* Config request types */
-#define REQTYPE_HOST_TO_DEVICE 0x41
-#define REQTYPE_DEVICE_TO_HOST 0xc1
+#define REQTYPE_HOST_TO_INTERFACE 0x41
+#define REQTYPE_INTERFACE_TO_HOST 0xc1
+#define REQTYPE_HOST_TO_DEVICE 0x40
+#define REQTYPE_DEVICE_TO_HOST 0xc0
/* Config request codes */
#define CP210X_IFC_ENABLE 0x00
@@ -286,7 +288,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request,
/* Issue the request, attempting to read 'size' bytes */
result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
- request, REQTYPE_DEVICE_TO_HOST, 0x0000,
+ request, REQTYPE_INTERFACE_TO_HOST, 0x0000,
port_priv->bInterfaceNumber, buf, size,
USB_CTRL_GET_TIMEOUT);
@@ -340,13 +342,13 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,
if (size > 2) {
result = usb_control_msg(serial->dev,
usb_sndctrlpipe(serial->dev, 0),
- request, REQTYPE_HOST_TO_DEVICE, 0x0000,
+ request, REQTYPE_HOST_TO_INTERFACE, 0x0000,
port_priv->bInterfaceNumber, buf, size,
USB_CTRL_SET_TIMEOUT);
} else {
result = usb_control_msg(serial->dev,
usb_sndctrlpipe(serial->dev, 0),
- request, REQTYPE_HOST_TO_DEVICE, data[0],
+ request, REQTYPE_HOST_TO_INTERFACE, data[0],
port_priv->bInterfaceNumber, NULL, 0,
USB_CTRL_SET_TIMEOUT);
}
--
1.7.5.4
^ permalink raw reply related
* Re: Deterministic behavior for TTY serial
From: Ivo Sieben @ 2012-05-01 14:30 UTC (permalink / raw)
To: Greg KH; +Cc: linux-serial, Alan Cox, RT
In-Reply-To: <CAMSQXEEN=6M59CR3riNA5-kFFv7QAsn_g3PHi3A8P9mh3SfdeQ@mail.gmail.com>
Hello,
2012/4/26 Ivo Sieben <meltedpianoman@gmail.com>:
>
> I did some analyses using the ftrace 'function_graph' tracer to find
> out what causes the TTY read to take longer than expected.
> I use a test application, running on RT prioirty 99 that writes bursts
> of 24 Bytes data to a my TTY device. A loop back connector is used, so
> the application also reads back these 24 bytes. Non blocking reads &
> writes are used.
>
> This analyses is still ongoing...
> Regards,
> Ivo Sieben
I've proceeded with my analyses, and I think I've found one cause for
the non deterministic read behavior ...
(there is also an issue with the flip buffer read handling, but I'm
still investigating that)
On line 47 of tty_ldisc.c a Spin Lock is defined that guards the line
discipline administration.
It protects two reference counters:
"users", atomic counter in the tty_ldisc struct, that holds the number
of active users of the ldisc in each tty instance. Used for "idle"
handling.
"refcount", counter in the tty_ldisc_ops struct, that holds the number
of lines using the discipline. (when the user count of a line reaches
0, the refcount of the line discipline is decreased by one) Only when
the refcount is 0, it is allowed to unregister the line discipline.
This Spin Lock is defined globally, This causes that my high priority
process to get blocked because of a lower priority process that holds
this spin lock. Of course you get priority inheritance, but this adds
quite a lot of extra execution time to the read function (because of
additional spin lock behavior, and scheduling to the lower priority
process)
Since the "user" and "refcount" reference counters have combined
behavior (refcount is decremented when users reaches zero), I don't
see a way to remove this global lock. Any ideas how this can be
improved?
We are considering to implement our UART device driver as a "normal"
character device driver and bypass the TTY framework. But that would
be a pitty, since we would have to re-implement some functionality
that is already in the TTY framework.
Regards,
Ivo Sieben
^ permalink raw reply
* Re: Deterministic behavior for TTY serial
From: Alan Cox @ 2012-05-01 15:04 UTC (permalink / raw)
To: Ivo Sieben; +Cc: Greg KH, linux-serial, Alan Cox, RT
In-Reply-To: <CAMSQXEGb9moJbCQwwXgEq7H-HvaSiuS5JBL55jr0ZhEEeAmqzw@mail.gmail.com>
> This Spin Lock is defined globally, This causes that my high priority
> process to get blocked because of a lower priority process that holds
> this spin lock. Of course you get priority inheritance, but this adds
> quite a lot of extra execution time to the read function (because of
> additional spin lock behavior, and scheduling to the lower priority
> process)
It's a spin lock and its only held across very small numbers of
instructions in any normal path so this rather surprises me - in your
actual capture data can you see what is holding the lock for long times
causing this ?
> Since the "user" and "refcount" reference counters have combined
> behavior (refcount is decremented when users reaches zero), I don't
> see a way to remove this global lock. Any ideas how this can be
> improved?
I've never really thought about it because it should never be contended
in any meaningful way.
Alan
^ permalink raw reply
* Re: [PATCH 2/3] usb: cp210x: Added in support to get and store part number
From: Sergei Shtylyov @ 2012-05-01 16:16 UTC (permalink / raw)
To: Preston Fick; +Cc: gregkh, linux-usb, linux-kernel, linux-serial, preston.fick
In-Reply-To: <1335845210-5147-2-git-send-email-preston.fick@silabs.com>
Hello.
On 01-05-2012 8:06, Preston Fick wrote:
> This change gets the part number of the device when the driver is loaded and
> stores it in the private portion of the port structure. This addition will
> allow for part specific functionality to be added to the driver if needed.
> Signed-off-by: Preston Fick<preston.fick@silabs.com>
> ---
> drivers/usb/serial/cp210x.c | 24 ++++++++++++++++++++++++
> 1 files changed, 24 insertions(+), 0 deletions(-)
> diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
> index e67ccf3..b3646b8 100644
> --- a/drivers/usb/serial/cp210x.c
> +++ b/drivers/usb/serial/cp210x.c
[...]
> @@ -862,6 +874,7 @@ static int cp210x_startup(struct usb_serial *serial)
> {
> struct cp210x_port_private *port_priv;
> int i;
> + unsigned int partNum;
>
> /* cp210x buffers behave strangely unless device is reset */
> usb_reset_device(serial->dev);
> @@ -876,6 +889,17 @@ static int cp210x_startup(struct usb_serial *serial)
> serial->interface->cur_altsetting->desc.bInterfaceNumber;
>
> usb_set_serial_port_data(serial->port[i], port_priv);
> +
> + /* Get the 1-byte part number of the cp210x device */
> + usb_control_msg(serial->dev,
This may involve DMA...
> + usb_rcvctrlpipe(serial->dev, 0),
> + CP210X_VENDOR_SPECIFIC,
> + REQTYPE_DEVICE_TO_HOST,
> + CP210X_GET_PARTNUM,
> + port_priv->bInterfaceNumber,
> + &partNum, 1,
You can't do DMA to a buffer situated on stack. You should kmalloc() the
buffer.
> + USB_CTRL_GET_TIMEOUT);
> + port_priv->bPartNumber = partNum& 0xFF;
> }
>
> return 0;
WBR, Sergei
^ permalink raw reply
* Re: Question: How to power-manage UART-attached devices.
From: Mark Brown @ 2012-05-01 16:33 UTC (permalink / raw)
To: NeilBrown; +Cc: linux-serial, linux-pm, lkml
In-Reply-To: <20120501093559.5c14087d@notabene.brown>
[-- Attachment #1: Type: text/plain, Size: 475 bytes --]
On Tue, May 01, 2012 at 09:35:59AM +1000, NeilBrown wrote:
> On Mon, 30 Apr 2012 23:33:22 +0100 Mark Brown
> > On Tue, May 01, 2012 at 08:22:09AM +1000, NeilBrown wrote:
> > The userspace consumer was added for users like this that live entirely
> > in userspace.
> I assume you mean REGULATOR_VIRTUAL_CONSUMER (drivers/regulator/virtual.c)?
No, that's just for testing drivers in development. I mean the
userspace consumer which is hidden away in userspace-consumer.c.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox