static int av8100_codec_setup_hdmi_format(void)
{
	union av8100_configuration config;
	int ret;

	pr_debug("%s: Enter.\n", __func__);

	pr_debug("%s: hdmi_mode = AV8100_HDMI_ON.", __func__);
	pr_debug("%s: hdmi_format = AV8100_HDMI.", __func__);
	config.hdmi_format.hdmi_mode = AV8100_HDMI_ON;
	config.hdmi_format.hdmi_format = AV8100_HDMI;
	config.hdmi_format.dvi_format = AV8100_DVI_CTRL_CTL0;
	ret = av8100_conf_prep(AV8100_COMMAND_HDMI, &config);
	if (ret != 0) {
		pr_err("%s: Setting hdmi_format failed "
			"(av8100_conf_prep returned %d)!\n",
			__func__,
			ret);
		return -EINVAL;
	}
	ret = av8100_conf_w(AV8100_COMMAND_HDMI,
			NULL,
			NULL,
			I2C_INTERFACE);
	if (ret != 0) {
		pr_err("%s: Setting hdmi_format failed "
			"(av8100_conf_w returned %d)!\n",
			__func__,
			ret);
		return -EINVAL;
	}

	return 0;
}
static int av8100_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
				unsigned int fmt)
{
	union av8100_configuration config;
	int ret;

	pr_debug("%s: Enter.\n", __func__);

	/* Set the HDMI format of AV8100 */
	ret = av8100_codec_setup_hdmi_format();
	if (ret != 0)
		return ret;

	/* Set the audio input format of AV8100 */
	config.audio_input_format.audio_input_if_format	=
		((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_DSP_A) ?
		AV8100_AUDIO_TDM_MODE : AV8100_AUDIO_I2SDELAYED_MODE;
	config.audio_input_format.audio_if_mode	=
		((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM) ?
		AV8100_AUDIO_MASTER : AV8100_AUDIO_SLAVE;
	pr_info("%s: Setting audio_input_format "
		"(if_format = %d, if_mode = %d).",
		__func__,
		config.audio_input_format.audio_input_if_format,
		config.audio_input_format.audio_if_mode);
	config.audio_input_format.i2s_input_nb = 1;
	config.audio_input_format.sample_audio_freq = AV8100_AUDIO_FREQ_48KHZ;
	config.audio_input_format.audio_word_lg	= AV8100_AUDIO_16BITS;
	config.audio_input_format.audio_format = AV8100_AUDIO_LPCM_MODE;
	config.audio_input_format.audio_mute = AV8100_AUDIO_MUTE_DISABLE;
	av8100_conf_lock();
	ret = av8100_conf_prep(AV8100_COMMAND_AUDIO_INPUT_FORMAT, &config);
	if (ret != 0) {
		pr_err("%s: Setting audio_input_format failed "
			"(av8100_conf_prep returned %d)!\n",
			__func__,
			ret);
		av8100_conf_unlock();
		return -EINVAL;
	}
	ret = av8100_conf_w(AV8100_COMMAND_AUDIO_INPUT_FORMAT,
			NULL,
			NULL,
			I2C_INTERFACE);
	if (ret != 0) {
		pr_err("%s: Setting audio_input_format failed "
			"(av8100_conf_w returned %d)!\n",
			__func__,
			ret);
		av8100_conf_unlock();
		return -EINVAL;
	}

	av8100_conf_unlock();
	return 0;
}
static int av8100_codec_send_audio_infoframe(struct hdmi_audio_settings *as)
{
	union av8100_configuration config;
	struct av8100_infoframes_format_cmd info_fr;
	int ret;

	pr_debug("%s: Enter.\n", __func__);

	pr_debug("%s: HDMI-settings:\n", __func__);
	pr_debug("%s:	audio_coding_type = %d\n", __func__, audio_coding_type);
	pr_debug("%s:	audio_channel_count = %d\n", __func__, as->audio_channel_count);
	pr_debug("%s:	sampling_frequency = %d\n", __func__, as->sampling_frequency);
	pr_debug("%s:	sample_size = %d\n", __func__, as->sample_size);
	pr_debug("%s:	channel_allocation = %d\n", __func__, as->channel_allocation);
	pr_debug("%s:	level_shift_value = %d\n", __func__, as->level_shift_value);
	pr_debug("%s:	downmix_inhibit = %d\n", __func__, as->downmix_inhibit);

	/* Prepare the infoframe from the hdmi_audio_settings struct */
	pr_info("%s: Preparing audio info-frame.", __func__);
	info_fr.type = 0x84;
	info_fr.version = 0x01;
	info_fr.length = 0x0a;
	info_fr.data[0] = (audio_coding_type << 4) | as->audio_channel_count;
	info_fr.data[1] = (as->sampling_frequency << 2) | as->sample_size;
	info_fr.data[2] = 0;
	info_fr.data[3] = as->channel_allocation;
	info_fr.data[4] = ((int)as->downmix_inhibit << 7) |
			(as->level_shift_value << 3);
	info_fr.data[5] = 0;
	info_fr.data[6] = 0;
	info_fr.data[7] = 0;
	info_fr.data[8] = 0;
	info_fr.data[9] = 0;
	info_fr.crc = 0x100 - (info_fr.type +
		info_fr.version +
		info_fr.length +
		info_fr.data[0] +
		info_fr.data[1] +
		info_fr.data[3] +
		info_fr.data[4]);
	config.infoframes_format.type = info_fr.type;
	config.infoframes_format.version = info_fr.version;
	config.infoframes_format.crc = info_fr.crc;
	config.infoframes_format.length = info_fr.length;
	memcpy(&config.infoframes_format.data, info_fr.data, info_fr.length);

	/* Send audio info-frame */
	pr_info("%s: Sending audio info-frame.", __func__);
	ret = av8100_conf_prep(AV8100_COMMAND_INFOFRAMES, &config);
	if (ret != 0) {
		pr_err("%s: Sending audio info-frame failed "
			"(av8100_conf_prep returned %d)!\n",
			__func__,
			ret);
		return -EINVAL;
	}
	ret = av8100_conf_w(AV8100_COMMAND_INFOFRAMES,
			NULL,
			NULL,
			I2C_INTERFACE);
	if (ret != 0) {
		pr_err("%s: Sending audio info-frame failed "
			"(av8100_conf_w returned %d)!\n",
			__func__,
			ret);
		return -EINVAL;
	}

	return 0;
}