usb: r8a66597-hcd: add function for external controller
R8A66597 has the pin of WR0 and WR1. So, if one write-pin of CPU connects to the pins, we have to change the setting of FIFOSEL register in the controller. If we don't change the setting, the controller cannot send the data of odd length. Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
		
					parent
					
						
							
								81463c1d70
							
						
					
				
			
			
				commit
				
					
						f2e9039a43
					
				
			
		
					 3 changed files with 25 additions and 18 deletions
				
			
		|  | @ -1438,7 +1438,7 @@ static void packet_write(struct r8a66597 *r8a66597, u16 pipenum) | ||||||
| 	if (pipenum > 0) | 	if (pipenum > 0) | ||||||
| 		r8a66597_write(r8a66597, ~(1 << pipenum), BEMPSTS); | 		r8a66597_write(r8a66597, ~(1 << pipenum), BEMPSTS); | ||||||
| 	if (urb->transfer_buffer) { | 	if (urb->transfer_buffer) { | ||||||
| 		r8a66597_write_fifo(r8a66597, td->pipe->fifoaddr, buf, size); | 		r8a66597_write_fifo(r8a66597, td->pipe, buf, size); | ||||||
| 		if (!usb_pipebulk(urb->pipe) || td->maxpacket != size) | 		if (!usb_pipebulk(urb->pipe) || td->maxpacket != size) | ||||||
| 			r8a66597_write(r8a66597, BVAL, td->pipe->fifoctr); | 			r8a66597_write(r8a66597, BVAL, td->pipe->fifoctr); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -201,11 +201,26 @@ static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val, | ||||||
| 	iowrite16(val, r8a66597->reg + offset); | 	iowrite16(val, r8a66597->reg + offset); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static inline void r8a66597_mdfy(struct r8a66597 *r8a66597, | ||||||
|  | 				 u16 val, u16 pat, unsigned long offset) | ||||||
|  | { | ||||||
|  | 	u16 tmp; | ||||||
|  | 	tmp = r8a66597_read(r8a66597, offset); | ||||||
|  | 	tmp = tmp & (~pat); | ||||||
|  | 	tmp = tmp | val; | ||||||
|  | 	r8a66597_write(r8a66597, tmp, offset); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #define r8a66597_bclr(r8a66597, val, offset)	\ | ||||||
|  | 			r8a66597_mdfy(r8a66597, 0, val, offset) | ||||||
|  | #define r8a66597_bset(r8a66597, val, offset)	\ | ||||||
|  | 			r8a66597_mdfy(r8a66597, val, 0, offset) | ||||||
|  | 
 | ||||||
| static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, | static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, | ||||||
| 				       unsigned long offset, u16 *buf, | 				       struct r8a66597_pipe *pipe, u16 *buf, | ||||||
| 				       int len) | 				       int len) | ||||||
| { | { | ||||||
| 	void __iomem *fifoaddr = r8a66597->reg + offset; | 	void __iomem *fifoaddr = r8a66597->reg + pipe->fifoaddr; | ||||||
| 	unsigned long count; | 	unsigned long count; | ||||||
| 	unsigned char *pb; | 	unsigned char *pb; | ||||||
| 	int i; | 	int i; | ||||||
|  | @ -230,26 +245,15 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, | ||||||
| 		iowrite16_rep(fifoaddr, buf, len); | 		iowrite16_rep(fifoaddr, buf, len); | ||||||
| 		if (unlikely(odd)) { | 		if (unlikely(odd)) { | ||||||
| 			buf = &buf[len]; | 			buf = &buf[len]; | ||||||
|  | 			if (r8a66597->pdata->wr0_shorted_to_wr1) | ||||||
|  | 				r8a66597_bclr(r8a66597, MBW_16, pipe->fifosel); | ||||||
| 			iowrite8((unsigned char)*buf, fifoaddr); | 			iowrite8((unsigned char)*buf, fifoaddr); | ||||||
|  | 			if (r8a66597->pdata->wr0_shorted_to_wr1) | ||||||
|  | 				r8a66597_bset(r8a66597, MBW_16, pipe->fifosel); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline void r8a66597_mdfy(struct r8a66597 *r8a66597, |  | ||||||
| 				 u16 val, u16 pat, unsigned long offset) |  | ||||||
| { |  | ||||||
| 	u16 tmp; |  | ||||||
| 	tmp = r8a66597_read(r8a66597, offset); |  | ||||||
| 	tmp = tmp & (~pat); |  | ||||||
| 	tmp = tmp | val; |  | ||||||
| 	r8a66597_write(r8a66597, tmp, offset); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #define r8a66597_bclr(r8a66597, val, offset)	\ |  | ||||||
| 			r8a66597_mdfy(r8a66597, 0, val, offset) |  | ||||||
| #define r8a66597_bset(r8a66597, val, offset)	\ |  | ||||||
| 			r8a66597_mdfy(r8a66597, val, 0, offset) |  | ||||||
| 
 |  | ||||||
| static inline unsigned long get_syscfg_reg(int port) | static inline unsigned long get_syscfg_reg(int port) | ||||||
| { | { | ||||||
| 	return port == 0 ? SYSCFG0 : SYSCFG1; | 	return port == 0 ? SYSCFG0 : SYSCFG1; | ||||||
|  |  | ||||||
|  | @ -42,6 +42,9 @@ struct r8a66597_platdata { | ||||||
| 
 | 
 | ||||||
| 	/* set one = big endian, set zero = little endian */ | 	/* set one = big endian, set zero = little endian */ | ||||||
| 	unsigned	endian:1; | 	unsigned	endian:1; | ||||||
|  | 
 | ||||||
|  | 	/* (external controller only) set one = WR0_N shorted to WR1_N */ | ||||||
|  | 	unsigned	wr0_shorted_to_wr1:1; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /* Register definitions */ | /* Register definitions */ | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Yoshihiro Shimoda
				Yoshihiro Shimoda