?? sync_serial.c
字號:
port->odd_input = 0; init_waitqueue_head(&port->out_wait_q); init_waitqueue_head(&port->in_wait_q); port->ctrl_data_shadow = IO_STATE(R_SYNC_SERIAL1_CTRL, tr_baud, c115k2Hz) | IO_STATE(R_SYNC_SERIAL1_CTRL, mode, master_output) | IO_STATE(R_SYNC_SERIAL1_CTRL, error, ignore) | IO_STATE(R_SYNC_SERIAL1_CTRL, rec_enable, disable) | IO_STATE(R_SYNC_SERIAL1_CTRL, f_synctype, normal) | IO_STATE(R_SYNC_SERIAL1_CTRL, f_syncsize, word) | IO_STATE(R_SYNC_SERIAL1_CTRL, f_sync, on) | IO_STATE(R_SYNC_SERIAL1_CTRL, clk_mode, normal) | IO_STATE(R_SYNC_SERIAL1_CTRL, clk_halt, stopped) | IO_STATE(R_SYNC_SERIAL1_CTRL, bitorder, msb) | IO_STATE(R_SYNC_SERIAL1_CTRL, tr_enable, disable) | IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit) | IO_STATE(R_SYNC_SERIAL1_CTRL, buf_empty, lmt_8) | IO_STATE(R_SYNC_SERIAL1_CTRL, buf_full, lmt_8) | IO_STATE(R_SYNC_SERIAL1_CTRL, flow_ctrl, enabled) | IO_STATE(R_SYNC_SERIAL1_CTRL, clk_polarity, neg) | IO_STATE(R_SYNC_SERIAL1_CTRL, frame_polarity, normal)| IO_STATE(R_SYNC_SERIAL1_CTRL, status_polarity, inverted)| IO_STATE(R_SYNC_SERIAL1_CTRL, clk_driver, normal) | IO_STATE(R_SYNC_SERIAL1_CTRL, frame_driver, normal) | IO_STATE(R_SYNC_SERIAL1_CTRL, status_driver, normal)| IO_STATE(R_SYNC_SERIAL1_CTRL, def_out0, high); if (port->use_dma) port->ctrl_data_shadow |= IO_STATE(R_SYNC_SERIAL1_CTRL, dma_enable, on); else port->ctrl_data_shadow |= IO_STATE(R_SYNC_SERIAL1_CTRL, dma_enable, off); *port->ctrl_data = port->ctrl_data_shadow;}static int sync_serial_open(struct inode *inode, struct file *file){ int dev = MINOR(inode->i_rdev); DEBUG(printk("Open sync serial port %d\n", dev)); if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { DEBUG(printk("Invalid minor %d\n", dev)); return -ENODEV; } if (ports[dev].busy) { DEBUG(printk("Device is busy.. \n")); return -EBUSY; } ports[dev].busy = 1; return 0;}static int sync_serial_release(struct inode *inode, struct file *file){ int dev = MINOR(inode->i_rdev); if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { DEBUG(printk("Invalid minor %d\n", dev)); return -ENODEV; } ports[dev].busy = 0; return 0;}static int sync_serial_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ int return_val = 0; int dev = MINOR(file->f_dentry->d_inode->i_rdev); sync_port* port; if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { DEBUG(printk("Invalid minor %d\n", dev)); return -1; } port = &ports[dev]; /* Disable port while changing config */ if (dev) { RESET_DMA(4); WAIT_DMA(4); *R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop, do) | IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do); SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, async); } else { RESET_DMA(8); WAIT_DMA(8); *R_DMA_CH8_CLR_INTR = IO_STATE(R_DMA_CH8_CLR_INTR, clr_eop, do) | IO_STATE(R_DMA_CH8_CLR_INTR, clr_descr, do); SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async); } *R_GEN_CONFIG_II = gen_config_ii_shadow; switch(cmd) { case SSP_SPEED: if (GET_SPEED(arg) == CODEC) { if (dev) SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, codec); else SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, codec); SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, prescaler, GET_FREQ(arg)); SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, frame_rate, GET_FRAME_RATE(arg)); SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, word_rate, GET_WORD_RATE(arg)); } else { SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_baud, GET_SPEED(arg)); if (dev) SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, baudrate); else SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, baudrate); } break; case SSP_MODE: if (arg > 5) return -EINVAL; SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, arg); break; case SSP_FRAME_SYNC: if (arg & NORMAL_SYNC) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, normal); else if (arg & EARLY_SYNC) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, early); if (arg & BIT_SYNC) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, bit); else if (arg & WORD_SYNC) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, word); else if (arg & EXTENDED_SYNC) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, extended); if (arg & SYNC_ON) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on); else if (arg & SYNC_OFF) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, off); if (arg & WORD_SIZE_8) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size8bit); else if (arg & WORD_SIZE_12) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size12bit); else if (arg & WORD_SIZE_16) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size16bit); else if (arg & WORD_SIZE_24) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size24bit); else if (arg & WORD_SIZE_32) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size32bit); if (arg & BIT_ORDER_MSB) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, msb); else if (arg & BIT_ORDER_LSB) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, lsb); if (arg & FLOW_CONTROL_ENABLE) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, enabled); else if (arg & FLOW_CONTROL_DISABLE) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, disabled); if (arg & CLOCK_NOT_GATED) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, normal); else if (arg & CLOCK_GATED) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, gated); break; case SSP_IPOLARITY: if (arg & CLOCK_NORMAL) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, neg); else if (arg & CLOCK_INVERT) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, pos); if (arg & FRAME_NORMAL) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, normal); else if (arg & FRAME_INVERT) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, inverted); if (arg & STATUS_NORMAL) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_polarity, normal); else if (arg & STATUS_INVERT) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_polarity, inverted); break; case SSP_OPOLARITY: if (arg & CLOCK_NORMAL) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, normal); else if (arg & CLOCK_INVERT) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, inverted); if (arg & FRAME_NORMAL) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, normal); else if (arg & FRAME_INVERT) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, inverted); if (arg & STATUS_NORMAL) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_driver, normal); else if (arg & STATUS_INVERT) SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_driver, inverted); break; case SSP_SPI: SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, disabled); SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, msb); SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size8bit); SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on); SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, word); SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, normal); if (arg & SPI_SLAVE) { SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, inverted); SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, neg); SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, SLAVE_INPUT); } else { SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, inverted); SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, inverted); SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, MASTER_OUTPUT); } break; default: return_val = -1; } /* Set config and enable port */ *port->ctrl_data = port->ctrl_data_shadow; *R_SYNC_SERIAL_PRESCALE = sync_serial_prescale_shadow; if (dev) SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, sync); else SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, sync); *R_GEN_CONFIG_II = gen_config_ii_shadow; return return_val;}static ssize_t sync_serial_manual_write(struct file * file, const char * buf, size_t count, loff_t *ppos){ int dev = MINOR(file->f_dentry->d_inode->i_rdev); DECLARE_WAITQUEUE(wait, current); sync_port* port; if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { DEBUG(printk("Invalid minor %d\n", dev)); return -ENODEV; } port = &ports[dev]; copy_from_user(port->out_buffer, buf, count); port->outp = port->out_buffer; port->out_count = count; port->odd_output = 1; add_wait_queue(&port->out_wait_q, &wait); set_current_state(TASK_INTERRUPTIBLE); *R_IRQ_MASK1_SET = 1 << port->ready_irq_bit; /* transmitter ready IRQ on */ send_word(port); /* Start sender by sending first word */ schedule(); set_current_state(TASK_RUNNING); remove_wait_queue(&port->out_wait_q, &wait); if (signal_pending(current)) { return -EINTR; } return count;}static ssize_t sync_serial_write(struct file * file, const char * buf, size_t count, loff_t *ppos){ int dev = MINOR(file->f_dentry->d_inode->i_rdev); DECLARE_WAITQUEUE(wait, current); sync_port *port; if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) { DEBUG(printk("Invalid minor %d\n", dev)); return -ENODEV; } port = &ports[dev]; DEBUG(printk("Write dev %d count %d\n", port->port_nbr, count)); count = count > OUT_BUFFER_SIZE ? OUT_BUFFER_SIZE : count; /* Make sure transmitter is running */ SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt, running); SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable, enable); *port->ctrl_data = port->ctrl_data_shadow; if (!port->use_dma) { return sync_serial_manual_write(file, buf, count, ppos); } copy_from_user(port->out_buffer, buf, count);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -