linux/drivers/usb/serial/mos7840.c
<<
>>
Prefs
   1/*
   2 * This program is free software; you can redistribute it and/or modify
   3 * it under the terms of the GNU General Public License as published by
   4 * the Free Software Foundation; either version 2 of the License, or
   5 * (at your option) any later version.
   6 *
   7 * This program is distributed in the hope that it will be useful,
   8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
   9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10 * GNU General Public License for more details.
  11 *
  12 * You should have received a copy of the GNU General Public License
  13 * along with this program; if not, write to the Free Software
  14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  15 *
  16 * Clean ups from Moschip version and a few ioctl implementations by:
  17 *      Paul B Schroeder <pschroeder "at" uplogix "dot" com>
  18 *
  19 * Originally based on drivers/usb/serial/io_edgeport.c which is:
  20 *      Copyright (C) 2000 Inside Out Networks, All rights reserved.
  21 *      Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com>
  22 *
  23 */
  24
  25#include <linux/kernel.h>
  26#include <linux/errno.h>
  27#include <linux/init.h>
  28#include <linux/slab.h>
  29#include <linux/tty.h>
  30#include <linux/tty_driver.h>
  31#include <linux/tty_flip.h>
  32#include <linux/module.h>
  33#include <linux/serial.h>
  34#include <linux/usb.h>
  35#include <linux/usb/serial.h>
  36#include <asm/uaccess.h>
  37
  38/*
  39 * Version Information
  40 */
  41#define DRIVER_VERSION "1.3.1"
  42#define DRIVER_DESC "Moschip 7840/7820 USB Serial Driver"
  43
  44/*
  45 * 16C50 UART register defines
  46 */
  47
  48#define LCR_BITS_5             0x00     /* 5 bits/char */
  49#define LCR_BITS_6             0x01     /* 6 bits/char */
  50#define LCR_BITS_7             0x02     /* 7 bits/char */
  51#define LCR_BITS_8             0x03     /* 8 bits/char */
  52#define LCR_BITS_MASK          0x03     /* Mask for bits/char field */
  53
  54#define LCR_STOP_1             0x00     /* 1 stop bit */
  55#define LCR_STOP_1_5           0x04     /* 1.5 stop bits (if 5   bits/char) */
  56#define LCR_STOP_2             0x04     /* 2 stop bits   (if 6-8 bits/char) */
  57#define LCR_STOP_MASK          0x04     /* Mask for stop bits field */
  58
  59#define LCR_PAR_NONE           0x00     /* No parity */
  60#define LCR_PAR_ODD            0x08     /* Odd parity */
  61#define LCR_PAR_EVEN           0x18     /* Even parity */
  62#define LCR_PAR_MARK           0x28     /* Force parity bit to 1 */
  63#define LCR_PAR_SPACE          0x38     /* Force parity bit to 0 */
  64#define LCR_PAR_MASK           0x38     /* Mask for parity field */
  65
  66#define LCR_SET_BREAK          0x40     /* Set Break condition */
  67#define LCR_DL_ENABLE          0x80     /* Enable access to divisor latch */
  68
  69#define MCR_DTR                0x01     /* Assert DTR */
  70#define MCR_RTS                0x02     /* Assert RTS */
  71#define MCR_OUT1               0x04     /* Loopback only: Sets state of RI */
  72#define MCR_MASTER_IE          0x08     /* Enable interrupt outputs */
  73#define MCR_LOOPBACK           0x10     /* Set internal (digital) loopback mode */
  74#define MCR_XON_ANY            0x20     /* Enable any char to exit XOFF mode */
  75
  76#define MOS7840_MSR_CTS        0x10     /* Current state of CTS */
  77#define MOS7840_MSR_DSR        0x20     /* Current state of DSR */
  78#define MOS7840_MSR_RI         0x40     /* Current state of RI */
  79#define MOS7840_MSR_CD         0x80     /* Current state of CD */
  80
  81/*
  82 * Defines used for sending commands to port
  83 */
  84
  85#define WAIT_FOR_EVER   (HZ * 0 )       /* timeout urb is wait for ever */
  86#define MOS_WDR_TIMEOUT (HZ * 5 )       /* default urb timeout */
  87
  88#define MOS_PORT1       0x0200
  89#define MOS_PORT2       0x0300
  90#define MOS_VENREG      0x0000
  91#define MOS_MAX_PORT    0x02
  92#define MOS_WRITE       0x0E
  93#define MOS_READ        0x0D
  94
  95/* Requests */
  96#define MCS_RD_RTYPE    0xC0
  97#define MCS_WR_RTYPE    0x40
  98#define MCS_RDREQ       0x0D
  99#define MCS_WRREQ       0x0E
 100#define MCS_CTRL_TIMEOUT        500
 101#define VENDOR_READ_LENGTH      (0x01)
 102
 103#define MAX_NAME_LEN    64
 104
 105#define ZLP_REG1  0x3A          //Zero_Flag_Reg1    58
 106#define ZLP_REG5  0x3E          //Zero_Flag_Reg5    62
 107
 108/* For higher baud Rates use TIOCEXBAUD */
 109#define TIOCEXBAUD     0x5462
 110
 111/* vendor id and device id defines */
 112
 113#define USB_VENDOR_ID_MOSCHIP           0x9710
 114#define MOSCHIP_DEVICE_ID_7840          0x7840
 115#define MOSCHIP_DEVICE_ID_7820          0x7820
 116
 117/* Interrupt Rotinue Defines    */
 118
 119#define SERIAL_IIR_RLS      0x06
 120#define SERIAL_IIR_MS       0x00
 121
 122/*
 123 *  Emulation of the bit mask on the LINE STATUS REGISTER.
 124 */
 125#define SERIAL_LSR_DR       0x0001
 126#define SERIAL_LSR_OE       0x0002
 127#define SERIAL_LSR_PE       0x0004
 128#define SERIAL_LSR_FE       0x0008
 129#define SERIAL_LSR_BI       0x0010
 130
 131#define MOS_MSR_DELTA_CTS   0x10
 132#define MOS_MSR_DELTA_DSR   0x20
 133#define MOS_MSR_DELTA_RI    0x40
 134#define MOS_MSR_DELTA_CD    0x80
 135
 136// Serial Port register Address
 137#define INTERRUPT_ENABLE_REGISTER  ((__u16)(0x01))
 138#define FIFO_CONTROL_REGISTER      ((__u16)(0x02))
 139#define LINE_CONTROL_REGISTER      ((__u16)(0x03))
 140#define MODEM_CONTROL_REGISTER     ((__u16)(0x04))
 141#define LINE_STATUS_REGISTER       ((__u16)(0x05))
 142#define MODEM_STATUS_REGISTER      ((__u16)(0x06))
 143#define SCRATCH_PAD_REGISTER       ((__u16)(0x07))
 144#define DIVISOR_LATCH_LSB          ((__u16)(0x00))
 145#define DIVISOR_LATCH_MSB          ((__u16)(0x01))
 146
 147#define CLK_MULTI_REGISTER         ((__u16)(0x02))
 148#define CLK_START_VALUE_REGISTER   ((__u16)(0x03))
 149
 150#define SERIAL_LCR_DLAB            ((__u16)(0x0080))
 151
 152/*
 153 * URB POOL related defines
 154 */
 155#define NUM_URBS                        16      /* URB Count */
 156#define URB_TRANSFER_BUFFER_SIZE        32      /* URB Size  */
 157
 158
 159static struct usb_device_id moschip_port_id_table[] = {
 160        {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
 161        {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
 162        {}                      /* terminating entry */
 163};
 164
 165static __devinitdata struct usb_device_id moschip_id_table_combined[] = {
 166        {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
 167        {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
 168        {}                      /* terminating entry */
 169};
 170
 171MODULE_DEVICE_TABLE(usb, moschip_id_table_combined);
 172
 173/* This structure holds all of the local port information */
 174
 175struct moschip_port {
 176        int port_num;           /*Actual port number in the device(1,2,etc) */
 177        struct urb *write_urb;  /* write URB for this port */
 178        struct urb *read_urb;   /* read URB for this port */
 179        struct urb *int_urb;
 180        __u8 shadowLCR;         /* last LCR value received */
 181        __u8 shadowMCR;         /* last MCR value received */
 182        char open;
 183        char open_ports;
 184        char zombie;
 185        wait_queue_head_t wait_chase;   /* for handling sleeping while waiting for chase to finish */
 186        wait_queue_head_t delta_msr_wait;       /* for handling sleeping while waiting for msr change to happen */
 187        int delta_msr_cond;
 188        struct async_icount icount;
 189        struct usb_serial_port *port;   /* loop back to the owner of this object */
 190
 191        /*Offsets */
 192        __u8 SpRegOffset;
 193        __u8 ControlRegOffset;
 194        __u8 DcrRegOffset;
 195        //for processing control URBS in interrupt context
 196        struct urb *control_urb;
 197        struct usb_ctrlrequest *dr;
 198        char *ctrl_buf;
 199        int MsrLsr;
 200
 201        spinlock_t pool_lock;
 202        struct urb *write_urb_pool[NUM_URBS];
 203        char busy[NUM_URBS];
 204};
 205
 206
 207static int debug;
 208
 209/*
 210 * mos7840_set_reg_sync
 211 *      To set the Control register by calling usb_fill_control_urb function
 212 *      by passing usb_sndctrlpipe function as parameter.
 213 */
 214
 215static int mos7840_set_reg_sync(struct usb_serial_port *port, __u16 reg,
 216                                __u16 val)
 217{
 218        struct usb_device *dev = port->serial->dev;
 219        val = val & 0x00ff;
 220        dbg("mos7840_set_reg_sync offset is %x, value %x\n", reg, val);
 221
 222        return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MCS_WRREQ,
 223                               MCS_WR_RTYPE, val, reg, NULL, 0,
 224                               MOS_WDR_TIMEOUT);
 225}
 226
 227/*
 228 * mos7840_get_reg_sync
 229 *      To set the Uart register by calling usb_fill_control_urb function by
 230 *      passing usb_rcvctrlpipe function as parameter.
 231 */
 232
 233static int mos7840_get_reg_sync(struct usb_serial_port *port, __u16 reg,
 234                                __u16 * val)
 235{
 236        struct usb_device *dev = port->serial->dev;
 237        int ret = 0;
 238
 239        ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
 240                              MCS_RD_RTYPE, 0, reg, val, VENDOR_READ_LENGTH,
 241                              MOS_WDR_TIMEOUT);
 242        dbg("mos7840_get_reg_sync offset is %x, return val %x\n", reg, *val);
 243        *val = (*val) & 0x00ff;
 244        return ret;
 245}
 246
 247/*
 248 * mos7840_set_uart_reg
 249 *      To set the Uart register by calling usb_fill_control_urb function by
 250 *      passing usb_sndctrlpipe function as parameter.
 251 */
 252
 253static int mos7840_set_uart_reg(struct usb_serial_port *port, __u16 reg,
 254                                __u16 val)
 255{
 256
 257        struct usb_device *dev = port->serial->dev;
 258        val = val & 0x00ff;
 259        // For the UART control registers, the application number need to be Or'ed
 260        if (port->serial->num_ports == 4) {
 261                val |=
 262                    (((__u16) port->number - (__u16) (port->serial->minor)) +
 263                     1) << 8;
 264                dbg("mos7840_set_uart_reg application number is %x\n", val);
 265        } else {
 266                if (((__u16) port->number - (__u16) (port->serial->minor)) == 0) {
 267                        val |=
 268                            (((__u16) port->number -
 269                              (__u16) (port->serial->minor)) + 1) << 8;
 270                        dbg("mos7840_set_uart_reg application number is %x\n",
 271                            val);
 272                } else {
 273                        val |=
 274                            (((__u16) port->number -
 275                              (__u16) (port->serial->minor)) + 2) << 8;
 276                        dbg("mos7840_set_uart_reg application number is %x\n",
 277                            val);
 278                }
 279        }
 280        return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MCS_WRREQ,
 281                               MCS_WR_RTYPE, val, reg, NULL, 0,
 282                               MOS_WDR_TIMEOUT);
 283
 284}
 285
 286/*
 287 * mos7840_get_uart_reg
 288 *      To set the Control register by calling usb_fill_control_urb function
 289 *      by passing usb_rcvctrlpipe function as parameter.
 290 */
 291static int mos7840_get_uart_reg(struct usb_serial_port *port, __u16 reg,
 292                                __u16 * val)
 293{
 294        struct usb_device *dev = port->serial->dev;
 295        int ret = 0;
 296        __u16 Wval;
 297
 298        //dbg("application number is %4x \n",(((__u16)port->number - (__u16)(port->serial->minor))+1)<<8);
 299        /*Wval  is same as application number */
 300        if (port->serial->num_ports == 4) {
 301                Wval =
 302                    (((__u16) port->number - (__u16) (port->serial->minor)) +
 303                     1) << 8;
 304                dbg("mos7840_get_uart_reg application number is %x\n", Wval);
 305        } else {
 306                if (((__u16) port->number - (__u16) (port->serial->minor)) == 0) {
 307                        Wval =
 308                            (((__u16) port->number -
 309                              (__u16) (port->serial->minor)) + 1) << 8;
 310                        dbg("mos7840_get_uart_reg application number is %x\n",
 311                            Wval);
 312                } else {
 313                        Wval =
 314                            (((__u16) port->number -
 315                              (__u16) (port->serial->minor)) + 2) << 8;
 316                        dbg("mos7840_get_uart_reg application number is %x\n",
 317                            Wval);
 318                }
 319        }
 320        ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
 321                              MCS_RD_RTYPE, Wval, reg, val, VENDOR_READ_LENGTH,
 322                              MOS_WDR_TIMEOUT);
 323        *val = (*val) & 0x00ff;
 324        return ret;
 325}
 326
 327static void mos7840_dump_serial_port(struct moschip_port *mos7840_port)
 328{
 329
 330        dbg("***************************************\n");
 331        dbg("SpRegOffset is %2x\n", mos7840_port->SpRegOffset);
 332        dbg("ControlRegOffset is %2x \n", mos7840_port->ControlRegOffset);
 333        dbg("DCRRegOffset is %2x \n", mos7840_port->DcrRegOffset);
 334        dbg("***************************************\n");
 335
 336}
 337
 338/************************************************************************/
 339/************************************************************************/
 340/*             I N T E R F A C E   F U N C T I O N S                    */
 341/*             I N T E R F A C E   F U N C T I O N S                    */
 342/************************************************************************/
 343/************************************************************************/
 344
 345static inline void mos7840_set_port_private(struct usb_serial_port *port,
 346                                            struct moschip_port *data)
 347{
 348        usb_set_serial_port_data(port, (void *)data);
 349}
 350
 351static inline struct moschip_port *mos7840_get_port_private(struct
 352                                                            usb_serial_port
 353                                                            *port)
 354{
 355        return (struct moschip_port *)usb_get_serial_port_data(port);
 356}
 357
 358static void mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr)
 359{
 360        struct moschip_port *mos7840_port;
 361        struct async_icount *icount;
 362        mos7840_port = port;
 363        icount = &mos7840_port->icount;
 364        if (new_msr &
 365            (MOS_MSR_DELTA_CTS | MOS_MSR_DELTA_DSR | MOS_MSR_DELTA_RI |
 366             MOS_MSR_DELTA_CD)) {
 367                icount = &mos7840_port->icount;
 368
 369                /* update input line counters */
 370                if (new_msr & MOS_MSR_DELTA_CTS) {
 371                        icount->cts++;
 372                        smp_wmb();
 373                }
 374                if (new_msr & MOS_MSR_DELTA_DSR) {
 375                        icount->dsr++;
 376                        smp_wmb();
 377                }
 378                if (new_msr & MOS_MSR_DELTA_CD) {
 379                        icount->dcd++;
 380                        smp_wmb();
 381                }
 382                if (new_msr & MOS_MSR_DELTA_RI) {
 383                        icount->rng++;
 384                        smp_wmb();
 385                }
 386        }
 387}
 388
 389static void mos7840_handle_new_lsr(struct moschip_port *port, __u8 new_lsr)
 390{
 391        struct async_icount *icount;
 392
 393        dbg("%s - %02x", __FUNCTION__, new_lsr);
 394
 395        if (new_lsr & SERIAL_LSR_BI) {
 396                //
 397                // Parity and Framing errors only count if they
 398                // occur exclusive of a break being
 399                // received.
 400                //
 401                new_lsr &= (__u8) (SERIAL_LSR_OE | SERIAL_LSR_BI);
 402        }
 403
 404        /* update input line counters */
 405        icount = &port->icount;
 406        if (new_lsr & SERIAL_LSR_BI) {
 407                icount->brk++;
 408                smp_wmb();
 409        }
 410        if (new_lsr & SERIAL_LSR_OE) {
 411                icount->overrun++;
 412                smp_wmb();
 413        }
 414        if (new_lsr & SERIAL_LSR_PE) {
 415                icount->parity++;
 416                smp_wmb();
 417        }
 418        if (new_lsr & SERIAL_LSR_FE) {
 419                icount->frame++;
 420                smp_wmb();
 421        }
 422}
 423
 424/************************************************************************/
 425/************************************************************************/
 426/*            U S B  C A L L B A C K   F U N C T I O N S                */
 427/*            U S B  C A L L B A C K   F U N C T I O N S                */
 428/************************************************************************/
 429/************************************************************************/
 430
 431static void mos7840_control_callback(struct urb *urb)
 432{
 433        unsigned char *data;
 434        struct moschip_port *mos7840_port;
 435        __u8 regval = 0x0;
 436        int result = 0;
 437        int status = urb->status;
 438
 439        mos7840_port = (struct moschip_port *)urb->context;
 440
 441        switch (status) {
 442        case 0:
 443                /* success */
 444                break;
 445        case -ECONNRESET:
 446        case -ENOENT:
 447        case -ESHUTDOWN:
 448                /* this urb is terminated, clean up */
 449                dbg("%s - urb shutting down with status: %d", __FUNCTION__,
 450                    status);
 451                return;
 452        default:
 453                dbg("%s - nonzero urb status received: %d", __FUNCTION__,
 454                    status);
 455                goto exit;
 456        }
 457
 458        dbg("%s urb buffer size is %d\n", __FUNCTION__, urb->actual_length);
 459        dbg("%s mos7840_port->MsrLsr is %d port %d\n", __FUNCTION__,
 460            mos7840_port->MsrLsr, mos7840_port->port_num);
 461        data = urb->transfer_buffer;
 462        regval = (__u8) data[0];
 463        dbg("%s data is %x\n", __FUNCTION__, regval);
 464        if (mos7840_port->MsrLsr == 0)
 465                mos7840_handle_new_msr(mos7840_port, regval);
 466        else if (mos7840_port->MsrLsr == 1)
 467                mos7840_handle_new_lsr(mos7840_port, regval);
 468
 469exit:
 470        spin_lock(&mos7840_port->pool_lock);
 471        if (!mos7840_port->zombie)
 472                result = usb_submit_urb(mos7840_port->int_urb, GFP_ATOMIC);
 473        spin_unlock(&mos7840_port->pool_lock);
 474        if (result) {
 475                dev_err(&urb->dev->dev,
 476                        "%s - Error %d submitting interrupt urb\n",
 477                        __FUNCTION__, result);
 478        }
 479}
 480
 481static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg,
 482                           __u16 * val)
 483{
 484        struct usb_device *dev = mcs->port->serial->dev;
 485        struct usb_ctrlrequest *dr = mcs->dr;
 486        unsigned char *buffer = mcs->ctrl_buf;
 487        int ret;
 488
 489        dr->bRequestType = MCS_RD_RTYPE;
 490        dr->bRequest = MCS_RDREQ;
 491        dr->wValue = cpu_to_le16(Wval); //0;
 492        dr->wIndex = cpu_to_le16(reg);
 493        dr->wLength = cpu_to_le16(2);
 494
 495        usb_fill_control_urb(mcs->control_urb, dev, usb_rcvctrlpipe(dev, 0),
 496                             (unsigned char *)dr, buffer, 2,
 497                             mos7840_control_callback, mcs);
 498        mcs->control_urb->transfer_buffer_length = 2;
 499        ret = usb_submit_urb(mcs->control_urb, GFP_ATOMIC);
 500        return ret;
 501}
 502
 503/*****************************************************************************
 504 * mos7840_interrupt_callback
 505 *      this is the callback function for when we have received data on the
 506 *      interrupt endpoint.
 507 *****************************************************************************/
 508
 509static void mos7840_interrupt_callback(struct urb *urb)
 510{
 511        int result;
 512        int length;
 513        struct moschip_port *mos7840_port;
 514        struct usb_serial *serial;
 515        __u16 Data;
 516        unsigned char *data;
 517        __u8 sp[5], st;
 518        int i, rv = 0;
 519        __u16 wval, wreg = 0;
 520        int status = urb->status;
 521
 522        dbg("%s", " : Entering\n");
 523
 524        switch (status) {
 525        case 0:
 526                /* success */
 527                break;
 528        case -ECONNRESET:
 529        case -ENOENT:
 530        case -ESHUTDOWN:
 531                /* this urb is terminated, clean up */
 532                dbg("%s - urb shutting down with status: %d", __FUNCTION__,
 533                    status);
 534                return;
 535        default:
 536                dbg("%s - nonzero urb status received: %d", __FUNCTION__,
 537                    status);
 538                goto exit;
 539        }
 540
 541        length = urb->actual_length;
 542        data = urb->transfer_buffer;
 543
 544        serial = (struct usb_serial *)urb->context;
 545
 546        /* Moschip get 5 bytes
 547         * Byte 1 IIR Port 1 (port.number is 0)
 548         * Byte 2 IIR Port 2 (port.number is 1)
 549         * Byte 3 IIR Port 3 (port.number is 2)
 550         * Byte 4 IIR Port 4 (port.number is 3)
 551         * Byte 5 FIFO status for both */
 552
 553        if (length && length > 5) {
 554                dbg("%s \n", "Wrong data !!!");
 555                return;
 556        }
 557
 558        sp[0] = (__u8) data[0];
 559        sp[1] = (__u8) data[1];
 560        sp[2] = (__u8) data[2];
 561        sp[3] = (__u8) data[3];
 562        st = (__u8) data[4];
 563
 564        for (i = 0; i < serial->num_ports; i++) {
 565                mos7840_port = mos7840_get_port_private(serial->port[i]);
 566                wval =
 567                    (((__u16) serial->port[i]->number -
 568                      (__u16) (serial->minor)) + 1) << 8;
 569                if (mos7840_port->open) {
 570                        if (sp[i] & 0x01) {
 571                                dbg("SP%d No Interrupt !!!\n", i);
 572                        } else {
 573                                switch (sp[i] & 0x0f) {
 574                                case SERIAL_IIR_RLS:
 575                                        dbg("Serial Port %d: Receiver status error or ", i);
 576                                        dbg("address bit detected in 9-bit mode\n");
 577                                        mos7840_port->MsrLsr = 1;
 578                                        wreg = LINE_STATUS_REGISTER;
 579                                        break;
 580                                case SERIAL_IIR_MS:
 581                                        dbg("Serial Port %d: Modem status change\n", i);
 582                                        mos7840_port->MsrLsr = 0;
 583                                        wreg = MODEM_STATUS_REGISTER;
 584                                        break;
 585                                }
 586                                spin_lock(&mos7840_port->pool_lock);
 587                                if (!mos7840_port->zombie) {
 588                                        rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data);
 589                                } else {
 590                                        spin_unlock(&mos7840_port->pool_lock);
 591                                        return;
 592                                }
 593                                spin_unlock(&mos7840_port->pool_lock);
 594                        }
 595                }
 596        }
 597        if (!(rv < 0)) /* the completion handler for the control urb will resubmit */
 598                return;
 599exit:
 600        result = usb_submit_urb(urb, GFP_ATOMIC);
 601        if (result) {
 602                dev_err(&urb->dev->dev,
 603                        "%s - Error %d submitting interrupt urb\n",
 604                        __FUNCTION__, result);
 605        }
 606}
 607
 608static int mos7840_port_paranoia_check(struct usb_serial_port *port,
 609                                       const char *function)
 610{
 611        if (!port) {
 612                dbg("%s - port == NULL", function);
 613                return -1;
 614        }
 615        if (!port->serial) {
 616                dbg("%s - port->serial == NULL", function);
 617                return -1;
 618        }
 619
 620        return 0;
 621}
 622
 623/* Inline functions to check the sanity of a pointer that is passed to us */
 624static int mos7840_serial_paranoia_check(struct usb_serial *serial,
 625                                         const char *function)
 626{
 627        if (!serial) {
 628                dbg("%s - serial == NULL", function);
 629                return -1;
 630        }
 631        if (!serial->type) {
 632                dbg("%s - serial->type == NULL!", function);
 633                return -1;
 634        }
 635
 636        return 0;
 637}
 638
 639static struct usb_serial *mos7840_get_usb_serial(struct usb_serial_port *port,
 640                                                 const char *function)
 641{
 642        /* if no port was specified, or it fails a paranoia check */
 643        if (!port ||
 644            mos7840_port_paranoia_check(port, function) ||
 645            mos7840_serial_paranoia_check(port->serial, function)) {
 646                /* then say that we don't have a valid usb_serial thing, which will
 647                 * end up genrating -ENODEV return values */
 648                return NULL;
 649        }
 650
 651        return port->serial;
 652}
 653
 654/*****************************************************************************
 655 * mos7840_bulk_in_callback
 656 *      this is the callback function for when we have received data on the
 657 *      bulk in endpoint.
 658 *****************************************************************************/
 659
 660static void mos7840_bulk_in_callback(struct urb *urb)
 661{
 662        int retval;
 663        unsigned char *data;
 664        struct usb_serial *serial;
 665        struct usb_serial_port *port;
 666        struct moschip_port *mos7840_port;
 667        struct tty_struct *tty;
 668        int status = urb->status;
 669
 670        if (status) {
 671                dbg("nonzero read bulk status received: %d", status);
 672                return;
 673        }
 674
 675        mos7840_port = (struct moschip_port *)urb->context;
 676        if (!mos7840_port) {
 677                dbg("%s", "NULL mos7840_port pointer \n");
 678                return;
 679        }
 680
 681        port = (struct usb_serial_port *)mos7840_port->port;
 682        if (mos7840_port_paranoia_check(port, __FUNCTION__)) {
 683                dbg("%s", "Port Paranoia failed \n");
 684                return;
 685        }
 686
 687        serial = mos7840_get_usb_serial(port, __FUNCTION__);
 688        if (!serial) {
 689                dbg("%s\n", "Bad serial pointer ");
 690                return;
 691        }
 692
 693        dbg("%s\n", "Entering... \n");
 694
 695        data = urb->transfer_buffer;
 696
 697        dbg("%s", "Entering ........... \n");
 698
 699        if (urb->actual_length) {
 700                tty = mos7840_port->port->tty;
 701                if (tty) {
 702                        tty_buffer_request_room(tty, urb->actual_length);
 703                        tty_insert_flip_string(tty, data, urb->actual_length);
 704                        dbg(" %s \n", data);
 705                        tty_flip_buffer_push(tty);
 706                }
 707                mos7840_port->icount.rx += urb->actual_length;
 708                smp_wmb();
 709                dbg("mos7840_port->icount.rx is %d:\n",
 710                    mos7840_port->icount.rx);
 711        }
 712
 713        if (!mos7840_port->read_urb) {
 714                dbg("%s", "URB KILLED !!!\n");
 715                return;
 716        }
 717
 718
 719        mos7840_port->read_urb->dev = serial->dev;
 720
 721        retval = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);
 722
 723        if (retval) {
 724                dbg(" usb_submit_urb(read bulk) failed, retval = %d",
 725                 retval);
 726        }
 727}
 728
 729/*****************************************************************************
 730 * mos7840_bulk_out_data_callback
 731 *      this is the callback function for when we have finished sending serial data
 732 *      on the bulk out endpoint.
 733 *****************************************************************************/
 734
 735static void mos7840_bulk_out_data_callback(struct urb *urb)
 736{
 737        struct moschip_port *mos7840_port;
 738        struct tty_struct *tty;
 739        int status = urb->status;
 740        int i;
 741
 742        mos7840_port = (struct moschip_port *)urb->context;
 743        spin_lock(&mos7840_port->pool_lock);
 744        for (i = 0; i < NUM_URBS; i++) {
 745                if (urb == mos7840_port->write_urb_pool[i]) {
 746                        mos7840_port->busy[i] = 0;
 747                        break;
 748                }
 749        }
 750        spin_unlock(&mos7840_port->pool_lock);
 751
 752        if (status) {
 753                dbg("nonzero write bulk status received:%d\n", status);
 754                return;
 755        }
 756
 757        if (mos7840_port_paranoia_check(mos7840_port->port, __FUNCTION__)) {
 758                dbg("%s", "Port Paranoia failed \n");
 759                return;
 760        }
 761
 762        dbg("%s \n", "Entering .........");
 763
 764        tty = mos7840_port->port->tty;
 765
 766        if (tty && mos7840_port->open)
 767                tty_wakeup(tty);
 768
 769}
 770
 771/************************************************************************/
 772/*       D R I V E R  T T Y  I N T E R F A C E  F U N C T I O N S       */
 773/************************************************************************/
 774#ifdef MCSSerialProbe
 775static int mos7840_serial_probe(struct usb_serial *serial,
 776                                const struct usb_device_id *id)
 777{
 778
 779        /*need to implement the mode_reg reading and updating\
 780           structures usb_serial_ device_type\
 781           (i.e num_ports, num_bulkin,bulkout etc) */
 782        /* Also we can update the changes  attach */
 783        return 1;
 784}
 785#endif
 786
 787/*****************************************************************************
 788 * mos7840_open
 789 *      this function is called by the tty driver when a port is opened
 790 *      If successful, we return 0
 791 *      Otherwise we return a negative error number.
 792 *****************************************************************************/
 793
 794static int mos7840_open(struct usb_serial_port *port, struct file *filp)
 795{
 796        int response;
 797        int j;
 798        struct usb_serial *serial;
 799        struct urb *urb;
 800        __u16 Data;
 801        int status;
 802        struct moschip_port *mos7840_port;
 803        struct moschip_port *port0;
 804
 805        if (mos7840_port_paranoia_check(port, __FUNCTION__)) {
 806                dbg("%s", "Port Paranoia failed \n");
 807                return -ENODEV;
 808        }
 809
 810        serial = port->serial;
 811
 812        if (mos7840_serial_paranoia_check(serial, __FUNCTION__)) {
 813                dbg("%s", "Serial Paranoia failed \n");
 814                return -ENODEV;
 815        }
 816
 817        mos7840_port = mos7840_get_port_private(port);
 818        port0 = mos7840_get_port_private(serial->port[0]);
 819
 820        if (mos7840_port == NULL || port0 == NULL)
 821                return -ENODEV;
 822
 823        usb_clear_halt(serial->dev, port->write_urb->pipe);
 824        usb_clear_halt(serial->dev, port->read_urb->pipe);
 825        port0->open_ports++;
 826
 827        /* Initialising the write urb pool */
 828        for (j = 0; j < NUM_URBS; ++j) {
 829                urb = usb_alloc_urb(0, GFP_KERNEL);
 830                mos7840_port->write_urb_pool[j] = urb;
 831
 832                if (urb == NULL) {
 833                        err("No more urbs???");
 834                        continue;
 835                }
 836
 837                urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
 838                if (!urb->transfer_buffer) {
 839                        usb_free_urb(urb);
 840                        mos7840_port->write_urb_pool[j] = NULL;
 841                        err("%s-out of memory for urb buffers.", __FUNCTION__);
 842                        continue;
 843                }
 844        }
 845
 846/*****************************************************************************
 847 * Initialize MCS7840 -- Write Init values to corresponding Registers
 848 *
 849 * Register Index
 850 * 1 : IER
 851 * 2 : FCR
 852 * 3 : LCR
 853 * 4 : MCR
 854 *
 855 * 0x08 : SP1/2 Control Reg
 856 *****************************************************************************/
 857
 858//NEED to check the following Block
 859
 860        status = 0;
 861        Data = 0x0;
 862        status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, &Data);
 863        if (status < 0) {
 864                dbg("Reading Spreg failed\n");
 865                return -1;
 866        }
 867        Data |= 0x80;
 868        status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);
 869        if (status < 0) {
 870                dbg("writing Spreg failed\n");
 871                return -1;
 872        }
 873
 874        Data &= ~0x80;
 875        status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);
 876        if (status < 0) {
 877                dbg("writing Spreg failed\n");
 878                return -1;
 879        }
 880//End of block to be checked
 881
 882        status = 0;
 883        Data = 0x0;
 884        status =
 885            mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset, &Data);
 886        if (status < 0) {
 887                dbg("Reading Controlreg failed\n");
 888                return -1;
 889        }
 890        Data |= 0x08;           //Driver done bit
 891        Data |= 0x20;           //rx_disable
 892        status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, Data);
 893        if (status < 0) {
 894                dbg("writing Controlreg failed\n");
 895                return -1;
 896        }
 897        //do register settings here
 898        // Set all regs to the device default values.
 899        ////////////////////////////////////
 900        // First Disable all interrupts.
 901        ////////////////////////////////////
 902
 903        Data = 0x00;
 904        status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
 905        if (status < 0) {
 906                dbg("disableing interrupts failed\n");
 907                return -1;
 908        }
 909        // Set FIFO_CONTROL_REGISTER to the default value
 910        Data = 0x00;
 911        status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
 912        if (status < 0) {
 913                dbg("Writing FIFO_CONTROL_REGISTER  failed\n");
 914                return -1;
 915        }
 916
 917        Data = 0xcf;
 918        status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
 919        if (status < 0) {
 920                dbg("Writing FIFO_CONTROL_REGISTER  failed\n");
 921                return -1;
 922        }
 923
 924        Data = 0x03;
 925        status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
 926        mos7840_port->shadowLCR = Data;
 927
 928        Data = 0x0b;
 929        status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
 930        mos7840_port->shadowMCR = Data;
 931
 932        Data = 0x00;
 933        status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);
 934        mos7840_port->shadowLCR = Data;
 935
 936        Data |= SERIAL_LCR_DLAB;        //data latch enable in LCR 0x80
 937        status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
 938
 939        Data = 0x0c;
 940        status = 0;
 941        status = mos7840_set_uart_reg(port, DIVISOR_LATCH_LSB, Data);
 942
 943        Data = 0x0;
 944        status = 0;
 945        status = mos7840_set_uart_reg(port, DIVISOR_LATCH_MSB, Data);
 946
 947        Data = 0x00;
 948        status = 0;
 949        status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);
 950
 951        Data = Data & ~SERIAL_LCR_DLAB;
 952        status = 0;
 953        status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
 954        mos7840_port->shadowLCR = Data;
 955
 956        //clearing Bulkin and Bulkout Fifo
 957        Data = 0x0;
 958        status = 0;
 959        status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, &Data);
 960
 961        Data = Data | 0x0c;
 962        status = 0;
 963        status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);
 964
 965        Data = Data & ~0x0c;
 966        status = 0;
 967        status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);
 968        //Finally enable all interrupts
 969        Data = 0x0;
 970        Data = 0x0c;
 971        status = 0;
 972        status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
 973
 974        //clearing rx_disable
 975        Data = 0x0;
 976        status = 0;
 977        status =
 978            mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset, &Data);
 979        Data = Data & ~0x20;
 980        status = 0;
 981        status =
 982            mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, Data);
 983
 984        // rx_negate
 985        Data = 0x0;
 986        status = 0;
 987        status =
 988            mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset, &Data);
 989        Data = Data | 0x10;
 990        status = 0;
 991        status =
 992            mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, Data);
 993
 994        /* force low_latency on so that our tty_push actually forces *
 995         * the data through,otherwise it is scheduled, and with      *
 996         * high data rates (like with OHCI) data can get lost.       */
 997
 998        if (port->tty)
 999                port->tty->low_latency = 1;
1000/* Check to see if we've set up our endpoint info yet    *
1001     * (can't set it up in mos7840_startup as the structures *
1002     * were not set up at that time.)                        */
1003        if (port0->open_ports == 1) {
1004                if (serial->port[0]->interrupt_in_buffer == NULL) {
1005
1006                        /* set up interrupt urb */
1007
1008                        usb_fill_int_urb(serial->port[0]->interrupt_in_urb,
1009                                         serial->dev,
1010                                         usb_rcvintpipe(serial->dev,
1011                                                        serial->port[0]->
1012                                                        interrupt_in_endpointAddress),
1013                                         serial->port[0]->interrupt_in_buffer,
1014                                         serial->port[0]->interrupt_in_urb->
1015                                         transfer_buffer_length,
1016                                         mos7840_interrupt_callback,
1017                                         serial,
1018                                         serial->port[0]->interrupt_in_urb->
1019                                         interval);
1020
1021                        /* start interrupt read for mos7840               *
1022                         * will continue as long as mos7840 is connected  */
1023
1024                        response =
1025                            usb_submit_urb(serial->port[0]->interrupt_in_urb,
1026                                           GFP_KERNEL);
1027                        if (response) {
1028                                err("%s - Error %d submitting interrupt urb",
1029                                    __FUNCTION__, response);
1030                        }
1031
1032                }
1033
1034        }
1035
1036        /* see if we've set up our endpoint info yet   *
1037         * (can't set it up in mos7840_startup as the  *
1038         * structures were not set up at that time.)   */
1039
1040        dbg("port number is %d \n", port->number);
1041        dbg("serial number is %d \n", port->serial->minor);
1042        dbg("Bulkin endpoint is %d \n", port->bulk_in_endpointAddress);
1043        dbg("BulkOut endpoint is %d \n", port->bulk_out_endpointAddress);
1044        dbg("Interrupt endpoint is %d \n", port->interrupt_in_endpointAddress);
1045        dbg("port's number in the device is %d\n", mos7840_port->port_num);
1046        mos7840_port->read_urb = port->read_urb;
1047
1048        /* set up our bulk in urb */
1049
1050        usb_fill_bulk_urb(mos7840_port->read_urb,
1051                          serial->dev,
1052                          usb_rcvbulkpipe(serial->dev,
1053                                          port->bulk_in_endpointAddress),
1054                          port->bulk_in_buffer,
1055                          mos7840_port->read_urb->transfer_buffer_length,
1056                          mos7840_bulk_in_callback, mos7840_port);
1057
1058        dbg("mos7840_open: bulkin endpoint is %d\n",
1059            port->bulk_in_endpointAddress);
1060        response = usb_submit_urb(mos7840_port->read_urb, GFP_KERNEL);
1061        if (response) {
1062                err("%s - Error %d submitting control urb", __FUNCTION__,
1063                    response);
1064        }
1065
1066        /* initialize our wait queues */
1067        init_waitqueue_head(&mos7840_port->wait_chase);
1068        init_waitqueue_head(&mos7840_port->delta_msr_wait);
1069
1070        /* initialize our icount structure */
1071        memset(&(mos7840_port->icount), 0x00, sizeof(mos7840_port->icount));
1072
1073        /* initialize our port settings */
1074        mos7840_port->shadowMCR = MCR_MASTER_IE;        /* Must set to enable ints! */
1075        /* send a open port command */
1076        mos7840_port->open = 1;
1077        //mos7840_change_port_settings(mos7840_port,old_termios);
1078        mos7840_port->icount.tx = 0;
1079        mos7840_port->icount.rx = 0;
1080
1081        dbg("\n\nusb_serial serial:%p       mos7840_port:%p\n      usb_serial_port port:%p\n\n", serial, mos7840_port, port);
1082
1083        return 0;
1084
1085}
1086
1087/*****************************************************************************
1088 * mos7840_chars_in_buffer
1089 *      this function is called by the tty driver when it wants to know how many
1090 *      bytes of data we currently have outstanding in the port (data that has
1091 *      been written, but hasn't made it out the port yet)
1092 *      If successful, we return the number of bytes left to be written in the
1093 *      system,
1094 *      Otherwise we return a negative error number.
1095 *****************************************************************************/
1096
1097static int mos7840_chars_in_buffer(struct usb_serial_port *port)
1098{
1099        int i;
1100        int chars = 0;
1101        unsigned long flags;
1102        struct moschip_port *mos7840_port;
1103
1104        dbg("%s \n", " mos7840_chars_in_buffer:entering ...........");
1105
1106        if (mos7840_port_paranoia_check(port, __FUNCTION__)) {
1107                dbg("%s", "Invalid port \n");
1108                return -1;
1109        }
1110
1111        mos7840_port = mos7840_get_port_private(port);
1112        if (mos7840_port == NULL) {
1113                dbg("%s \n", "mos7840_break:leaving ...........");
1114                return -1;
1115        }
1116
1117        spin_lock_irqsave(&mos7840_port->pool_lock,flags);
1118        for (i = 0; i < NUM_URBS; ++i) {
1119                if (mos7840_port->busy[i]) {
1120                        chars += URB_TRANSFER_BUFFER_SIZE;
1121                }
1122        }
1123        spin_unlock_irqrestore(&mos7840_port->pool_lock,flags);
1124        dbg("%s - returns %d", __FUNCTION__, chars);
1125        return chars;
1126
1127}
1128
1129/************************************************************************
1130 *
1131 * mos7840_block_until_tx_empty
1132 *
1133 *      This function will block the close until one of the following:
1134 *              1. TX count are 0
1135 *              2. The mos7840 has stopped
1136 *              3. A timout of 3 seconds without activity has expired
1137 *
1138 ************************************************************************/
1139static void mos7840_block_until_tx_empty(struct moschip_port *mos7840_port)
1140{
1141        int timeout = HZ / 10;
1142        int wait = 30;
1143        int count;
1144
1145        while (1) {
1146
1147                count = mos7840_chars_in_buffer(mos7840_port->port);
1148
1149                /* Check for Buffer status */
1150                if (count <= 0) {
1151                        return;
1152                }
1153
1154                /* Block the thread for a while */
1155                interruptible_sleep_on_timeout(&mos7840_port->wait_chase,
1156                                               timeout);
1157
1158                /* No activity.. count down section */
1159                wait--;
1160                if (wait == 0) {
1161                        dbg("%s - TIMEOUT", __FUNCTION__);
1162                        return;
1163                } else {
1164                        /* Reset timout value back to seconds */
1165                        wait = 30;
1166                }
1167        }
1168}
1169
1170/*****************************************************************************
1171 * mos7840_close
1172 *      this function is called by the tty driver when a port is closed
1173 *****************************************************************************/
1174
1175static void mos7840_close(struct usb_serial_port *port, struct file *filp)
1176{
1177        struct usb_serial *serial;
1178        struct moschip_port *mos7840_port;
1179        struct moschip_port *port0;
1180        int j;
1181        __u16 Data;
1182
1183        dbg("%s\n", "mos7840_close:entering...");
1184
1185        if (mos7840_port_paranoia_check(port, __FUNCTION__)) {
1186                dbg("%s", "Port Paranoia failed \n");
1187                return;
1188        }
1189
1190        serial = mos7840_get_usb_serial(port, __FUNCTION__);
1191        if (!serial) {
1192                dbg("%s", "Serial Paranoia failed \n");
1193                return;
1194        }
1195
1196        mos7840_port = mos7840_get_port_private(port);
1197        port0 = mos7840_get_port_private(serial->port[0]);
1198
1199        if (mos7840_port == NULL || port0 == NULL)
1200                return;
1201
1202        for (j = 0; j < NUM_URBS; ++j)
1203                usb_kill_urb(mos7840_port->write_urb_pool[j]);
1204
1205        /* Freeing Write URBs */
1206        for (j = 0; j < NUM_URBS; ++j) {
1207                if (mos7840_port->write_urb_pool[j]) {
1208                        if (mos7840_port->write_urb_pool[j]->transfer_buffer)
1209                                kfree(mos7840_port->write_urb_pool[j]->
1210                                      transfer_buffer);
1211
1212                        usb_free_urb(mos7840_port->write_urb_pool[j]);
1213                }
1214        }
1215
1216        if (serial->dev) {
1217                /* flush and block until tx is empty */
1218                mos7840_block_until_tx_empty(mos7840_port);
1219        }
1220
1221        /* While closing port, shutdown all bulk read, write  *
1222         * and interrupt read if they exists                  */
1223        if (serial->dev) {
1224
1225                if (mos7840_port->write_urb) {
1226                        dbg("%s", "Shutdown bulk write\n");
1227                        usb_kill_urb(mos7840_port->write_urb);
1228                }
1229
1230                if (mos7840_port->read_urb) {
1231                        dbg("%s", "Shutdown bulk read\n");
1232                        usb_kill_urb(mos7840_port->read_urb);
1233                }
1234                if ((&mos7840_port->control_urb)) {
1235                        dbg("%s", "Shutdown control read\n");
1236                        //      usb_kill_urb (mos7840_port->control_urb);
1237
1238                }
1239        }
1240//              if(mos7840_port->ctrl_buf != NULL)
1241//                      kfree(mos7840_port->ctrl_buf);
1242        port0->open_ports--;
1243        dbg("mos7840_num_open_ports in close%d:in port%d\n",
1244            port0->open_ports, port->number);
1245        if (port0->open_ports == 0) {
1246                if (serial->port[0]->interrupt_in_urb) {
1247                        dbg("%s", "Shutdown interrupt_in_urb\n");
1248                        usb_kill_urb(serial->port[0]->interrupt_in_urb);
1249                }
1250        }
1251
1252        if (mos7840_port->write_urb) {
1253                /* if this urb had a transfer buffer already (old tx) free it */
1254
1255                if (mos7840_port->write_urb->transfer_buffer != NULL) {
1256                        kfree(mos7840_port->write_urb->transfer_buffer);
1257                }
1258                usb_free_urb(mos7840_port->write_urb);
1259        }
1260
1261        Data = 0x0;
1262        mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
1263
1264        Data = 0x00;
1265        mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
1266
1267        mos7840_port->open = 0;
1268
1269        dbg("%s \n", "Leaving ............");
1270}
1271
1272/************************************************************************
1273 *
1274 * mos7840_block_until_chase_response
1275 *
1276 *      This function will block the close until one of the following:
1277 *              1. Response to our Chase comes from mos7840
1278 *              2. A timout of 10 seconds without activity has expired
1279 *                 (1K of mos7840 data @ 2400 baud ==> 4 sec to empty)
1280 *
1281 ************************************************************************/
1282
1283static void mos7840_block_until_chase_response(struct moschip_port
1284                                               *mos7840_port)
1285{
1286        int timeout = 1 * HZ;
1287        int wait = 10;
1288        int count;
1289
1290        while (1) {
1291                count = mos7840_chars_in_buffer(mos7840_port->port);
1292
1293                /* Check for Buffer status */
1294                if (count <= 0) {
1295                        return;
1296                }
1297
1298                /* Block the thread for a while */
1299                interruptible_sleep_on_timeout(&mos7840_port->wait_chase,
1300                                               timeout);
1301                /* No activity.. count down section */
1302                wait--;
1303                if (wait == 0) {
1304                        dbg("%s - TIMEOUT", __FUNCTION__);
1305                        return;
1306                } else {
1307                        /* Reset timout value back to seconds */
1308                        wait = 10;
1309                }
1310        }
1311
1312}
1313
1314/*****************************************************************************
1315 * mos7840_break
1316 *      this function sends a break to the port
1317 *****************************************************************************/
1318static void mos7840_break(struct usb_serial_port *port, int break_state)
1319{
1320        unsigned char data;
1321        struct usb_serial *serial;
1322        struct moschip_port *mos7840_port;
1323
1324        dbg("%s \n", "Entering ...........");
1325        dbg("mos7840_break: Start\n");
1326
1327        if (mos7840_port_paranoia_check(port, __FUNCTION__)) {
1328                dbg("%s", "Port Paranoia failed \n");
1329                return;
1330        }
1331
1332        serial = mos7840_get_usb_serial(port, __FUNCTION__);
1333        if (!serial) {
1334                dbg("%s", "Serial Paranoia failed \n");
1335                return;
1336        }
1337
1338        mos7840_port = mos7840_get_port_private(port);
1339
1340        if (mos7840_port == NULL) {
1341                return;
1342        }
1343
1344        if (serial->dev) {
1345
1346                /* flush and block until tx is empty */
1347                mos7840_block_until_chase_response(mos7840_port);
1348        }
1349
1350        if (break_state == -1) {
1351                data = mos7840_port->shadowLCR | LCR_SET_BREAK;
1352        } else {
1353                data = mos7840_port->shadowLCR & ~LCR_SET_BREAK;
1354        }
1355
1356        mos7840_port->shadowLCR = data;
1357        dbg("mcs7840_break mos7840_port->shadowLCR is %x\n",
1358            mos7840_port->shadowLCR);
1359        mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER,
1360                             mos7840_port->shadowLCR);
1361
1362        return;
1363}
1364
1365/*****************************************************************************
1366 * mos7840_write_room
1367 *      this function is called by the tty driver when it wants to know how many
1368 *      bytes of data we can accept for a specific port.
1369 *      If successful, we return the amount of room that we have for this port
1370 *      Otherwise we return a negative error number.
1371 *****************************************************************************/
1372
1373static int mos7840_write_room(struct usb_serial_port *port)
1374{
1375        int i;
1376        int room = 0;
1377        unsigned long flags;
1378        struct moschip_port *mos7840_port;
1379
1380        dbg("%s \n", " mos7840_write_room:entering ...........");
1381
1382        if (mos7840_port_paranoia_check(port, __FUNCTION__)) {
1383                dbg("%s", "Invalid port \n");
1384                dbg("%s \n", " mos7840_write_room:leaving ...........");
1385                return -1;
1386        }
1387
1388        mos7840_port = mos7840_get_port_private(port);
1389        if (mos7840_port == NULL) {
1390                dbg("%s \n", "mos7840_break:leaving ...........");
1391                return -1;
1392        }
1393
1394        spin_lock_irqsave(&mos7840_port->pool_lock, flags);
1395        for (i = 0; i < NUM_URBS; ++i) {
1396                if (!mos7840_port->busy[i]) {
1397                        room += URB_TRANSFER_BUFFER_SIZE;
1398                }
1399        }
1400        spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
1401
1402        room = (room == 0) ? 0 : room - URB_TRANSFER_BUFFER_SIZE + 1;
1403        dbg("%s - returns %d", __FUNCTION__, room);
1404        return room;
1405
1406}
1407
1408/*****************************************************************************
1409 * mos7840_write
1410 *      this function is called by the tty driver when data should be written to
1411 *      the port.
1412 *      If successful, we return the number of bytes written, otherwise we
1413 *      return a negative error number.
1414 *****************************************************************************/
1415
1416static int mos7840_write(struct usb_serial_port *port,
1417                         const unsigned char *data, int count)
1418{
1419        int status;
1420        int i;
1421        int bytes_sent = 0;
1422        int transfer_size;
1423        unsigned long flags;
1424
1425        struct moschip_port *mos7840_port;
1426        struct usb_serial *serial;
1427        struct urb *urb;
1428        //__u16 Data;
1429        const unsigned char *current_position = data;
1430        unsigned char *data1;
1431        dbg("%s \n", "entering ...........");
1432        //dbg("mos7840_write: mos7840_port->shadowLCR is %x\n",mos7840_port->shadowLCR);
1433
1434#ifdef NOTMOS7840
1435        Data = 0x00;
1436        status = 0;
1437        status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);
1438        mos7840_port->shadowLCR = Data;
1439        dbg("mos7840_write: LINE_CONTROL_REGISTER is %x\n", Data);
1440        dbg("mos7840_write: mos7840_port->shadowLCR is %x\n",
1441            mos7840_port->shadowLCR);
1442
1443        //Data = 0x03;
1444        //status = mos7840_set_uart_reg(port,LINE_CONTROL_REGISTER,Data);
1445        //mos7840_port->shadowLCR=Data;//Need to add later
1446
1447        Data |= SERIAL_LCR_DLAB;        //data latch enable in LCR 0x80
1448        status = 0;
1449        status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
1450
1451        //Data = 0x0c;
1452        //status = mos7840_set_uart_reg(port,DIVISOR_LATCH_LSB,Data);
1453        Data = 0x00;
1454        status = 0;
1455        status = mos7840_get_uart_reg(port, DIVISOR_LATCH_LSB, &Data);
1456        dbg("mos7840_write:DLL value is %x\n", Data);
1457
1458        Data = 0x0;
1459        status = 0;
1460        status = mos7840_get_uart_reg(port, DIVISOR_LATCH_MSB, &Data);
1461        dbg("mos7840_write:DLM value is %x\n", Data);
1462
1463        Data = Data & ~SERIAL_LCR_DLAB;
1464        dbg("mos7840_write: mos7840_port->shadowLCR is %x\n",
1465            mos7840_port->shadowLCR);
1466        status = 0;
1467        status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
1468#endif
1469
1470        if (mos7840_port_paranoia_check(port, __FUNCTION__)) {
1471                dbg("%s", "Port Paranoia failed \n");
1472                return -1;
1473        }
1474
1475        serial = port->serial;
1476        if (mos7840_serial_paranoia_check(serial, __FUNCTION__)) {
1477                dbg("%s", "Serial Paranoia failed \n");
1478                return -1;
1479        }
1480
1481        mos7840_port = mos7840_get_port_private(port);
1482        if (mos7840_port == NULL) {
1483                dbg("%s", "mos7840_port is NULL\n");
1484                return -1;
1485        }
1486
1487        /* try to find a free urb in the list */
1488        urb = NULL;
1489
1490        spin_lock_irqsave(&mos7840_port->pool_lock, flags);
1491        for (i = 0; i < NUM_URBS; ++i) {
1492                if (!mos7840_port->busy[i]) {
1493                        mos7840_port->busy[i] = 1;
1494                        urb = mos7840_port->write_urb_pool[i];
1495                        dbg("\nURB:%d", i);
1496                        break;
1497                }
1498        }
1499        spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
1500
1501        if (urb == NULL) {
1502                dbg("%s - no more free urbs", __FUNCTION__);
1503                goto exit;
1504        }
1505
1506        if (urb->transfer_buffer == NULL) {
1507                urb->transfer_buffer =
1508                    kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
1509
1510                if (urb->transfer_buffer == NULL) {
1511                        err("%s no more kernel memory...", __FUNCTION__);
1512                        goto exit;
1513                }
1514        }
1515        transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE);
1516
1517        memcpy(urb->transfer_buffer, current_position, transfer_size);
1518
1519        /* fill urb with data and submit  */
1520        usb_fill_bulk_urb(urb,
1521                          serial->dev,
1522                          usb_sndbulkpipe(serial->dev,
1523                                          port->bulk_out_endpointAddress),
1524                          urb->transfer_buffer,
1525                          transfer_size,
1526                          mos7840_bulk_out_data_callback, mos7840_port);
1527
1528        data1 = urb->transfer_buffer;
1529        dbg("\nbulkout endpoint is %d", port->bulk_out_endpointAddress);
1530
1531        /* send it down the pipe */
1532        status = usb_submit_urb(urb, GFP_ATOMIC);
1533
1534        if (status) {
1535                mos7840_port->busy[i] = 0;
1536                err("%s - usb_submit_urb(write bulk) failed with status = %d",
1537                    __FUNCTION__, status);
1538                bytes_sent = status;
1539                goto exit;
1540        }
1541        bytes_sent = transfer_size;
1542        mos7840_port->icount.tx += transfer_size;
1543        smp_wmb();
1544        dbg("mos7840_port->icount.tx is %d:\n", mos7840_port->icount.tx);
1545      exit:
1546
1547        return bytes_sent;
1548
1549}
1550
1551/*****************************************************************************
1552 * mos7840_throttle
1553 *      this function is called by the tty driver when it wants to stop the data
1554 *      being read from the port.
1555 *****************************************************************************/
1556
1557static void mos7840_throttle(struct usb_serial_port *port)
1558{
1559        struct moschip_port *mos7840_port;
1560        struct tty_struct *tty;
1561        int status;
1562
1563        if (mos7840_port_paranoia_check(port, __FUNCTION__)) {
1564                dbg("%s", "Invalid port \n");
1565                return;
1566        }
1567
1568        dbg("- port %d\n", port->number);
1569
1570        mos7840_port = mos7840_get_port_private(port);
1571
1572        if (mos7840_port == NULL)
1573                return;
1574
1575        if (!mos7840_port->open) {
1576                dbg("%s\n", "port not opened");
1577                return;
1578        }
1579
1580        dbg("%s", "Entering .......... \n");
1581
1582        tty = port->tty;
1583        if (!tty) {
1584                dbg("%s - no tty available", __FUNCTION__);
1585                return;
1586        }
1587
1588        /* if we are implementing XON/XOFF, send the stop character */
1589        if (I_IXOFF(tty)) {
1590                unsigned char stop_char = STOP_CHAR(tty);
1591                status = mos7840_write(port, &stop_char, 1);
1592                if (status <= 0) {
1593                        return;
1594                }
1595        }
1596
1597        /* if we are implementing RTS/CTS, toggle that line */
1598        if (tty->termios->c_cflag & CRTSCTS) {
1599                mos7840_port->shadowMCR &= ~MCR_RTS;
1600                status = 0;
1601                status =
1602                    mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
1603                                         mos7840_port->shadowMCR);
1604
1605                if (status < 0) {
1606                        return;
1607                }
1608        }
1609
1610        return;
1611}
1612
1613/*****************************************************************************
1614 * mos7840_unthrottle
1615 *      this function is called by the tty driver when it wants to resume the data
1616 *      being read from the port (called after SerialThrottle is called)
1617 *****************************************************************************/
1618static void mos7840_unthrottle(struct usb_serial_port *port)
1619{
1620        struct tty_struct *tty;
1621        int status;
1622        struct moschip_port *mos7840_port = mos7840_get_port_private(port);
1623
1624        if (mos7840_port_paranoia_check(port, __FUNCTION__)) {
1625                dbg("%s", "Invalid port \n");
1626                return;
1627        }
1628
1629        if (mos7840_port == NULL)
1630                return;
1631
1632        if (!mos7840_port->open) {
1633                dbg("%s - port not opened", __FUNCTION__);
1634                return;
1635        }
1636
1637        dbg("%s", "Entering .......... \n");
1638
1639        tty = port->tty;
1640        if (!tty) {
1641                dbg("%s - no tty available", __FUNCTION__);
1642                return;
1643        }
1644
1645        /* if we are implementing XON/XOFF, send the start character */
1646        if (I_IXOFF(tty)) {
1647                unsigned char start_char = START_CHAR(tty);
1648                status = mos7840_write(port, &start_char, 1);
1649                if (status <= 0) {
1650                        return;
1651                }
1652        }
1653
1654        /* if we are implementing RTS/CTS, toggle that line */
1655        if (tty->termios->c_cflag & CRTSCTS) {
1656                mos7840_port->shadowMCR |= MCR_RTS;
1657                status = 0;
1658                status =
1659                    mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
1660                                         mos7840_port->shadowMCR);
1661                if (status < 0) {
1662                        return;
1663                }
1664        }
1665
1666        return;
1667}
1668
1669static int mos7840_tiocmget(struct usb_serial_port *port, struct file *file)
1670{
1671        struct moschip_port *mos7840_port;
1672        unsigned int result;
1673        __u16 msr;
1674        __u16 mcr;
1675        int status = 0;
1676        mos7840_port = mos7840_get_port_private(port);
1677
1678        dbg("%s - port %d", __FUNCTION__, port->number);
1679
1680        if (mos7840_port == NULL)
1681                return -ENODEV;
1682
1683        status = mos7840_get_uart_reg(port, MODEM_STATUS_REGISTER, &msr);
1684        status = mos7840_get_uart_reg(port, MODEM_CONTROL_REGISTER, &mcr);
1685        result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0)
1686            | ((mcr & MCR_RTS) ? TIOCM_RTS : 0)
1687            | ((mcr & MCR_LOOPBACK) ? TIOCM_LOOP : 0)
1688            | ((msr & MOS7840_MSR_CTS) ? TIOCM_CTS : 0)
1689            | ((msr & MOS7840_MSR_CD) ? TIOCM_CAR : 0)
1690            | ((msr & MOS7840_MSR_RI) ? TIOCM_RI : 0)
1691            | ((msr & MOS7840_MSR_DSR) ? TIOCM_DSR : 0);
1692
1693        dbg("%s - 0x%04X", __FUNCTION__, result);
1694
1695        return result;
1696}
1697
1698static int mos7840_tiocmset(struct usb_serial_port *port, struct file *file,
1699                            unsigned int set, unsigned int clear)
1700{
1701        struct moschip_port *mos7840_port;
1702        unsigned int mcr;
1703        unsigned int status;
1704
1705        dbg("%s - port %d", __FUNCTION__, port->number);
1706
1707        mos7840_port = mos7840_get_port_private(port);
1708
1709        if (mos7840_port == NULL)
1710                return -ENODEV;
1711
1712        mcr = mos7840_port->shadowMCR;
1713        if (clear & TIOCM_RTS)
1714                mcr &= ~MCR_RTS;
1715        if (clear & TIOCM_DTR)
1716                mcr &= ~MCR_DTR;
1717        if (clear & TIOCM_LOOP)
1718                mcr &= ~MCR_LOOPBACK;
1719
1720        if (set & TIOCM_RTS)
1721                mcr |= MCR_RTS;
1722        if (set & TIOCM_DTR)
1723                mcr |= MCR_DTR;
1724        if (set & TIOCM_LOOP)
1725                mcr |= MCR_LOOPBACK;
1726
1727        mos7840_port->shadowMCR = mcr;
1728
1729        status = 0;
1730        status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, mcr);
1731        if (status < 0) {
1732                dbg("setting MODEM_CONTROL_REGISTER Failed\n");
1733                return -1;
1734        }
1735
1736        return 0;
1737}
1738
1739/*****************************************************************************
1740 * mos7840_calc_baud_rate_divisor
1741 *      this function calculates the proper baud rate divisor for the specified
1742 *      baud rate.
1743 *****************************************************************************/
1744static int mos7840_calc_baud_rate_divisor(int baudRate, int *divisor,
1745                                          __u16 * clk_sel_val)
1746{
1747
1748        dbg("%s - %d", __FUNCTION__, baudRate);
1749
1750        if (baudRate <= 115200) {
1751                *divisor = 115200 / baudRate;
1752                *clk_sel_val = 0x0;
1753        }
1754        if ((baudRate > 115200) && (baudRate <= 230400)) {
1755                *divisor = 230400 / baudRate;
1756                *clk_sel_val = 0x10;
1757        } else if ((baudRate > 230400) && (baudRate <= 403200)) {
1758                *divisor = 403200 / baudRate;
1759                *clk_sel_val = 0x20;
1760        } else if ((baudRate > 403200) && (baudRate <= 460800)) {
1761                *divisor = 460800 / baudRate;
1762                *clk_sel_val = 0x30;
1763        } else if ((baudRate > 460800) && (baudRate <= 806400)) {
1764                *divisor = 806400 / baudRate;
1765                *clk_sel_val = 0x40;
1766        } else if ((baudRate > 806400) && (baudRate <= 921600)) {
1767                *divisor = 921600 / baudRate;
1768                *clk_sel_val = 0x50;
1769        } else if ((baudRate > 921600) && (baudRate <= 1572864)) {
1770                *divisor = 1572864 / baudRate;
1771                *clk_sel_val = 0x60;
1772        } else if ((baudRate > 1572864) && (baudRate <= 3145728)) {
1773                *divisor = 3145728 / baudRate;
1774                *clk_sel_val = 0x70;
1775        }
1776        return 0;
1777
1778#ifdef NOTMCS7840
1779
1780        for (i = 0; i < ARRAY_SIZE(mos7840_divisor_table); i++) {
1781                if (mos7840_divisor_table[i].BaudRate == baudrate) {
1782                        *divisor = mos7840_divisor_table[i].Divisor;
1783                        return 0;
1784                }
1785        }
1786
1787        /* After trying for all the standard baud rates    *
1788         * Try calculating the divisor for this baud rate  */
1789
1790        if (baudrate > 75 && baudrate < 230400) {
1791                /* get the divisor */
1792                custom = (__u16) (230400L / baudrate);
1793
1794                /* Check for round off */
1795                round1 = (__u16) (2304000L / baudrate);
1796                round = (__u16) (round1 - (custom * 10));
1797                if (round > 4) {
1798                        custom++;
1799                }
1800                *divisor = custom;
1801
1802                dbg(" Baud %d = %d\n", baudrate, custom);
1803                return 0;
1804        }
1805
1806        dbg("%s\n", " Baud calculation Failed...");
1807        return -1;
1808#endif
1809}
1810
1811/*****************************************************************************
1812 * mos7840_send_cmd_write_baud_rate
1813 *      this function sends the proper command to change the baud rate of the
1814 *      specified port.
1815 *****************************************************************************/
1816
1817static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port,
1818                                            int baudRate)
1819{
1820        int divisor = 0;
1821        int status;
1822        __u16 Data;
1823        unsigned char number;
1824        __u16 clk_sel_val;
1825        struct usb_serial_port *port;
1826
1827        if (mos7840_port == NULL)
1828                return -1;
1829
1830        port = (struct usb_serial_port *)mos7840_port->port;
1831        if (mos7840_port_paranoia_check(port, __FUNCTION__)) {
1832                dbg("%s", "Invalid port \n");
1833                return -1;
1834        }
1835
1836        if (mos7840_serial_paranoia_check(port->serial, __FUNCTION__)) {
1837                dbg("%s", "Invalid Serial \n");
1838                return -1;
1839        }
1840
1841        dbg("%s", "Entering .......... \n");
1842
1843        number = mos7840_port->port->number - mos7840_port->port->serial->minor;
1844
1845        dbg("%s - port = %d, baud = %d", __FUNCTION__,
1846            mos7840_port->port->number, baudRate);
1847        //reset clk_uart_sel in spregOffset
1848        if (baudRate > 115200) {
1849#ifdef HW_flow_control
1850                //NOTE: need to see the pther register to modify
1851                //setting h/w flow control bit to 1;
1852                status = 0;
1853                Data = 0x2b;
1854                mos7840_port->shadowMCR = Data;
1855                status =
1856                    mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
1857                if (status < 0) {
1858                        dbg("Writing spreg failed in set_serial_baud\n");
1859                        return -1;
1860                }
1861#endif
1862
1863        } else {
1864#ifdef HW_flow_control
1865                //setting h/w flow control bit to 0;
1866                status = 0;
1867                Data = 0xb;
1868                mos7840_port->shadowMCR = Data;
1869                status =
1870                    mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
1871                if (status < 0) {
1872                        dbg("Writing spreg failed in set_serial_baud\n");
1873                        return -1;
1874                }
1875#endif
1876
1877        }
1878
1879        if (1)                  //baudRate <= 115200)
1880        {
1881                clk_sel_val = 0x0;
1882                Data = 0x0;
1883                status = 0;
1884                status =
1885                    mos7840_calc_baud_rate_divisor(baudRate, &divisor,
1886                                                   &clk_sel_val);
1887                status =
1888                    mos7840_get_reg_sync(port, mos7840_port->SpRegOffset,
1889                                         &Data);
1890                if (status < 0) {
1891                        dbg("reading spreg failed in set_serial_baud\n");
1892                        return -1;
1893                }
1894                Data = (Data & 0x8f) | clk_sel_val;
1895                status = 0;
1896                status =
1897                    mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);
1898                if (status < 0) {
1899                        dbg("Writing spreg failed in set_serial_baud\n");
1900                        return -1;
1901                }
1902                /* Calculate the Divisor */
1903
1904                if (status) {
1905                        err("%s - bad baud rate", __FUNCTION__);
1906                        dbg("%s\n", "bad baud rate");
1907                        return status;
1908                }
1909                /* Enable access to divisor latch */
1910                Data = mos7840_port->shadowLCR | SERIAL_LCR_DLAB;
1911                mos7840_port->shadowLCR = Data;
1912                mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
1913
1914                /* Write the divisor */
1915                Data = (unsigned char)(divisor & 0xff);
1916                dbg("set_serial_baud Value to write DLL is %x\n", Data);
1917                mos7840_set_uart_reg(port, DIVISOR_LATCH_LSB, Data);
1918
1919                Data = (unsigned char)((divisor & 0xff00) >> 8);
1920                dbg("set_serial_baud Value to write DLM is %x\n", Data);
1921                mos7840_set_uart_reg(port, DIVISOR_LATCH_MSB, Data);
1922
1923                /* Disable access to divisor latch */
1924                Data = mos7840_port->shadowLCR & ~SERIAL_LCR_DLAB;
1925                mos7840_port->shadowLCR = Data;
1926                mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
1927
1928        }
1929
1930        return status;
1931}
1932
1933/*****************************************************************************
1934 * mos7840_change_port_settings
1935 *      This routine is called to set the UART on the device to match
1936 *      the specified new settings.
1937 *****************************************************************************/
1938
1939static void mos7840_change_port_settings(struct moschip_port *mos7840_port,
1940                                         struct ktermios *old_termios)
1941{
1942        struct tty_struct *tty;
1943        int baud;
1944        unsigned cflag;
1945        unsigned iflag;
1946        __u8 lData;
1947        __u8 lParity;
1948        __u8 lStop;
1949        int status;
1950        __u16 Data;
1951        struct usb_serial_port *port;
1952        struct usb_serial *serial;
1953
1954        if (mos7840_port == NULL)
1955                return;
1956
1957        port = (struct usb_serial_port *)mos7840_port->port;
1958
1959        if (mos7840_port_paranoia_check(port, __FUNCTION__)) {
1960                dbg("%s", "Invalid port \n");
1961                return;
1962        }
1963
1964        if (mos7840_serial_paranoia_check(port->serial, __FUNCTION__)) {
1965                dbg("%s", "Invalid Serial \n");
1966                return;
1967        }
1968
1969        serial = port->serial;
1970
1971        dbg("%s - port %d", __FUNCTION__, mos7840_port->port->number);
1972
1973        if (!mos7840_port->open) {
1974                dbg("%s - port not opened", __FUNCTION__);
1975                return;
1976        }
1977
1978        tty = mos7840_port->port->tty;
1979
1980        dbg("%s", "Entering .......... \n");
1981
1982        lData = LCR_BITS_8;
1983        lStop = LCR_STOP_1;
1984        lParity = LCR_PAR_NONE;
1985
1986        cflag = tty->termios->c_cflag;
1987        iflag = tty->termios->c_iflag;
1988
1989        /* Change the number of bits */
1990        if (cflag & CSIZE) {
1991                switch (cflag & CSIZE) {
1992                case CS5:
1993                        lData = LCR_BITS_5;
1994                        break;
1995
1996                case CS6:
1997                        lData = LCR_BITS_6;
1998                        break;
1999
2000                case CS7:
2001                        lData = LCR_BITS_7;
2002                        break;
2003                default:
2004                case CS8:
2005                        lData = LCR_BITS_8;
2006                        break;
2007                }
2008        }
2009        /* Change the Parity bit */
2010        if (cflag & PARENB) {
2011                if (cflag & PARODD) {
2012                        lParity = LCR_PAR_ODD;
2013                        dbg("%s - parity = odd", __FUNCTION__);
2014                } else {
2015                        lParity = LCR_PAR_EVEN;
2016                        dbg("%s - parity = even", __FUNCTION__);
2017                }
2018
2019        } else {
2020                dbg("%s - parity = none", __FUNCTION__);
2021        }
2022
2023        if (cflag & CMSPAR) {
2024                lParity = lParity | 0x20;
2025        }
2026
2027        /* Change the Stop bit */
2028        if (cflag & CSTOPB) {
2029                lStop = LCR_STOP_2;
2030                dbg("%s - stop bits = 2", __FUNCTION__);
2031        } else {
2032                lStop = LCR_STOP_1;
2033                dbg("%s - stop bits = 1", __FUNCTION__);
2034        }
2035
2036        /* Update the LCR with the correct value */
2037        mos7840_port->shadowLCR &=
2038            ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK);
2039        mos7840_port->shadowLCR |= (lData | lParity | lStop);
2040
2041        dbg("mos7840_change_port_settings mos7840_port->shadowLCR is %x\n",
2042            mos7840_port->shadowLCR);
2043        /* Disable Interrupts */
2044        Data = 0x00;
2045        mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
2046
2047        Data = 0x00;
2048        mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
2049
2050        Data = 0xcf;
2051        mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
2052
2053        /* Send the updated LCR value to the mos7840 */
2054        Data = mos7840_port->shadowLCR;
2055
2056        mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
2057
2058        Data = 0x00b;
2059        mos7840_port->shadowMCR = Data;
2060        mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
2061        Data = 0x00b;
2062        mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
2063
2064        /* set up the MCR register and send it to the mos7840 */
2065
2066        mos7840_port->shadowMCR = MCR_MASTER_IE;
2067        if (cflag & CBAUD) {
2068                mos7840_port->shadowMCR |= (MCR_DTR | MCR_RTS);
2069        }
2070
2071        if (cflag & CRTSCTS) {
2072                mos7840_port->shadowMCR |= (MCR_XON_ANY);
2073
2074        } else {
2075                mos7840_port->shadowMCR &= ~(MCR_XON_ANY);
2076        }
2077
2078        Data = mos7840_port->shadowMCR;
2079        mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
2080
2081        /* Determine divisor based on baud rate */
2082        baud = tty_get_baud_rate(tty);
2083
2084        if (!baud) {
2085                /* pick a default, any default... */
2086                dbg("%s\n", "Picked default baud...");
2087                baud = 9600;
2088        }
2089
2090        dbg("%s - baud rate = %d", __FUNCTION__, baud);
2091        status = mos7840_send_cmd_write_baud_rate(mos7840_port, baud);
2092
2093        /* Enable Interrupts */
2094        Data = 0x0c;
2095        mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
2096
2097        if (mos7840_port->read_urb->status != -EINPROGRESS) {
2098                mos7840_port->read_urb->dev = serial->dev;
2099
2100                status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);
2101
2102                if (status) {
2103                        dbg(" usb_submit_urb(read bulk) failed, status = %d",
2104                            status);
2105                }
2106        }
2107        wake_up(&mos7840_port->delta_msr_wait);
2108        mos7840_port->delta_msr_cond = 1;
2109        dbg("mos7840_change_port_settings mos7840_port->shadowLCR is End %x\n",
2110            mos7840_port->shadowLCR);
2111
2112        return;
2113}
2114
2115/*****************************************************************************
2116 * mos7840_set_termios
2117 *      this function is called by the tty driver when it wants to change
2118 *      the termios structure
2119 *****************************************************************************/
2120
2121static void mos7840_set_termios(struct usb_serial_port *port,
2122                                struct ktermios *old_termios)
2123{
2124        int status;
2125        unsigned int cflag;
2126        struct usb_serial *serial;
2127        struct moschip_port *mos7840_port;
2128        struct tty_struct *tty;
2129        dbg("mos7840_set_termios: START\n");
2130        if (mos7840_port_paranoia_check(port, __FUNCTION__)) {
2131                dbg("%s", "Invalid port \n");
2132                return;
2133        }
2134
2135        serial = port->serial;
2136
2137        if (mos7840_serial_paranoia_check(serial, __FUNCTION__)) {
2138                dbg("%s", "Invalid Serial \n");
2139                return;
2140        }
2141
2142        mos7840_port = mos7840_get_port_private(port);
2143
2144        if (mos7840_port == NULL)
2145                return;
2146
2147        tty = port->tty;
2148
2149        if (!mos7840_port->open) {
2150                dbg("%s - port not opened", __FUNCTION__);
2151                return;
2152        }
2153
2154        dbg("%s\n", "setting termios - ");
2155
2156        cflag = tty->termios->c_cflag;
2157
2158        dbg("%s - clfag %08x iflag %08x", __FUNCTION__,
2159            tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag));
2160        dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__,
2161            old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag));
2162        dbg("%s - port %d", __FUNCTION__, port->number);
2163
2164        /* change the port settings to the new ones specified */
2165
2166        mos7840_change_port_settings(mos7840_port, old_termios);
2167
2168        if (!mos7840_port->read_urb) {
2169                dbg("%s", "URB KILLED !!!!!\n");
2170                return;
2171        }
2172
2173        if (mos7840_port->read_urb->status != -EINPROGRESS) {
2174                mos7840_port->read_urb->dev = serial->dev;
2175                status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);
2176                if (status) {
2177                        dbg(" usb_submit_urb(read bulk) failed, status = %d",
2178                            status);
2179                }
2180        }
2181        return;
2182}
2183
2184/*****************************************************************************
2185 * mos7840_get_lsr_info - get line status register info
2186 *
2187 * Purpose: Let user call ioctl() to get info when the UART physically
2188 *          is emptied.  On bus types like RS485, the transmitter must
2189 *          release the bus after transmitting. This must be done when
2190 *          the transmit shift register is empty, not be done when the
2191 *          transmit holding register is empty.  This functionality
2192 *          allows an RS485 driver to be written in user space.
2193 *****************************************************************************/
2194
2195static int mos7840_get_lsr_info(struct moschip_port *mos7840_port,
2196                                unsigned int __user *value)
2197{
2198        int count;
2199        unsigned int result = 0;
2200
2201        count = mos7840_chars_in_buffer(mos7840_port->port);
2202        if (count == 0) {
2203                dbg("%s -- Empty", __FUNCTION__);
2204                result = TIOCSER_TEMT;
2205        }
2206
2207        if (copy_to_user(value, &result, sizeof(int)))
2208                return -EFAULT;
2209        return 0;
2210}
2211
2212/*****************************************************************************
2213 * mos7840_set_modem_info
2214 *      function to set modem info
2215 *****************************************************************************/
2216
2217static int mos7840_set_modem_info(struct moschip_port *mos7840_port,
2218                                  unsigned int cmd, unsigned int __user *value)
2219{
2220        unsigned int mcr;
2221        unsigned int arg;
2222        __u16 Data;
2223        int status;
2224        struct usb_serial_port *port;
2225
2226        if (mos7840_port == NULL)
2227                return -1;
2228
2229        port = (struct usb_serial_port *)mos7840_port->port;
2230        if (mos7840_port_paranoia_check(port, __FUNCTION__)) {
2231                dbg("%s", "Invalid port \n");
2232                return -1;
2233        }
2234
2235        mcr = mos7840_port->shadowMCR;
2236
2237        if (copy_from_user(&arg, value, sizeof(int)))
2238                return -EFAULT;
2239
2240        switch (cmd) {
2241        case TIOCMBIS:
2242                if (arg & TIOCM_RTS)
2243                        mcr |= MCR_RTS;
2244                if (arg & TIOCM_DTR)
2245                        mcr |= MCR_RTS;
2246                if (arg & TIOCM_LOOP)
2247                        mcr |= MCR_LOOPBACK;
2248                break;
2249
2250        case TIOCMBIC:
2251                if (arg & TIOCM_RTS)
2252                        mcr &= ~MCR_RTS;
2253                if (arg & TIOCM_DTR)
2254                        mcr &= ~MCR_RTS;
2255                if (arg & TIOCM_LOOP)
2256                        mcr &= ~MCR_LOOPBACK;
2257                break;
2258
2259        case TIOCMSET:
2260                /* turn off the RTS and DTR and LOOPBACK
2261                 * and then only turn on what was asked to */
2262                mcr &= ~(MCR_RTS | MCR_DTR | MCR_LOOPBACK);
2263                mcr |= ((arg & TIOCM_RTS) ? MCR_RTS : 0);
2264                mcr |= ((arg & TIOCM_DTR) ? MCR_DTR : 0);
2265                mcr |= ((arg & TIOCM_LOOP) ? MCR_LOOPBACK : 0);
2266                break;
2267        }
2268
2269        mos7840_port->shadowMCR = mcr;
2270
2271        Data = mos7840_port->shadowMCR;
2272        status = 0;
2273        status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
2274        if (status < 0) {
2275                dbg("setting MODEM_CONTROL_REGISTER Failed\n");
2276                return -1;
2277        }
2278
2279        return 0;
2280}
2281
2282/*****************************************************************************
2283 * mos7840_get_modem_info
2284 *      function to get modem info
2285 *****************************************************************************/
2286
2287static int mos7840_get_modem_info(struct moschip_port *mos7840_port,
2288                                  unsigned int __user *value)
2289{
2290        unsigned int result = 0;
2291        __u16 msr;
2292        unsigned int mcr = mos7840_port->shadowMCR;
2293        int status = 0;
2294        status =
2295            mos7840_get_uart_reg(mos7840_port->port, MODEM_STATUS_REGISTER,
2296                                 &msr);
2297        result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0)      /* 0x002 */
2298            |((mcr & MCR_RTS) ? TIOCM_RTS : 0)  /* 0x004 */
2299            |((msr & MOS7840_MSR_CTS) ? TIOCM_CTS : 0)  /* 0x020 */
2300            |((msr & MOS7840_MSR_CD) ? TIOCM_CAR : 0)   /* 0x040 */
2301            |((msr & MOS7840_MSR_RI) ? TIOCM_RI : 0)    /* 0x080 */
2302            |((msr & MOS7840_MSR_DSR) ? TIOCM_DSR : 0); /* 0x100 */
2303
2304        dbg("%s -- %x", __FUNCTION__, result);
2305
2306        if (copy_to_user(value, &result, sizeof(int)))
2307                return -EFAULT;
2308        return 0;
2309}
2310
2311/*****************************************************************************
2312 * mos7840_get_serial_info
2313 *      function to get information about serial port
2314 *****************************************************************************/
2315
2316static int mos7840_get_serial_info(struct moschip_port *mos7840_port,
2317                                   struct serial_struct __user *retinfo)
2318{
2319        struct serial_struct tmp;
2320
2321        if (mos7840_port == NULL)
2322                return -1;
2323
2324        if (!retinfo)
2325                return -EFAULT;
2326
2327        memset(&tmp, 0, sizeof(tmp));
2328
2329        tmp.type = PORT_16550A;
2330        tmp.line = mos7840_port->port->serial->minor;
2331        tmp.port = mos7840_port->port->number;
2332        tmp.irq = 0;
2333        tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
2334        tmp.xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE;
2335        tmp.baud_base = 9600;
2336        tmp.close_delay = 5 * HZ;
2337        tmp.closing_wait = 30 * HZ;
2338
2339        if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
2340                return -EFAULT;
2341        return 0;
2342}
2343
2344/*****************************************************************************
2345 * SerialIoctl
2346 *      this function handles any ioctl calls to the driver
2347 *****************************************************************************/
2348
2349static int mos7840_ioctl(struct usb_serial_port *port, struct file *file,
2350                         unsigned int cmd, unsigned long arg)
2351{
2352        void __user *argp = (void __user *)arg;
2353        struct moschip_port *mos7840_port;
2354        struct tty_struct *tty;
2355
2356        struct async_icount cnow;
2357        struct async_icount cprev;
2358        struct serial_icounter_struct icount;
2359        int mosret = 0;
2360
2361        if (mos7840_port_paranoia_check(port, __FUNCTION__)) {
2362                dbg("%s", "Invalid port \n");
2363                return -1;
2364        }
2365
2366        mos7840_port = mos7840_get_port_private(port);
2367
2368        if (mos7840_port == NULL)
2369                return -1;
2370
2371        tty = mos7840_port->port->tty;
2372
2373        dbg("%s - port %d, cmd = 0x%x", __FUNCTION__, port->number, cmd);
2374
2375        switch (cmd) {
2376                /* return number of bytes available */
2377
2378        case TIOCSERGETLSR:
2379                dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__, port->number);
2380                return mos7840_get_lsr_info(mos7840_port, argp);
2381                return 0;
2382
2383        case TIOCMBIS:
2384        case TIOCMBIC:
2385        case TIOCMSET:
2386                dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __FUNCTION__,
2387                    port->number);
2388                mosret =
2389                    mos7840_set_modem_info(mos7840_port, cmd, argp);
2390                return mosret;
2391
2392        case TIOCMGET:
2393                dbg("%s (%d) TIOCMGET", __FUNCTION__, port->number);
2394                return mos7840_get_modem_info(mos7840_port, argp);
2395
2396        case TIOCGSERIAL:
2397                dbg("%s (%d) TIOCGSERIAL", __FUNCTION__, port->number);
2398                return mos7840_get_serial_info(mos7840_port, argp);
2399
2400        case TIOCSSERIAL:
2401                dbg("%s (%d) TIOCSSERIAL", __FUNCTION__, port->number);
2402                break;
2403
2404        case TIOCMIWAIT:
2405                dbg("%s (%d) TIOCMIWAIT", __FUNCTION__, port->number);
2406                cprev = mos7840_port->icount;
2407                while (1) {
2408                        //interruptible_sleep_on(&mos7840_port->delta_msr_wait);
2409                        mos7840_port->delta_msr_cond = 0;
2410                        wait_event_interruptible(mos7840_port->delta_msr_wait,
2411                                                 (mos7840_port->
2412                                                  delta_msr_cond == 1));
2413
2414                        /* see if a signal did it */
2415                        if (signal_pending(current))
2416                                return -ERESTARTSYS;
2417                        cnow = mos7840_port->icount;
2418                        smp_rmb();
2419                        if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
2420                            cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
2421                                return -EIO;    /* no change => error */
2422                        if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
2423                            ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
2424                            ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
2425                            ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
2426                                return 0;
2427                        }
2428                        cprev = cnow;
2429                }
2430                /* NOTREACHED */
2431                break;
2432
2433        case TIOCGICOUNT:
2434                cnow = mos7840_port->icount;
2435                smp_rmb();
2436                icount.cts = cnow.cts;
2437                icount.dsr = cnow.dsr;
2438                icount.rng = cnow.rng;
2439                icount.dcd = cnow.dcd;
2440                icount.rx = cnow.rx;
2441                icount.tx = cnow.tx;
2442                icount.frame = cnow.frame;
2443                icount.overrun = cnow.overrun;
2444                icount.parity = cnow.parity;
2445                icount.brk = cnow.brk;
2446                icount.buf_overrun = cnow.buf_overrun;
2447
2448                dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __FUNCTION__,
2449                    port->number, icount.rx, icount.tx);
2450                if (copy_to_user(argp, &icount, sizeof(icount)))
2451                        return -EFAULT;
2452                return 0;
2453
2454        case TIOCEXBAUD:
2455                return 0;
2456        default:
2457                break;
2458        }
2459
2460        return -ENOIOCTLCMD;
2461}
2462
2463static int mos7840_calc_num_ports(struct usb_serial *serial)
2464{
2465        int mos7840_num_ports = 0;
2466
2467        dbg("numberofendpoints: %d \n",
2468            (int)serial->interface->cur_altsetting->desc.bNumEndpoints);
2469        dbg("numberofendpoints: %d \n",
2470            (int)serial->interface->altsetting->desc.bNumEndpoints);
2471        if (serial->interface->cur_altsetting->desc.bNumEndpoints == 5) {
2472                mos7840_num_ports = serial->num_ports = 2;
2473        } else if (serial->interface->cur_altsetting->desc.bNumEndpoints == 9) {
2474                serial->num_bulk_in = 4;
2475                serial->num_bulk_out = 4;
2476                mos7840_num_ports = serial->num_ports = 4;
2477        }
2478
2479        return mos7840_num_ports;
2480}
2481
2482/****************************************************************************
2483 * mos7840_startup
2484 ****************************************************************************/
2485
2486static int mos7840_startup(struct usb_serial *serial)
2487{
2488        struct moschip_port *mos7840_port;
2489        struct usb_device *dev;
2490        int i, status;
2491
2492        __u16 Data;
2493        dbg("%s \n", " mos7840_startup :entering..........");
2494
2495        if (!serial) {
2496                dbg("%s\n", "Invalid Handler");
2497                return -1;
2498        }
2499
2500        dev = serial->dev;
2501
2502        dbg("%s\n", "Entering...");
2503
2504        /* we set up the pointers to the endpoints in the mos7840_open *
2505         * function, as the structures aren't created yet.             */
2506
2507        /* set up port private structures */
2508        for (i = 0; i < serial->num_ports; ++i) {
2509                mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL);
2510                if (mos7840_port == NULL) {
2511                        err("%s - Out of memory", __FUNCTION__);
2512                        status = -ENOMEM;
2513                        i--; /* don't follow NULL pointer cleaning up */
2514                        goto error;
2515                }
2516
2517                /* Initialize all port interrupt end point to port 0 int endpoint *
2518                 * Our device has only one interrupt end point comman to all port */
2519
2520                mos7840_port->port = serial->port[i];
2521                mos7840_set_port_private(serial->port[i], mos7840_port);
2522                spin_lock_init(&mos7840_port->pool_lock);
2523
2524                mos7840_port->port_num = ((serial->port[i]->number -
2525                                           (serial->port[i]->serial->minor)) +
2526                                          1);
2527
2528                if (mos7840_port->port_num == 1) {
2529                        mos7840_port->SpRegOffset = 0x0;
2530                        mos7840_port->ControlRegOffset = 0x1;
2531                        mos7840_port->DcrRegOffset = 0x4;
2532                } else if ((mos7840_port->port_num == 2)
2533                           && (serial->num_ports == 4)) {
2534                        mos7840_port->SpRegOffset = 0x8;
2535                        mos7840_port->ControlRegOffset = 0x9;
2536                        mos7840_port->DcrRegOffset = 0x16;
2537                } else if ((mos7840_port->port_num == 2)
2538                           && (serial->num_ports == 2)) {
2539                        mos7840_port->SpRegOffset = 0xa;
2540                        mos7840_port->ControlRegOffset = 0xb;
2541                        mos7840_port->DcrRegOffset = 0x19;
2542                } else if ((mos7840_port->port_num == 3)
2543                           && (serial->num_ports == 4)) {
2544                        mos7840_port->SpRegOffset = 0xa;
2545                        mos7840_port->ControlRegOffset = 0xb;
2546                        mos7840_port->DcrRegOffset = 0x19;
2547                } else if ((mos7840_port->port_num == 4)
2548                           && (serial->num_ports == 4)) {
2549                        mos7840_port->SpRegOffset = 0xc;
2550                        mos7840_port->ControlRegOffset = 0xd;
2551                        mos7840_port->DcrRegOffset = 0x1c;
2552                }
2553                mos7840_dump_serial_port(mos7840_port);
2554
2555                mos7840_set_port_private(serial->port[i], mos7840_port);
2556
2557                //enable rx_disable bit in control register
2558
2559                status =
2560                    mos7840_get_reg_sync(serial->port[i],
2561                                         mos7840_port->ControlRegOffset, &Data);
2562                if (status < 0) {
2563                        dbg("Reading ControlReg failed status-0x%x\n", status);
2564                        break;
2565                } else
2566                        dbg("ControlReg Reading success val is %x, status%d\n",
2567                            Data, status);
2568                Data |= 0x08;   //setting driver done bit
2569                Data |= 0x04;   //sp1_bit to have cts change reflect in modem status reg
2570
2571                //Data |= 0x20; //rx_disable bit
2572                status = 0;
2573                status =
2574                    mos7840_set_reg_sync(serial->port[i],
2575                                         mos7840_port->ControlRegOffset, Data);
2576                if (status < 0) {
2577                        dbg("Writing ControlReg failed(rx_disable) status-0x%x\n", status);
2578                        break;
2579                } else
2580                        dbg("ControlReg Writing success(rx_disable) status%d\n",
2581                            status);
2582
2583                //Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2 and 0x24 in DCR3
2584                Data = 0x01;
2585                status = 0;
2586                status =
2587                    mos7840_set_reg_sync(serial->port[i],
2588                                         (__u16) (mos7840_port->DcrRegOffset +
2589                                                  0), Data);
2590                if (status < 0) {
2591                        dbg("Writing DCR0 failed status-0x%x\n", status);
2592                        break;
2593                } else
2594                        dbg("DCR0 Writing success status%d\n", status);
2595
2596                Data = 0x05;
2597                status = 0;
2598                status =
2599                    mos7840_set_reg_sync(serial->port[i],
2600                                         (__u16) (mos7840_port->DcrRegOffset +
2601                                                  1), Data);
2602                if (status < 0) {
2603                        dbg("Writing DCR1 failed status-0x%x\n", status);
2604                        break;
2605                } else
2606                        dbg("DCR1 Writing success status%d\n", status);
2607
2608                Data = 0x24;
2609                status = 0;
2610                status =
2611                    mos7840_set_reg_sync(serial->port[i],
2612                                         (__u16) (mos7840_port->DcrRegOffset +
2613                                                  2), Data);
2614                if (status < 0) {
2615                        dbg("Writing DCR2 failed status-0x%x\n", status);
2616                        break;
2617                } else
2618                        dbg("DCR2 Writing success status%d\n", status);
2619
2620                // write values in clkstart0x0 and clkmulti 0x20
2621                Data = 0x0;
2622                status = 0;
2623                status =
2624                    mos7840_set_reg_sync(serial->port[i],
2625                                         CLK_START_VALUE_REGISTER, Data);
2626                if (status < 0) {
2627                        dbg("Writing CLK_START_VALUE_REGISTER failed status-0x%x\n", status);
2628                        break;
2629                } else
2630                        dbg("CLK_START_VALUE_REGISTER Writing success status%d\n", status);
2631
2632                Data = 0x20;
2633                status =
2634                    mos7840_set_reg_sync(serial->port[i], CLK_MULTI_REGISTER,
2635                                         Data);
2636                if (status < 0) {
2637                        dbg("Writing CLK_MULTI_REGISTER failed status-0x%x\n",
2638                            status);
2639                        goto error;
2640                } else
2641                        dbg("CLK_MULTI_REGISTER Writing success status%d\n",
2642                            status);
2643
2644                //write value 0x0 to scratchpad register
2645                Data = 0x00;
2646                status =
2647                    mos7840_set_uart_reg(serial->port[i], SCRATCH_PAD_REGISTER,
2648                                         Data);
2649                if (status < 0) {
2650                        dbg("Writing SCRATCH_PAD_REGISTER failed status-0x%x\n",
2651                            status);
2652                        break;
2653                } else
2654                        dbg("SCRATCH_PAD_REGISTER Writing success status%d\n",
2655                            status);
2656
2657                //Zero Length flag register
2658                if ((mos7840_port->port_num != 1)
2659                    && (serial->num_ports == 2)) {
2660
2661                        Data = 0xff;
2662                        status = 0;
2663                        status = mos7840_set_reg_sync(serial->port[i],
2664                                                      (__u16) (ZLP_REG1 +
2665                                                               ((__u16)
2666                                                                mos7840_port->
2667                                                                port_num)),
2668                                                      Data);
2669                        dbg("ZLIP offset%x\n",
2670                            (__u16) (ZLP_REG1 +
2671                                     ((__u16) mos7840_port->port_num)));
2672                        if (status < 0) {
2673                                dbg("Writing ZLP_REG%d failed status-0x%x\n",
2674                                    i + 2, status);
2675                                break;
2676                        } else
2677                                dbg("ZLP_REG%d Writing success status%d\n",
2678                                    i + 2, status);
2679                } else {
2680                        Data = 0xff;
2681                        status = 0;
2682                        status = mos7840_set_reg_sync(serial->port[i],
2683                                                      (__u16) (ZLP_REG1 +
2684                                                               ((__u16)
2685                                                                mos7840_port->
2686                                                                port_num) -
2687                                                               0x1), Data);
2688                        dbg("ZLIP offset%x\n",
2689                            (__u16) (ZLP_REG1 +
2690                                     ((__u16) mos7840_port->port_num) - 0x1));
2691                        if (status < 0) {
2692                                dbg("Writing ZLP_REG%d failed status-0x%x\n",
2693                                    i + 1, status);
2694                                break;
2695                        } else
2696                                dbg("ZLP_REG%d Writing success status%d\n",
2697                                    i + 1, status);
2698
2699                }
2700                mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL);
2701                mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL);
2702                mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
2703                if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf || !mos7840_port->dr) {
2704                        status = -ENOMEM;
2705                        goto error;
2706                }
2707        }
2708
2709        //Zero Length flag enable
2710        Data = 0x0f;
2711        status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data);
2712        if (status < 0) {
2713                dbg("Writing ZLP_REG5 failed status-0x%x\n", status);
2714                goto error;
2715        } else
2716                dbg("ZLP_REG5 Writing success status%d\n", status);
2717
2718        /* setting configuration feature to one */
2719        usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
2720                        (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5 * HZ);
2721        return 0;
2722error:
2723        for (/* nothing */; i >= 0; i--) {
2724                mos7840_port = mos7840_get_port_private(serial->port[i]);
2725
2726                kfree(mos7840_port->dr);
2727                kfree(mos7840_port->ctrl_buf);
2728                usb_free_urb(mos7840_port->control_urb);
2729                kfree(mos7840_port);
2730                serial->port[i] = NULL;
2731        }
2732        return status;
2733}
2734
2735/****************************************************************************
2736 * mos7840_shutdown
2737 *      This function is called whenever the device is removed from the usb bus.
2738 ****************************************************************************/
2739
2740static void mos7840_shutdown(struct usb_serial *serial)
2741{
2742        int i;
2743        unsigned long flags;
2744        struct moschip_port *mos7840_port;
2745        dbg("%s \n", " shutdown :entering..........");
2746
2747        if (!serial) {
2748                dbg("%s", "Invalid Handler \n");
2749                return;
2750        }
2751
2752        /*      check for the ports to be closed,close the ports and disconnect         */
2753
2754        /* free private structure allocated for serial port  *
2755         * stop reads and writes on all ports                */
2756
2757        for (i = 0; i < serial->num_ports; ++i) {
2758                mos7840_port = mos7840_get_port_private(serial->port[i]);
2759                spin_lock_irqsave(&mos7840_port->pool_lock, flags);
2760                mos7840_port->zombie = 1;
2761                spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
2762                usb_kill_urb(mos7840_port->control_urb);
2763                kfree(mos7840_port->ctrl_buf);
2764                kfree(mos7840_port->dr);
2765                kfree(mos7840_port);
2766                mos7840_set_port_private(serial->port[i], NULL);
2767        }
2768
2769        dbg("%s\n", "Thank u :: ");
2770
2771}
2772
2773static struct usb_driver io_driver = {
2774        .name = "mos7840",
2775        .probe = usb_serial_probe,
2776        .disconnect = usb_serial_disconnect,
2777        .id_table = moschip_id_table_combined,
2778        .no_dynamic_id = 1,
2779};
2780
2781static struct usb_serial_driver moschip7840_4port_device = {
2782        .driver = {
2783                   .owner = THIS_MODULE,
2784                   .name = "mos7840",
2785                   },
2786        .description = DRIVER_DESC,
2787        .usb_driver = &io_driver,
2788        .id_table = moschip_port_id_table,
2789        .num_interrupt_in = 1,  //NUM_DONT_CARE,//1,
2790#ifdef check
2791        .num_bulk_in = 4,
2792        .num_bulk_out = 4,
2793        .num_ports = 4,
2794#endif
2795        .open = mos7840_open,
2796        .close = mos7840_close,
2797        .write = mos7840_write,
2798        .write_room = mos7840_write_room,
2799        .chars_in_buffer = mos7840_chars_in_buffer,
2800        .throttle = mos7840_throttle,
2801        .unthrottle = mos7840_unthrottle,
2802        .calc_num_ports = mos7840_calc_num_ports,
2803#ifdef MCSSerialProbe
2804        .probe = mos7840_serial_probe,
2805#endif
2806        .ioctl = mos7840_ioctl,
2807        .set_termios = mos7840_set_termios,
2808        .break_ctl = mos7840_break,
2809        .tiocmget = mos7840_tiocmget,
2810        .tiocmset = mos7840_tiocmset,
2811        .attach = mos7840_startup,
2812        .shutdown = mos7840_shutdown,
2813        .read_bulk_callback = mos7840_bulk_in_callback,
2814        .read_int_callback = mos7840_interrupt_callback,
2815};
2816
2817/****************************************************************************
2818 * moschip7840_init
2819 *      This is called by the module subsystem, or on startup to initialize us
2820 ****************************************************************************/
2821static int __init moschip7840_init(void)
2822{
2823        int retval;
2824
2825        dbg("%s \n", " mos7840_init :entering..........");
2826
2827        /* Register with the usb serial */
2828        retval = usb_serial_register(&moschip7840_4port_device);
2829
2830        if (retval)
2831                goto failed_port_device_register;
2832
2833        dbg("%s\n", "Entring...");
2834        info(DRIVER_DESC " " DRIVER_VERSION);
2835
2836        /* Register with the usb */
2837        retval = usb_register(&io_driver);
2838
2839        if (retval)
2840                goto failed_usb_register;
2841
2842        if (retval == 0) {
2843                dbg("%s\n", "Leaving...");
2844                return 0;
2845        }
2846
2847      failed_usb_register:
2848        usb_serial_deregister(&moschip7840_4port_device);
2849
2850      failed_port_device_register:
2851
2852        return retval;
2853}
2854
2855/****************************************************************************
2856 * moschip7840_exit
2857 *      Called when the driver is about to be unloaded.
2858 ****************************************************************************/
2859static void __exit moschip7840_exit(void)
2860{
2861
2862        dbg("%s \n", " mos7840_exit :entering..........");
2863
2864        usb_deregister(&io_driver);
2865
2866        usb_serial_deregister(&moschip7840_4port_device);
2867
2868        dbg("%s\n", "Entring...");
2869}
2870
2871module_init(moschip7840_init);
2872module_exit(moschip7840_exit);
2873
2874/* Module information */
2875MODULE_DESCRIPTION(DRIVER_DESC);
2876MODULE_LICENSE("GPL");
2877
2878module_param(debug, bool, S_IRUGO | S_IWUSR);
2879MODULE_PARM_DESC(debug, "Debug enabled or not");
2880