static int smbus_readrtc(int slaveaddr,int devaddr) { uint32_t err,data; if (wait_busy() < 0) return -1; chip_write(SMB_CMD1, ((devaddr & 0xFF) & 0xFF),32); chip_write(SMB_STRT1, SMB_STRT_WR1B | slaveaddr,32); err = wait_busy(); if (err < 0) return err; /* * Read the data */ chip_write(SMB_STRT1, SMB_STRT_RD1B | slaveaddr, 32); err = wait_busy(); if (err < 0) return err; data = chip_read(SMB_DATA1,32); return (data & 0xFF); }
static void tx_d_frame(struct hfc4s8s_l1 *l1p) { struct sk_buff *skb; u_char f1, f2; u_char *cp; long cnt; if (l1p->l1_state != 7) return; /* TX fifo */ Write_hfc8(l1p->hw, R_FIFO, (l1p->st_num * 8 + 4)); wait_busy(l1p->hw); f1 = Read_hfc8(l1p->hw, A_F1); f2 = Read_hfc8_stable(l1p->hw, A_F2); if ((f1 ^ f2) & MAX_F_CNT) return; /* fifo is still filled */ if (l1p->tx_cnt > 0) { cnt = l1p->tx_cnt; l1p->tx_cnt = 0; l1p->d_if.ifc.l1l2(&l1p->d_if.ifc, PH_DATA | CONFIRM, (void *) cnt); } if ((skb = skb_dequeue(&l1p->d_tx_queue))) { cp = skb->data; cnt = skb->len; SetRegAddr(l1p->hw, A_FIFO_DATA0); while (cnt >= 4) { SetRegAddr(l1p->hw, A_FIFO_DATA0); fWrite_hfc32(l1p->hw, *(unsigned long *) cp); cp += 4; cnt -= 4; } while (cnt--) fWrite_hfc8(l1p->hw, *cp++); l1p->tx_cnt = skb->truesize; Write_hfc8(l1p->hw, A_INC_RES_FIFO, 1); /* increment f counter */ wait_busy(l1p->hw); dev_kfree_skb(skb); } } /* tx_d_frame */
void USART::put_string(const char *str,uint16_t length) { #if (USE_DMA == 1) wait_busy(); DMA_DeInit(_DMA1_Channelx); //将DMA的通道1寄存器重设为缺省值 _DMA1_Channelx->CPAR = (u32)&_USARTx->DR; //外设地址 _DMA1_Channelx->CMAR = (u32) str; //mem地址 _DMA1_Channelx->CNDTR = length ; //传输长度 _DMA1_Channelx->CCR = (0 << 14) | // 非存储器到存储器模式 (2 << 12) | // 通道优先级高 (0 << 11) | // 存储器数据宽度8bit (0 << 10) | // 存储器数据宽度8bit (0 << 9) | // 外设数据宽度8bit (0 << 8) | // 外设数据宽度8bit (1 << 7) | // 存储器地址增量模式 (0 << 6) | // 外设地址增量模式(不增) (0 << 5) | // 非循环模式 (1 << 4) | // 从存储器读 (1 << 3) | // 是否允许传输错误中断 (0 << 2) | // 是否允许半传输中断 (0 << 1) | // 是否允许传输完成中断 (1); // 通道开启 #else while(length--) { USART_SendData(_USARTx,*str++); while(USART_GetFlagStatus(_USARTx, USART_FLAG_TC) == RESET); } #endif }
int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len) { int timeout = I2C_MAX_TIMEOUT; char i = 0; //printf("%s chip: 0x%02x addr: 0x%04x alen: %d len: %d, data: %d\n", __func__, chip, addr, alen, len, *buf); __REG16(i2c_port_addr[i2c_port_num] + I2SR) = 0; __REG16(i2c_port_addr[i2c_port_num] + I2CR) = I2CR_IEN; /* Wait controller to be stable */ udelay(50); __REG16(i2c_port_addr[i2c_port_num] + I2CR) |= I2CR_MSTA; /* Start I2C transaction */ wait_busy(); __REG16(i2c_port_addr[i2c_port_num] + I2CR) |= I2CR_IIEN | I2CR_MTX | I2CR_TX_NO_AK; __REG16(i2c_port_addr[i2c_port_num] + I2DR) = chip << 1; wait_complete(); for(i = 0; i < len; i++){ __REG16(i2c_port_addr[i2c_port_num] + I2DR) = *(buf+i); wait_complete(); } __REG16(i2c_port_addr[i2c_port_num] + I2CR) &= ~(I2CR_MSTA | I2CR_MTX); wait_idle(); __REG16(i2c_port_addr[i2c_port_num] + I2CR) = 0; return 0; }
void USART::printf_length(const char *str,uint16_t length) { #if (USE_DMA == 1) uint16_t i = 0; uint16_t tmp_length; tmp_length = length; wait_busy(); while(tmp_length--) { send_buf[i++] = *str++; }; DMA_DeInit(_DMA1_Channelx); //将DMA的通道1寄存器重设为缺省值 _DMA1_Channelx->CPAR = (u32)&_USARTx->DR; //外设地址 _DMA1_Channelx->CMAR = (u32) send_buf; //mem地址 _DMA1_Channelx->CNDTR = length ; //传输长度 _DMA1_Channelx->CCR = (0 << 14) | // 非存储器到存储器模式 (2 << 12) | // 通道优先级高 (0 << 11) | // 存储器数据宽度8bit (0 << 10) | // 存储器数据宽度8bit (0 << 9) | // 外设数据宽度8bit (0 << 8) | // 外设数据宽度8bit (1 << 7) | // 存储器地址增量模式 (0 << 6) | // 外设地址增量模式(不增) (0 << 5) | // 非循环模式 (1 << 4) | // 从存储器读 (1 << 3) | // 是否允许传输错误中断 (0 << 2) | // 是否允许半传输中断 (0 << 1) | // 是否允许传输完成中断 (1); // 通道开启 #else putString(str,length); #endif }
void USART::put_string(const char *str) { while(*str!='\0') { USART_SendData(_USARTx,*str++); wait_busy(); } }
static int write_optb(int byte, uint8_t value) { volatile int16_t *hword = (uint16_t *)(STM32_OPTB_BASE + byte); int rv; rv = wait_busy(); if (rv) return rv; /* The target byte is the value we want to write. */ if (*(uint8_t *)hword == value) return EC_SUCCESS; /* Try to erase that byte back to 0xff. */ rv = preserve_optb(byte); if (rv) return rv; /* The value is 0xff after erase. No need to write 0xff again. */ if (value == 0xff) return EC_SUCCESS; rv = unlock(OPT_LOCK); if (rv) return rv; /* set OPTPG bit */ STM32_FLASH_CR |= OPTPG; *hword = ((~value) << STM32_OPTB_COMPL_SHIFT) | value; /* reset OPTPG bit */ STM32_FLASH_CR &= ~OPTPG; rv = wait_busy(); if (rv) return rv; lock(); return EC_SUCCESS; }
int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) { int timeout = I2C_MAX_TIMEOUT; char i = 0; uchar temp = 0; uchar temp2 = 0; DPRINTF("%s chip: 0x%02x addr: 0x%04x alen: %d len: %d\n", __func__, chip, addr, alen, len); __REG16(i2c_port_addr[i2c_port_num] + I2SR) = 0; __REG16(i2c_port_addr[i2c_port_num] + I2CR) = I2CR_IEN; /* Wait controller to be stable */ udelay(50); __REG16(i2c_port_addr[i2c_port_num] + I2CR) |= I2CR_MSTA; /* Start I2C transaction */ wait_busy(); __REG16(i2c_port_addr[i2c_port_num] + I2CR) |= I2CR_IIEN | I2CR_MTX | I2CR_TX_NO_AK; __REG16(i2c_port_addr[i2c_port_num] + I2DR) = chip << 1; wait_complete(); __REG16(i2c_port_addr[i2c_port_num] + I2DR) = addr; // address 0 -> version wait_complete(); // write finish: address and addr //DPRINTF("i2c_read: write addr done\n"); udelay(500); __REG16(i2c_port_addr[i2c_port_num] + I2CR) = I2CR_IEN | I2CR_MSTA | I2CR_MTX | I2CR_RSTA; /* Restart I2C transaction */ wait_busy(); __REG16(i2c_port_addr[i2c_port_num] + I2DR) = (chip << 1) | 0x01; wait_complete(); //DPRINTF("i2c_read: read action send\n"); udelay(500); __REG16(i2c_port_addr[i2c_port_num] + I2CR) = I2CR_IEN | I2CR_MSTA | I2CR_TX_NO_AK; temp = __REG16(i2c_port_addr[i2c_port_num] + I2DR); wait_complete(); __REG16(i2c_port_addr[i2c_port_num] + I2CR) &= ~(I2CR_MSTA | I2CR_MTX); wait_idle(); *buf = __REG16(i2c_port_addr[i2c_port_num] + I2DR); DPRINTF("i2c_read temp: 0x%x, buf: 0x%x\n", temp, *buf); __REG16(i2c_port_addr[i2c_port_num] + I2CR) = 0; return 0; }
static int smbus_writertc(int slaveaddr,int devaddr,int b) { int err; /* * Make sure the bus is idle (probably should * ignore error here) */ if (wait_busy() < 0) return -1; /* * Write the device address to the controller. There are two * parts, the high part goes in the "CMD" field, and the * low part is the data field. */ chip_write(SMB_CMD1,((devaddr & 0xFF) & 0xFF),32); chip_write(SMB_DATA1,((b & 0xFF) & 0xFF),32); /* * Start the command. Keep pounding on the device until it * submits or the timer expires, whichever comes first. The * datasheet says writes can take up to 10ms, so we'll give it 500. */ chip_write(SMB_STRT1,SMB_STRT_WR2B|slaveaddr,32); /* * Wait till the SMBus interface is done */ err = wait_busy(); if (err < 0) return err; return err; }
void USART::printf(const char* fmt,...) { __IO uint16_t length = 0; wait_busy(); va_list va_params; va_start(va_params,fmt); length = vsprintf(send_buf,fmt,va_params); va_end(va_params); #if (USE_DMA == 1) if(length != 0) { DMA_DeInit(_DMA1_Channelx); //将DMA的通道1寄存器重设为缺省值 _DMA1_Channelx->CPAR = (u32)&_USARTx->DR; //外设地址 _DMA1_Channelx->CMAR = (u32) send_buf; //mem地址 _DMA1_Channelx->CNDTR = length ; //传输长度 _DMA1_Channelx->CCR = (0 << 14) | // 非存储器到存储器模式 (2 << 12) | // 通道优先级高 (0 << 11) | // 存储器数据宽度8bit (0 << 10) | // 存储器数据宽度8bit (0 << 9) | // 外设数据宽度8bit (0 << 8) | // 外设数据宽度8bit (1 << 7) | // 存储器地址增量模式 (0 << 6) | // 外设地址增量模式(不增) (0 << 5) | // 非循环模式 (1 << 4) | // 从存储器读 (1 << 3) | // 是否允许传输错误中断 (0 << 2) | // 是否允许半传输中断 (0 << 1) | // 是否允许传输完成中断 (1); // 通道开启 // DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&_USARTx->DR; //DMA外设ADC基地址 // DMA_InitStructure.DMA_MemoryBaseAddr = (u32)send_buf; //DMA内存基地址 // DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; // // DMA_InitStructure.DMA_BufferSize = 128; //DMA通道的DMA缓存的大小 // DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // // DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // // DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // // DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte; // // DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在循环缓存模式 // DMA_InitStructure.DMA_Priority = DMA_Priority_High; // // DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输 // DMA_Init(_DMA1_Channelx, &DMA_InitStructure); // // // DMA_SetCurrDataCounter(_DMA1_Channelx,length); // DMA_Cmd(_DMA1_Channelx,ENABLE); } #else putString(send_buf); #endif }
static int erase_optb(void) { int rv; rv = wait_busy(); if (rv) return rv; rv = unlock(OPT_LOCK); if (rv) return rv; /* Must be set in 2 separate lines. */ STM32_FLASH_CR |= OPTER; STM32_FLASH_CR |= STRT; rv = wait_busy(); if (rv) return rv; lock(); return EC_SUCCESS; }
int USART::put_char(char ch) { USART_SendData(_USARTx,ch); wait_busy(); return ch; }
static void tx_b_frame(struct hfc4s8s_btype *bch) { struct sk_buff *skb; struct hfc4s8s_l1 *l1 = bch->l1p; u_char *cp; int cnt, max, hdlc_num; long ack_len = 0; if (!l1->enabled || (bch->mode == L1_MODE_NULL)) return; /* TX fifo */ Write_hfc8(l1->hw, R_FIFO, (l1->st_num * 8 + ((bch->bchan == 1) ? 0 : 2))); wait_busy(l1->hw); do { if (bch->mode == L1_MODE_HDLC) { hdlc_num = Read_hfc8(l1->hw, A_F1) & MAX_F_CNT; hdlc_num -= (Read_hfc8_stable(l1->hw, A_F2) & MAX_F_CNT); if (hdlc_num < 0) hdlc_num += 16; if (hdlc_num >= 15) break; /* fifo still filled up with hdlc frames */ } else hdlc_num = 0; if (!(skb = bch->tx_skb)) { if (!(skb = skb_dequeue(&bch->tx_queue))) { l1->hw->mr.fifo_slow_timer_service[l1-> st_num] &= ~((bch->bchan == 1) ? 1 : 4); break; /* list empty */ } bch->tx_skb = skb; bch->tx_cnt = 0; } if (!hdlc_num) l1->hw->mr.fifo_slow_timer_service[l1->st_num] |= ((bch->bchan == 1) ? 1 : 4); else l1->hw->mr.fifo_slow_timer_service[l1->st_num] &= ~((bch->bchan == 1) ? 1 : 4); max = Read_hfc16_stable(l1->hw, A_Z2); max -= Read_hfc16(l1->hw, A_Z1); if (max <= 0) max += 384; max--; if (max < 16) break; /* don't write to small amounts of bytes */ cnt = skb->len - bch->tx_cnt; if (cnt > max) cnt = max; cp = skb->data + bch->tx_cnt; bch->tx_cnt += cnt; #ifndef HISAX_HFC4S8S_PCIMEM SetRegAddr(l1->hw, A_FIFO_DATA0); #endif while (cnt >= 4) { #ifdef HISAX_HFC4S8S_PCIMEM fWrite_hfc32(l1->hw, A_FIFO_DATA0, *(unsigned long *) cp); #else fWrite_hfc32(l1->hw, *(unsigned long *) cp); #endif cp += 4; cnt -= 4; } while (cnt--) #ifdef HISAX_HFC4S8S_PCIMEM fWrite_hfc8(l1->hw, A_FIFO_DATA0, *cp++); #else fWrite_hfc8(l1->hw, *cp++); #endif if (bch->tx_cnt >= skb->len) { if (bch->mode == L1_MODE_HDLC) { /* increment f counter */ Write_hfc8(l1->hw, A_INC_RES_FIFO, 1); } ack_len += skb->truesize; bch->tx_skb = NULL; bch->tx_cnt = 0; dev_kfree_skb(skb); } else /* Re-Select */ Write_hfc8(l1->hw, R_FIFO, (l1->st_num * 8 + ((bch->bchan == 1) ? 0 : 2))); wait_busy(l1->hw); } while (1); if (ack_len) bch->b_if.ifc.l1l2((struct hisax_if *) &bch->b_if, PH_DATA | CONFIRM, (void *) ack_len); } /* tx_b_frame */
static void rx_b_frame(struct hfc4s8s_btype *bch) { int z1, z2, hdlc_complete; u_char f1, f2; struct hfc4s8s_l1 *l1 = bch->l1p; struct sk_buff *skb; if (!l1->enabled || (bch->mode == L1_MODE_NULL)) return; do { /* RX Fifo */ Write_hfc8(l1->hw, R_FIFO, (l1->st_num * 8 + ((bch->bchan == 1) ? 1 : 3))); wait_busy(l1->hw); if (bch->mode == L1_MODE_HDLC) { f1 = Read_hfc8_stable(l1->hw, A_F1); f2 = Read_hfc8(l1->hw, A_F2); hdlc_complete = ((f1 ^ f2) & MAX_F_CNT); } else hdlc_complete = 0; z1 = Read_hfc16_stable(l1->hw, A_Z1); z2 = Read_hfc16(l1->hw, A_Z2); z1 = (z1 - z2); if (hdlc_complete) z1++; if (z1 < 0) z1 += 384; if (!z1) break; if (!(skb = bch->rx_skb)) { if (! (skb = dev_alloc_skb((bch->mode == L1_MODE_TRANS) ? z1 : (MAX_B_FRAME_SIZE + 3)))) { printk(KERN_ERR "HFC-4S/8S: Could not allocate B " "channel receive buffer"); return; } bch->rx_ptr = skb->data; bch->rx_skb = skb; } skb->len = (bch->rx_ptr - skb->data) + z1; /* HDLC length check */ if ((bch->mode == L1_MODE_HDLC) && ((hdlc_complete && (skb->len < 4)) || (skb->len > (MAX_B_FRAME_SIZE + 3)))) { skb->len = 0; bch->rx_ptr = skb->data; Write_hfc8(l1->hw, A_INC_RES_FIFO, 2); /* reset fifo */ wait_busy(l1->hw); return; } #ifndef HISAX_HFC4S8S_PCIMEM SetRegAddr(l1->hw, A_FIFO_DATA0); #endif while (z1 >= 4) { #ifdef HISAX_HFC4S8S_PCIMEM *((unsigned long *) bch->rx_ptr) = Read_hfc32(l1->hw, A_FIFO_DATA0); #else *((unsigned long *) bch->rx_ptr) = fRead_hfc32(l1->hw); #endif bch->rx_ptr += 4; z1 -= 4; } while (z1--) #ifdef HISAX_HFC4S8S_PCIMEM *(bch->rx_ptr++) = Read_hfc8(l1->hw, A_FIFO_DATA0); #else *(bch->rx_ptr++) = fRead_hfc8(l1->hw); #endif if (hdlc_complete) { /* increment f counter */ Write_hfc8(l1->hw, A_INC_RES_FIFO, 1); wait_busy(l1->hw); /* hdlc crc check */ bch->rx_ptr--; if (*bch->rx_ptr) { skb->len = 0; bch->rx_ptr = skb->data; continue; } skb->len -= 3; } if (hdlc_complete || (bch->mode == L1_MODE_TRANS)) { bch->rx_skb = NULL; bch->rx_ptr = NULL; bch->b_if.ifc.l1l2(&bch->b_if.ifc, PH_DATA | INDICATION, skb); } } while (1); } /* rx_b_frame */
static void rx_d_frame(struct hfc4s8s_l1 *l1p, int ech) { int z1, z2; u_char f1, f2, df; struct sk_buff *skb; u_char *cp; if (!l1p->enabled) return; do { /* E/D RX fifo */ Write_hfc8(l1p->hw, R_FIFO, (l1p->st_num * 8 + ((ech) ? 7 : 5))); wait_busy(l1p->hw); f1 = Read_hfc8_stable(l1p->hw, A_F1); f2 = Read_hfc8(l1p->hw, A_F2); df = f1 - f2; if ((f1 - f2) < 0) df = f1 - f2 + MAX_F_CNT + 1; if (!df) { return; /* no complete frame in fifo */ } z1 = Read_hfc16_stable(l1p->hw, A_Z1); z2 = Read_hfc16(l1p->hw, A_Z2); z1 = z1 - z2 + 1; if (z1 < 0) z1 += 384; if (!(skb = dev_alloc_skb(MAX_D_FRAME_SIZE))) { printk(KERN_INFO "HFC-4S/8S: Could not allocate D/E " "channel receive buffer"); Write_hfc8(l1p->hw, A_INC_RES_FIFO, 2); wait_busy(l1p->hw); return; } if (((z1 < 4) || (z1 > MAX_D_FRAME_SIZE))) { if (skb) dev_kfree_skb(skb); /* remove errornous D frame */ if (df == 1) { /* reset fifo */ Write_hfc8(l1p->hw, A_INC_RES_FIFO, 2); wait_busy(l1p->hw); return; } else { /* read errornous D frame */ #ifndef HISAX_HFC4S8S_PCIMEM SetRegAddr(l1p->hw, A_FIFO_DATA0); #endif while (z1 >= 4) { #ifdef HISAX_HFC4S8S_PCIMEM Read_hfc32(l1p->hw, A_FIFO_DATA0); #else fRead_hfc32(l1p->hw); #endif z1 -= 4; } while (z1--) #ifdef HISAX_HFC4S8S_PCIMEM Read_hfc8(l1p->hw, A_FIFO_DATA0); #else fRead_hfc8(l1p->hw); #endif Write_hfc8(l1p->hw, A_INC_RES_FIFO, 1); wait_busy(l1p->hw); return; } } cp = skb->data; #ifndef HISAX_HFC4S8S_PCIMEM SetRegAddr(l1p->hw, A_FIFO_DATA0); #endif while (z1 >= 4) { #ifdef HISAX_HFC4S8S_PCIMEM *((unsigned long *) cp) = Read_hfc32(l1p->hw, A_FIFO_DATA0); #else *((unsigned long *) cp) = fRead_hfc32(l1p->hw); #endif cp += 4; z1 -= 4; } while (z1--) #ifdef HISAX_HFC4S8S_PCIMEM *cp++ = Read_hfc8(l1p->hw, A_FIFO_DATA0); #else *cp++ = fRead_hfc8(l1p->hw); #endif Write_hfc8(l1p->hw, A_INC_RES_FIFO, 1); /* increment f counter */ wait_busy(l1p->hw); if (*(--cp)) { dev_kfree_skb(skb); } else { skb->len = (cp - skb->data) - 2; if (ech) l1p->d_if.ifc.l1l2(&l1p->d_if.ifc, PH_DATA_E | INDICATION, skb); else l1p->d_if.ifc.l1l2(&l1p->d_if.ifc, PH_DATA | INDICATION, skb); } } while (1); } /* rx_d_frame */
void VngoClear3D::flush() { run_dl(); clrFlush(); wait_busy(); }
static void bch_l2l1(struct hisax_if *ifc, int pr, void *arg) { struct hfc4s8s_btype *bch = ifc->priv; struct hfc4s8s_l1 *l1 = bch->l1p; struct sk_buff *skb = (struct sk_buff *) arg; long mode = (long) arg; u_long flags; switch (pr) { case (PH_DATA | REQUEST): if (!l1->enabled || (bch->mode == L1_MODE_NULL)) { dev_kfree_skb(skb); break; } spin_lock_irqsave(&l1->lock, flags); skb_queue_tail(&bch->tx_queue, skb); if (!bch->tx_skb && (bch->tx_cnt <= 0)) { l1->hw->mr.r_irq_fifo_blx[l1->st_num] |= ((bch->bchan == 1) ? 1 : 4); spin_unlock_irqrestore(&l1->lock, flags); schedule_work(&l1->hw->tqueue); } else spin_unlock_irqrestore(&l1->lock, flags); break; case (PH_ACTIVATE | REQUEST): case (PH_DEACTIVATE | REQUEST): if (!l1->enabled) break; if (pr == (PH_DEACTIVATE | REQUEST)) mode = L1_MODE_NULL; switch (mode) { case L1_MODE_HDLC: spin_lock_irqsave(&l1->lock, flags); l1->hw->mr.timer_usg_cnt++; l1->hw->mr. fifo_slow_timer_service[l1-> st_num] |= ((bch->bchan == 1) ? 0x2 : 0x8); Write_hfc8(l1->hw, R_FIFO, (l1->st_num * 8 + ((bch->bchan == 1) ? 0 : 2))); wait_busy(l1->hw); Write_hfc8(l1->hw, A_CON_HDLC, 0xc); /* HDLC mode, flag fill, connect ST */ Write_hfc8(l1->hw, A_SUBCH_CFG, 0); /* 8 bits */ Write_hfc8(l1->hw, A_IRQ_MSK, 1); /* enable TX interrupts for hdlc */ Write_hfc8(l1->hw, A_INC_RES_FIFO, 2); /* reset fifo */ wait_busy(l1->hw); Write_hfc8(l1->hw, R_FIFO, (l1->st_num * 8 + ((bch->bchan == 1) ? 1 : 3))); wait_busy(l1->hw); Write_hfc8(l1->hw, A_CON_HDLC, 0xc); /* HDLC mode, flag fill, connect ST */ Write_hfc8(l1->hw, A_SUBCH_CFG, 0); /* 8 bits */ Write_hfc8(l1->hw, A_IRQ_MSK, 1); /* enable RX interrupts for hdlc */ Write_hfc8(l1->hw, A_INC_RES_FIFO, 2); /* reset fifo */ Write_hfc8(l1->hw, R_ST_SEL, l1->st_num); l1->hw->mr.r_ctrl0 |= (bch->bchan & 3); Write_hfc8(l1->hw, A_ST_CTRL0, l1->hw->mr.r_ctrl0); bch->mode = L1_MODE_HDLC; spin_unlock_irqrestore(&l1->lock, flags); bch->b_if.ifc.l1l2(&bch->b_if.ifc, PH_ACTIVATE | INDICATION, NULL); break; case L1_MODE_TRANS: spin_lock_irqsave(&l1->lock, flags); l1->hw->mr. fifo_rx_trans_enables[l1-> st_num] |= ((bch->bchan == 1) ? 0x2 : 0x8); l1->hw->mr.timer_usg_cnt++; Write_hfc8(l1->hw, R_FIFO, (l1->st_num * 8 + ((bch->bchan == 1) ? 0 : 2))); wait_busy(l1->hw); Write_hfc8(l1->hw, A_CON_HDLC, 0xf); /* Transparent mode, 1 fill, connect ST */ Write_hfc8(l1->hw, A_SUBCH_CFG, 0); /* 8 bits */ Write_hfc8(l1->hw, A_IRQ_MSK, 0); /* disable TX interrupts */ Write_hfc8(l1->hw, A_INC_RES_FIFO, 2); /* reset fifo */ wait_busy(l1->hw); Write_hfc8(l1->hw, R_FIFO, (l1->st_num * 8 + ((bch->bchan == 1) ? 1 : 3))); wait_busy(l1->hw); Write_hfc8(l1->hw, A_CON_HDLC, 0xf); /* Transparent mode, 1 fill, connect ST */ Write_hfc8(l1->hw, A_SUBCH_CFG, 0); /* 8 bits */ Write_hfc8(l1->hw, A_IRQ_MSK, 0); /* disable RX interrupts */ Write_hfc8(l1->hw, A_INC_RES_FIFO, 2); /* reset fifo */ Write_hfc8(l1->hw, R_ST_SEL, l1->st_num); l1->hw->mr.r_ctrl0 |= (bch->bchan & 3); Write_hfc8(l1->hw, A_ST_CTRL0, l1->hw->mr.r_ctrl0); bch->mode = L1_MODE_TRANS; spin_unlock_irqrestore(&l1->lock, flags); bch->b_if.ifc.l1l2(&bch->b_if.ifc, PH_ACTIVATE | INDICATION, NULL); break; default: if (bch->mode == L1_MODE_NULL) break; spin_lock_irqsave(&l1->lock, flags); l1->hw->mr. fifo_slow_timer_service[l1-> st_num] &= ~((bch->bchan == 1) ? 0x3 : 0xc); l1->hw->mr. fifo_rx_trans_enables[l1-> st_num] &= ~((bch->bchan == 1) ? 0x3 : 0xc); l1->hw->mr.timer_usg_cnt--; Write_hfc8(l1->hw, R_FIFO, (l1->st_num * 8 + ((bch->bchan == 1) ? 0 : 2))); wait_busy(l1->hw); Write_hfc8(l1->hw, A_IRQ_MSK, 0); /* disable TX interrupts */ wait_busy(l1->hw); Write_hfc8(l1->hw, R_FIFO, (l1->st_num * 8 + ((bch->bchan == 1) ? 1 : 3))); wait_busy(l1->hw); Write_hfc8(l1->hw, A_IRQ_MSK, 0); /* disable RX interrupts */ Write_hfc8(l1->hw, R_ST_SEL, l1->st_num); l1->hw->mr.r_ctrl0 &= ~(bch->bchan & 3); Write_hfc8(l1->hw, A_ST_CTRL0, l1->hw->mr.r_ctrl0); spin_unlock_irqrestore(&l1->lock, flags); bch->mode = L1_MODE_NULL; bch->b_if.ifc.l1l2(&bch->b_if.ifc, PH_DEACTIVATE | INDICATION, NULL); if (bch->tx_skb) { dev_kfree_skb(bch->tx_skb); bch->tx_skb = NULL; } if (bch->rx_skb) { dev_kfree_skb(bch->rx_skb); bch->rx_skb = NULL; } skb_queue_purge(&bch->tx_queue); bch->tx_cnt = 0; bch->rx_ptr = NULL; break; } /* timer is only used when at least one b channel */ /* is set up to transparent mode */ if (l1->hw->mr.timer_usg_cnt) { Write_hfc8(l1->hw, R_IRQMSK_MISC, M_TI_IRQMSK); } else { Write_hfc8(l1->hw, R_IRQMSK_MISC, 0); } break; default: printk(KERN_INFO "HFC-4S/8S: Unknown B-chan cmd 0x%x received, ignored\n", pr); break; } if (!l1->enabled) bch->b_if.ifc.l1l2(&bch->b_if.ifc, PH_DEACTIVATE | INDICATION, NULL); } /* bch_l2l1 */
static void tx_d_frame(struct hfc4s8s_l1 *l1p) { struct sk_buff *skb; u_char f1, f2; u_char *cp; long cnt; if (l1p->l1_state != 7) return; /* */ Write_hfc8(l1p->hw, R_FIFO, (l1p->st_num * 8 + 4)); wait_busy(l1p->hw); f1 = Read_hfc8(l1p->hw, A_F1); f2 = Read_hfc8_stable(l1p->hw, A_F2); if ((f1 ^ f2) & MAX_F_CNT) return; /* */ if (l1p->tx_cnt > 0) { cnt = l1p->tx_cnt; l1p->tx_cnt = 0; l1p->d_if.ifc.l1l2(&l1p->d_if.ifc, PH_DATA | CONFIRM, (void *) cnt); } if ((skb = skb_dequeue(&l1p->d_tx_queue))) { cp = skb->data; cnt = skb->len; #ifndef HISAX_HFC4S8S_PCIMEM SetRegAddr(l1p->hw, A_FIFO_DATA0); #endif while (cnt >= 4) { #ifdef HISAX_HFC4S8S_PCIMEM fWrite_hfc32(l1p->hw, A_FIFO_DATA0, *(unsigned long *) cp); #else SetRegAddr(l1p->hw, A_FIFO_DATA0); fWrite_hfc32(l1p->hw, *(unsigned long *) cp); #endif cp += 4; cnt -= 4; } #ifdef HISAX_HFC4S8S_PCIMEM while (cnt--) fWrite_hfc8(l1p->hw, A_FIFO_DATA0, *cp++); #else while (cnt--) fWrite_hfc8(l1p->hw, *cp++); #endif l1p->tx_cnt = skb->truesize; Write_hfc8(l1p->hw, A_INC_RES_FIFO, 1); /* */ wait_busy(l1p->hw); dev_kfree_skb(skb); } } /* */