// SPDX-License-Identifier: MediaTekProprietary
/*
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;
	}

	if (g_all_mixer_handler) {
		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;
	}

	if (mixer_ctrl_name && strlen(mixer_ctrl_name) >= STR_SIZE)
		return -1;

	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) {
		ret = initial_all_mixer_handler();
		if (ret) {
			printf("%s, initial_all_mixer_handler failed\n", __func__);
			return ret;
		}
	}

	/* 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) {
		ret = initial_all_mixer_handler();
		if (ret) {
			printf("%s, initial_all_mixer_handler failed\n", __func__);
			return ret;
		}
	}

	/* 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) {
		ret = initial_all_mixer_handler();
		if (ret) {
			printf("%s, initial_all_mixer_handler failed\n", __func__);
			return ret;
		}
	}

	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) {
		ret = initial_all_mixer_handler();
		if (ret) {
			printf("%s, initial_all_mixer_handler failed\n", __func__);
			return ret;
		}
	}

	/*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) {
		ret = initial_all_mixer_handler();
		if (ret) {
			printf("%s, initial_all_mixer_handler failed\n", __func__);
			return ret;
		}
	}

	/* 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) {
		ret = initial_all_mixer_handler();
		if (ret) {
			printf("%s, initial_all_mixer_handler failed\n", __func__);
			return ret;
		}
	}

	/* 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);
		} else {
			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) {
		ret = initial_all_mixer_handler();
		if (ret) {
			printf("%s, initial_all_mixer_handler failed\n", __func__);
			return ret;
		}
	}

	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 = NULL;
	int mixer_value_int = get_mixer_ctrl_value_int(mixer_ctrl_name);
	int ret;
	char item_name[STR_SIZE];

	if (!g_all_mixer_handler) {
		ret = initial_all_mixer_handler();
		if (ret) {
			printf("%s, initial_all_mixer_handler failed\n", __func__);
			return ret;
		}
	}

	mixer_item_handler = get_mixer_item_handler(mixer_ctrl_name);
	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);
}

