📄 mos7840.c
字号:
Data = Data & ~0x0c; status = 0; status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data); //Finally enable all interrupts Data = 0x0; Data = 0x0c; status = 0; status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); //clearing rx_disable Data = 0x0; status = 0; status = mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset, &Data); Data = Data & ~0x20; status = 0; status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, Data); // rx_negate Data = 0x0; status = 0; status = mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset, &Data); Data = Data | 0x10; status = 0; status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, Data); /* force low_latency on so that our tty_push actually forces * * the data through,otherwise it is scheduled, and with * * high data rates (like with OHCI) data can get lost. */ if (port->tty) port->tty->low_latency = 1;/* Check to see if we've set up our endpoint info yet * * (can't set it up in mos7840_startup as the structures * * were not set up at that time.) */ if (port0->open_ports == 1) { if (serial->port[0]->interrupt_in_buffer == NULL) { /* set up interrupt urb */ usb_fill_int_urb(serial->port[0]->interrupt_in_urb, serial->dev, usb_rcvintpipe(serial->dev, serial->port[0]-> interrupt_in_endpointAddress), serial->port[0]->interrupt_in_buffer, serial->port[0]->interrupt_in_urb-> transfer_buffer_length, mos7840_interrupt_callback, serial, serial->port[0]->interrupt_in_urb-> interval); /* start interrupt read for mos7840 * * will continue as long as mos7840 is connected */ response = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL); if (response) { err("%s - Error %d submitting interrupt urb", __FUNCTION__, response); } } } /* see if we've set up our endpoint info yet * * (can't set it up in mos7840_startup as the * * structures were not set up at that time.) */ dbg("port number is %d \n", port->number); dbg("serial number is %d \n", port->serial->minor); dbg("Bulkin endpoint is %d \n", port->bulk_in_endpointAddress); dbg("BulkOut endpoint is %d \n", port->bulk_out_endpointAddress); dbg("Interrupt endpoint is %d \n", port->interrupt_in_endpointAddress); dbg("port's number in the device is %d\n", mos7840_port->port_num); mos7840_port->read_urb = port->read_urb; /* set up our bulk in urb */ usb_fill_bulk_urb(mos7840_port->read_urb, serial->dev, usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), port->bulk_in_buffer, mos7840_port->read_urb->transfer_buffer_length, mos7840_bulk_in_callback, mos7840_port); dbg("mos7840_open: bulkin endpoint is %d\n", port->bulk_in_endpointAddress); response = usb_submit_urb(mos7840_port->read_urb, GFP_KERNEL); if (response) { err("%s - Error %d submitting control urb", __FUNCTION__, response); } /* initialize our wait queues */ init_waitqueue_head(&mos7840_port->wait_chase); init_waitqueue_head(&mos7840_port->delta_msr_wait); /* initialize our icount structure */ memset(&(mos7840_port->icount), 0x00, sizeof(mos7840_port->icount)); /* initialize our port settings */ mos7840_port->shadowMCR = MCR_MASTER_IE; /* Must set to enable ints! */ /* send a open port command */ mos7840_port->open = 1; //mos7840_change_port_settings(mos7840_port,old_termios); mos7840_port->icount.tx = 0; mos7840_port->icount.rx = 0; dbg("\n\nusb_serial serial:%p mos7840_port:%p\n usb_serial_port port:%p\n\n", serial, mos7840_port, port); return 0;}/***************************************************************************** * mos7840_chars_in_buffer * this function is called by the tty driver when it wants to know how many * bytes of data we currently have outstanding in the port (data that has * been written, but hasn't made it out the port yet) * If successful, we return the number of bytes left to be written in the * system, * Otherwise we return a negative error number. *****************************************************************************/static int mos7840_chars_in_buffer(struct usb_serial_port *port){ int i; int chars = 0; unsigned long flags; struct moschip_port *mos7840_port; dbg("%s \n", " mos7840_chars_in_buffer:entering ..........."); if (mos7840_port_paranoia_check(port, __FUNCTION__)) { dbg("%s", "Invalid port \n"); return -1; } mos7840_port = mos7840_get_port_private(port); if (mos7840_port == NULL) { dbg("%s \n", "mos7840_break:leaving ..........."); return -1; } spin_lock_irqsave(&mos7840_port->pool_lock,flags); for (i = 0; i < NUM_URBS; ++i) { if (mos7840_port->busy[i]) { chars += URB_TRANSFER_BUFFER_SIZE; } } spin_unlock_irqrestore(&mos7840_port->pool_lock,flags); dbg("%s - returns %d", __FUNCTION__, chars); return chars;}/************************************************************************ * * mos7840_block_until_tx_empty * * This function will block the close until one of the following: * 1. TX count are 0 * 2. The mos7840 has stopped * 3. A timout of 3 seconds without activity has expired * ************************************************************************/static void mos7840_block_until_tx_empty(struct moschip_port *mos7840_port){ int timeout = HZ / 10; int wait = 30; int count; while (1) { count = mos7840_chars_in_buffer(mos7840_port->port); /* Check for Buffer status */ if (count <= 0) { return; } /* Block the thread for a while */ interruptible_sleep_on_timeout(&mos7840_port->wait_chase, timeout); /* No activity.. count down section */ wait--; if (wait == 0) { dbg("%s - TIMEOUT", __FUNCTION__); return; } else { /* Reset timout value back to seconds */ wait = 30; } }}/***************************************************************************** * mos7840_close * this function is called by the tty driver when a port is closed *****************************************************************************/static void mos7840_close(struct usb_serial_port *port, struct file *filp){ struct usb_serial *serial; struct moschip_port *mos7840_port; struct moschip_port *port0; int j; __u16 Data; dbg("%s\n", "mos7840_close:entering..."); if (mos7840_port_paranoia_check(port, __FUNCTION__)) { dbg("%s", "Port Paranoia failed \n"); return; } serial = mos7840_get_usb_serial(port, __FUNCTION__); if (!serial) { dbg("%s", "Serial Paranoia failed \n"); return; } mos7840_port = mos7840_get_port_private(port); port0 = mos7840_get_port_private(serial->port[0]); if (mos7840_port == NULL || port0 == NULL) return; for (j = 0; j < NUM_URBS; ++j) usb_kill_urb(mos7840_port->write_urb_pool[j]); /* Freeing Write URBs */ for (j = 0; j < NUM_URBS; ++j) { if (mos7840_port->write_urb_pool[j]) { if (mos7840_port->write_urb_pool[j]->transfer_buffer) kfree(mos7840_port->write_urb_pool[j]-> transfer_buffer); usb_free_urb(mos7840_port->write_urb_pool[j]); } } if (serial->dev) { /* flush and block until tx is empty */ mos7840_block_until_tx_empty(mos7840_port); } /* While closing port, shutdown all bulk read, write * * and interrupt read if they exists */ if (serial->dev) { if (mos7840_port->write_urb) { dbg("%s", "Shutdown bulk write\n"); usb_kill_urb(mos7840_port->write_urb); } if (mos7840_port->read_urb) { dbg("%s", "Shutdown bulk read\n"); usb_kill_urb(mos7840_port->read_urb); } if ((&mos7840_port->control_urb)) { dbg("%s", "Shutdown control read\n"); // usb_kill_urb (mos7840_port->control_urb); } }// if(mos7840_port->ctrl_buf != NULL)// kfree(mos7840_port->ctrl_buf); port0->open_ports--; dbg("mos7840_num_open_ports in close%d:in port%d\n", port0->open_ports, port->number); if (port0->open_ports == 0) { if (serial->port[0]->interrupt_in_urb) { dbg("%s", "Shutdown interrupt_in_urb\n"); usb_kill_urb(serial->port[0]->interrupt_in_urb); } } if (mos7840_port->write_urb) { /* if this urb had a transfer buffer already (old tx) free it */ if (mos7840_port->write_urb->transfer_buffer != NULL) { kfree(mos7840_port->write_urb->transfer_buffer); } usb_free_urb(mos7840_port->write_urb); } Data = 0x0; mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); Data = 0x00; mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); mos7840_port->open = 0; dbg("%s \n", "Leaving ............");}/************************************************************************ * * mos7840_block_until_chase_response * * This function will block the close until one of the following: * 1. Response to our Chase comes from mos7840 * 2. A timout of 10 seconds without activity has expired * (1K of mos7840 data @ 2400 baud ==> 4 sec to empty) * ************************************************************************/static void mos7840_block_until_chase_response(struct moschip_port *mos7840_port){ int timeout = 1 * HZ; int wait = 10; int count; while (1) { count = mos7840_chars_in_buffer(mos7840_port->port); /* Check for Buffer status */ if (count <= 0) { return; } /* Block the thread for a while */ interruptible_sleep_on_timeout(&mos7840_port->wait_chase, timeout); /* No activity.. count down section */ wait--; if (wait == 0) { dbg("%s - TIMEOUT", __FUNCTION__); return; } else { /* Reset timout value back to seconds */ wait = 10; } }}/***************************************************************************** * mos7840_break * this function sends a break to the port *****************************************************************************/static void mos7840_break(struct usb_serial_port *port, int break_state){ unsigned char data; struct usb_serial *serial; struct moschip_port *mos7840_port; dbg("%s \n", "Entering ..........."); dbg("mos7840_break: Start\n"); if (mos7840_port_paranoia_check(port, __FUNCTION__)) { dbg("%s", "Port Paranoia failed \n"); return; } serial = mos7840_get_usb_serial(port, __FUNCTION__); if (!serial) { dbg("%s", "Serial Paranoia failed \n"); return; } mos7840_port = mos7840_get_port_private(port); if (mos7840_port == NULL) { return; } if (serial->dev) { /* flush and block until tx is empty */ mos7840_block_until_chase_response(mos7840_port); } if (break_state == -1) { data = mos7840_port->shadowLCR | LCR_SET_BREAK; } else { data = mos7840_port->shadowLCR & ~LCR_SET_BREAK; } mos7840_port->shadowLCR = data; dbg("mcs7840_break mos7840_port->shadowLCR is %x\n", mos7840_port->shadowLCR); mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, mos7840_port->shadowLCR); return;}/***************************************************************************** * mos7840_write_room * this function is called by the tty driver when it wants to know how many * bytes of data we can accept for a specific port. * If successful, we return the amount of room that we have for this port * Otherwise we return a negative error number. *****************************************************************************/static int mos7840_write_room(struct usb_serial_port *port){ int i; int room = 0; unsigned long flags; struct moschip_port *mos7840_port; dbg("%s \n", " mos7840_write_room:entering ..........."); if (mos7840_port_paranoia_check(port, __FUNCTION__)) { dbg("%s", "Invalid port \n"); dbg("%s \n", " mos7840_write_room:leaving ..........."); return -1; } mos7840_port = mos7840_get_port_private(port); if (mos7840_port == NULL) { dbg("%s \n", "mos7840_break:leaving ..........."); return -1; } spin_lock_irqsave(&mos7840_port->pool_lock, flags); for (i = 0; i < NUM_URBS; ++i) { if (!mos7840_port->busy[i]) { room += URB_TRANSFER_BUFFER_SIZE; } } spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); room = (room == 0) ? 0 : room - URB_TRANSFER_BUFFER_SIZE + 1; dbg("%s - returns %d", __FUNCTION__, room); return room;}/***************************************************************************** * mos7840_write * this function is called by the tty driver when data should be written to * the port. * If successful, we return the number of bytes written, otherwise we * return a negative error number. *****************************************************************************/static int mos7840_write(struct usb_serial_port *port, const unsigned char *data, int count){ int status; int i; int bytes_sent = 0; int transfer_size; unsigned long flags; struct moschip_port *mos7840_port; struct usb_serial *serial; struct urb *urb; //__u16 Data; const unsigned char *current_position = data; unsigned char *data1; dbg("%s \n", "entering ..........."); //dbg("mos7840_write: mos7840_port->shadowLCR is %x\n",mos7840_port->shadowLCR);#ifdef NOTMOS7840 Data = 0x00; status = 0; status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data); mos7840_port->shadowLCR = Data; dbg("mos7840_write: LINE_CONTROL_REGISTER is %x\n", Data); dbg("mos7840_write: mos7840_port->shadowLCR is %x\n", mos7840_port->shadowLCR); //Data = 0x03; //status = mos7840_set_uart_reg(port,LINE_CONTROL_REGISTER,Data); //mos7840_port->shadowLCR=Data;//Need to add later
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -