/*
Copyright Statement:

This software/firmware and related documentation ("MediaTek Software") are
protected under relevant copyright laws. The information contained herein is
confidential and proprietary to MediaTek Inc. and/or its licensors. Without
the prior written permission of MediaTek inc. and/or its licensors, any
reproduction, modification, use or disclosure of MediaTek Software, and
information contained herein, in whole or in part, shall be strictly
prohibited.

MediaTek Inc. (C) 2016. All rights reserved.

BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.

Auther: Garlic Tseng <garlic.tseng@mediatek.com>
*/

#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <alsa/asoundlib.h>
#define STR_SIZE 128
#define DEFAULT_CARD_NAME "hw:0"

//mixer control structure for sound card
static snd_mixer_t *g_all_mixer_handler;
static char g_customize_card_name[STR_SIZE] = {'\0'};

static snd_mixer_elem_t *get_mixer_item_handler(const char *mixer_ctrl_name)
{
	snd_mixer_selem_id_t *mixer_select = NULL;
	snd_mixer_elem_t *mixer_item_handler = NULL;
	int ret = 0;


	ret = snd_mixer_selem_id_malloc(&mixer_select);
	if (ret) {
		printf("%s, snd_mixer_open failed: %d\n", __func__, ret);
		goto MIXER_ITEM_CREATE_ERROR;
	}

	snd_mixer_selem_id_set_index(mixer_select, 0);
	if (ret) {
		printf("%s, snd_mixer_selem_id_set_index failed: %d\n",
			__func__, ret);
		goto MIXER_ITEM_CREATE_ERROR;
	}

	snd_mixer_selem_id_set_name(mixer_select, mixer_ctrl_name);
	if (ret) {
		printf("%s, snd_mixer_selem_id_set_name failed: %d\n",
			__func__, ret);
		goto MIXER_ITEM_CREATE_ERROR;
	}

	mixer_item_handler = snd_mixer_find_selem(g_all_mixer_handler,
						  mixer_select);

	if (!mixer_item_handler) {
		printf("%s, snd_mixer_find_selem not found\n", __func__);
	}

	snd_mixer_selem_id_free(mixer_select);
	return mixer_item_handler;

MIXER_ITEM_CREATE_ERROR:
	snd_mixer_selem_id_free(mixer_select);
	return NULL;
}

int set_card_name(const char *mixer_ctrl_name)
{
	if (g_all_mixer_handler) {
		snd_mixer_close(g_all_mixer_handler);
		g_all_mixer_handler = 0;
	}

	strncpy(g_customize_card_name, mixer_ctrl_name, STR_SIZE);
	return 0;
}

static int initial_all_mixer_handler()
{
	int ret = 0;
	ret = snd_mixer_open(&g_all_mixer_handler, 0);
	if (ret) {
		printf("%s, snd_mixer_open failed: %d\n", __func__, ret);
		goto ALL_MIXER_CREATE_ERROR;
	}

	if (g_customize_card_name[0] == '\0')
		ret = snd_mixer_attach(g_all_mixer_handler, DEFAULT_CARD_NAME);
	else
		ret = snd_mixer_attach(g_all_mixer_handler, g_customize_card_name);

	if (ret) {
		printf("%s, snd_mixer_attach failed: %d\n", __func__, ret);
		goto ALL_MIXER_CREATE_ERROR;
	}

	ret = snd_mixer_selem_register(g_all_mixer_handler, NULL, NULL);
	if (ret) {
		printf("%s, snd_mixer_selem_register failed: %d\n", __func__,
			ret);
		goto ALL_MIXER_CREATE_ERROR;
	}

	ret = snd_mixer_load(g_all_mixer_handler);
	if (ret) {
		printf("%s, snd_mixer_load failed: %d\n", __func__, ret);
		/* goto ALL_MIXER_CREATE_ERROR; */
	}
	return 0;

ALL_MIXER_CREATE_ERROR:
	snd_mixer_close(g_all_mixer_handler);
	g_all_mixer_handler = 0;
	return ret;
}


int set_mixer_ctrl_value_int(const char *mixer_ctrl_name,
			     const int option_int)
{
	snd_mixer_elem_t *mixer_item_handler = NULL;
	int ret;

	if (!g_all_mixer_handler)
		initial_all_mixer_handler();

	/* mixer control item */
	mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
	if (!mixer_item_handler) {
		printf("%s, get_mixer_item_handler failed!\n", __func__);
		return -EINVAL;
	}

	ret = snd_mixer_selem_set_enum_item(mixer_item_handler, 0, option_int);
	if (ret) {
		printf("%s, set_enum_item failed: %d, option_int: %d\n",
			__func__, ret, option_int);
		return ret;
	}

	return 0;
}

int set_mixer_ctrl_volume_value(const char *mixer_ctrl_name,
				const long volume)
{
	snd_mixer_elem_t *mixer_item_handler = NULL;
	int ret;

	if (!g_all_mixer_handler)
		initial_all_mixer_handler();

	/* mixer control item */
	mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
	if (!mixer_item_handler) {
		printf("%s, get_mixer_item_handler failed!\n", __func__);
		return -EINVAL;
	}

	ret = snd_mixer_selem_set_playback_volume(mixer_item_handler, 0, volume);
	if (ret) {
		printf("%s, set_enum_item failed: %d, volume: %ld\n",
			__func__, ret, volume);
		return ret;
	}

	return 0;
}

long get_mixer_ctrl_volume_value(const char *mixer_ctrl_name)
{
	snd_mixer_elem_t *mixer_item_handler = NULL;
	long mixer_item_value[1];
	int ret;

	if (!g_all_mixer_handler)
		initial_all_mixer_handler();

	mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
	if (!mixer_item_handler) {
		printf("%s, get_mixer_item_handler failed!\n", __func__);
		return -EINVAL;
	}

	ret = snd_mixer_selem_get_playback_volume(mixer_item_handler, 0,
						  mixer_item_value);

	if (ret) {
		printf("%s, snd_mixer_selem_get_playback_volume failed: %d\n",
		       __func__, ret);
		return ret;
	}

	return mixer_item_value[0];
}

int set_mixer_ctrl_interconn_value(const char *mixer_ctrl_name,
				int is_on)
{
	snd_mixer_elem_t *mixer_item_handler = NULL;
	int ret = 0;

	if (!g_all_mixer_handler)
		initial_all_mixer_handler();

	/*printf("%s, mixerctrl (%s)  is_on (%d)!\n", __func__, mixer_ctrl_name, is_on); */

	/* mixer control item */
	mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
	if (!mixer_item_handler) {
		printf("%s, get_mixer_item_handler failed!\n", __func__);
		return -EINVAL;
	}

	ret =
		snd_mixer_selem_set_playback_switch(mixer_item_handler, SND_MIXER_SCHN_MONO , is_on);
	/* printf("%s, snd_mixer_selem_set_playback_switch: %d\n", __func__, ret); */

	/* if failed, get_enum_items return nagetive error num. */
	if (ret < 0) {
		printf("%s, snd_mixer_selem_set_playback_switch failed: %d\n",
			__func__, ret);
	}

	return ret;
}

int get_mixer_ctrl_interconn_value(const char *mixer_ctrl_name)
{
	snd_mixer_elem_t *mixer_item_handler = NULL;
	unsigned int mixer_item_value;
	int ret;
	if (!g_all_mixer_handler)
		initial_all_mixer_handler();

	/* mixer control item */
	mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
	if (!mixer_item_handler) {
		printf("%s, get_mixer_item_handler failed!\n", __func__);
		return -EINVAL;
	}
	ret =
		snd_mixer_selem_get_playback_switch(mixer_item_handler, SND_MIXER_SCHN_MONO, &mixer_item_value);
	/* printf("%s, snd_mixer_selem_get_playback_switch: %d\n", __func__, ret); */

	/* if failed, get_enum_items return nagetive error num. */
	if (ret < 0) {
		printf("%s, snd_mixer_selem_get_playback_switch failed: %d\n",
			__func__, ret);
	}

	/* printf("%s, mixerctrl (%s)  mixer_item_value (%d)!\n", __func__, mixer_ctrl_name, mixer_item_value[0]); */

	return mixer_item_value;
}

int set_mixer_ctrl_value_string(const char *mixer_ctrl_name,
				const char *option_name)
{
	snd_mixer_elem_t *mixer_item_handler = NULL;
	int mixer_item_option_num = 0;
	int i, ret;
	char item_name[STR_SIZE];

	if (!g_all_mixer_handler)
		initial_all_mixer_handler();

	/* mixer control item */
	mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
	if (!mixer_item_handler) {
		printf("%s, get_mixer_item_handler failed!\n", __func__);
		return -EINVAL;
	}
	mixer_item_option_num =
		snd_mixer_selem_get_enum_items(mixer_item_handler);

	/* if failed, get_enum_items return nagetive error num. */
	if (mixer_item_option_num < 0) {
		printf("%s, snd_mixer_selem_get_enum_items failed: %d\n",
			__func__, mixer_item_option_num);
		return mixer_item_option_num;
	}

	/* find option_name index */
	for (i = 0; i < mixer_item_option_num; i++) {
		ret = snd_mixer_selem_get_enum_item_name(mixer_item_handler, i,
							 STR_SIZE, item_name);
		if (ret)
			printf("%s, get_enum_item_name failed: %d, i: %d\n",
				__func__, ret, i);
		if (!strcmp(option_name, item_name))
			break;
	}

	/* not found */
	if (i == mixer_item_option_num) {
		printf("%s, option_name (%s) not found in mixerctrl (%s)!\n",
			__func__, option_name, mixer_ctrl_name);
		return -EINVAL;
	}

	/* found: the index is 'i' */
	ret = snd_mixer_selem_set_enum_item(mixer_item_handler, 0, i);
	if (ret) {
		printf("%s, set_enum_item failed: %d, i: %d\n",
			__func__, ret, i);
		return ret;
	}

	return 0;
}

int get_mixer_ctrl_value_int(const char *mixer_ctrl_name)
{
	snd_mixer_elem_t *mixer_item_handler = NULL;
	unsigned int mixer_item_value[1];
	int ret;

	if (!g_all_mixer_handler)
		initial_all_mixer_handler();

	mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
	if (!mixer_item_handler) {
		printf("%s, get_mixer_item_handler failed!\n", __func__);
		return -EINVAL;
	}

	ret = snd_mixer_selem_get_enum_item(mixer_item_handler, 0,
					    mixer_item_value);

	if (ret) {
		printf("%s, selem_get_enum_item failed: %d\n", __func__, ret);
		return ret;
	}

	return mixer_item_value[0];
}

char *get_mixer_ctrl_value_string(const char *mixer_ctrl_name,
				  char *returned_value_name,
				  int value_name_size)
{
	snd_mixer_elem_t *mixer_item_handler =
		get_mixer_item_handler(mixer_ctrl_name);
	int mixer_value_int = get_mixer_ctrl_value_int(mixer_ctrl_name);
	int ret;
	char item_name[STR_SIZE];

	ret = snd_mixer_selem_get_enum_item_name(mixer_item_handler,
						 mixer_value_int,
						 STR_SIZE, item_name);
	if (ret) {
		printf("%s, get_enum_item_name failed: %d, mixer_value_int: %d\n",
			__func__, ret, mixer_value_int);
		return NULL;
	}

	return strncpy(returned_value_name, item_name, value_name_size);
}

