aboutsummaryrefslogtreecommitdiff
path: root/drivers/staging/uc2322/aten2011.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/uc2322/aten2011.c')
-rw-r--r--drivers/staging/uc2322/aten2011.c401
1 files changed, 399 insertions, 2 deletions
diff --git a/drivers/staging/uc2322/aten2011.c b/drivers/staging/uc2322/aten2011.c
index b78363d3b41..9a91f236f45 100644
--- a/drivers/staging/uc2322/aten2011.c
+++ b/drivers/staging/uc2322/aten2011.c
@@ -63,8 +63,405 @@
#define KERNEL_2_6 1
#include <linux/usb/serial.h>
-#include "aten2011.h" /* ATEN2011 Defines */
-#include "aten2011_16C50.h" /* 16C50 UART defines */
+
+#define MAX_RS232_PORTS 2 /* Max # of RS-232 ports per device */
+
+#include <linux/version.h>
+
+/*
+ * All typedef goes here
+ */
+
+
+/* typedefs that the insideout headers need */
+
+#ifndef TRUE
+ #define TRUE (1)
+#endif
+
+#ifndef FALSE
+ #define FALSE (0)
+#endif
+
+#ifndef LOW8
+ #define LOW8(val) ((unsigned char)(val & 0xff))
+#endif
+
+#ifndef HIGH8
+ #define HIGH8(val) ((unsigned char)((val & 0xff00) >> 8))
+#endif
+
+#ifndef NUM_ENTRIES
+ #define NUM_ENTRIES(x) (sizeof(x)/sizeof((x)[0]))
+#endif
+
+#define MAX_SERIALNUMBER_LEN 12
+
+/* The following table is used to map the USBx port number to
+ * the device serial number (or physical USB path), */
+
+#define MAX_ATENPORTS 2
+#define MAX_NAME_LEN 64
+
+#define RAID_REG1 0x30
+#define RAID_REG2 0x31
+
+#define ZLP_REG1 0x3A //Zero_Flag_Reg1 58
+#define ZLP_REG2 0x3B //Zero_Flag_Reg2 59
+#define ZLP_REG3 0x3C //Zero_Flag_Reg3 60
+#define ZLP_REG4 0x3D //Zero_Flag_Reg4 61
+#define ZLP_REG5 0x3E //Zero_Flag_Reg5 62
+
+#define THRESHOLD_VAL_SP1_1 0x3F
+#define THRESHOLD_VAL_SP1_2 0x40
+#define THRESHOLD_VAL_SP2_1 0x41
+#define THRESHOLD_VAL_SP2_2 0x42
+
+#define THRESHOLD_VAL_SP3_1 0x43
+#define THRESHOLD_VAL_SP3_2 0x44
+#define THRESHOLD_VAL_SP4_1 0x45
+#define THRESHOLD_VAL_SP4_2 0x46
+
+
+/* For higher baud Rates use TIOCEXBAUD */
+#define TIOCEXBAUD 0x5462
+
+#define BAUD_1152 0 /* 115200bps * 1 */
+#define BAUD_2304 1 /* 230400bps * 2 */
+#define BAUD_4032 2 /* 403200bps * 3.5 */
+#define BAUD_4608 3 /* 460800bps * 4 */
+#define BAUD_8064 4 /* 806400bps * 7 */
+#define BAUD_9216 5 /* 921600bps * 8 */
+
+#define CHASE_TIMEOUT (5*HZ) /* 5 seconds */
+#define OPEN_TIMEOUT (5*HZ) /* 5 seconds */
+#define COMMAND_TIMEOUT (5*HZ) /* 5 seconds */
+
+#ifndef SERIAL_MAGIC
+ #define SERIAL_MAGIC 0x6702
+#endif
+
+#define PORT_MAGIC 0x7301
+
+
+
+/* vendor id and device id defines */
+
+#define USB_VENDOR_ID_ATENINTL 0x0557
+#define ATENINTL_DEVICE_ID_2011 0x2011
+#define ATENINTL_DEVICE_ID_7820 0x7820
+
+/* Product information read from the ATENINTL. Provided for later upgrade */
+
+/* Interrupt Rotinue Defines */
+
+#define SERIAL_IIR_RLS 0x06
+#define SERIAL_IIR_RDA 0x04
+#define SERIAL_IIR_CTI 0x0c
+#define SERIAL_IIR_THR 0x02
+#define SERIAL_IIR_MS 0x00
+
+/*
+ * Emulation of the bit mask on the LINE STATUS REGISTER.
+ */
+#define SERIAL_LSR_DR 0x0001
+#define SERIAL_LSR_OE 0x0002
+#define SERIAL_LSR_PE 0x0004
+#define SERIAL_LSR_FE 0x0008
+#define SERIAL_LSR_BI 0x0010
+#define SERIAL_LSR_THRE 0x0020
+#define SERIAL_LSR_TEMT 0x0040
+#define SERIAL_LSR_FIFOERR 0x0080
+
+//MSR bit defines(place holders)
+#define ATEN_MSR_CTS 0x01
+#define ATEN_MSR_DSR 0x02
+#define ATEN_MSR_RI 0x04
+#define ATEN_MSR_CD 0x08
+#define ATEN_MSR_DELTA_CTS 0x10
+#define ATEN_MSR_DELTA_DSR 0x20
+#define ATEN_MSR_DELTA_RI 0x40
+#define ATEN_MSR_DELTA_CD 0x80
+
+// Serial Port register Address
+#define RECEIVE_BUFFER_REGISTER ((__u16)(0x00))
+#define TRANSMIT_HOLDING_REGISTER ((__u16)(0x00))
+#define INTERRUPT_ENABLE_REGISTER ((__u16)(0x01))
+#define INTERRUPT_IDENT_REGISTER ((__u16)(0x02))
+#define FIFO_CONTROL_REGISTER ((__u16)(0x02))
+#define LINE_CONTROL_REGISTER ((__u16)(0x03))
+#define MODEM_CONTROL_REGISTER ((__u16)(0x04))
+#define LINE_STATUS_REGISTER ((__u16)(0x05))
+#define MODEM_STATUS_REGISTER ((__u16)(0x06))
+#define SCRATCH_PAD_REGISTER ((__u16)(0x07))
+#define DIVISOR_LATCH_LSB ((__u16)(0x00))
+#define DIVISOR_LATCH_MSB ((__u16)(0x01))
+
+#define SP_REGISTER_BASE ((__u16)(0x08))
+#define CONTROL_REGISTER_BASE ((__u16)(0x09))
+#define DCR_REGISTER_BASE ((__u16)(0x16))
+
+#define SP1_REGISTER ((__u16)(0x00))
+#define CONTROL1_REGISTER ((__u16)(0x01))
+#define CLK_MULTI_REGISTER ((__u16)(0x02))
+#define CLK_START_VALUE_REGISTER ((__u16)(0x03))
+#define DCR1_REGISTER ((__u16)(0x04))
+#define GPIO_REGISTER ((__u16)(0x07))
+
+#define CLOCK_SELECT_REG1 ((__u16)(0x13))
+#define CLOCK_SELECT_REG2 ((__u16)(0x14))
+
+#define SERIAL_LCR_DLAB ((__u16)(0x0080))
+
+/*
+ * URB POOL related defines
+ */
+#define NUM_URBS 16 /* URB Count */
+#define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */
+
+struct ATENINTL_product_info
+{
+ __u16 ProductId; /* Product Identifier */
+ __u8 NumPorts; /* Number of ports on ATENINTL */
+ __u8 ProdInfoVer; /* What version of structure is this? */
+
+ __u32 IsServer :1; /* Set if Server */
+ __u32 IsRS232 :1; /* Set if RS-232 ports exist */
+ __u32 IsRS422 :1; /* Set if RS-422 ports exist */
+ __u32 IsRS485 :1; /* Set if RS-485 ports exist */
+ __u32 IsReserved :28; /* Reserved for later expansion */
+
+ __u8 CpuRev; /* CPU revision level (chg only if s/w visible) */
+ __u8 BoardRev; /* PCB revision level (chg only if s/w visible) */
+
+ __u8 ManufactureDescDate[3]; /* MM/DD/YY when descriptor template was compiled */
+ __u8 Unused1[1]; /* Available */
+};
+
+// different USB-serial Adapter's ID's table
+static struct usb_device_id ATENINTL_port_id_table [] = {
+ { USB_DEVICE(USB_VENDOR_ID_ATENINTL,ATENINTL_DEVICE_ID_2011) },
+ { USB_DEVICE(USB_VENDOR_ID_ATENINTL,ATENINTL_DEVICE_ID_7820) },
+ { } /* terminating entry */
+};
+
+static __devinitdata struct usb_device_id id_table_combined [] = {
+ { USB_DEVICE(USB_VENDOR_ID_ATENINTL,ATENINTL_DEVICE_ID_2011) },
+ { USB_DEVICE(USB_VENDOR_ID_ATENINTL,ATENINTL_DEVICE_ID_7820) },
+ { } /* terminating entry */
+};
+
+MODULE_DEVICE_TABLE (usb, id_table_combined);
+
+/* This structure holds all of the local port information */
+struct ATENINTL_port
+{
+ int port_num; /*Actual port number in the device(1,2,etc)*/
+ __u8 bulk_out_endpoint; /* the bulk out endpoint handle */
+ unsigned char *bulk_out_buffer; /* buffer used for the bulk out endpoint */
+ struct urb *write_urb; /* write URB for this port */
+ __u8 bulk_in_endpoint; /* the bulk in endpoint handle */
+ unsigned char *bulk_in_buffer; /* the buffer we use for the bulk in endpoint */
+ struct urb *read_urb; /* read URB for this port */
+ __s16 rxBytesAvail;/*the number of bytes that we need to read from this device */
+ __s16 rxBytesRemaining; /* the number of port bytes left to read */
+ char write_in_progress; /* TRUE while a write URB is outstanding */
+ __u8 shadowLCR; /* last LCR value received */
+ __u8 shadowMCR; /* last MCR value received */
+ __u8 shadowMSR; /* last MSR value received */
+ __u8 shadowLSR; /* last LSR value received */
+ __u8 shadowXonChar; /* last value set as XON char in ATENINTL */
+ __u8 shadowXoffChar; /* last value set as XOFF char in ATENINTL */
+ __u8 validDataMask;
+ __u32 baudRate;
+ char open;
+ char openPending;
+ char commandPending;
+ char closePending;
+ char chaseResponsePending;
+ wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */
+ wait_queue_head_t wait_open; /* for handling sleeping while waiting for open to finish */
+ wait_queue_head_t wait_command; /* for handling sleeping while waiting for command to finish */
+ wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */
+ int delta_msr_cond;
+ struct async_icount icount;
+ struct usb_serial_port *port; /* loop back to the owner of this object */
+ /*Offsets*/
+ __u16 AppNum;
+ __u8 SpRegOffset;
+ __u8 ControlRegOffset;
+ __u8 DcrRegOffset;
+ __u8 ClkSelectRegOffset;
+ //for processing control URBS in interrupt context
+ struct urb *control_urb;
+ // __le16 rx_creg;
+ char *ctrl_buf;
+ int MsrLsr;
+
+ struct urb *write_urb_pool[NUM_URBS];
+ /* we pass a pointer to this as the arguement sent to cypress_set_termios old_termios */
+ struct ktermios tmp_termios; /* stores the old termios settings */
+ spinlock_t lock; /* private lock */
+};
+
+
+/* This structure holds all of the individual serial device information */
+struct ATENINTL_serial
+{
+ char name[MAX_NAME_LEN+1]; /* string name of this device */
+ struct ATENINTL_product_info product_info; /* Product Info */
+ __u8 interrupt_in_endpoint; /* the interrupt endpoint handle */
+ unsigned char *interrupt_in_buffer; /* the buffer we use for the interrupt endpoint */
+ struct urb * interrupt_read_urb; /* our interrupt urb */
+ __u8 bulk_in_endpoint; /* the bulk in endpoint handle */
+ unsigned char *bulk_in_buffer; /* the buffer we use for the bulk in endpoint */
+ struct urb *read_urb; /* our bulk read urb */
+ __u8 bulk_out_endpoint; /* the bulk out endpoint handle */
+ __s16 rxBytesAvail; /* the number of bytes that we need to read from this device */
+ __u8 rxPort; /* the port that we are currently receiving data for */
+ __u8 rxStatusCode; /* the receive status code */
+ __u8 rxStatusParam; /* the receive status paramater */
+ __s16 rxBytesRemaining; /* the number of port bytes left to read */
+ struct usb_serial *serial; /* loop back to the owner of this object */
+ int ATEN2011_spectrum_2or4ports; //this says the number of ports in the device
+ // Indicates about the no.of opened ports of an individual USB-serial adapater.
+ unsigned int NoOfOpenPorts;
+ // a flag for Status endpoint polling
+ unsigned char status_polling_started;
+};
+
+/* baud rate information */
+struct ATEN2011_divisor_table_entry
+{
+ __u32 BaudRate;
+ __u16 Divisor;
+};
+
+/* Define table of divisors for ATENINTL 2011 hardware *
+ * These assume a 3.6864MHz crystal, the standard /16, and *
+ * MCR.7 = 0. */
+#ifdef NOTATEN2011
+static struct ATEN2011_divisor_table_entry ATEN2011_divisor_table[] = {
+ { 50, 2304},
+ { 110, 1047}, /* 2094.545455 => 230450 => .0217 % over */
+ { 134, 857}, /* 1713.011152 => 230398.5 => .00065% under */
+ { 150, 768},
+ { 300, 384},
+ { 600, 192},
+ { 1200, 96},
+ { 1800, 64},
+ { 2400, 48},
+ { 4800, 24},
+ { 7200, 16},
+ { 9600, 12},
+ { 19200, 6},
+ { 38400, 3},
+ { 57600, 2},
+ { 115200, 1},
+};
+#endif
+
+/* local function prototypes */
+/* function prototypes for all URB callbacks */
+static void ATEN2011_interrupt_callback(struct urb *urb);
+static void ATEN2011_bulk_in_callback(struct urb *urb);
+static void ATEN2011_bulk_out_data_callback(struct urb *urb);
+static void ATEN2011_control_callback(struct urb *urb);
+static int ATEN2011_get_reg(struct ATENINTL_port *ATEN,__u16 Wval, __u16 reg, __u16 * val);
+int handle_newMsr(struct ATENINTL_port *port,__u8 newMsr);
+int handle_newLsr(struct ATENINTL_port *port,__u8 newLsr);
+/* function prototypes for the usbserial callbacks */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+static int ATEN2011_open(struct tty_struct *tty, struct usb_serial_port *port, struct file *filp);
+static void ATEN2011_close(struct tty_struct *tty, struct usb_serial_port *port, struct file *filp);
+static int ATEN2011_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *data, int count);
+static int ATEN2011_write_room(struct tty_struct *tty);
+static int ATEN2011_chars_in_buffer(struct tty_struct *tty);
+static void ATEN2011_throttle(struct tty_struct *tty);
+static void ATEN2011_unthrottle(struct tty_struct *tty);
+static void ATEN2011_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios);
+static int ATEN2011_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear);
+static int ATEN2011_tiocmget(struct tty_struct *tty, struct file *file);
+static int ATEN2011_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
+static void ATEN2011_break(struct tty_struct *tty, int break_state);
+#else
+static int ATEN2011_open(struct usb_serial_port *port, struct file *filp);
+static void ATEN2011_close(struct usb_serial_port *port, struct file *filp);
+static int ATEN2011_write(struct usb_serial_port *port, const unsigned char *data, int count);
+static int ATEN2011_write_room(struct usb_serial_port *port);
+static int ATEN2011_chars_in_buffer(struct usb_serial_port *port);
+static void ATEN2011_throttle(struct usb_serial_port *port);
+static void ATEN2011_unthrottle(struct usb_serial_port *port);
+static void ATEN2011_set_termios (struct usb_serial_port *port, struct ktermios *old_termios);
+static int ATEN2011_tiocmset(struct usb_serial_port *port, struct file *file,
+ unsigned int set, unsigned int clear);
+static int ATEN2011_tiocmget(struct usb_serial_port *port, struct file *file);
+static int ATEN2011_ioctl(struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg);
+static void ATEN2011_break(struct usb_serial_port *port, int break_state);
+#endif
+
+//static void ATEN2011_break_ctl(struct usb_serial_port *port, int break_state );
+
+static int ATEN2011_startup(struct usb_serial *serial);
+static void ATEN2011_shutdown(struct usb_serial *serial);
+//static int ATEN2011_serial_probe(struct usb_serial *serial, const struct usb_device_id *id);
+static int ATEN2011_calc_num_ports(struct usb_serial *serial);
+
+/* function prototypes for all of our local functions */
+static int ATEN2011_calc_baud_rate_divisor(int baudRate, int *divisor,__u16 *clk_sel_val);
+static int ATEN2011_send_cmd_write_baud_rate(struct ATENINTL_port *ATEN2011_port, int baudRate);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+static void ATEN2011_change_port_settings(struct tty_struct *tty, struct ATENINTL_port *ATEN2011_port, struct ktermios *old_termios);
+static void ATEN2011_block_until_chase_response(struct tty_struct *tty, struct ATENINTL_port *ATEN2011_port);
+static void ATEN2011_block_until_tx_empty(struct tty_struct *tty, struct ATENINTL_port *ATEN2011_port);
+#else
+static void ATEN2011_change_port_settings(struct ATENINTL_port *ATEN2011_port, struct ktermios *old_termios);
+static void ATEN2011_block_until_chase_response(struct ATENINTL_port *ATEN2011_port);
+static void ATEN2011_block_until_tx_empty(struct ATENINTL_port *ATEN2011_port);
+#endif
+
+int __init ATENINTL2011_init(void);
+void __exit ATENINTL2011_exit(void);
+
+
+/*************************************
+ * Bit definitions for each register *
+ *************************************/
+#define LCR_BITS_5 0x00 /* 5 bits/char */
+#define LCR_BITS_6 0x01 /* 6 bits/char */
+#define LCR_BITS_7 0x02 /* 7 bits/char */
+#define LCR_BITS_8 0x03 /* 8 bits/char */
+#define LCR_BITS_MASK 0x03 /* Mask for bits/char field */
+
+#define LCR_STOP_1 0x00 /* 1 stop bit */
+#define LCR_STOP_1_5 0x04 /* 1.5 stop bits (if 5 bits/char) */
+#define LCR_STOP_2 0x04 /* 2 stop bits (if 6-8 bits/char) */
+#define LCR_STOP_MASK 0x04 /* Mask for stop bits field */
+
+#define LCR_PAR_NONE 0x00 /* No parity */
+#define LCR_PAR_ODD 0x08 /* Odd parity */
+#define LCR_PAR_EVEN 0x18 /* Even parity */
+#define LCR_PAR_MARK 0x28 /* Force parity bit to 1 */
+#define LCR_PAR_SPACE 0x38 /* Force parity bit to 0 */
+#define LCR_PAR_MASK 0x38 /* Mask for parity field */
+
+#define LCR_SET_BREAK 0x40 /* Set Break condition */
+#define LCR_DL_ENABLE 0x80 /* Enable access to divisor latch */
+
+#define MCR_DTR 0x01 /* Assert DTR */
+#define MCR_RTS 0x02 /* Assert RTS */
+#define MCR_OUT1 0x04 /* Loopback only: Sets state of RI */
+#define MCR_MASTER_IE 0x08 /* Enable interrupt outputs */
+#define MCR_LOOPBACK 0x10 /* Set internal (digital) loopback mode */
+#define MCR_XON_ANY 0x20 /* Enable any char to exit XOFF mode */
+
+#define ATEN2011_MSR_CTS 0x10 /* Current state of CTS */
+#define ATEN2011_MSR_DSR 0x20 /* Current state of DSR */
+#define ATEN2011_MSR_RI 0x40 /* Current state of RI */
+#define ATEN2011_MSR_CD 0x80 /* Current state of CD */
+
/* all defines goes here */