/**
 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
 *
 * This source file is released under GPL v2 license (no other versions).
 * See the COPYING file included in the main directory of this source
 * distribution for the license terms and conditions.
 *
 * @File	ctresource.c
 *
 * @Brief
 * This file contains the implementation of some generic helper functions.
 *
 * @Author	Liu Chun
 * @Date 	May 15 2008
 *
 */

#include "ctresource.h"
#include "cthardware.h"
#include <linux/err.h>
#include <linux/slab.h>

#define AUDIO_SLOT_BLOCK_NUM 	256

/* Resource allocation based on bit-map management mechanism */
static int
get_resource(u8 *rscs, unsigned int amount,
	     unsigned int multi, unsigned int *ridx)
{
	int i, j, k, n;

	/* Check whether there are sufficient resources to meet request. */
	for (i = 0, n = multi; i < amount; i++) {
		j = i / 8;
		k = i % 8;
		if (rscs[j] & ((u8)1 << k)) {
			n = multi;
			continue;
		}
		if (!(--n))
			break; /* found sufficient contiguous resources */
	}

	if (i >= amount) {
		/* Can not find sufficient contiguous resources */
		return -ENOENT;
	}

	/* Mark the contiguous bits in resource bit-map as used */
	for (n = multi; n > 0; n--) {
		j = i / 8;
		k = i % 8;
		rscs[j] |= ((u8)1 << k);
		i--;
	}

	*ridx = i + 1;

	return 0;
}

static int put_resource(u8 *rscs, unsigned int multi, unsigned int idx)
{
	unsigned int i, j, k, n;

	/* Mark the contiguous bits in resource bit-map as used */
	for (n = multi, i = idx; n > 0; n--) {
		j = i / 8;
		k = i % 8;
		rscs[j] &= ~((u8)1 << k);
		i++;
	}

	return 0;
}

int mgr_get_resource(struct rsc_mgr *mgr, unsigned int n, unsigned int *ridx)
{
	int err;

	if (n > mgr->avail)
		return -ENOENT;

	err = get_resource(mgr->rscs, mgr->amount, n, ridx);
	if (!err)
		mgr->avail -= n;

	return err;
}

int mgr_put_resource(struct rsc_mgr *mgr, unsigned int n, unsigned int idx)
{
	put_resource(mgr->rscs, n, idx);
	mgr->avail += n;

	return 0;
}

static unsigned char offset_in_audio_slot_block[NUM_RSCTYP] = {
	/* SRC channel is at Audio Ring slot 1 every 16 slots. */
	[SRC]		= 0x1,
	[AMIXER]	= 0x4,
	[SUM]		= 0xc,
};

static int rsc_index(const struct rsc *rsc)
{
    return rsc->conj;
}

static int audio_ring_slot(const struct rsc *rsc)
{
    return (rsc->conj << 4) + offset_in_audio_slot_block[rsc->type];
}

static int rsc_next_conj(struct rsc *rsc)
{
	unsigned int i;
	for (i = 0; (i < 8) && (!(rsc->msr & (0x1 << i))); )
		i++;
	rsc->conj += (AUDIO_SLOT_BLOCK_NUM >> i);
	return rsc->conj;
}

static int rsc_master(struct rsc *rsc)
{
	return rsc->conj = rsc->idx;
}

static struct rsc_ops rsc_generic_ops = {
	.index		= rsc_index,
	.output_slot	= audio_ring_slot,
	.master		= rsc_master,
	.next_conj	= rsc_next_conj,
};

int rsc_init(struct rsc *rsc, u32 idx, enum RSCTYP type, u32 msr, void *hw)
{
	int err = 0;

	rsc->idx = idx;
	rsc->conj = idx;
	rsc->type = type;
	rsc->msr = msr;
	rsc->hw = hw;
	rsc->ops = &rsc_generic_ops;
	if (NULL == hw) {
		rsc->ctrl_blk = NULL;
		return 0;
	}

	switch (type) {
	case SRC:
		err = ((struct hw *)hw)->src_rsc_get_ctrl_blk(&rsc->ctrl_blk);
		break;
	case AMIXER:
		err = ((struct hw *)hw)->
				amixer_rsc_get_ctrl_blk(&rsc->ctrl_blk);
		break;
	case SRCIMP:
	case SUM:
	case DAIO:
		break;
	default:
		printk(KERN_ERR
		       "ctxfi: Invalid resource type value %d!\n", type);
		return -EINVAL;
	}

	if (err) {
		printk(KERN_ERR
		       "ctxfi: Failed to get resource control block!\n");
		return err;
	}

	return 0;
}

int rsc_uninit(struct rsc *rsc)
{
	if ((NULL != rsc->hw) && (NULL != rsc->ctrl_blk)) {
		switch (rsc->type) {
		case SRC:
			((struct hw *)rsc->hw)->
				src_rsc_put_ctrl_blk(rsc->ctrl_blk);
			break;
		case AMIXER:
			((struct hw *)rsc->hw)->
				amixer_rsc_put_ctrl_blk(rsc->ctrl_blk);
			break;
		case SUM:
		case DAIO:
			break;
		default:
			printk(KERN_ERR "ctxfi: "
			       "Invalid resource type value %d!\n", rsc->type);
			break;
		}

		rsc->hw = rsc->ctrl_blk = NULL;
	}

	rsc->idx = rsc->conj = 0;
	rsc->type = NUM_RSCTYP;
	rsc->msr = 0;

	return 0;
}

int rsc_mgr_init(struct rsc_mgr *mgr, enum RSCTYP type,
		 unsigned int amount, void *hw_obj)
{
	int err = 0;
	struct hw *hw = hw_obj;

	mgr->type = NUM_RSCTYP;

	mgr->rscs = kzalloc(((amount + 8 - 1) / 8), GFP_KERNEL);
	if (NULL == mgr->rscs)
		return -ENOMEM;

	switch (type) {
	case SRC:
		err = hw->src_mgr_get_ctrl_blk(&mgr->ctrl_blk);
		break;
	case SRCIMP:
		err = hw->srcimp_mgr_get_ctrl_blk(&mgr->ctrl_blk);
		break;
	case AMIXER:
		err = hw->amixer_mgr_get_ctrl_blk(&mgr->ctrl_blk);
		break;
	case DAIO:
		err = hw->daio_mgr_get_ctrl_blk(hw, &mgr->ctrl_blk);
		break;
	case SUM:
		break;
	default:
		printk(KERN_ERR
		       "ctxfi: Invalid resource type value %d!\n", type);
		err = -EINVAL;
		goto error;
	}

	if (err) {
		printk(KERN_ERR
		       "ctxfi: Failed to get manager control block!\n");
		goto error;
	}

	mgr->type = type;
	mgr->avail = mgr->amount = amount;
	mgr->hw = hw;

	return 0;

error:
	kfree(mgr->rscs);
	return err;
}

int rsc_mgr_uninit(struct rsc_mgr *mgr)
{
	if (NULL != mgr->rscs) {
		kfree(mgr->rscs);
		mgr->rscs = NULL;
	}

	if ((NULL != mgr->hw) && (NULL != mgr->ctrl_blk)) {
		switch (mgr->type) {
		case SRC:
			((struct hw *)mgr->hw)->
				src_mgr_put_ctrl_blk(mgr->ctrl_blk);
			break;
		case SRCIMP:
			((struct hw *)mgr->hw)->
				srcimp_mgr_put_ctrl_blk(mgr->ctrl_blk);
			break;
		case AMIXER:
			((struct hw *)mgr->hw)->
				amixer_mgr_put_ctrl_blk(mgr->ctrl_blk);
			break;
		case DAIO:
			((struct hw *)mgr->hw)->
				daio_mgr_put_ctrl_blk(mgr->ctrl_blk);
			break;
		case SUM:
			break;
		default:
			printk(KERN_ERR "ctxfi: "
			       "Invalid resource type value %d!\n", mgr->type);
			break;
		}

		mgr->hw = mgr->ctrl_blk = NULL;
	}

	mgr->type = NUM_RSCTYP;
	mgr->avail = mgr->amount = 0;

	return 0;
}
