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