Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.13.7.
  1/*
  2 * Public header for the MPC52xx processor BestComm driver
  3 *
  4 *
  5 * Copyright (C) 2006      Sylvain Munaut <tnt@246tNt.com>
  6 * Copyright (C) 2005      Varma Electronics Oy,
  7 *                         ( by Andrey Volkov <avolkov@varma-el.com> )
  8 * Copyright (C) 2003-2004 MontaVista, Software, Inc.
  9 *                         ( by Dale Farnsworth <dfarnsworth@mvista.com> )
 10 *
 11 * This file is licensed under the terms of the GNU General Public License
 12 * version 2. This program is licensed "as is" without any warranty of any
 13 * kind, whether express or implied.
 14 */
 15
 16#ifndef __BESTCOMM_H__
 17#define __BESTCOMM_H__
 18
 19/**
 20 * struct bcom_bd - Structure describing a generic BestComm buffer descriptor
 21 * @status: The current status of this buffer. Exact meaning depends on the
 22 *          task type
 23 * @data: An array of u32 extra data.  Size of array is task dependent.
 24 *
 25 * Note: Don't dereference a bcom_bd pointer as an array.  The size of the
 26 *       bcom_bd is variable.  Use bcom_get_bd() instead.
 27 */
 28struct bcom_bd {
 29	u32	status;
 30	u32	data[0];	/* variable payload size */
 31};
 32
 33/* ======================================================================== */
 34/* Generic task management                                                   */
 35/* ======================================================================== */
 36
 37/**
 38 * struct bcom_task - Structure describing a loaded BestComm task
 39 *
 40 * This structure is never built by the driver it self. It's built and
 41 * filled the intermediate layer of the BestComm API, the task dependent
 42 * support code.
 43 *
 44 * Most likely you don't need to poke around inside this structure. The
 45 * fields are exposed in the header just for the sake of inline functions
 46 */
 47struct bcom_task {
 48	unsigned int	tasknum;
 49	unsigned int	flags;
 50	int		irq;
 51
 52	struct bcom_bd	*bd;
 53	phys_addr_t	bd_pa;
 54	void		**cookie;
 55	unsigned short	index;
 56	unsigned short	outdex;
 57	unsigned int	num_bd;
 58	unsigned int	bd_size;
 59
 60	void*		priv;
 61};
 62
 63#define BCOM_FLAGS_NONE         0x00000000ul
 64#define BCOM_FLAGS_ENABLE_TASK  (1ul <<  0)
 65
 66/**
 67 * bcom_enable - Enable a BestComm task
 68 * @tsk: The BestComm task structure
 69 *
 70 * This function makes sure the given task is enabled and can be run
 71 * by the BestComm engine as needed
 72 */
 73extern void bcom_enable(struct bcom_task *tsk);
 74
 75/**
 76 * bcom_disable - Disable a BestComm task
 77 * @tsk: The BestComm task structure
 78 *
 79 * This function disable a given task, making sure it's not executed
 80 * by the BestComm engine.
 81 */
 82extern void bcom_disable(struct bcom_task *tsk);
 83
 84
 85/**
 86 * bcom_get_task_irq - Returns the irq number of a BestComm task
 87 * @tsk: The BestComm task structure
 88 */
 89static inline int
 90bcom_get_task_irq(struct bcom_task *tsk) {
 91	return tsk->irq;
 92}
 93
 94/* ======================================================================== */
 95/* BD based tasks helpers                                                   */
 96/* ======================================================================== */
 97
 98#define BCOM_BD_READY	0x40000000ul
 99
100/** _bcom_next_index - Get next input index.
101 * @tsk: pointer to task structure
102 *
103 * Support function; Device drivers should not call this
104 */
105static inline int
106_bcom_next_index(struct bcom_task *tsk)
107{
108	return ((tsk->index + 1) == tsk->num_bd) ? 0 : tsk->index + 1;
109}
110
111/** _bcom_next_outdex - Get next output index.
112 * @tsk: pointer to task structure
113 *
114 * Support function; Device drivers should not call this
115 */
116static inline int
117_bcom_next_outdex(struct bcom_task *tsk)
118{
119	return ((tsk->outdex + 1) == tsk->num_bd) ? 0 : tsk->outdex + 1;
120}
121
122/**
123 * bcom_queue_empty - Checks if a BestComm task BD queue is empty
124 * @tsk: The BestComm task structure
125 */
126static inline int
127bcom_queue_empty(struct bcom_task *tsk)
128{
129	return tsk->index == tsk->outdex;
130}
131
132/**
133 * bcom_queue_full - Checks if a BestComm task BD queue is full
134 * @tsk: The BestComm task structure
135 */
136static inline int
137bcom_queue_full(struct bcom_task *tsk)
138{
139	return tsk->outdex == _bcom_next_index(tsk);
140}
141
142/**
143 * bcom_get_bd - Get a BD from the queue
144 * @tsk: The BestComm task structure
145 * index: Index of the BD to fetch
146 */
147static inline struct bcom_bd
148*bcom_get_bd(struct bcom_task *tsk, unsigned int index)
149{
150	/* A cast to (void*) so the address can be incremented by the
151	 * real size instead of by sizeof(struct bcom_bd) */
152	return ((void *)tsk->bd) + (index * tsk->bd_size);
153}
154
155/**
156 * bcom_buffer_done - Checks if a BestComm 
157 * @tsk: The BestComm task structure
158 */
159static inline int
160bcom_buffer_done(struct bcom_task *tsk)
161{
162	struct bcom_bd *bd;
163	if (bcom_queue_empty(tsk))
164		return 0;
165
166	bd = bcom_get_bd(tsk, tsk->outdex);
167	return !(bd->status & BCOM_BD_READY);
168}
169
170/**
171 * bcom_prepare_next_buffer - clear status of next available buffer.
172 * @tsk: The BestComm task structure
173 *
174 * Returns pointer to next buffer descriptor
175 */
176static inline struct bcom_bd *
177bcom_prepare_next_buffer(struct bcom_task *tsk)
178{
179	struct bcom_bd *bd;
180
181	bd = bcom_get_bd(tsk, tsk->index);
182	bd->status = 0;	/* cleanup last status */
183	return bd;
184}
185
186static inline void
187bcom_submit_next_buffer(struct bcom_task *tsk, void *cookie)
188{
189	struct bcom_bd *bd = bcom_get_bd(tsk, tsk->index);
190
191	tsk->cookie[tsk->index] = cookie;
192	mb();	/* ensure the bd is really up-to-date */
193	bd->status |= BCOM_BD_READY;
194	tsk->index = _bcom_next_index(tsk);
195	if (tsk->flags & BCOM_FLAGS_ENABLE_TASK)
196		bcom_enable(tsk);
197}
198
199static inline void *
200bcom_retrieve_buffer(struct bcom_task *tsk, u32 *p_status, struct bcom_bd **p_bd)
201{
202	void *cookie = tsk->cookie[tsk->outdex];
203	struct bcom_bd *bd = bcom_get_bd(tsk, tsk->outdex);
204
205	if (p_status)
206		*p_status = bd->status;
207	if (p_bd)
208		*p_bd = bd;
209	tsk->outdex = _bcom_next_outdex(tsk);
210	return cookie;
211}
212
213#endif /* __BESTCOMM_H__ */