| 
									
										
										
										
											2007-09-16 20:53:27 +10:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Public header for the MPC52xx processor BestComm driver | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (C) 2006      Sylvain Munaut <tnt@246tNt.com> | 
					
						
							|  |  |  |  * Copyright (C) 2005      Varma Electronics Oy, | 
					
						
							|  |  |  |  *                         ( by Andrey Volkov <avolkov@varma-el.com> ) | 
					
						
							|  |  |  |  * Copyright (C) 2003-2004 MontaVista, Software, Inc. | 
					
						
							|  |  |  |  *                         ( by Dale Farnsworth <dfarnsworth@mvista.com> ) | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This file is licensed under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * version 2. This program is licensed "as is" without any warranty of any | 
					
						
							|  |  |  |  * kind, whether express or implied. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef __BESTCOMM_H__
 | 
					
						
							|  |  |  | #define __BESTCOMM_H__
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-21 02:54:27 -07:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * struct bcom_bd - Structure describing a generic BestComm buffer descriptor | 
					
						
							|  |  |  |  * @status: The current status of this buffer. Exact meaning depends on the | 
					
						
							|  |  |  |  *          task type | 
					
						
							|  |  |  |  * @data: An array of u32 extra data.  Size of array is task dependant. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Note: Don't dereference a bcom_bd pointer as an array.  The size of the | 
					
						
							|  |  |  |  *       bcom_bd is variable.  Use bcom_get_bd() instead. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | struct bcom_bd { | 
					
						
							|  |  |  | 	u32	status; | 
					
						
							|  |  |  | 	u32	data[0];	/* variable payload size */ | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2007-09-16 20:53:27 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* ======================================================================== */ | 
					
						
							| 
									
										
										
										
											2007-12-18 06:30:12 +11:00
										 |  |  | /* Generic task management                                                   */ | 
					
						
							| 
									
										
										
										
											2007-09-16 20:53:27 +10:00
										 |  |  | /* ======================================================================== */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * struct bcom_task - Structure describing a loaded BestComm task | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This structure is never built by the driver it self. It's built and | 
					
						
							|  |  |  |  * filled the intermediate layer of the BestComm API, the task dependent | 
					
						
							|  |  |  |  * support code. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Most likely you don't need to poke around inside this structure. The | 
					
						
							|  |  |  |  * fields are exposed in the header just for the sake of inline functions | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | struct bcom_task { | 
					
						
							|  |  |  | 	unsigned int	tasknum; | 
					
						
							|  |  |  | 	unsigned int	flags; | 
					
						
							|  |  |  | 	int		irq; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct bcom_bd	*bd; | 
					
						
							|  |  |  | 	phys_addr_t	bd_pa; | 
					
						
							|  |  |  | 	void		**cookie; | 
					
						
							|  |  |  | 	unsigned short	index; | 
					
						
							|  |  |  | 	unsigned short	outdex; | 
					
						
							|  |  |  | 	unsigned int	num_bd; | 
					
						
							|  |  |  | 	unsigned int	bd_size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	void*		priv; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define BCOM_FLAGS_NONE         0x00000000ul
 | 
					
						
							|  |  |  | #define BCOM_FLAGS_ENABLE_TASK  (1ul <<  0)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * bcom_enable - Enable a BestComm task | 
					
						
							|  |  |  |  * @tsk: The BestComm task structure | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This function makes sure the given task is enabled and can be run | 
					
						
							|  |  |  |  * by the BestComm engine as needed | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | extern void bcom_enable(struct bcom_task *tsk); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * bcom_disable - Disable a BestComm task | 
					
						
							|  |  |  |  * @tsk: The BestComm task structure | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This function disable a given task, making sure it's not executed | 
					
						
							|  |  |  |  * by the BestComm engine. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | extern void bcom_disable(struct bcom_task *tsk); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * bcom_get_task_irq - Returns the irq number of a BestComm task | 
					
						
							|  |  |  |  * @tsk: The BestComm task structure | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static inline int | 
					
						
							|  |  |  | bcom_get_task_irq(struct bcom_task *tsk) { | 
					
						
							|  |  |  | 	return tsk->irq; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ======================================================================== */ | 
					
						
							|  |  |  | /* BD based tasks helpers                                                   */ | 
					
						
							|  |  |  | /* ======================================================================== */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define BCOM_BD_READY	0x40000000ul
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** _bcom_next_index - Get next input index.
 | 
					
						
							|  |  |  |  * @tsk: pointer to task structure | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Support function; Device drivers should not call this | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static inline int | 
					
						
							|  |  |  | _bcom_next_index(struct bcom_task *tsk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return ((tsk->index + 1) == tsk->num_bd) ? 0 : tsk->index + 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** _bcom_next_outdex - Get next output index.
 | 
					
						
							|  |  |  |  * @tsk: pointer to task structure | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Support function; Device drivers should not call this | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static inline int | 
					
						
							|  |  |  | _bcom_next_outdex(struct bcom_task *tsk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return ((tsk->outdex + 1) == tsk->num_bd) ? 0 : tsk->outdex + 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * bcom_queue_empty - Checks if a BestComm task BD queue is empty | 
					
						
							|  |  |  |  * @tsk: The BestComm task structure | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static inline int | 
					
						
							|  |  |  | bcom_queue_empty(struct bcom_task *tsk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return tsk->index == tsk->outdex; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * bcom_queue_full - Checks if a BestComm task BD queue is full | 
					
						
							|  |  |  |  * @tsk: The BestComm task structure | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static inline int | 
					
						
							|  |  |  | bcom_queue_full(struct bcom_task *tsk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return tsk->outdex == _bcom_next_index(tsk); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-21 02:54:27 -07:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * bcom_get_bd - Get a BD from the queue | 
					
						
							|  |  |  |  * @tsk: The BestComm task structure | 
					
						
							|  |  |  |  * index: Index of the BD to fetch | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static inline struct bcom_bd | 
					
						
							|  |  |  | *bcom_get_bd(struct bcom_task *tsk, unsigned int index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* A cast to (void*) so the address can be incremented by the
 | 
					
						
							|  |  |  | 	 * real size instead of by sizeof(struct bcom_bd) */ | 
					
						
							|  |  |  | 	return ((void *)tsk->bd) + (index * tsk->bd_size); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-16 20:53:27 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * bcom_buffer_done - Checks if a BestComm  | 
					
						
							|  |  |  |  * @tsk: The BestComm task structure | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static inline int | 
					
						
							|  |  |  | bcom_buffer_done(struct bcom_task *tsk) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-21 02:54:27 -07:00
										 |  |  | 	struct bcom_bd *bd; | 
					
						
							| 
									
										
										
										
											2007-09-16 20:53:27 +10:00
										 |  |  | 	if (bcom_queue_empty(tsk)) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2008-12-21 02:54:27 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	bd = bcom_get_bd(tsk, tsk->outdex); | 
					
						
							|  |  |  | 	return !(bd->status & BCOM_BD_READY); | 
					
						
							| 
									
										
										
										
											2007-09-16 20:53:27 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * bcom_prepare_next_buffer - clear status of next available buffer. | 
					
						
							|  |  |  |  * @tsk: The BestComm task structure | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Returns pointer to next buffer descriptor | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static inline struct bcom_bd * | 
					
						
							|  |  |  | bcom_prepare_next_buffer(struct bcom_task *tsk) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-21 02:54:27 -07:00
										 |  |  | 	struct bcom_bd *bd; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bd = bcom_get_bd(tsk, tsk->index); | 
					
						
							|  |  |  | 	bd->status = 0;	/* cleanup last status */ | 
					
						
							|  |  |  | 	return bd; | 
					
						
							| 
									
										
										
										
											2007-09-16 20:53:27 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void | 
					
						
							|  |  |  | bcom_submit_next_buffer(struct bcom_task *tsk, void *cookie) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-21 02:54:27 -07:00
										 |  |  | 	struct bcom_bd *bd = bcom_get_bd(tsk, tsk->index); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-16 20:53:27 +10:00
										 |  |  | 	tsk->cookie[tsk->index] = cookie; | 
					
						
							|  |  |  | 	mb();	/* ensure the bd is really up-to-date */ | 
					
						
							| 
									
										
										
										
											2008-12-21 02:54:27 -07:00
										 |  |  | 	bd->status |= BCOM_BD_READY; | 
					
						
							| 
									
										
										
										
											2007-09-16 20:53:27 +10:00
										 |  |  | 	tsk->index = _bcom_next_index(tsk); | 
					
						
							|  |  |  | 	if (tsk->flags & BCOM_FLAGS_ENABLE_TASK) | 
					
						
							|  |  |  | 		bcom_enable(tsk); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void * | 
					
						
							|  |  |  | bcom_retrieve_buffer(struct bcom_task *tsk, u32 *p_status, struct bcom_bd **p_bd) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	void *cookie = tsk->cookie[tsk->outdex]; | 
					
						
							| 
									
										
										
										
											2008-12-21 02:54:27 -07:00
										 |  |  | 	struct bcom_bd *bd = bcom_get_bd(tsk, tsk->outdex); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-16 20:53:27 +10:00
										 |  |  | 	if (p_status) | 
					
						
							| 
									
										
										
										
											2008-12-21 02:54:27 -07:00
										 |  |  | 		*p_status = bd->status; | 
					
						
							| 
									
										
										
										
											2007-09-16 20:53:27 +10:00
										 |  |  | 	if (p_bd) | 
					
						
							| 
									
										
										
										
											2008-12-21 02:54:27 -07:00
										 |  |  | 		*p_bd = bd; | 
					
						
							| 
									
										
										
										
											2007-09-16 20:53:27 +10:00
										 |  |  | 	tsk->outdex = _bcom_next_outdex(tsk); | 
					
						
							|  |  |  | 	return cookie; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /* __BESTCOMM_H__ */
 |