1/* 2 * USB Cypress M8 driver 3 * 4 * Copyright (C) 2004 5 * Lonnie Mendez (dignome@gmail.com) 6 * Copyright (C) 2003,2004 7 * Neil Whelchel (koyama@firstlight.net) 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * See Documentation/usb/usb-serial.txt for more information on using this 15 * driver 16 * 17 * See http://geocities.com/i0xox0i for information on this driver and the 18 * earthmate usb device. 19 */ 20 21/* Thanks to Neil Whelchel for writing the first cypress m8 implementation 22 for linux. */ 23/* Thanks to cypress for providing references for the hid reports. */ 24/* Thanks to Jiang Zhang for providing links and for general help. */ 25/* Code originates and was built up from ftdi_sio, belkin, pl2303 and others.*/ 26 27 28#include <linux/kernel.h> 29#include <linux/errno.h> 30#include <linux/slab.h> 31#include <linux/tty.h> 32#include <linux/tty_driver.h> 33#include <linux/tty_flip.h> 34#include <linux/module.h> 35#include <linux/moduleparam.h> 36#include <linux/spinlock.h> 37#include <linux/usb.h> 38#include <linux/usb/serial.h> 39#include <linux/serial.h> 40#include <linux/kfifo.h> 41#include <linux/delay.h> 42#include <linux/uaccess.h> 43#include <asm/unaligned.h> 44 45#include "cypress_m8.h" 46 47 48static bool stats; 49static int interval; 50static bool unstable_bauds; 51 52#define DRIVER_AUTHOR "Lonnie Mendez <dignome@gmail.com>, Neil Whelchel <koyama@firstlight.net>" 53#define DRIVER_DESC "Cypress USB to Serial Driver" 54 55/* write buffer size defines */ 56#define CYPRESS_BUF_SIZE 1024 57 58static const struct usb_device_id id_table_earthmate[] = { 59 { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, 60 { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) }, 61 { } /* Terminating entry */ 62}; 63 64static const struct usb_device_id id_table_cyphidcomrs232[] = { 65 { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, 66 { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) }, 67 { USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) }, 68 { } /* Terminating entry */ 69}; 70 71static const struct usb_device_id id_table_nokiaca42v2[] = { 72 { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) }, 73 { } /* Terminating entry */ 74}; 75 76static const struct usb_device_id id_table_combined[] = { 77 { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, 78 { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) }, 79 { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, 80 { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) }, 81 { USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) }, 82 { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) }, 83 { } /* Terminating entry */ 84}; 85 86MODULE_DEVICE_TABLE(usb, id_table_combined); 87 88enum packet_format { 89 packet_format_1, /* b0:status, b1:payload count */ 90 packet_format_2 /* b0[7:3]:status, b0[2:0]:payload count */ 91}; 92 93struct cypress_private { 94 spinlock_t lock; /* private lock */ 95 int chiptype; /* identifier of device, for quirks/etc */ 96 int bytes_in; /* used for statistics */ 97 int bytes_out; /* used for statistics */ 98 int cmd_count; /* used for statistics */ 99 int cmd_ctrl; /* always set this to 1 before issuing a command */ 100 struct kfifo write_fifo; /* write fifo */ 101 int write_urb_in_use; /* write urb in use indicator */ 102 int write_urb_interval; /* interval to use for write urb */ 103 int read_urb_interval; /* interval to use for read urb */ 104 int comm_is_ok; /* true if communication is (still) ok */ 105 int termios_initialized; 106 __u8 line_control; /* holds dtr / rts value */ 107 __u8 current_status; /* received from last read - info on dsr,cts,cd,ri,etc */ 108 __u8 current_config; /* stores the current configuration byte */ 109 __u8 rx_flags; /* throttling - used from whiteheat/ftdi_sio */ 110 enum packet_format pkt_fmt; /* format to use for packet send / receive */ 111 int get_cfg_unsafe; /* If true, the CYPRESS_GET_CONFIG is unsafe */ 112 int baud_rate; /* stores current baud rate in 113 integer form */ 114 int isthrottled; /* if throttled, discard reads */ 115 char prev_status; /* used for TIOCMIWAIT */ 116 /* we pass a pointer to this as the argument sent to 117 cypress_set_termios old_termios */ 118 struct ktermios tmp_termios; /* stores the old termios settings */ 119}; 120 121/* function prototypes for the Cypress USB to serial device */ 122static int cypress_earthmate_port_probe(struct usb_serial_port *port); 123static int cypress_hidcom_port_probe(struct usb_serial_port *port); 124static int cypress_ca42v2_port_probe(struct usb_serial_port *port); 125static int cypress_port_remove(struct usb_serial_port *port); 126static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port); 127static void cypress_close(struct usb_serial_port *port); 128static void cypress_dtr_rts(struct usb_serial_port *port, int on); 129static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port, 130 const unsigned char *buf, int count); 131static void cypress_send(struct usb_serial_port *port); 132static int cypress_write_room(struct tty_struct *tty); 133static void cypress_set_termios(struct tty_struct *tty, 134 struct usb_serial_port *port, struct ktermios *old); 135static int cypress_tiocmget(struct tty_struct *tty); 136static int cypress_tiocmset(struct tty_struct *tty, 137 unsigned int set, unsigned int clear); 138static int cypress_chars_in_buffer(struct tty_struct *tty); 139static void cypress_throttle(struct tty_struct *tty); 140static void cypress_unthrottle(struct tty_struct *tty); 141static void cypress_set_dead(struct usb_serial_port *port); 142static void cypress_read_int_callback(struct urb *urb); 143static void cypress_write_int_callback(struct urb *urb); 144 145static struct usb_serial_driver cypress_earthmate_device = { 146 .driver = { 147 .owner = THIS_MODULE, 148 .name = "earthmate", 149 }, 150 .description = "DeLorme Earthmate USB", 151 .id_table = id_table_earthmate, 152 .num_ports = 1, 153 .port_probe = cypress_earthmate_port_probe, 154 .port_remove = cypress_port_remove, 155 .open = cypress_open, 156 .close = cypress_close, 157 .dtr_rts = cypress_dtr_rts, 158 .write = cypress_write, 159 .write_room = cypress_write_room, 160 .set_termios = cypress_set_termios, 161 .tiocmget = cypress_tiocmget, 162 .tiocmset = cypress_tiocmset, 163 .tiocmiwait = usb_serial_generic_tiocmiwait, 164 .chars_in_buffer = cypress_chars_in_buffer, 165 .throttle = cypress_throttle, 166 .unthrottle = cypress_unthrottle, 167 .read_int_callback = cypress_read_int_callback, 168 .write_int_callback = cypress_write_int_callback, 169}; 170 171static struct usb_serial_driver cypress_hidcom_device = { 172 .driver = { 173 .owner = THIS_MODULE, 174 .name = "cyphidcom", 175 }, 176 .description = "HID->COM RS232 Adapter", 177 .id_table = id_table_cyphidcomrs232, 178 .num_ports = 1, 179 .port_probe = cypress_hidcom_port_probe, 180 .port_remove = cypress_port_remove, 181 .open = cypress_open, 182 .close = cypress_close, 183 .dtr_rts = cypress_dtr_rts, 184 .write = cypress_write, 185 .write_room = cypress_write_room, 186 .set_termios = cypress_set_termios, 187 .tiocmget = cypress_tiocmget, 188 .tiocmset = cypress_tiocmset, 189 .tiocmiwait = usb_serial_generic_tiocmiwait, 190 .chars_in_buffer = cypress_chars_in_buffer, 191 .throttle = cypress_throttle, 192 .unthrottle = cypress_unthrottle, 193 .read_int_callback = cypress_read_int_callback, 194 .write_int_callback = cypress_write_int_callback, 195}; 196 197static struct usb_serial_driver cypress_ca42v2_device = { 198 .driver = { 199 .owner = THIS_MODULE, 200 .name = "nokiaca42v2", 201 }, 202 .description = "Nokia CA-42 V2 Adapter", 203 .id_table = id_table_nokiaca42v2, 204 .num_ports = 1, 205 .port_probe = cypress_ca42v2_port_probe, 206 .port_remove = cypress_port_remove, 207 .open = cypress_open, 208 .close = cypress_close, 209 .dtr_rts = cypress_dtr_rts, 210 .write = cypress_write, 211 .write_room = cypress_write_room, 212 .set_termios = cypress_set_termios, 213 .tiocmget = cypress_tiocmget, 214 .tiocmset = cypress_tiocmset, 215 .tiocmiwait = usb_serial_generic_tiocmiwait, 216 .chars_in_buffer = cypress_chars_in_buffer, 217 .throttle = cypress_throttle, 218 .unthrottle = cypress_unthrottle, 219 .read_int_callback = cypress_read_int_callback, 220 .write_int_callback = cypress_write_int_callback, 221}; 222 223static struct usb_serial_driver * const serial_drivers[] = { 224 &cypress_earthmate_device, &cypress_hidcom_device, 225 &cypress_ca42v2_device, NULL 226}; 227 228/***************************************************************************** 229 * Cypress serial helper functions 230 *****************************************************************************/ 231 232/* FRWD Dongle hidcom needs to skip reset and speed checks */ 233static inline bool is_frwd(struct usb_device *dev) 234{ 235 return ((le16_to_cpu(dev->descriptor.idVendor) == VENDOR_ID_FRWD) && 236 (le16_to_cpu(dev->descriptor.idProduct) == PRODUCT_ID_CYPHIDCOM_FRWD)); 237} 238 239static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate) 240{ 241 struct cypress_private *priv; 242 priv = usb_get_serial_port_data(port); 243 244 if (unstable_bauds) 245 return new_rate; 246 247 /* FRWD Dongle uses 115200 bps */ 248 if (is_frwd(port->serial->dev)) 249 return new_rate; 250 251 /* 252 * The general purpose firmware for the Cypress M8 allows for 253 * a maximum speed of 57600bps (I have no idea whether DeLorme 254 * chose to use the general purpose firmware or not), if you 255 * need to modify this speed setting for your own project 256 * please add your own chiptype and modify the code likewise. 257 * The Cypress HID->COM device will work successfully up to 258 * 115200bps (but the actual throughput is around 3kBps). 259 */ 260 if (port->serial->dev->speed == USB_SPEED_LOW) { 261 /* 262 * Mike Isely <isely@pobox.com> 2-Feb-2008: The 263 * Cypress app note that describes this mechanism 264 * states the the low-speed part can't handle more 265 * than 800 bytes/sec, in which case 4800 baud is the 266 * safest speed for a part like that. 267 */ 268 if (new_rate > 4800) { 269 dev_dbg(&port->dev, 270 "%s - failed setting baud rate, device incapable speed %d\n", 271 __func__, new_rate); 272 return -1; 273 } 274 } 275 switch (priv->chiptype) { 276 case CT_EARTHMATE: 277 if (new_rate <= 600) { 278 /* 300 and 600 baud rates are supported under 279 * the generic firmware, but are not used with 280 * NMEA and SiRF protocols */ 281 dev_dbg(&port->dev, 282 "%s - failed setting baud rate, unsupported speed of %d on Earthmate GPS\n", 283 __func__, new_rate); 284 return -1; 285 } 286 break; 287 default: 288 break; 289 } 290 return new_rate; 291} 292 293 294/* This function can either set or retrieve the current serial line settings */ 295static int cypress_serial_control(struct tty_struct *tty, 296 struct usb_serial_port *port, speed_t baud_rate, int data_bits, 297 int stop_bits, int parity_enable, int parity_type, int reset, 298 int cypress_request_type) 299{ 300 int new_baudrate = 0, retval = 0, tries = 0; 301 struct cypress_private *priv; 302 struct device *dev = &port->dev; 303 u8 *feature_buffer; 304 const unsigned int feature_len = 5; 305 unsigned long flags; 306 307 priv = usb_get_serial_port_data(port); 308 309 if (!priv->comm_is_ok) 310 return -ENODEV; 311 312 feature_buffer = kcalloc(feature_len, sizeof(u8), GFP_KERNEL); 313 if (!feature_buffer) 314 return -ENOMEM; 315 316 switch (cypress_request_type) { 317 case CYPRESS_SET_CONFIG: 318 /* 0 means 'Hang up' so doesn't change the true bit rate */ 319 new_baudrate = priv->baud_rate; 320 if (baud_rate && baud_rate != priv->baud_rate) { 321 dev_dbg(dev, "%s - baud rate is changing\n", __func__); 322 retval = analyze_baud_rate(port, baud_rate); 323 if (retval >= 0) { 324 new_baudrate = retval; 325 dev_dbg(dev, "%s - New baud rate set to %d\n", 326 __func__, new_baudrate); 327 } 328 } 329 dev_dbg(dev, "%s - baud rate is being sent as %d\n", __func__, 330 new_baudrate); 331 332 /* fill the feature_buffer with new configuration */ 333 put_unaligned_le32(new_baudrate, feature_buffer); 334 feature_buffer[4] |= data_bits; /* assign data bits in 2 bit space ( max 3 ) */ 335 /* 1 bit gap */ 336 feature_buffer[4] |= (stop_bits << 3); /* assign stop bits in 1 bit space */ 337 feature_buffer[4] |= (parity_enable << 4); /* assign parity flag in 1 bit space */ 338 feature_buffer[4] |= (parity_type << 5); /* assign parity type in 1 bit space */ 339 /* 1 bit gap */ 340 feature_buffer[4] |= (reset << 7); /* assign reset at end of byte, 1 bit space */ 341 342 dev_dbg(dev, "%s - device is being sent this feature report:\n", __func__); 343 dev_dbg(dev, "%s - %02X - %02X - %02X - %02X - %02X\n", __func__, 344 feature_buffer[0], feature_buffer[1], 345 feature_buffer[2], feature_buffer[3], 346 feature_buffer[4]); 347 348 do { 349 retval = usb_control_msg(port->serial->dev, 350 usb_sndctrlpipe(port->serial->dev, 0), 351 HID_REQ_SET_REPORT, 352 USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS, 353 0x0300, 0, feature_buffer, 354 feature_len, 500); 355 356 if (tries++ >= 3) 357 break; 358 359 } while (retval != feature_len && 360 retval != -ENODEV); 361 362 if (retval != feature_len) { 363 dev_err(dev, "%s - failed sending serial line settings - %d\n", 364 __func__, retval); 365 cypress_set_dead(port); 366 } else { 367 spin_lock_irqsave(&priv->lock, flags); 368 priv->baud_rate = new_baudrate; 369 priv->current_config = feature_buffer[4]; 370 spin_unlock_irqrestore(&priv->lock, flags); 371 /* If we asked for a speed change encode it */ 372 if (baud_rate) 373 tty_encode_baud_rate(tty, 374 new_baudrate, new_baudrate); 375 } 376 break; 377 case CYPRESS_GET_CONFIG: 378 if (priv->get_cfg_unsafe) { 379 /* Not implemented for this device, 380 and if we try to do it we're likely 381 to crash the hardware. */ 382 retval = -ENOTTY; 383 goto out; 384 } 385 dev_dbg(dev, "%s - retreiving serial line settings\n", __func__); 386 do { 387 retval = usb_control_msg(port->serial->dev, 388 usb_rcvctrlpipe(port->serial->dev, 0), 389 HID_REQ_GET_REPORT, 390 USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS, 391 0x0300, 0, feature_buffer, 392 feature_len, 500); 393 394 if (tries++ >= 3) 395 break; 396 } while (retval != feature_len 397 && retval != -ENODEV); 398 399 if (retval != feature_len) { 400 dev_err(dev, "%s - failed to retrieve serial line settings - %d\n", 401 __func__, retval); 402 cypress_set_dead(port); 403 goto out; 404 } else { 405 spin_lock_irqsave(&priv->lock, flags); 406 /* store the config in one byte, and later 407 use bit masks to check values */ 408 priv->current_config = feature_buffer[4]; 409 priv->baud_rate = get_unaligned_le32(feature_buffer); 410 spin_unlock_irqrestore(&priv->lock, flags); 411 } 412 } 413 spin_lock_irqsave(&priv->lock, flags); 414 ++priv->cmd_count; 415 spin_unlock_irqrestore(&priv->lock, flags); 416out: 417 kfree(feature_buffer); 418 return retval; 419} /* cypress_serial_control */ 420 421 422static void cypress_set_dead(struct usb_serial_port *port) 423{ 424 struct cypress_private *priv = usb_get_serial_port_data(port); 425 unsigned long flags; 426 427 spin_lock_irqsave(&priv->lock, flags); 428 if (!priv->comm_is_ok) { 429 spin_unlock_irqrestore(&priv->lock, flags); 430 return; 431 } 432 priv->comm_is_ok = 0; 433 spin_unlock_irqrestore(&priv->lock, flags); 434 435 dev_err(&port->dev, "cypress_m8 suspending failing port %d - " 436 "interval might be too short\n", port->port_number); 437} 438 439 440/***************************************************************************** 441 * Cypress serial driver functions 442 *****************************************************************************/ 443 444 445static int cypress_generic_port_probe(struct usb_serial_port *port) 446{ 447 struct usb_serial *serial = port->serial; 448 struct cypress_private *priv; 449 450 if (!port->interrupt_out_urb || !port->interrupt_in_urb) { 451 dev_err(&port->dev, "required endpoint is missing\n"); 452 return -ENODEV; 453 } 454 455 priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL); 456 if (!priv) 457 return -ENOMEM; 458 459 priv->comm_is_ok = !0; 460 spin_lock_init(&priv->lock); 461 if (kfifo_alloc(&priv->write_fifo, CYPRESS_BUF_SIZE, GFP_KERNEL)) { 462 kfree(priv); 463 return -ENOMEM; 464 } 465 466 /* Skip reset for FRWD device. It is a workaound: 467 device hangs if it receives SET_CONFIGURE in Configured 468 state. */ 469 if (!is_frwd(serial->dev)) 470 usb_reset_configuration(serial->dev); 471 472 priv->cmd_ctrl = 0; 473 priv->line_control = 0; 474 priv->termios_initialized = 0; 475 priv->rx_flags = 0; 476 /* Default packet format setting is determined by packet size. 477 Anything with a size larger then 9 must have a separate 478 count field since the 3 bit count field is otherwise too 479 small. Otherwise we can use the slightly more compact 480 format. This is in accordance with the cypress_m8 serial 481 converter app note. */ 482 if (port->interrupt_out_size > 9) 483 priv->pkt_fmt = packet_format_1; 484 else 485 priv->pkt_fmt = packet_format_2; 486 487 if (interval > 0) { 488 priv->write_urb_interval = interval; 489 priv->read_urb_interval = interval; 490 dev_dbg(&port->dev, "%s - read & write intervals forced to %d\n", 491 __func__, interval); 492 } else { 493 priv->write_urb_interval = port->interrupt_out_urb->interval; 494 priv->read_urb_interval = port->interrupt_in_urb->interval; 495 dev_dbg(&port->dev, "%s - intervals: read=%d write=%d\n", 496 __func__, priv->read_urb_interval, 497 priv->write_urb_interval); 498 } 499 usb_set_serial_port_data(port, priv); 500 501 port->port.drain_delay = 256; 502 503 return 0; 504} 505 506 507static int cypress_earthmate_port_probe(struct usb_serial_port *port) 508{ 509 struct usb_serial *serial = port->serial; 510 struct cypress_private *priv; 511 int ret; 512 513 ret = cypress_generic_port_probe(port); 514 if (ret) { 515 dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__); 516 return ret; 517 } 518 519 priv = usb_get_serial_port_data(port); 520 priv->chiptype = CT_EARTHMATE; 521 /* All Earthmate devices use the separated-count packet 522 format! Idiotic. */ 523 priv->pkt_fmt = packet_format_1; 524 if (serial->dev->descriptor.idProduct != 525 cpu_to_le16(PRODUCT_ID_EARTHMATEUSB)) { 526 /* The old original USB Earthmate seemed able to 527 handle GET_CONFIG requests; everything they've 528 produced since that time crashes if this command is 529 attempted :-( */ 530 dev_dbg(&port->dev, 531 "%s - Marking this device as unsafe for GET_CONFIG commands\n", 532 __func__); 533 priv->get_cfg_unsafe = !0; 534 } 535 536 return 0; 537} 538 539static int cypress_hidcom_port_probe(struct usb_serial_port *port) 540{ 541 struct cypress_private *priv; 542 int ret; 543 544 ret = cypress_generic_port_probe(port); 545 if (ret) { 546 dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__); 547 return ret; 548 } 549 550 priv = usb_get_serial_port_data(port); 551 priv->chiptype = CT_CYPHIDCOM; 552 553 return 0; 554} 555 556static int cypress_ca42v2_port_probe(struct usb_serial_port *port) 557{ 558 struct cypress_private *priv; 559 int ret; 560 561 ret = cypress_generic_port_probe(port); 562 if (ret) { 563 dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__); 564 return ret; 565 } 566 567 priv = usb_get_serial_port_data(port); 568 priv->chiptype = CT_CA42V2; 569 570 return 0; 571} 572 573static int cypress_port_remove(struct usb_serial_port *port) 574{ 575 struct cypress_private *priv; 576 577 priv = usb_get_serial_port_data(port); 578 579 kfifo_free(&priv->write_fifo); 580 kfree(priv); 581 582 return 0; 583} 584 585static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port) 586{ 587 struct cypress_private *priv = usb_get_serial_port_data(port); 588 struct usb_serial *serial = port->serial; 589 unsigned long flags; 590 int result = 0; 591 592 if (!priv->comm_is_ok) 593 return -EIO; 594 595 /* clear halts before open */ 596 usb_clear_halt(serial->dev, 0x81); 597 usb_clear_halt(serial->dev, 0x02); 598 599 spin_lock_irqsave(&priv->lock, flags); 600 /* reset read/write statistics */ 601 priv->bytes_in = 0; 602 priv->bytes_out = 0; 603 priv->cmd_count = 0; 604 priv->rx_flags = 0; 605 spin_unlock_irqrestore(&priv->lock, flags); 606 607 /* Set termios */ 608 cypress_send(port); 609 610 if (tty) 611 cypress_set_termios(tty, port, &priv->tmp_termios); 612 613 /* setup the port and start reading from the device */ 614 usb_fill_int_urb(port->interrupt_in_urb, serial->dev, 615 usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress), 616 port->interrupt_in_urb->transfer_buffer, 617 port->interrupt_in_urb->transfer_buffer_length, 618 cypress_read_int_callback, port, priv->read_urb_interval); 619 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 620 621 if (result) { 622 dev_err(&port->dev, 623 "%s - failed submitting read urb, error %d\n", 624 __func__, result); 625 cypress_set_dead(port); 626 } 627 628 return result; 629} /* cypress_open */ 630 631static void cypress_dtr_rts(struct usb_serial_port *port, int on) 632{ 633 struct cypress_private *priv = usb_get_serial_port_data(port); 634 /* drop dtr and rts */ 635 spin_lock_irq(&priv->lock); 636 if (on == 0) 637 priv->line_control = 0; 638 else 639 priv->line_control = CONTROL_DTR | CONTROL_RTS; 640 priv->cmd_ctrl = 1; 641 spin_unlock_irq(&priv->lock); 642 cypress_write(NULL, port, NULL, 0); 643} 644 645static void cypress_close(struct usb_serial_port *port) 646{ 647 struct cypress_private *priv = usb_get_serial_port_data(port); 648 unsigned long flags; 649 650 spin_lock_irqsave(&priv->lock, flags); 651 kfifo_reset_out(&priv->write_fifo); 652 spin_unlock_irqrestore(&priv->lock, flags); 653 654 dev_dbg(&port->dev, "%s - stopping urbs\n", __func__); 655 usb_kill_urb(port->interrupt_in_urb); 656 usb_kill_urb(port->interrupt_out_urb); 657 658 if (stats) 659 dev_info(&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n", 660 priv->bytes_in, priv->bytes_out, priv->cmd_count); 661} /* cypress_close */ 662 663 664static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port, 665 const unsigned char *buf, int count) 666{ 667 struct cypress_private *priv = usb_get_serial_port_data(port); 668 669 dev_dbg(&port->dev, "%s - %d bytes\n", __func__, count); 670 671 /* line control commands, which need to be executed immediately, 672 are not put into the buffer for obvious reasons. 673 */ 674 if (priv->cmd_ctrl) { 675 count = 0; 676 goto finish; 677 } 678 679 if (!count) 680 return count; 681 682 count = kfifo_in_locked(&priv->write_fifo, buf, count, &priv->lock); 683 684finish: 685 cypress_send(port); 686 687 return count; 688} /* cypress_write */ 689 690 691static void cypress_send(struct usb_serial_port *port) 692{ 693 int count = 0, result, offset, actual_size; 694 struct cypress_private *priv = usb_get_serial_port_data(port); 695 struct device *dev = &port->dev; 696 unsigned long flags; 697 698 if (!priv->comm_is_ok) 699 return; 700 701 dev_dbg(dev, "%s - interrupt out size is %d\n", __func__, 702 port->interrupt_out_size); 703 704 spin_lock_irqsave(&priv->lock, flags); 705 if (priv->write_urb_in_use) { 706 dev_dbg(dev, "%s - can't write, urb in use\n", __func__); 707 spin_unlock_irqrestore(&priv->lock, flags); 708 return; 709 } 710 spin_unlock_irqrestore(&priv->lock, flags); 711 712 /* clear buffer */ 713 memset(port->interrupt_out_urb->transfer_buffer, 0, 714 port->interrupt_out_size); 715 716 spin_lock_irqsave(&priv->lock, flags); 717 switch (priv->pkt_fmt) { 718 default: 719 case packet_format_1: 720 /* this is for the CY7C64013... */ 721 offset = 2; 722 port->interrupt_out_buffer[0] = priv->line_control; 723 break; 724 case packet_format_2: 725 /* this is for the CY7C63743... */ 726 offset = 1; 727 port->interrupt_out_buffer[0] = priv->line_control; 728 break; 729 } 730 731 if (priv->line_control & CONTROL_RESET) 732 priv->line_control &= ~CONTROL_RESET; 733 734 if (priv->cmd_ctrl) { 735 priv->cmd_count++; 736 dev_dbg(dev, "%s - line control command being issued\n", __func__); 737 spin_unlock_irqrestore(&priv->lock, flags); 738 goto send; 739 } else 740 spin_unlock_irqrestore(&priv->lock, flags); 741 742 count = kfifo_out_locked(&priv->write_fifo, 743 &port->interrupt_out_buffer[offset], 744 port->interrupt_out_size - offset, 745 &priv->lock); 746 if (count == 0) 747 return; 748 749 switch (priv->pkt_fmt) { 750 default: 751 case packet_format_1: 752 port->interrupt_out_buffer[1] = count; 753 break; 754 case packet_format_2: 755 port->interrupt_out_buffer[0] |= count; 756 } 757 758 dev_dbg(dev, "%s - count is %d\n", __func__, count); 759 760send: 761 spin_lock_irqsave(&priv->lock, flags); 762 priv->write_urb_in_use = 1; 763 spin_unlock_irqrestore(&priv->lock, flags); 764 765 if (priv->cmd_ctrl) 766 actual_size = 1; 767 else 768 actual_size = count + 769 (priv->pkt_fmt == packet_format_1 ? 2 : 1); 770 771 usb_serial_debug_data(dev, __func__, port->interrupt_out_size, 772 port->interrupt_out_urb->transfer_buffer); 773 774 usb_fill_int_urb(port->interrupt_out_urb, port->serial->dev, 775 usb_sndintpipe(port->serial->dev, port->interrupt_out_endpointAddress), 776 port->interrupt_out_buffer, port->interrupt_out_size, 777 cypress_write_int_callback, port, priv->write_urb_interval); 778 result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC); 779 if (result) { 780 dev_err_console(port, 781 "%s - failed submitting write urb, error %d\n", 782 __func__, result); 783 priv->write_urb_in_use = 0; 784 cypress_set_dead(port); 785 } 786 787 spin_lock_irqsave(&priv->lock, flags); 788 if (priv->cmd_ctrl) 789 priv->cmd_ctrl = 0; 790 791 /* do not count the line control and size bytes */ 792 priv->bytes_out += count; 793 spin_unlock_irqrestore(&priv->lock, flags); 794 795 usb_serial_port_softint(port); 796} /* cypress_send */ 797 798 799/* returns how much space is available in the soft buffer */ 800static int cypress_write_room(struct tty_struct *tty) 801{ 802 struct usb_serial_port *port = tty->driver_data; 803 struct cypress_private *priv = usb_get_serial_port_data(port); 804 int room = 0; 805 unsigned long flags; 806 807 spin_lock_irqsave(&priv->lock, flags); 808 room = kfifo_avail(&priv->write_fifo); 809 spin_unlock_irqrestore(&priv->lock, flags); 810 811 dev_dbg(&port->dev, "%s - returns %d\n", __func__, room); 812 return room; 813} 814 815 816static int cypress_tiocmget(struct tty_struct *tty) 817{ 818 struct usb_serial_port *port = tty->driver_data; 819 struct cypress_private *priv = usb_get_serial_port_data(port); 820 __u8 status, control; 821 unsigned int result = 0; 822 unsigned long flags; 823 824 spin_lock_irqsave(&priv->lock, flags); 825 control = priv->line_control; 826 status = priv->current_status; 827 spin_unlock_irqrestore(&priv->lock, flags); 828 829 result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0) 830 | ((control & CONTROL_RTS) ? TIOCM_RTS : 0) 831 | ((status & UART_CTS) ? TIOCM_CTS : 0) 832 | ((status & UART_DSR) ? TIOCM_DSR : 0) 833 | ((status & UART_RI) ? TIOCM_RI : 0) 834 | ((status & UART_CD) ? TIOCM_CD : 0); 835 836 dev_dbg(&port->dev, "%s - result = %x\n", __func__, result); 837 838 return result; 839} 840 841 842static int cypress_tiocmset(struct tty_struct *tty, 843 unsigned int set, unsigned int clear) 844{ 845 struct usb_serial_port *port = tty->driver_data; 846 struct cypress_private *priv = usb_get_serial_port_data(port); 847 unsigned long flags; 848 849 spin_lock_irqsave(&priv->lock, flags); 850 if (set & TIOCM_RTS) 851 priv->line_control |= CONTROL_RTS; 852 if (set & TIOCM_DTR) 853 priv->line_control |= CONTROL_DTR; 854 if (clear & TIOCM_RTS) 855 priv->line_control &= ~CONTROL_RTS; 856 if (clear & TIOCM_DTR) 857 priv->line_control &= ~CONTROL_DTR; 858 priv->cmd_ctrl = 1; 859 spin_unlock_irqrestore(&priv->lock, flags); 860 861 return cypress_write(tty, port, NULL, 0); 862} 863 864static void cypress_set_termios(struct tty_struct *tty, 865 struct usb_serial_port *port, struct ktermios *old_termios) 866{ 867 struct cypress_private *priv = usb_get_serial_port_data(port); 868 struct device *dev = &port->dev; 869 int data_bits, stop_bits, parity_type, parity_enable; 870 unsigned cflag, iflag; 871 unsigned long flags; 872 __u8 oldlines; 873 int linechange = 0; 874 875 spin_lock_irqsave(&priv->lock, flags); 876 /* We can't clean this one up as we don't know the device type 877 early enough */ 878 if (!priv->termios_initialized) { 879 if (priv->chiptype == CT_EARTHMATE) { 880 tty->termios = tty_std_termios; 881 tty->termios.c_cflag = B4800 | CS8 | CREAD | HUPCL | 882 CLOCAL; 883 tty->termios.c_ispeed = 4800; 884 tty->termios.c_ospeed = 4800; 885 } else if (priv->chiptype == CT_CYPHIDCOM) { 886 tty->termios = tty_std_termios; 887 tty->termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | 888 CLOCAL; 889 tty->termios.c_ispeed = 9600; 890 tty->termios.c_ospeed = 9600; 891 } else if (priv->chiptype == CT_CA42V2) { 892 tty->termios = tty_std_termios; 893 tty->termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | 894 CLOCAL; 895 tty->termios.c_ispeed = 9600; 896 tty->termios.c_ospeed = 9600; 897 } 898 priv->termios_initialized = 1; 899 } 900 spin_unlock_irqrestore(&priv->lock, flags); 901 902 /* Unsupported features need clearing */ 903 tty->termios.c_cflag &= ~(CMSPAR|CRTSCTS); 904 905 cflag = tty->termios.c_cflag; 906 iflag = tty->termios.c_iflag; 907 908 /* check if there are new settings */ 909 if (old_termios) { 910 spin_lock_irqsave(&priv->lock, flags); 911 priv->tmp_termios = tty->termios; 912 spin_unlock_irqrestore(&priv->lock, flags); 913 } 914 915 /* set number of data bits, parity, stop bits */ 916 /* when parity is disabled the parity type bit is ignored */ 917 918 /* 1 means 2 stop bits, 0 means 1 stop bit */ 919 stop_bits = cflag & CSTOPB ? 1 : 0; 920 921 if (cflag & PARENB) { 922 parity_enable = 1; 923 /* 1 means odd parity, 0 means even parity */ 924 parity_type = cflag & PARODD ? 1 : 0; 925 } else 926 parity_enable = parity_type = 0; 927 928 switch (cflag & CSIZE) { 929 case CS5: 930 data_bits = 0; 931 break; 932 case CS6: 933 data_bits = 1; 934 break; 935 case CS7: 936 data_bits = 2; 937 break; 938 case CS8: 939 data_bits = 3; 940 break; 941 default: 942 dev_err(dev, "%s - CSIZE was set, but not CS5-CS8\n", __func__); 943 data_bits = 3; 944 } 945 spin_lock_irqsave(&priv->lock, flags); 946 oldlines = priv->line_control; 947 if ((cflag & CBAUD) == B0) { 948 /* drop dtr and rts */ 949 dev_dbg(dev, "%s - dropping the lines, baud rate 0bps\n", __func__); 950 priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); 951 } else 952 priv->line_control = (CONTROL_DTR | CONTROL_RTS); 953 spin_unlock_irqrestore(&priv->lock, flags); 954 955 dev_dbg(dev, "%s - sending %d stop_bits, %d parity_enable, %d parity_type, %d data_bits (+5)\n", 956 __func__, stop_bits, parity_enable, parity_type, data_bits); 957 958 cypress_serial_control(tty, port, tty_get_baud_rate(tty), 959 data_bits, stop_bits, 960 parity_enable, parity_type, 961 0, CYPRESS_SET_CONFIG); 962 963 /* we perform a CYPRESS_GET_CONFIG so that the current settings are 964 * filled into the private structure this should confirm that all is 965 * working if it returns what we just set */ 966 cypress_serial_control(tty, port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG); 967 968 /* Here we can define custom tty settings for devices; the main tty 969 * termios flag base comes from empeg.c */ 970 971 spin_lock_irqsave(&priv->lock, flags); 972 if (priv->chiptype == CT_EARTHMATE && priv->baud_rate == 4800) { 973 dev_dbg(dev, "Using custom termios settings for a baud rate of 4800bps.\n"); 974 /* define custom termios settings for NMEA protocol */ 975 976 tty->termios.c_iflag /* input modes - */ 977 &= ~(IGNBRK /* disable ignore break */ 978 | BRKINT /* disable break causes interrupt */ 979 | PARMRK /* disable mark parity errors */ 980 | ISTRIP /* disable clear high bit of input char */ 981 | INLCR /* disable translate NL to CR */ 982 | IGNCR /* disable ignore CR */ 983 | ICRNL /* disable translate CR to NL */ 984 | IXON); /* disable enable XON/XOFF flow control */ 985 986 tty->termios.c_oflag /* output modes */ 987 &= ~OPOST; /* disable postprocess output char */ 988 989 tty->termios.c_lflag /* line discipline modes */ 990 &= ~(ECHO /* disable echo input characters */ 991 | ECHONL /* disable echo new line */ 992 | ICANON /* disable erase, kill, werase, and rprnt 993 special characters */ 994 | ISIG /* disable interrupt, quit, and suspend 995 special characters */ 996 | IEXTEN); /* disable non-POSIX special characters */ 997 } /* CT_CYPHIDCOM: Application should handle this for device */ 998 999 linechange = (priv->line_control != oldlines); 1000 spin_unlock_irqrestore(&priv->lock, flags); 1001 1002 /* if necessary, set lines */ 1003 if (linechange) { 1004 priv->cmd_ctrl = 1; 1005 cypress_write(tty, port, NULL, 0); 1006 } 1007} /* cypress_set_termios */ 1008 1009 1010/* returns amount of data still left in soft buffer */ 1011static int cypress_chars_in_buffer(struct tty_struct *tty) 1012{ 1013 struct usb_serial_port *port = tty->driver_data; 1014 struct cypress_private *priv = usb_get_serial_port_data(port); 1015 int chars = 0; 1016 unsigned long flags; 1017 1018 spin_lock_irqsave(&priv->lock, flags); 1019 chars = kfifo_len(&priv->write_fifo); 1020 spin_unlock_irqrestore(&priv->lock, flags); 1021 1022 dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars); 1023 return chars; 1024} 1025 1026 1027static void cypress_throttle(struct tty_struct *tty) 1028{ 1029 struct usb_serial_port *port = tty->driver_data; 1030 struct cypress_private *priv = usb_get_serial_port_data(port); 1031 1032 spin_lock_irq(&priv->lock); 1033 priv->rx_flags = THROTTLED; 1034 spin_unlock_irq(&priv->lock); 1035} 1036 1037 1038static void cypress_unthrottle(struct tty_struct *tty) 1039{ 1040 struct usb_serial_port *port = tty->driver_data; 1041 struct cypress_private *priv = usb_get_serial_port_data(port); 1042 int actually_throttled, result; 1043 1044 spin_lock_irq(&priv->lock); 1045 actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; 1046 priv->rx_flags = 0; 1047 spin_unlock_irq(&priv->lock); 1048 1049 if (!priv->comm_is_ok) 1050 return; 1051 1052 if (actually_throttled) { 1053 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 1054 if (result) { 1055 dev_err(&port->dev, "%s - failed submitting read urb, " 1056 "error %d\n", __func__, result); 1057 cypress_set_dead(port); 1058 } 1059 } 1060} 1061 1062 1063static void cypress_read_int_callback(struct urb *urb) 1064{ 1065 struct usb_serial_port *port = urb->context; 1066 struct cypress_private *priv = usb_get_serial_port_data(port); 1067 struct device *dev = &urb->dev->dev; 1068 struct tty_struct *tty; 1069 unsigned char *data = urb->transfer_buffer; 1070 unsigned long flags; 1071 char tty_flag = TTY_NORMAL; 1072 int havedata = 0; 1073 int bytes = 0; 1074 int result; 1075 int i = 0; 1076 int status = urb->status; 1077 1078 switch (status) { 1079 case 0: /* success */ 1080 break; 1081 case -ECONNRESET: 1082 case -ENOENT: 1083 case -ESHUTDOWN: 1084 /* precursor to disconnect so just go away */ 1085 return; 1086 case -EPIPE: 1087 /* Can't call usb_clear_halt while in_interrupt */ 1088 /* FALLS THROUGH */ 1089 default: 1090 /* something ugly is going on... */ 1091 dev_err(dev, "%s - unexpected nonzero read status received: %d\n", 1092 __func__, status); 1093 cypress_set_dead(port); 1094 return; 1095 } 1096 1097 spin_lock_irqsave(&priv->lock, flags); 1098 if (priv->rx_flags & THROTTLED) { 1099 dev_dbg(dev, "%s - now throttling\n", __func__); 1100 priv->rx_flags |= ACTUALLY_THROTTLED; 1101 spin_unlock_irqrestore(&priv->lock, flags); 1102 return; 1103 } 1104 spin_unlock_irqrestore(&priv->lock, flags); 1105 1106 tty = tty_port_tty_get(&port->port); 1107 if (!tty) { 1108 dev_dbg(dev, "%s - bad tty pointer - exiting\n", __func__); 1109 return; 1110 } 1111 1112 spin_lock_irqsave(&priv->lock, flags); 1113 result = urb->actual_length; 1114 switch (priv->pkt_fmt) { 1115 default: 1116 case packet_format_1: 1117 /* This is for the CY7C64013... */ 1118 priv->current_status = data[0] & 0xF8; 1119 bytes = data[1] + 2; 1120 i = 2; 1121 if (bytes > 2) 1122 havedata = 1; 1123 break; 1124 case packet_format_2: 1125 /* This is for the CY7C63743... */ 1126 priv->current_status = data[0] & 0xF8; 1127 bytes = (data[0] & 0x07) + 1; 1128 i = 1; 1129 if (bytes > 1) 1130 havedata = 1; 1131 break; 1132 } 1133 spin_unlock_irqrestore(&priv->lock, flags); 1134 if (result < bytes) { 1135 dev_dbg(dev, 1136 "%s - wrong packet size - received %d bytes but packet said %d bytes\n", 1137 __func__, result, bytes); 1138 goto continue_read; 1139 } 1140 1141 usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data); 1142 1143 spin_lock_irqsave(&priv->lock, flags); 1144 /* check to see if status has changed */ 1145 if (priv->current_status != priv->prev_status) { 1146 u8 delta = priv->current_status ^ priv->prev_status; 1147 1148 if (delta & UART_MSR_MASK) { 1149 if (delta & UART_CTS) 1150 port->icount.cts++; 1151 if (delta & UART_DSR) 1152 port->icount.dsr++; 1153 if (delta & UART_RI) 1154 port->icount.rng++; 1155 if (delta & UART_CD) 1156 port->icount.dcd++; 1157 1158 wake_up_interruptible(&port->port.delta_msr_wait); 1159 } 1160 1161 priv->prev_status = priv->current_status; 1162 } 1163 spin_unlock_irqrestore(&priv->lock, flags); 1164 1165 /* hangup, as defined in acm.c... this might be a bad place for it 1166 * though */ 1167 if (tty && !(tty->termios.c_cflag & CLOCAL) && 1168 !(priv->current_status & UART_CD)) { 1169 dev_dbg(dev, "%s - calling hangup\n", __func__); 1170 tty_hangup(tty); 1171 goto continue_read; 1172 } 1173 1174 /* There is one error bit... I'm assuming it is a parity error 1175 * indicator as the generic firmware will set this bit to 1 if a 1176 * parity error occurs. 1177 * I can not find reference to any other error events. */ 1178 spin_lock_irqsave(&priv->lock, flags); 1179 if (priv->current_status & CYP_ERROR) { 1180 spin_unlock_irqrestore(&priv->lock, flags); 1181 tty_flag = TTY_PARITY; 1182 dev_dbg(dev, "%s - Parity Error detected\n", __func__); 1183 } else 1184 spin_unlock_irqrestore(&priv->lock, flags); 1185 1186 /* process read if there is data other than line status */ 1187 if (bytes > i) { 1188 tty_insert_flip_string_fixed_flag(&port->port, data + i, 1189 tty_flag, bytes - i); 1190 tty_flip_buffer_push(&port->port); 1191 } 1192 1193 spin_lock_irqsave(&priv->lock, flags); 1194 /* control and status byte(s) are also counted */ 1195 priv->bytes_in += bytes; 1196 spin_unlock_irqrestore(&priv->lock, flags); 1197 1198continue_read: 1199 tty_kref_put(tty); 1200 1201 /* Continue trying to always read */ 1202 1203 if (priv->comm_is_ok) { 1204 usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev, 1205 usb_rcvintpipe(port->serial->dev, 1206 port->interrupt_in_endpointAddress), 1207 port->interrupt_in_urb->transfer_buffer, 1208 port->interrupt_in_urb->transfer_buffer_length, 1209 cypress_read_int_callback, port, 1210 priv->read_urb_interval); 1211 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); 1212 if (result && result != -EPERM) { 1213 dev_err(dev, "%s - failed resubmitting read urb, error %d\n", 1214 __func__, result); 1215 cypress_set_dead(port); 1216 } 1217 } 1218} /* cypress_read_int_callback */ 1219 1220 1221static void cypress_write_int_callback(struct urb *urb) 1222{ 1223 struct usb_serial_port *port = urb->context; 1224 struct cypress_private *priv = usb_get_serial_port_data(port); 1225 struct device *dev = &urb->dev->dev; 1226 int status = urb->status; 1227 1228 switch (status) { 1229 case 0: 1230 /* success */ 1231 break; 1232 case -ECONNRESET: 1233 case -ENOENT: 1234 case -ESHUTDOWN: 1235 /* this urb is terminated, clean up */ 1236 dev_dbg(dev, "%s - urb shutting down with status: %d\n", 1237 __func__, status); 1238 priv->write_urb_in_use = 0; 1239 return; 1240 case -EPIPE: 1241 /* Cannot call usb_clear_halt while in_interrupt */ 1242 /* FALLTHROUGH */ 1243 default: 1244 dev_err(dev, "%s - unexpected nonzero write status received: %d\n", 1245 __func__, status); 1246 cypress_set_dead(port); 1247 break; 1248 } 1249 priv->write_urb_in_use = 0; 1250 1251 /* send any buffered data */ 1252 cypress_send(port); 1253} 1254 1255module_usb_serial_driver(serial_drivers, id_table_combined); 1256 1257MODULE_AUTHOR(DRIVER_AUTHOR); 1258MODULE_DESCRIPTION(DRIVER_DESC); 1259MODULE_LICENSE("GPL"); 1260 1261module_param(stats, bool, S_IRUGO | S_IWUSR); 1262MODULE_PARM_DESC(stats, "Enable statistics or not"); 1263module_param(interval, int, S_IRUGO | S_IWUSR); 1264MODULE_PARM_DESC(interval, "Overrides interrupt interval"); 1265module_param(unstable_bauds, bool, S_IRUGO | S_IWUSR); 1266MODULE_PARM_DESC(unstable_bauds, "Allow unstable baud rates"); 1267