Example #1
0
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);
}
Example #2
0
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 */
Example #3
0
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
}	
Example #4
0
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;
}
Example #5
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
}
Example #6
0
void USART::put_string(const char *str)
{
	while(*str!='\0')
	{
		USART_SendData(_USARTx,*str++);
		wait_busy();
	}
}	
Example #7
0
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;
}
Example #8
0
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;
}
Example #9
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;
}
Example #10
0
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
	
}
Example #11
0
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;
}
Example #12
0
int USART::put_char(char ch)
{
	USART_SendData(_USARTx,ch);
	wait_busy();
	return ch;
}
Example #13
0
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 */
Example #14
0
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 */
Example #15
0
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 */
Example #16
0
void VngoClear3D::flush()
{
    run_dl();
    clrFlush();
    wait_busy();
}
Example #17
0
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);
	}
}				/*            */