/*
 * 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__

/**
 * 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 dependent.
 *
 * 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[];	/* variable payload size */
};

/* ======================================================================== */
/* Generic task management                                                   */
/* ======================================================================== */

/**
 * 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);
}

/**
 * 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);
}

/**
 * bcom_buffer_done - Checks if a BestComm 
 * @tsk: The BestComm task structure
 */
static inline int
bcom_buffer_done(struct bcom_task *tsk)
{
	struct bcom_bd *bd;
	if (bcom_queue_empty(tsk))
		return 0;

	bd = bcom_get_bd(tsk, tsk->outdex);
	return !(bd->status & BCOM_BD_READY);
}

/**
 * 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)
{
	struct bcom_bd *bd;

	bd = bcom_get_bd(tsk, tsk->index);
	bd->status = 0;	/* cleanup last status */
	return bd;
}

static inline void
bcom_submit_next_buffer(struct bcom_task *tsk, void *cookie)
{
	struct bcom_bd *bd = bcom_get_bd(tsk, tsk->index);

	tsk->cookie[tsk->index] = cookie;
	mb();	/* ensure the bd is really up-to-date */
	bd->status |= BCOM_BD_READY;
	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];
	struct bcom_bd *bd = bcom_get_bd(tsk, tsk->outdex);

	if (p_status)
		*p_status = bd->status;
	if (p_bd)
		*p_bd = bd;
	tsk->outdex = _bcom_next_outdex(tsk);
	return cookie;
}

#endif /* __BESTCOMM_H__ */
