Beispiel #1
0
static int rs_set_real_termios (void *ptr)
{
	struct rs_port *port = ptr;
	int t;

	switch (port->gs.baud) {
		/* Save some typing work... */
#define e(x) case x:t= TX3912_UART_CTRL2_B ## x ; break
		e(300);e(600);e(1200);e(2400);e(4800);e(9600);
		e(19200);e(38400);e(57600);e(76800);e(115200);e(230400);
	case 0      :t = -1;
		break;
	default:
		/* Can I return "invalid"? */
		t = TX3912_UART_CTRL2_B9600;
		printk (KERN_INFO "rs: unsupported baud rate: %d.\n", port->gs.baud);
		break;
	}
#undef e
	if (t >= 0) {
		/* Jim: Set Hardware Baud rate - there is some good
		   code in drivers/char/serial.c */

	  	/* Program hardware for parity, data bits, stop bits (note: these are hardcoded to 8N1 */
		UartA_Ctrl1 &= 0xf000000f;
		UartA_Ctrl1 &= ~(UART_DIS_TXD | SER_SEVEN_BIT | SER_EVEN_PARITY | SER_TWO_STOP);

#define CFLAG port->gs.tty->termios->c_cflag
		if (C_PARENB(port->gs.tty)) {
			if (!C_PARODD(port->gs.tty))
				UartA_Ctrl1 |= SER_EVEN_PARITY;
			else
				UartA_Ctrl1 |= SER_ODD_PARITY;
		}
		if ((CFLAG & CSIZE)==CS6)
			printk(KERN_ERR "6 bits not supported\n");
		if ((CFLAG & CSIZE)==CS5)
			printk(KERN_ERR "5 bits not supported\n");
		if ((CFLAG & CSIZE)==CS7)
			UartA_Ctrl1 |= SER_SEVEN_BIT;
		if (C_CSTOPB(port->gs.tty))
			UartA_Ctrl1 |= SER_TWO_STOP;

		outl(t, port->base + TX3912_UART_CTRL2);
		outl(0, port->base + TX3912_UART_DMA_CTRL1);
		outl(0, port->base + TX3912_UART_DMA_CTRL2);
        	UartA_Ctrl1 |= TX3912_UART_CTRL1_UARTON;

        /* wait until UARTA is stable */
        while (~UartA_Ctrl1 & TX3912_UART_CTRL1_UARTON);
	}

	func_exit ();
        return 0;
}
static int rs_set_real_termios (void *ptr)
{
    unsigned int ctrl1 = 0;
    unsigned int ctrl2 = 0;

    /* Set baud rate */
    switch (rs_port->gs.baud) {
    case 0:
        goto done;
    case 1200:
        ctrl2 = TX3912_UART_CTRL2_B1200;
        break;
    case 2400:
        ctrl2 = TX3912_UART_CTRL2_B2400;
        break;
    case 4800:
        ctrl2 = TX3912_UART_CTRL2_B4800;
        break;
    case 9600:
        ctrl2 = TX3912_UART_CTRL2_B9600;
        break;
    case 19200:
        ctrl2 = TX3912_UART_CTRL2_B19200;
        break;
    case 38400:
        ctrl2 = TX3912_UART_CTRL2_B38400;
        break;
    case 57600:
        ctrl2 = TX3912_UART_CTRL2_B57600;
        break;
    case 115200:
    default:
        ctrl2 = TX3912_UART_CTRL2_B115200;
        break;
    }

    /* Clear current UARTA settings */
    ctrl1 = inl(TX3912_UARTA_CTRL1) & 0xf000000f;

    /* Set parity */
    if(C_PARENB(rs_port->gs.tty)) {
        if (!C_PARODD(rs_port->gs.tty))
            ctrl1 |= (TX3912_UART_CTRL1_ENPARITY |
                      TX3912_UART_CTRL1_EVENPARITY);
        else
            ctrl1 |= TX3912_UART_CTRL1_ENPARITY;
    }

    /* Set data size */
    switch(rs_port->gs.tty->termios->c_cflag & CSIZE) {
    case CS7:
        ctrl1 |= TX3912_UART_CTRL1_BIT_7;
        break;
    case CS5:
    case CS6:
        printk(KERN_ERR "Data byte size unsupported. Defaulting to CS8\n");
    case CS8:
    default:
        ctrl1 &= ~TX3912_UART_CTRL1_BIT_7;
    }

    /* Set stop bits */
    if(C_CSTOPB(rs_port->gs.tty))
        ctrl1 |= TX3912_UART_CTRL1_TWOSTOP;

    /* Write the control registers */
    outl(ctrl2, TX3912_UARTA_CTRL2);
    outl(0, TX3912_UARTA_DMA_CTRL1);
    outl(0, TX3912_UARTA_DMA_CTRL2);
    outl(ctrl1, TX3912_UARTA_CTRL1);

    /* Loop until the UART is on */
    while(~inl(TX3912_UARTA_CTRL1) & TX3912_UART_CTRL1_UARTON);

done:
    func_exit();
    return 0;
}
Beispiel #3
0
static void mxu1_set_termios(struct tty_struct *tty,
			     struct usb_serial_port *port,
			     struct ktermios *old_termios)
{
	struct mxu1_port *mxport = usb_get_serial_port_data(port);
	struct mxu1_uart_config *config;
	tcflag_t cflag, iflag;
	speed_t baud;
	int status;
	unsigned int mcr;

	dev_dbg(&port->dev, "%s\n", __func__);

	cflag = tty->termios.c_cflag;
	iflag = tty->termios.c_iflag;

	if (old_termios &&
	    !tty_termios_hw_change(&tty->termios, old_termios) &&
	    tty->termios.c_iflag == old_termios->c_iflag) {
		dev_dbg(&port->dev, "%s - nothing to change\n", __func__);
		return;
	}

	dev_dbg(&port->dev,
		"%s - clfag %08x, iflag %08x\n", __func__, cflag, iflag);

	if (old_termios) {
		dev_dbg(&port->dev, "%s - old clfag %08x, old iflag %08x\n",
			__func__,
			old_termios->c_cflag,
			old_termios->c_iflag);
	}

	config = kzalloc(sizeof(*config), GFP_KERNEL);
	if (!config)
		return;

	config->wFlags = 0;

	/* these flags must be set */
	config->wFlags |= MXU1_UART_ENABLE_MS_INTS;
	config->wFlags |= MXU1_UART_ENABLE_AUTO_START_DMA;
	if (mxport->mxp_send_break == MXU1_LCR_BREAK)
		config->wFlags |= MXU1_UART_SEND_BREAK_SIGNAL;
	config->bUartMode = (u8)(mxport->mxp_uart_mode);

	switch (C_CSIZE(tty)) {
	case CS5:
		config->bDataBits = MXU1_UART_5_DATA_BITS;
		break;
	case CS6:
		config->bDataBits = MXU1_UART_6_DATA_BITS;
		break;
	case CS7:
		config->bDataBits = MXU1_UART_7_DATA_BITS;
		break;
	default:
	case CS8:
		config->bDataBits = MXU1_UART_8_DATA_BITS;
		break;
	}

	if (C_PARENB(tty)) {
		config->wFlags |= MXU1_UART_ENABLE_PARITY_CHECKING;
		if (C_CMSPAR(tty)) {
			if (C_PARODD(tty))
				config->bParity = MXU1_UART_MARK_PARITY;
			else
				config->bParity = MXU1_UART_SPACE_PARITY;
		} else {
			if (C_PARODD(tty))
				config->bParity = MXU1_UART_ODD_PARITY;
			else
				config->bParity = MXU1_UART_EVEN_PARITY;
		}
	} else {
		config->bParity = MXU1_UART_NO_PARITY;
	}

	if (C_CSTOPB(tty))
		config->bStopBits = MXU1_UART_2_STOP_BITS;
	else
		config->bStopBits = MXU1_UART_1_STOP_BITS;

	if (C_CRTSCTS(tty)) {
		/* RTS flow control must be off to drop RTS for baud rate B0 */
		if (C_BAUD(tty) != B0)
			config->wFlags |= MXU1_UART_ENABLE_RTS_IN;
		config->wFlags |= MXU1_UART_ENABLE_CTS_OUT;
	}

	if (I_IXOFF(tty) || I_IXON(tty)) {
		config->cXon  = START_CHAR(tty);
		config->cXoff = STOP_CHAR(tty);

		if (I_IXOFF(tty))
			config->wFlags |= MXU1_UART_ENABLE_X_IN;

		if (I_IXON(tty))
			config->wFlags |= MXU1_UART_ENABLE_X_OUT;
	}

	baud = tty_get_baud_rate(tty);
	if (!baud)
		baud = 9600;
	config->wBaudRate = MXU1_BAUD_BASE / baud;

	dev_dbg(&port->dev, "%s - BaudRate=%d, wBaudRate=%d, wFlags=0x%04X, bDataBits=%d, bParity=%d, bStopBits=%d, cXon=%d, cXoff=%d, bUartMode=%d\n",
		__func__, baud, config->wBaudRate, config->wFlags,
		config->bDataBits, config->bParity, config->bStopBits,
		config->cXon, config->cXoff, config->bUartMode);

	cpu_to_be16s(&config->wBaudRate);
	cpu_to_be16s(&config->wFlags);

	status = mxu1_send_ctrl_data_urb(port->serial, MXU1_SET_CONFIG, 0,
					 MXU1_UART1_PORT, (u8 *)config,
					 sizeof(*config));
	if (status)
		dev_err(&port->dev, "cannot set config: %d\n", status);

	mutex_lock(&mxport->mxp_mutex);
	mcr = mxport->mxp_mcr;

	if (C_BAUD(tty) == B0)
		mcr &= ~(MXU1_MCR_DTR | MXU1_MCR_RTS);
	else if (old_termios && (old_termios->c_cflag & CBAUD) == B0)
		mcr |= ~(MXU1_MCR_DTR | MXU1_MCR_RTS);

	status = mxu1_set_mcr(port, mcr);
	if (status)
		dev_err(&port->dev, "cannot set modem control: %d\n", status);
	else
		mxport->mxp_mcr = mcr;

	mutex_unlock(&mxport->mxp_mutex);

	kfree(config);
}
static void pl2303_set_termios(struct tty_struct *tty,
		struct usb_serial_port *port, struct ktermios *old_termios)
{
	struct usb_serial *serial = port->serial;
	struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
	struct pl2303_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;
	unsigned char *buf;
	int i;
	u8 control;

	if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios))
		return;

	buf = kzalloc(7, GFP_KERNEL);
	if (!buf) {
		dev_err(&port->dev, "%s - out of memory.\n", __func__);
		/* Report back no change occurred */
		if (old_termios)
			tty->termios = *old_termios;
		return;
	}

	i = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
			    GET_LINE_REQUEST, GET_LINE_REQUEST_TYPE,
			    0, 0, buf, 7, 100);
	dev_dbg(&port->dev, "0xa1:0x21:0:0  %d - %7ph\n", i, buf);

	switch (C_CSIZE(tty)) {
	case CS5:
		buf[6] = 5;
		break;
	case CS6:
		buf[6] = 6;
		break;
	case CS7:
		buf[6] = 7;
		break;
	default:
	case CS8:
		buf[6] = 8;
	}
	dev_dbg(&port->dev, "data bits = %d\n", buf[6]);

	/* For reference buf[0]:buf[3] baud rate value */
	pl2303_encode_baudrate(tty, port, &buf[0]);

	/* For reference buf[4]=0 is 1 stop bits */
	/* For reference buf[4]=1 is 1.5 stop bits */
	/* For reference buf[4]=2 is 2 stop bits */
	if (C_CSTOPB(tty)) {
		/*
		 * NOTE: Comply with "real" UARTs / RS232:
		 *       use 1.5 instead of 2 stop bits with 5 data bits
		 */
		if (C_CSIZE(tty) == CS5) {
			buf[4] = 1;
			dev_dbg(&port->dev, "stop bits = 1.5\n");
		} else {
			buf[4] = 2;
			dev_dbg(&port->dev, "stop bits = 2\n");
		}
	} else {
		buf[4] = 0;
		dev_dbg(&port->dev, "stop bits = 1\n");
	}

	if (C_PARENB(tty)) {
		/* For reference buf[5]=0 is none parity */
		/* For reference buf[5]=1 is odd parity */
		/* For reference buf[5]=2 is even parity */
		/* For reference buf[5]=3 is mark parity */
		/* For reference buf[5]=4 is space parity */
		if (C_PARODD(tty)) {
			if (tty->termios.c_cflag & CMSPAR) {
				buf[5] = 3;
				dev_dbg(&port->dev, "parity = mark\n");
			} else {
				buf[5] = 1;
				dev_dbg(&port->dev, "parity = odd\n");
			}
		} else {
			if (tty->termios.c_cflag & CMSPAR) {
				buf[5] = 4;
				dev_dbg(&port->dev, "parity = space\n");
			} else {
				buf[5] = 2;
				dev_dbg(&port->dev, "parity = even\n");
			}
		}
	} else {
		buf[5] = 0;
		dev_dbg(&port->dev, "parity = none\n");
	}

	/*
	 * Some PL2303 are known to lose bytes if you change serial settings
	 * even to the same values as before. Thus we actually need to filter
	 * in this specific case.
	 *
	 * Note that the tty_termios_hw_change check above is not sufficient
	 * as a previously requested baud rate may differ from the one
	 * actually used (and stored in old_termios).
	 *
	 * NOTE: No additional locking needed for line_settings as it is
	 *       only used in set_termios, which is serialised against itself.
	 */
	if (!old_termios || memcmp(buf, priv->line_settings, 7)) {
		i = usb_control_msg(serial->dev,
				    usb_sndctrlpipe(serial->dev, 0),
				    SET_LINE_REQUEST, SET_LINE_REQUEST_TYPE,
				    0, 0, buf, 7, 100);

		dev_dbg(&port->dev, "0x21:0x20:0:0  %d\n", i);

		if (i == 7)
			memcpy(priv->line_settings, buf, 7);
	}

	/* change control lines if we are switching to or from B0 */
	spin_lock_irqsave(&priv->lock, flags);
	control = priv->line_control;
	if (C_BAUD(tty) == B0)
		priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
	else if (old_termios && (old_termios->c_cflag & CBAUD) == B0)
		priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
	if (control != priv->line_control) {
		control = priv->line_control;
		spin_unlock_irqrestore(&priv->lock, flags);
		pl2303_set_control_lines(port, control);
	} else {
		spin_unlock_irqrestore(&priv->lock, flags);
	}

	memset(buf, 0, 7);
	i = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
			    GET_LINE_REQUEST, GET_LINE_REQUEST_TYPE,
			    0, 0, buf, 7, 100);
	dev_dbg(&port->dev, "0xa1:0x21:0:0  %d - %7ph\n", i, buf);

	if (C_CRTSCTS(tty)) {
		if (spriv->type == HX)
			pl2303_vendor_write(0x0, 0x61, serial);
		else
			pl2303_vendor_write(0x0, 0x41, serial);
	} else {
		pl2303_vendor_write(0x0, 0x0, serial);
	}

	kfree(buf);
}