Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 165008
b: refs/heads/master
c: 492896f
h: refs/heads/master
v: v3
  • Loading branch information
Tim Small authored and Greg Kroah-Hartman committed Sep 23, 2009
1 parent 5014946 commit b3728c4
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 823c3fd9cc71714fe22ea415a68da746800d5a9a
refs/heads/master: 492896f011a411d17d02e696adbc4a9b4ff68e7f
52 changes: 52 additions & 0 deletions trunk/drivers/usb/serial/ch341.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,18 @@
#define CH341_BAUDBASE_FACTOR 1532620800
#define CH341_BAUDBASE_DIVMAX 3

/* Break support - the information used to implement this was gleaned from
* the Net/FreeBSD uchcom.c driver by Takanori Watanabe. Domo arigato.
*/

#define CH341_REQ_WRITE_REG 0x9A
#define CH341_REQ_READ_REG 0x95
#define CH341_REG_BREAK1 0x05
#define CH341_REG_BREAK2 0x18
#define CH341_NBREAK_BITS_REG1 0x01
#define CH341_NBREAK_BITS_REG2 0x40


static int debug;

static struct usb_device_id id_table [] = {
Expand Down Expand Up @@ -373,6 +385,45 @@ static void ch341_set_termios(struct tty_struct *tty,
*/
}

static void ch341_break_ctl(struct tty_struct *tty, int break_state)
{
const uint16_t ch341_break_reg =
CH341_REG_BREAK1 | ((uint16_t) CH341_REG_BREAK2 << 8);
struct usb_serial_port *port = tty->driver_data;
int r;
uint16_t reg_contents;
uint8_t break_reg[2];

dbg("%s()", __func__);

r = ch341_control_in(port->serial->dev, CH341_REQ_READ_REG,
ch341_break_reg, 0, break_reg, sizeof(break_reg));
if (r < 0) {
printk(KERN_WARNING "%s: USB control read error whilst getting"
" break register contents.\n", __FILE__);
return;
}
dbg("%s - initial ch341 break register contents - reg1: %x, reg2: %x",
__func__, break_reg[0], break_reg[1]);
if (break_state != 0) {
dbg("%s - Enter break state requested", __func__);
break_reg[0] &= ~CH341_NBREAK_BITS_REG1;
break_reg[1] &= ~CH341_NBREAK_BITS_REG2;
} else {
dbg("%s - Leave break state requested", __func__);
break_reg[0] |= CH341_NBREAK_BITS_REG1;
break_reg[1] |= CH341_NBREAK_BITS_REG2;
}
dbg("%s - New ch341 break register contents - reg1: %x, reg2: %x",
__func__, break_reg[0], break_reg[1]);
reg_contents = (uint16_t)break_reg[0] | ((uint16_t)break_reg[1] << 8);
r = ch341_control_out(port->serial->dev, CH341_REQ_WRITE_REG,
ch341_break_reg, reg_contents);
if (r < 0)
printk(KERN_WARNING "%s: USB control write error whilst setting"
" break register contents.\n", __FILE__);
}

static int ch341_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
Expand Down Expand Up @@ -576,6 +627,7 @@ static struct usb_serial_driver ch341_device = {
.close = ch341_close,
.ioctl = ch341_ioctl,
.set_termios = ch341_set_termios,
.break_ctl = ch341_break_ctl,
.tiocmget = ch341_tiocmget,
.tiocmset = ch341_tiocmset,
.read_int_callback = ch341_read_int_callback,
Expand Down

0 comments on commit b3728c4

Please sign in to comment.