/*
* Ours Technology Inc. OTi-6858 USB to serial adapter driver.
*
* Copyleft (C) 2007 Kees Lemmens (adapted for kernel 2.6.20)
* Copyright (C) 2006 Tomasz Michal Lukaszewski (FIXME: add e-mail)
* Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (C) 2003 IBM Corp.
*
* Many thanks to the authors of pl2303 driver: all functions in this file
* are heavily based on pl2303 code, buffering code is a 1-to-1 copy.
*
* Warning! You use this driver on your own risk! The only official
* description of this device I have is datasheet from manufacturer,
* and it doesn't contain almost any information needed to write a driver.
* Almost all knowlegde used while writing this driver was gathered by:
* - analyzing traffic between device and the M$ Windows 2000 driver,
* - trying different bit combinations and checking pin states
* with a voltmeter,
* - receiving malformed frames and producing buffer overflows
* to learn how errors are reported,
* So, THIS CODE CAN DESTROY OTi-6858 AND ANY OTHER DEVICES, THAT ARE
* CONNECTED TO IT!
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License.
*
* See Documentation/usb/usb-serial.txt for more information on using this driver
*
* TODO:
* - implement correct flushing for ioctls and oti6858_close()
* - check how errors (rx overflow, parity error, framing error) are reported
* - implement oti6858_break_ctl()
* - implement more ioctls
* - test/implement flow control
* - allow setting custom baud rates
*/
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/serial.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/spinlock.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include <asm/uaccess.h>
#include "oti6858.h"
#define OTI6858_DESCRIPTION \
"Ours Technology Inc. OTi-6858 USB to serial adapter driver"
#define OTI6858_AUTHOR "Tomasz Michal Lukaszewski <FIXME@FIXME>"
#define OTI6858_VERSION "0.1"
static struct usb_device_id id_table [] = {
{ USB_DEVICE(OTI6858_VENDOR_ID, OTI6858_PRODUCT_ID) },
{ }
};
MODULE_DEVICE_TABLE(usb, id_table);
static struct usb_driver oti6858_driver = {
.name = "oti6858",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
.id_table = id_table,
.no_dynamic_id = 1,
};
static int debug;
/* buffering code, copied from pl2303 driver */
#define PL2303_BUF_SIZE 1024
#define PL2303_TMP_BUF_SIZE 1024
struct pl2303_buf {
unsigned int buf_size;
char *buf_buf;
char *buf_get;
char *buf_put;
};
/* requests */
#define OTI6858_REQ_GET_STATUS (USB_DIR_IN | USB_TYPE_VENDOR | 0x00)
#define OTI6858_REQ_T_GET_STATUS 0x01
#define OTI6858_REQ_SET_LINE (USB_DIR_OUT | USB_TYPE_VENDOR | 0x00)
#define OTI6858_REQ_T_SET_LINE 0x00
#define OTI6858_REQ_CHECK_TXBUFF (USB_DIR_IN | USB_TYPE_VENDOR | 0x01)
#define OTI6858_REQ_T_CHECK_TXBUFF 0x00
/* format of the control packet */
struct oti6858_control_pkt {
u16 divisor; /* baud rate = 96000000 / (16 * divisor), LE */
#define OTI6858_MAX_BAUD_RATE 3000000
u8 frame_fmt;
#define FMT_STOP_BITS_MASK 0xc0
#define FMT_STOP_BITS_1 0x00
#define FMT_STOP_BITS_2 0x40 /* 1.5 stop bits if FMT_DATA_BITS_5 */
#define FMT_PARITY_MASK 0x38
#define FMT_PARITY_NONE 0x00
#define FMT_PARITY_ODD 0x08
#define FMT_PARITY_EVEN 0x18
#define FMT_PARITY_MARK 0x28
#define FMT_PARITY_SPACE 0x38
#define FMT_DATA_BITS_MASK 0x03
#define FMT_DATA_BITS_5 0x00
#define FMT_DATA_BITS_6 0x01
#define FMT_DATA_BITS_7 0x02
#define FMT_DATA_BITS_8 0x03
u8 something; /* always equals 0x43 */
u8 control; /* settings of flow control lines */
#define CONTROL_MASK 0x0c
#define CONTROL_DTR_HIGH 0x08