Did quatech changes make 3.8? (was: Re: Comments requested: driver for Quatech PCI serial cards)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Nov 29, 2012 at 09:03:00AM +1030, Jonathan Woithe wrote:
> On Wed, Nov 28, 2012 at 09:30:10AM -0800, Greg KH wrote:
> > On Thu, Nov 29, 2012 at 12:11:40AM +1030, Jonathan Woithe wrote:
> > > On Wed, Nov 28, 2012 at 01:24:19PM +0000, Alan Cox wrote:
> > > > Can we get a Signed-off-by: for the first patch so we can try and get it
> > > > into 3.8 ?
> > > 
> > > Sure.  See below.  The rest of the previous commit message was fine so I
> > > haven't replicated it here.
> > 
> > Please do, otherwise I have to hand-edit the patch to add it back, and
> > odds are, I will get it wrong...
> 
> No problem.  See below.  I took the opportunity to tweak the commit message
> a touch.

I am wondering (for documentation purposes) whether the quatech changes
below made 3.8 or whether they'll appear in 3.9.  I don't see them in
linux-next or tty-next, but I'm still learning git and might have done
something wrong while searching.

jonathan

> From: Alan Cox <alan@xxxxxxxxxxxxxxx>
> 
> quatech: add the other serial identifiers and preliminary control code
>     
> Jonathan Woithe posted an out of tree enabler/control module for these
> cards.  Lift the relevant identifiers and put them in the 8250_pci driver
> along with code used to control custom registers on these cards.
>     
> Signed-off-by: Alan Cox <alan@xxxxxxxxxxxxxxx>
> Signed-off-by: Jonathan Woithe <jwoithe@xxxxxxxxxx>
> 
> ---
> diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
> index 17b7d26..43c6b4f 100644
> --- a/drivers/tty/serial/8250/8250_pci.c
> +++ b/drivers/tty/serial/8250/8250_pci.c
> @@ -1040,6 +1040,253 @@ static int pci_asix_setup(struct serial_private *priv,
>  	return pci_default_setup(priv, board, port, idx);
>  }
>  
> +/* Quatech devices have their own extra interface features */
> +
> +struct quatech_feature {
> +	u16 devid;
> +	bool amcc;
> +};
> +
> +#define QPCR_TEST_FOR1		0x3F
> +#define QPCR_TEST_GET1		0x00
> +#define QPCR_TEST_FOR2		0x40
> +#define QPCR_TEST_GET2		0x40
> +#define QPCR_TEST_FOR3		0x80
> +#define QPCR_TEST_GET3		0x40
> +#define QPCR_TEST_FOR4		0xC0
> +#define QPCR_TEST_GET4		0x80
> +
> +#define QOPR_CLOCK_X1		0x0000
> +#define QOPR_CLOCK_X2		0x0001
> +#define QOPR_CLOCK_X4		0x0002
> +#define QOPR_CLOCK_X8		0x0003
> +#define QOPR_CLOCK_RATE_MASK	0x0003
> +
> +
> +static struct quatech_feature quatech_cards[] = {
> +	{ PCI_DEVICE_ID_QUATECH_QSC100,   1 },
> +	{ PCI_DEVICE_ID_QUATECH_DSC100,   1 },
> +	{ PCI_DEVICE_ID_QUATECH_DSC100E,  0 },
> +	{ PCI_DEVICE_ID_QUATECH_DSC200,   1 },
> +	{ PCI_DEVICE_ID_QUATECH_DSC200E,  0 },
> +	{ PCI_DEVICE_ID_QUATECH_ESC100D,  1 },
> +	{ PCI_DEVICE_ID_QUATECH_ESC100M,  1 },
> +	{ PCI_DEVICE_ID_QUATECH_QSCP100,  1 },
> +	{ PCI_DEVICE_ID_QUATECH_DSCP100,  1 },
> +	{ PCI_DEVICE_ID_QUATECH_QSCP200,  1 },
> +	{ PCI_DEVICE_ID_QUATECH_DSCP200,  1 },
> +	{ PCI_DEVICE_ID_QUATECH_ESCLP100, 0 },
> +	{ PCI_DEVICE_ID_QUATECH_QSCLP100, 0 },
> +	{ PCI_DEVICE_ID_QUATECH_DSCLP100, 0 },
> +	{ PCI_DEVICE_ID_QUATECH_SSCLP100, 0 },
> +	{ PCI_DEVICE_ID_QUATECH_QSCLP200, 0 },
> +	{ PCI_DEVICE_ID_QUATECH_DSCLP200, 0 },
> +	{ PCI_DEVICE_ID_QUATECH_SSCLP200, 0 },
> +	{ PCI_DEVICE_ID_QUATECH_SPPXP_100, 0 },
> +	{ 0, }
> +};
> +
> +static int pci_quatech_amcc(u16 devid)
> +{
> +	struct quatech_feature *qf = &quatech_cards[0];
> +	while (qf->devid) {
> +		if (qf->devid == devid)
> +			return qf->amcc;
> +		qf++;
> +	}
> +	pr_err("quatech: unknown port type '0x%04X'.\n", devid);
> +	return 0;
> +};
> +
> +static int pci_quatech_rqopr(struct uart_8250_port *port)
> +{
> +	unsigned long base = port->port.iobase;
> +	u8 LCR, val;
> +
> +	LCR = inb(base + UART_LCR);
> +	outb(0xBF, base + UART_LCR);
> +	val = inb(base + UART_SCR);
> +	outb(LCR, base + UART_LCR);
> +	return val;
> +}
> +
> +static void pci_quatech_wqopr(struct uart_8250_port *port, u8 qopr)
> +{
> +	unsigned long base = port->port.iobase;
> +	u8 LCR, val;
> +
> +	LCR = inb(base + UART_LCR);
> +	outb(0xBF, base + UART_LCR);
> +	val = inb(base + UART_SCR);
> +	outb(qopr, base + UART_SCR);
> +	outb(LCR, base + UART_LCR);
> +}
> +
> +static int pci_quatech_rqmcr(struct uart_8250_port *port)
> +{
> +	unsigned long base = port->port.iobase;
> +	u8 LCR, val, qmcr;
> +
> +	LCR = inb(base + UART_LCR);
> +	outb(0xBF, base + UART_LCR);
> +	val = inb(base + UART_SCR);
> +	outb(val | 0x10, base + UART_SCR);
> +	qmcr = inb(base + UART_MCR);
> +	outb(val, base + UART_SCR);
> +	outb(LCR, base + UART_LCR);
> +
> +	return qmcr;
> +}
> +
> +static void pci_quatech_wqmcr(struct uart_8250_port *port, u8 qmcr)
> +{
> +	unsigned long base = port->port.iobase;
> +	u8 LCR, val;
> +
> +	LCR = inb(base + UART_LCR);
> +	outb(0xBF, base + UART_LCR);
> +	val = inb(base + UART_SCR);
> +	outb(val | 0x10, base + UART_SCR);
> +	outb(qmcr, base + UART_MCR);
> +	outb(val, base + UART_SCR);
> +	outb(LCR, base + UART_LCR);
> +}
> +
> +static int pci_quatech_has_qmcr(struct uart_8250_port *port)
> +{
> +	unsigned long base = port->port.iobase;
> +	u8 LCR, val;
> +
> +	LCR = inb(base + UART_LCR);
> +	outb(0xBF, base + UART_LCR);
> +	val = inb(base + UART_SCR);
> +	if (val & 0x20) {
> +		outb(0x80, UART_LCR);
> +		if (!(inb(UART_SCR) & 0x20)) {
> +			outb(LCR, base + UART_LCR);
> +			return 1;
> +		}
> +	}
> +	return 0;
> +}
> +
> +static int pci_quatech_test(struct uart_8250_port *port)
> +{
> +	u8 reg;
> +	u8 qopr = pci_quatech_rqopr(port);
> +	pci_quatech_wqopr(port, qopr & QPCR_TEST_FOR1);
> +	reg = pci_quatech_rqopr(port) & 0xC0;
> +	if (reg != QPCR_TEST_GET1)
> +		return -EINVAL;
> +	pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR2);
> +	reg = pci_quatech_rqopr(port) & 0xC0;
> +	if (reg != QPCR_TEST_GET2)
> +		return -EINVAL;
> +	pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR3);
> +	reg = pci_quatech_rqopr(port) & 0xC0;
> +	if (reg != QPCR_TEST_GET3)
> +		return -EINVAL;
> +	pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR4);
> +	reg = pci_quatech_rqopr(port) & 0xC0;
> +	if (reg != QPCR_TEST_GET4)
> +		return -EINVAL;
> +
> +	pci_quatech_wqopr(port, qopr);
> +	return 0;	
> +}
> +
> +static int pci_quatech_clock(struct uart_8250_port *port)
> +{
> +	u8 qopr, reg, set;
> +	unsigned long clock;
> +
> +	if (pci_quatech_test(port) < 0)
> +		return 1843200;
> +
> +	qopr = pci_quatech_rqopr(port);
> +
> +	pci_quatech_wqopr(port, qopr & ~QOPR_CLOCK_X8);
> +	reg = pci_quatech_rqopr(port);
> +	if (reg & QOPR_CLOCK_X8) {
> +		clock = 1843200;
> +		goto out;
> +	}
> +	pci_quatech_wqopr(port, qopr | QOPR_CLOCK_X8);
> +	reg = pci_quatech_rqopr(port);
> +	if (!(reg & QOPR_CLOCK_X8)) {
> +		clock = 1843200;
> +		goto out;
> +	}
> +	reg &= QOPR_CLOCK_X8;
> +	if (reg == QOPR_CLOCK_X2) {
> +		clock =  3685400;
> +		set = QOPR_CLOCK_X2;
> +	} else if (reg == QOPR_CLOCK_X4) {
> +		clock = 7372800;
> +		set = QOPR_CLOCK_X4;
> +	} else if (reg == QOPR_CLOCK_X8) {
> +		clock = 14745600;
> +		set = QOPR_CLOCK_X8;
> +	} else {
> +		clock = 1843200;
> +		set = QOPR_CLOCK_X1;
> +	}
> +	qopr &= ~QOPR_CLOCK_RATE_MASK;
> +	qopr |= set;
> +
> +out:
> +	pci_quatech_wqopr(port, qopr);
> +	return clock;
> +}
> +
> +static int pci_quatech_rs422(struct uart_8250_port *port)
> +{
> +	u8 qmcr;
> +	int rs422 = 0;
> +
> +	if (!pci_quatech_has_qmcr(port))
> +		return 0;
> +	qmcr = pci_quatech_rqmcr(port);
> +	pci_quatech_wqmcr(port, 0xFF);
> +	if (pci_quatech_rqmcr(port))
> +		rs422 = 1;
> +	pci_quatech_wqmcr(port, qmcr);
> +	return rs422;
> +}
> +
> +static int pci_quatech_init(struct pci_dev *dev)
> +{
> +	if (pci_quatech_amcc(dev->device)) {
> +		unsigned long base = pci_resource_start(dev, 0);
> +		if (base) {
> +			u32 tmp;
> +			outl(inl(base + 0x38), base + 0x38);
> +			tmp = inl(base + 0x3c);
> +			outl(tmp | 0x01000000, base + 0x3c);
> +			outl(tmp, base + 0x3c);
> +		}
> +	}
> +	return 0;
> +}
> +
> +static int pci_quatech_setup(struct serial_private *priv,
> +		  const struct pciserial_board *board,
> +		  struct uart_8250_port *port, int idx)
> +{
> +	/* Needed by pci_quatech calls below */
> +	port->port.iobase = pci_resource_start(priv->dev, FL_GET_BASE(board->flags));
> +	/* Set up the clocking */
> +	port->port.uartclk = pci_quatech_clock(port);
> +	/* For now just warn about RS422 */
> +	if (pci_quatech_rs422(port)) 
> +		pr_warn( "quatech: software control of RS422 features not currently supported.\n");
> +	return pci_default_setup(priv, board, port, idx);
> +}
> +
> +static void __devexit pci_quatech_exit(struct pci_dev *dev)
> +{
> +}
> +
>  static int pci_default_setup(struct serial_private *priv,
>  		  const struct pciserial_board *board,
>  		  struct uart_8250_port *port, int idx)
> @@ -1503,6 +1750,16 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
>  		.setup		= pci_default_setup,
>  		.exit		= __devexit_p(pci_plx9050_exit),
>  	},
> +	/* Quatech */
> +	{
> +		.vendor		= PCI_VENDOR_ID_QUATECH,
> +		.device		= PCI_ANY_ID,
> +		.subvendor	= PCI_ANY_ID,
> +		.subdevice	= PCI_ANY_ID,
> +		.init		= pci_quatech_init,
> +		.setup		= pci_quatech_setup,
> +		.exit		= __devexit_p(pci_quatech_exit),
> +	},
>  	/*
>  	 * SBS Technologies, Inc., PMC-OCTALPRO 232
>  	 */
> @@ -3257,18 +3514,70 @@ static struct pci_device_id serial_pci_tbl[] = {
>  	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS,
>  		0x10b5, 0x106a, 0, 0,
>  		pbn_plx_romulus },
> +	/*
> +	 * Quatech cards. These actually have configurable clocks but for
> +	 * now we just use the default.
> +	 *
> +	 * 100 series are RS232, 200 series RS422, 
> +	 */
>  	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC100,
>  		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
>  		pbn_b1_4_115200 },
>  	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100,
>  		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
>  		pbn_b1_2_115200 },
> +	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100E,
> +		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> +		pbn_b2_2_115200 },
> +	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC200,
> +		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> +		pbn_b1_2_115200 },
> +	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC200E,
> +		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> +		pbn_b2_2_115200 },
> +	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC200,
> +		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> +		pbn_b1_4_115200 },
>  	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100D,
>  		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
>  		pbn_b1_8_115200 },
>  	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M,
>  		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
>  		pbn_b1_8_115200 },
> +	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCP100,
> +		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> +		pbn_b1_4_115200 },
> +	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCP100,
> +		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> +		pbn_b1_2_115200 },
> +	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCP200,
> +		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> +		pbn_b1_4_115200 },
> +	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCP200,
> +		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> +		pbn_b1_2_115200 },
> +	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCLP100,
> +		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> +		pbn_b2_4_115200 },
> +	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCLP100,
> +		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> +		pbn_b2_2_115200 },
> +	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SSCLP100,
> +		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> +		pbn_b2_1_115200 },
> +	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCLP200,
> +		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> +		pbn_b2_4_115200 },
> +	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCLP200,
> +		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> +		pbn_b2_2_115200 },
> +	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SSCLP200,
> +		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> +		pbn_b2_1_115200 },
> +	{	PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESCLP100,
> +		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
> +		pbn_b0_8_115200 },
> +
>  	{	PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954,
>  		PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4,
>  		0, 0,
> diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
> index 9d36b82..ce45006 100644
> --- a/include/linux/pci_ids.h
> +++ b/include/linux/pci_ids.h
> @@ -1867,8 +1867,23 @@
>  #define PCI_VENDOR_ID_QUATECH		0x135C
>  #define PCI_DEVICE_ID_QUATECH_QSC100	0x0010
>  #define PCI_DEVICE_ID_QUATECH_DSC100	0x0020
> +#define PCI_DEVICE_ID_QUATECH_DSC200	0x0030
> +#define PCI_DEVICE_ID_QUATECH_QSC200	0x0040
>  #define PCI_DEVICE_ID_QUATECH_ESC100D	0x0050
>  #define PCI_DEVICE_ID_QUATECH_ESC100M	0x0060
> +#define PCI_DEVICE_ID_QUATECH_QSCP100	0x0120
> +#define PCI_DEVICE_ID_QUATECH_DSCP100	0x0130
> +#define PCI_DEVICE_ID_QUATECH_QSCP200	0x0140
> +#define PCI_DEVICE_ID_QUATECH_DSCP200	0x0150
> +#define PCI_DEVICE_ID_QUATECH_QSCLP100	0x0170
> +#define PCI_DEVICE_ID_QUATECH_DSCLP100	0x0180
> +#define PCI_DEVICE_ID_QUATECH_DSC100E	0x0181
> +#define PCI_DEVICE_ID_QUATECH_SSCLP100	0x0190
> +#define PCI_DEVICE_ID_QUATECH_QSCLP200	0x01A0
> +#define PCI_DEVICE_ID_QUATECH_DSCLP200	0x01B0
> +#define PCI_DEVICE_ID_QUATECH_DSC200E	0x01B1
> +#define PCI_DEVICE_ID_QUATECH_SSCLP200	0x01C0
> +#define PCI_DEVICE_ID_QUATECH_ESCLP100	0x01E0
>  #define PCI_DEVICE_ID_QUATECH_SPPXP_100 0x0278
>  
>  #define PCI_VENDOR_ID_SEALEVEL		0x135e
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux