⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb_phci.c

📁 philips公司ISP1362 USB OTG控制芯片的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
			/**********************************************************************/

			ram_data[2] = ((__u8)((ed->hwINFO & HC_ED_MPS) >> 16));


			/************************************************************************/
			/* ptd_header[3]: 7..4		End point number(3...0)		from ED EN		*/
			/* ptd_header[3]: 3		 	reserved(0)					0 (always) 		*/
			/* ptd_header[3]: 2		 	speed(0)					from ED			*/
			/* ptd_header[3]: 1..0		Max.PacketSize(9..8)		from ED MPS		*/
			/************************************************************************/

			ram_data[3] = (((__u8)((ed->hwINFO & HC_ED_EN) >> 7)) << 4);

			if(ed->hwINFO & HC_ED_SPD) {				/* Check if speed device or not */
				ram_data[3] |= PTD_SPEED;
			}

			ram_data[3] |= (((__u8)((ed->hwINFO & HC_ED_MPS) >> 24)) & 0x03);
	

			/********************************************************************************/
			/* ptd_header[4]: 7..0		Total Bytes(7...0)		from td cbp & be			*/
			/* ptd_header[5]: 1..0 		total bytes(9..8)			from td cbp & be		*/
			/********************************************************************************/

			if(td->hwCBP) {
				payload_bytes = td->hwBE - td->hwCBP + 1;				/* get the total bytes from td cbp & be */
				ram_data[4] = (__u8)payload_bytes;
				ram_data[5] = (__u8)(payload_bytes >> 8);
			} else {			/* Null data packet */
				payload_bytes = 0;
				ram_data[4] = 0;
				ram_data[5] = 0;
			}
	
			/********************************************************************************/
			/* ptd_header[5]: 7			paired(0)					from ping_pong input 	*/
			/* ptd_header[5]: 6		 	ping_pong(0)				from ping_pong input 	*/
			/* ptd_header[5]: 5..4	 	reserved(1..0)				00 always 				*/
			/* ptd_header[5]: 3..2 		token direction(1..0)		from ed DIR 			*/
			/* ptd_header[5]: 1..0 		total bytes(9..8)			already filled before 	*/
			/********************************************************************************/

#ifdef CONFIG_USB_PHCD_PING_PONG

			if(td_ptd_map->ping_pong) {
				ptd_map_buff->ping_pong.fill_seq &= (~PP_SEQ_START);
				if(ptd_map_buff->ping_pong.fill_count < 3) ptd_map_buff->ping_pong.fill_count++;
				else isp1362_printk("error: ptd_map_buff->ping_pong.fill_count = %x\n",ptd_map_buff->ping_pong.fill_count);
			}

			ram_data[5] |= td_ptd_map->ping_pong;

#endif /* CONFIG_USB_PHCD_PING_PONG */

			byte_data = (__u8)((ed->hwINFO & HC_ED_DIR) >> 11);
			if(byte_data != OHCI_OUT && byte_data != OHCI_IN) {
				byte_data = (__u8)((td->hwINFO & HC_GTD_DP) >> 19);
			}

			ram_data[5] |= (byte_data << 2);

			/********************************************************************************/
			/* ptd_header[6]: 7			format(0)					0	always 				*/
			/* ptd_header[6]: 6..0	 	function address(6..0)		from ED FA				*/
			/********************************************************************************/

			ram_data[6] = ((__u8)(ed->hwINFO & HC_ED_FA));

			/*************************************************************************************/
			/* ptd_header[7]: 7..0	 	Frame Number/Int polling Interval(7..0)	poll_frame# input*/
			/*************************************************************************************/
			ram_data[7] = 0;

			if(ed->type == PIPE_INTERRUPT) {
				__u8	int_interval, byte;

				int_interval = (ed->int_interval >> 1);
				byte = 0;
				while(int_interval) {int_interval >>= 1; byte++;}

#ifdef CONFIG_USB_PHCD_EVEN_SCH
				ram_data[7] = (byte << 5);				/* Check the last 5 bits of Interrupt polling interval */
				ram_data[7] |= ed->int_branch ;
#else
				ram_data[7] = (byte << 1);				/* Always schedule on even frame */
#endif /* CONFIG_USB_PHCD_EVEN_SCH */

			}

			/* start sendig the data for this ptd */

			ram_addr = ptd_map_buff->ram_buff_addr+index*(ptd_map_buff->regs.block_pl_size + HC_PTD_HEADER_SIZE);
			ptd_payload = (__u8*)(td->hwCBP);

			if( (byte_data != OHCI_IN ) && payload_bytes && ptd_payload ) {			/* Don's send data in case of IN token */
				total_bytes += payload_bytes;

				fnvPhciRamWrite(phci,payload_bytes, HC_DIR_ADDR_INCREMENT, (ram_addr+HC_PTD_HEADER_SIZE), ptd_payload);

			}

			if(ram_addr < 2*HC_ISTL_BUFFER_LENGTH) 
				isp1362_printk("Something bad is going to happen, trying to write at %x for A/INTL ptd's", ram_addr);

			fnvPhciRamWrite(phci,HC_PTD_HEADER_SIZE, HC_DIR_ADDR_INCREMENT, ram_addr, ram_data);		/* Send the ptd header */


			td_ptd_map->total_bytes = payload_bytes+HC_PTD_HEADER_SIZE;			/* Set the total bytes size for this td-ptd map */
			ptd_map_buff->active_ptd_bitmap |= td_ptd_map->ptd_bitmap;			/* Set this ptd is active in active ptd map */
			ptd_map_buff->active_ptds++;
				
			if(ptd_map_buff->active_ptds > TD_PTD_MAX_ATL_TDS) isp1362_printk("More active ptds %x\n",ptd_map_buff->active_ptds);

			finished_map &= (~(td_ptd_map->ptd_bitmap));						/* Set this ptd as finished one */

		}
	}

	switch(ptd_map_buff->buffer_type) {
		case TD_PTD_BUFF_TYPE_ATL:

			active_ptd_bitmap = ptd_map_buff->active_ptd_bitmap;
			ptd_map_buff->regs.last_ptd = 0x1;
			active_ptd_bitmap >>= 1;

			/* Activate the PTD's in ATL so that we can start the PTD's in the buffer */
			ptd_map_buff->regs.ptd_skip_map &= (~send_ptd_bitmap);									/* remove the skip on new ptd's */
			phci_reg_write32(REG_ATL_PTD_SKIP_MAP,ptd_map_buff->regs.ptd_skip_map);			/* write into the skip map buffer */


			phci_reg_read16(REG_BUFF_STS,&data_read);		/* Activate ATL buffer processing */

			if(!(data_read & ATL_ACTIVE)) {
				data_read |= ATL_ACTIVE;
				g_buff_sts |= ATL_ACTIVE;
				phci->hcd_operational_flags |= ATL_ACTIVE;
				phci_reg_write16(REG_BUFF_STS,data_read);		/* Activate ATL buffer processing */
			}
			break;

	 	case TD_PTD_BUFF_TYPE_INTL:

			active_ptd_bitmap = ptd_map_buff->active_ptd_bitmap;
			ptd_map_buff->regs.last_ptd = 0x1;
			active_ptd_bitmap >>= 1;

			/* Activate the PTD's in INTL so that we can start the PTD's in the buffer */
			ptd_map_buff->regs.ptd_skip_map &= (~send_ptd_bitmap);			/* remove the skip on new ptd's */
			phci_reg_write32(REG_INTL_PTD_SKIP_MAP,ptd_map_buff->regs.ptd_skip_map);	/* write into the skip map buffer */
	
			phci_reg_read16(REG_BUFF_STS,&data_read);		/* Activate INTL buffer processing */

			if(!(data_read & INTL_ACTIVE)) {
				phci->hcd_operational_flags |= INTL_ACTIVE;
				data_read |= INTL_ACTIVE;
				phci_reg_write16(REG_BUFF_STS,data_read);		/* Activate INTL buffer processing */
			}
			phci_reg_read32(REG_INTL_PTD_SKIP_MAP,&ptd_map_buff->regs.ptd_skip_map);	/* write into the skip map buffer */

			break;
	}
} /* phci_fill_send_ptd */

/*--------------------------------------------------------------*
 *--------------------------------------------------------------*
 phci_fill_send_isoc_ptd::
	
	send_ptd_bitmap:		32bit map for the ptds to be sent
	ptd_map_buff:	map buffer pointer of buffer to be written

	fill the ptd buffer and send it to HC

	Fill into the HC buffer all the ptd's indicated by the bitmap
	into their corresponding locations in the buffer.

	activate the corresponding istl buffer
 *--------------------------------------------------------------*
 *--------------------------------------------------------------*/
void phci_fill_send_isoc_ptd(phci_t	*phci,__u32	send_ptd_bitmap,td_ptd_map_buff_t *ptd_map_buff) {

	td_ptd_map_t		*td_ptd_map;
	__u8				*ptd_payload = NULL;
	__u8				ram_data[HC_PTD_HEADER_SIZE];
	__u8				byte_data = 0;
	__u16				payload_bytes = 0;					/* ptd payload bytes */
	__u16				total_bytes = HC_PTD_HEADER_SIZE;	/* ptd total bytes to be written to HC buffer */
	td_t				*td;
	ed_t				*ed;
	__u8				index = 0;

	__u32				finished_map = send_ptd_bitmap;	
	__u32				ram_addr = ptd_map_buff->ram_buff_addr;
	__u32				ram_buff_sts;

	detail_debug(("phci_fill_send_isoc_ptd(phci = 0x%p, send_ptd_map = 0x%x, ptd_map_buff = 0x%p)\n",phci,send_ptd_bitmap, ptd_map_buff))


	ptd_map_buff->active_ptd_bitmap = 0;			/* Set this ptd is active in active ptd map */

	if(!send_ptd_bitmap)	return;							/* If there is nothing to do, just return it */


	phci_reg_read16(REG_BUFF_STS, &ram_buff_sts);		/* Activate ITL buffer processing */

	if(ptd_map_buff->buffer_type == TD_PTD_BUFF_TYPE_ISTL0) {
		ram_buff_sts |= ISTL_0_BUFF_FULL;
	} else {
		ram_buff_sts |= ISTL_1_BUFF_FULL;
	}

	phci_reg_write16(REG_BUFF_STS,ram_buff_sts);		/* Activate ITL buffer processing */


	for( index = 0; (index < ptd_map_buff->max_ptds) || (finished_map != 0); index++) {

		td_ptd_map = &(ptd_map_buff->map_list[index]);
		if(td_ptd_map->ptd_bitmap & finished_map) {				/* This ptd needs to be filled */
	
			/* Start filling the ram_data to send it to HC */

			td = td_ptd_map->td;
			ed = td->ed;

	
			/* start filling the ptd header */

			total_bytes = HC_PTD_HEADER_SIZE;	/* ptd total bytes to be written to HC buffer, initialize to ptd header */
			
			/**********************************************************************/
			/* ptd_header[0]: 7..0		actual bytes(7...0)				0(always) */
			/**********************************************************************/
			ram_data[0] = 0;

			/************************************************************************/
			/* ptd_header[1]: 7..4		completion code(3...0)		1111 (always) 	*/
			/* ptd_header[1]: 3		 	active(0)					1 (always) 		*/
			/* ptd_header[1]: 2		 	toggle(0)					always data0	*/
			/* ptd_header[1]: 1..0		actual bytes(9..8)			0 (always)		*/
			/************************************************************************/

			/* for toggle bit of OUT its always DATA0, for IN it should accept either 
			DATA0 & DATA1, we set now DATA0 and if the device gives DATA1 the HC should 
			not crib such situation as error case. If HC gives data toggle error, sw
			ignores the error */

			ram_data[1] = (PTD_CC_MASK | PTD_ACTIVE);			
	
			/**********************************************************************/
			/* ptd_header[2]: 7..0		Max.PacketSize(7...0)		from ed MPS   */
			/**********************************************************************/

			ram_data[2] = ((__u8)((ed->hwINFO & HC_ED_MPS) >> 16));


			/************************************************************************/
			/* ptd_header[3]: 7..4		End point number(3...0)		from ED EN		*/
			/* ptd_header[3]: 3		 	last(0)						from finish map	*/
			/* ptd_header[3]: 2		 	speed(0)					from ED			*/
			/* ptd_header[3]: 1..0		Max.PacketSize(9..8)		from ED MPS		*/
			/************************************************************************/

			ram_data[3] = (((__u8)((ed->hwINFO & HC_ED_EN) >> 7)) << 4);

			if(ed->hwINFO & HC_ED_SPD) {				/* Check if speed device or not */
				ram_data[3] |= PTD_SPEED;
			}

			ram_data[3] |= (((__u8)((ed->hwINFO & HC_ED_MPS) >> 24)) & 0x03);

		
			/* As ptd's are finished, the finished map bits will go and finally for the last
			ptd, finished map is the ptd_bitmap */
			if( finished_map == td_ptd_map->ptd_bitmap) {
				ram_data[3] |= PTD_LAST;
			}
	

			/********************************************************************************/
			/* ptd_header[4]: 7..0		Total Bytes(7...0)		from td cbp & be			*/
			/* ptd_header[5]: 1..0 		total bytes(9..8)			from td cbp & be		*/
			/********************************************************************************/

			if(td->hwCBP) {
				payload_bytes = td->hwBE - (td->hwCBP+(td->hwPSW[0] & 0x0FFF)) + 1; /* get the total bytes from td cbp & be & psw */
				ram_data[4] = (__u8)payload_bytes;
				ram_data[5] = (__u8)(payload_bytes >> 8);
			} else {			/* Null data packet */
				payload_bytes = 0;
				ram_data[4] = 0;
				ram_data[5] = 0;
			}
	
			/********************************************************************************/
			/* ptd_header[5]: 7			(0)							always 0				*/
			/* ptd_header[5]: 6		 	(0)							always 0				*/
			/* ptd_header[5]: 5..4	 	reserved(1..0)				00 always 				*/
			/* ptd_header[5]: 3..2 		token direction(1..0)		from ed DIR 			*/
			/* ptd_header[5]: 1..0 		total bytes(9..8)			already filled before 	*/
			/********************************************************************************/

			byte_data = (__u8)((ed->hwINFO & HC_ED_DIR) >> 11);

			ram_data[5] |= (byte_data << 2);

			/********************************************************************************/
			/* ptd_header[6]: 7			format(1)					1	always for ISOC		*/
			/* ptd_header[6]: 6..0	 	function address(6..0)		from ED FA				*/
			/********************************************************************************/

			ram_data[6] = ((__u8)(ed->hwINFO & HC_ED_FA));
			ram_data[6] |= PTD_FORMAT;

			/*************************************************************************************/
			/* ptd_header[7]: 7..0	 	Frame Number/Int polling Interval(7..0)	poll_frame# input*/
			/*************************************************************************************/
			ram_data[7] = (td->hwINFO & 0xFF);

			/* start sendig the data for this ptd */

			ptd_payload = (__u8*)((td->hwCBP) + (td->hwPSW[0] & 0x0FFF));

			if( (byte_data != OHCI_IN ) && payload_bytes && ptd_payload ) {				/* Don's send data in case of IN token */
				total_bytes += payload_bytes;
				fnvPhciRamWrite(phci,payload_bytes, HC_DIR_ADDR_INCREMENT, (ram_addr+HC_PTD_HEADER_SIZE), ptd_payload);
			}


			fnvPhciRamWrite(phci, HC_PTD_HEADER_SIZE, HC_DIR_ADDR_INCREMENT, ram_addr, ram_data);		/* Send the ptd header */

			td_ptd_map->ram_addr = ram_addr;
	
			ALIGN_RAM_BUFF_LENGTH(payload_bytes);

			td_ptd_map->total_bytes = payload_bytes+HC_PTD_HEADER_SIZE;			/* Set the total bytes size for this td-ptd map */
			
			if(ram_addr > 2*HC_ISTL_BUFFER_LENGTH) {
				isp1362_printk("Something bad is going to happen, Writing at %x for ISTL ptd's\n", ram_addr);
			}

			ram_addr += td_ptd_map->total_bytes;

			ptd_map_buff->active_ptd_bitmap |= 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -