blob: 2821ed679f60033c7d2bb69bd42182e793dc4ec5 [file] [log] [blame]
/*
* sound/soc/amlogic/auge/spdif_hw.c
*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
#define DEBUG
#include <sound/soc.h>
#include "iomap.h"
#include "spdif_hw.h"
#include "ddr_mngr.h"
#include <linux/amlogic/media/sound/aout_notify.h>
/*#define G12A_PTM*/
/*#define __PTM_SPDIF_INTERNAL_LB__*/
unsigned int aml_spdif_ctrl_read(struct aml_audio_controller *actrl,
int stream, int index)
{
unsigned int offset, reg;
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * index;
} else {
reg = EE_AUDIO_SPDIFIN_CTRL0;
}
return aml_audiobus_read(actrl, reg);
}
void aml_spdif_ctrl_write(struct aml_audio_controller *actrl,
int stream, int index, int val)
{
unsigned int offset, reg;
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * index;
} else {
reg = EE_AUDIO_SPDIFIN_CTRL0;
}
aml_audiobus_write(actrl, reg, val);
}
void aml_spdifin_chnum_en(struct aml_audio_controller *actrl,
int index, bool is_enable)
{
unsigned int reg;
reg = EE_AUDIO_SPDIFIN_CTRL0;
aml_audiobus_update_bits(actrl, reg, 1 << 26, is_enable << 26);
pr_debug("%s spdifin ctrl0:0x%x\n",
__func__,
aml_audiobus_read(actrl, reg));
}
void aml_spdif_enable(
struct aml_audio_controller *actrl,
int stream,
int index,
bool is_enable)
{
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
unsigned int offset, reg;
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * index;
aml_audiobus_update_bits(actrl,
reg, 1<<31, is_enable<<31);
} else {
aml_audiobus_update_bits(actrl,
EE_AUDIO_SPDIFIN_CTRL0, 1<<31, is_enable<<31);
#ifdef __PTM_SPDIF_INTERNAL_LB__
if (index == 0)
aml_audiobus_update_bits(actrl,
EE_AUDIO_SPDIFIN_CTRL0, 0x3<<4, 0x1<<4);
#endif
}
}
void aml_spdif_mute(
struct aml_audio_controller *actrl,
int stream,
int index,
bool is_mute)
{
int mute_lr = 0;
if (is_mute)
mute_lr = 0x3;
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
unsigned int offset, reg;
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * index;
aml_audiobus_update_bits(actrl,
reg, 0x3 << 21, mute_lr << 21);
} else {
aml_audiobus_update_bits(actrl,
EE_AUDIO_SPDIFIN_CTRL0, 0x3 << 6, mute_lr << 6);
}
}
void aml_spdifout_mute_without_actrl(
int index,
bool is_mute)
{
unsigned int offset, reg;
int mute_lr = 0;
if (is_mute)
mute_lr = 0x3;
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * index;
audiobus_update_bits(reg, 0x3 << 21, mute_lr << 21);
}
void aml_spdif_arb_config(struct aml_audio_controller *actrl)
{
/* config ddr arb */
aml_audiobus_write(actrl, EE_AUDIO_ARB_CTRL, 1<<31|0xff<<0);
}
int aml_spdifin_status_check(struct aml_audio_controller *actrl)
{
unsigned int val;
val = aml_audiobus_read(actrl, EE_AUDIO_SPDIFIN_STAT0);
/* pr_info("\t--- spdif handles status0 %#x\n", val); */
return val;
}
void aml_spdifin_clr_irq(struct aml_audio_controller *actrl,
bool is_all_bits, int clr_bits_val)
{
if (is_all_bits) {
aml_audiobus_update_bits(actrl,
EE_AUDIO_SPDIFIN_CTRL0,
1 << 26,
1 << 26);
aml_audiobus_update_bits(actrl,
EE_AUDIO_SPDIFIN_CTRL0,
1 << 26,
0);
} else
aml_audiobus_update_bits(actrl,
EE_AUDIO_SPDIFIN_CTRL6,
0xff << 16,
clr_bits_val << 16);
}
void aml_spdif_fifo_reset(
struct aml_audio_controller *actrl,
int stream, int index)
{
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
/* reset afifo */
unsigned int offset, reg;
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * index;
aml_audiobus_update_bits(actrl,
reg, 3<<28, 0);
aml_audiobus_update_bits(actrl,
reg, 1<<29, 1<<29);
aml_audiobus_update_bits(actrl,
reg, 1<<28, 1<<28);
} else {
/* reset afifo */
aml_audiobus_update_bits(actrl,
EE_AUDIO_SPDIFIN_CTRL0, 3<<28, 0);
aml_audiobus_update_bits(actrl,
EE_AUDIO_SPDIFIN_CTRL0, 1<<29, 1<<29);
aml_audiobus_update_bits(actrl,
EE_AUDIO_SPDIFIN_CTRL0, 1<<28, 1<<28);
}
}
int spdifout_get_frddr_type(int bitwidth)
{
unsigned int frddr_type = 0;
switch (bitwidth) {
case 8:
frddr_type = 0;
break;
case 16:
frddr_type = 1;
break;
case 24:
frddr_type = 4;
break;
case 32:
frddr_type = 3;
break;
default:
pr_err("runtime format invalid bitwidth: %d\n",
bitwidth);
break;
}
return frddr_type;
}
void aml_spdif_fifo_ctrl(
struct aml_audio_controller *actrl,
int bitwidth,
int stream,
int index,
unsigned int fifo_id)
{
unsigned int toddr_type;
unsigned int frddr_type = spdifout_get_frddr_type(bitwidth);
switch (bitwidth) {
case 8:
toddr_type = 0;
break;
case 16:
toddr_type = 1;
break;
case 24:
toddr_type = 4;
break;
case 32:
toddr_type = 3;
break;
default:
pr_err("runtime format invalid bitwidth: %d\n",
bitwidth);
return;
}
pr_debug("%s, bit depth:%d, frddr type:%d, toddr:type:%d\n",
__func__,
bitwidth,
frddr_type,
toddr_type);
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
unsigned int offset, reg;
/* mask lane 0 L/R channels */
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * index;
aml_audiobus_update_bits(actrl,
reg,
0x1<<29|0x1<<28|0x1<<20|0x1<<19|0xff<<4,
1<<29|1<<28|0<<20|0<<19|0x3<<4);
offset = EE_AUDIO_SPDIFOUT_B_CTRL1 - EE_AUDIO_SPDIFOUT_CTRL1;
reg = EE_AUDIO_SPDIFOUT_CTRL1 + offset * index;
aml_audiobus_update_bits(actrl,
reg,
0x3 << 24 | 0x1f << 8 | 0x7 << 4,
fifo_id << 24 | (bitwidth - 1) << 8 | frddr_type<<4);
offset = EE_AUDIO_SPDIFOUT_B_SWAP - EE_AUDIO_SPDIFOUT_SWAP;
reg = EE_AUDIO_SPDIFOUT_SWAP + offset * index;
aml_audiobus_write(actrl,
reg,
1<<4);
} else {
unsigned int spdifin_clk = 500000000;
/* sysclk/rate/32(bit)/2(ch)/2(bmc) */
unsigned int counter_32k = (spdifin_clk / (32000 * 64));
unsigned int counter_44k = (spdifin_clk / (44100 * 64));
unsigned int counter_48k = (spdifin_clk / (48000 * 64));
unsigned int counter_88k = (spdifin_clk / (88200 * 64));
unsigned int counter_96k = (spdifin_clk / (96000 * 64));
unsigned int counter_176k = (spdifin_clk / (176400 * 64));
unsigned int counter_192k = (spdifin_clk / (192000 * 64));
unsigned int mode0_th = 3 * (counter_32k + counter_44k) >> 1;
unsigned int mode1_th = 3 * (counter_44k + counter_48k) >> 1;
unsigned int mode2_th = 3 * (counter_48k + counter_88k) >> 1;
unsigned int mode3_th = 3 * (counter_88k + counter_96k) >> 1;
unsigned int mode4_th = 3 * (counter_96k + counter_176k) >> 1;
unsigned int mode5_th = 3 * (counter_176k + counter_192k) >> 1;
unsigned int mode0_timer = counter_32k >> 1;
unsigned int mode1_timer = counter_44k >> 1;
unsigned int mode2_timer = counter_48k >> 1;
unsigned int mode3_timer = counter_88k >> 1;
unsigned int mode4_timer = counter_96k >> 1;
unsigned int mode5_timer = (counter_176k >> 1);
unsigned int mode6_timer = (counter_192k >> 1);
aml_audiobus_write(actrl,
EE_AUDIO_SPDIFIN_CTRL1,
0xff << 20 | (spdifin_clk / 10000) << 0);
aml_audiobus_write(actrl,
EE_AUDIO_SPDIFIN_CTRL2,
mode0_th << 20 |
mode1_th << 10 |
mode2_th << 0);
aml_audiobus_write(actrl,
EE_AUDIO_SPDIFIN_CTRL3,
mode3_th << 20 |
mode4_th << 10 |
mode5_th << 0);
aml_audiobus_write(actrl,
EE_AUDIO_SPDIFIN_CTRL4,
(mode0_timer << 24) |
(mode1_timer << 16) |
(mode2_timer << 8) |
(mode3_timer << 0)
);
aml_audiobus_write(actrl,
EE_AUDIO_SPDIFIN_CTRL5,
(mode4_timer << 24) |
(mode5_timer << 16) |
(mode6_timer << 8)
);
aml_audiobus_update_bits(actrl,
EE_AUDIO_SPDIFIN_CTRL0,
0x1 << 25 | 0x1 << 24 | 0xfff << 12,
0x1 << 25 | 0x0 << 24 | 0xff << 12);
}
}
int spdifin_get_mode(void)
{
int mode_val = audiobus_read(EE_AUDIO_SPDIFIN_STAT0);
mode_val >>= 28;
mode_val &= 0x7;
return mode_val;
}
int spdif_get_channel_status(int reg)
{
return audiobus_read(reg);
}
void spdifin_set_channel_status(int ch, int bits)
{
int ch_status_sel = (ch << 3 | bits) & 0xf;
/*which channel status would be got*/
audiobus_update_bits(EE_AUDIO_SPDIFIN_CTRL0,
0xf << 8,
ch_status_sel << 8);
}
void aml_spdifout_select_aed(bool enable, int spdifout_id)
{
unsigned int offset, reg;
/* select eq_drc output */
offset = EE_AUDIO_SPDIFOUT_B_CTRL1 - EE_AUDIO_SPDIFOUT_CTRL1;
reg = EE_AUDIO_SPDIFOUT_CTRL1 + offset * spdifout_id;
audiobus_update_bits(reg, 0x1 << 21, enable << 21);
}
void aml_spdifout_get_aed_info(int spdifout_id,
int *bitwidth, int *frddrtype)
{
unsigned int reg, offset, val;
offset = EE_AUDIO_SPDIFOUT_B_CTRL1
- EE_AUDIO_SPDIFOUT_CTRL1;
reg = EE_AUDIO_SPDIFOUT_CTRL1 + offset * spdifout_id;
val = audiobus_read(reg);
if (bitwidth)
*bitwidth = (val >> 8) & 0x1f;
if (frddrtype)
*frddrtype = (val >> 4) & 0x7;
}
/* spdifout to hdmix ctrl
* allow spdif out data to hdmitx
*/
void spdifout_to_hdmitx_ctrl(int spdif_index)
{
audiobus_write(EE_AUDIO_TOHDMITX_CTRL0,
1 << 31
| 1 << 3 /* spdif_clk_cap_inv */
| 0 << 2 /* spdif_clk_inv */
| spdif_index << 1 /* spdif_out */
| spdif_index << 0 /* spdif_clk */
);
}
#if 0
static void spdifout_clk_ctrl(int spdif_id, bool is_enable)
{
unsigned int offset, reg;
offset = EE_AUDIO_CLK_SPDIFOUT_B_CTRL - EE_AUDIO_CLK_SPDIFOUT_CTRL;
reg = EE_AUDIO_CLK_SPDIFOUT_CTRL + offset * spdif_id;
/* select : mpll 0, 24m, so spdif clk:6m */
audiobus_write(reg, is_enable << 31 | 0x0 << 24 | 0x3 << 0);
}
#endif
static void spdifout_fifo_ctrl(int spdif_id,
int fifo_id, int bitwidth, int channels, int lane_i2s)
{
unsigned int frddr_type = spdifout_get_frddr_type(bitwidth);
unsigned int offset, reg, i, chmask = 0;
unsigned int swap_masks = 0;
/* spdif always masks two channel */
if (lane_i2s * 2 >= channels) {
pr_err("invalid lane(%d) and channels(%d)\n",
lane_i2s, channels);
return;
}
for (i = 0; i < channels; i++)
chmask |= (1 << i);
swap_masks = (2 * lane_i2s) |
(2 * lane_i2s + 1) << 4;
pr_debug("spdif_%s fifo ctrl, frddr:%d type:%d, %d bits, chmask %#x, swap %#x\n",
(spdif_id == 0) ? "a":"b",
fifo_id,
frddr_type,
bitwidth,
chmask,
swap_masks);
/* mask lane 0 L/R channels */
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * spdif_id;
audiobus_update_bits(reg,
0x1<<20|0x1<<19|0xff<<4,
0<<20|0<<19|chmask<<4);
offset = EE_AUDIO_SPDIFOUT_B_CTRL1 - EE_AUDIO_SPDIFOUT_CTRL1;
reg = EE_AUDIO_SPDIFOUT_CTRL1 + offset * spdif_id;
audiobus_update_bits(reg,
0x3 << 24 | 0x1f << 8 | 0x7 << 4,
fifo_id << 24 | (bitwidth - 1) << 8 | frddr_type<<4);
offset = EE_AUDIO_SPDIFOUT_B_SWAP - EE_AUDIO_SPDIFOUT_SWAP;
reg = EE_AUDIO_SPDIFOUT_SWAP + offset * spdif_id;
audiobus_write(reg, swap_masks);
}
static bool spdifout_is_enable(int spdif_id)
{
unsigned int offset, reg, val;
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * spdif_id;
val = audiobus_read(reg);
return ((val >> 31) == 1);
}
void spdifout_enable(int spdif_id, bool is_enable, bool reenable)
{
unsigned int offset, reg;
pr_debug("spdif_%s is set to %s\n",
(spdif_id == 0) ? "a":"b",
is_enable ? "enable":"disable");
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * spdif_id;
if (!is_enable) {
/* share buffer, spdif should be active, so mute it */
/*audiobus_update_bits(reg, 0x3 << 21, 0x3 << 21);*/
return;
}
/* disable then for reset, to correct channel map */
if (reenable)
audiobus_update_bits(reg, 1<<31, 0x0<<31);
/* reset afifo */
audiobus_update_bits(reg, 3<<28, 0);
audiobus_update_bits(reg, 1<<29, 1<<29);
audiobus_update_bits(reg, 1<<28, 1<<28);
audiobus_update_bits(reg, 1<<31, is_enable<<31);
}
void spdifout_samesource_set(int spdif_index, int fifo_id,
int bitwidth, int channels, bool is_enable, int lane_i2s)
{
int spdif_id;
if (spdif_index == 1)
spdif_id = 1;
else
spdif_id = 0;
if (is_enable)
spdifout_fifo_ctrl(spdif_id,
fifo_id, bitwidth, channels, lane_i2s);
}
int spdifin_get_sample_rate(void)
{
unsigned int val;
/*EE_AUDIO_SPDIFIN_STAT0*/
/*r_width_max bit17:8 (the max width of two edge;)*/
unsigned int max_width = 0;
val = audiobus_read(EE_AUDIO_SPDIFIN_STAT0);
/* NA when check min width of two edges */
if (((val >> 18) & 0x3ff) == 0x3ff)
return 7;
/*check the max width of two edge when spdifin sr=32kHz*/
/*if max_width is more than 0x2f0(magic number),*/
/*sr(32kHz) is unavailable*/
max_width = ((val >> 8) & 0x3ff);
if ((((val >> 28) & 0x7) == 0) && (max_width == 0x3ff))
return 7;
return (val >> 28) & 0x7;
}
static int spdifin_get_channel_status(int sel)
{
unsigned int val;
/* set ch_status_sel to channel status */
audiobus_update_bits(EE_AUDIO_SPDIFIN_CTRL0, 0xf << 8, sel << 8);
val = audiobus_read(EE_AUDIO_SPDIFIN_STAT1);
return val;
}
int spdifin_get_ch_status0to31(void)
{
return spdifin_get_channel_status(0x0);
}
int spdifin_get_audio_type(void)
{
unsigned int val;
/* set ch_status_sel to read Pc */
val = spdifin_get_channel_status(0x6);
return (val >> 16) & 0xff;
}
void spdifin_set_src(int src)
{
audiobus_update_bits(EE_AUDIO_SPDIFIN_CTRL0, 0x3 << 4, src << 4);
}
void spdif_set_channel_status_info(
struct iec958_chsts *chsts, int spdif_id)
{
unsigned int offset, reg;
/* "ch status" = reg_chsts0~B */
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * spdif_id;
audiobus_update_bits(reg, 0x1 << 24, 0x0 << 24);
offset = EE_AUDIO_SPDIFOUT_B_CHSTS0 - EE_AUDIO_SPDIFOUT_CHSTS0;
reg = EE_AUDIO_SPDIFOUT_CHSTS0 + offset * spdif_id;
audiobus_write(reg, chsts->chstat1_l << 16 | chsts->chstat0_l);
offset = EE_AUDIO_SPDIFOUT_B_CHSTS1 - EE_AUDIO_SPDIFOUT_CHSTS1;
reg = EE_AUDIO_SPDIFOUT_CHSTS1 + offset * spdif_id;
audiobus_write(reg, chsts->chstat1_l << 16 | chsts->chstat0_l);
offset = EE_AUDIO_SPDIFOUT_B_CHSTS2 - EE_AUDIO_SPDIFOUT_CHSTS2;
reg = EE_AUDIO_SPDIFOUT_CHSTS2 + offset * spdif_id;
audiobus_write(reg, chsts->chstat1_l << 16 | chsts->chstat0_l);
offset = EE_AUDIO_SPDIFOUT_B_CHSTS3 - EE_AUDIO_SPDIFOUT_CHSTS3;
reg = EE_AUDIO_SPDIFOUT_CHSTS3 + offset * spdif_id;
audiobus_write(reg, chsts->chstat1_l << 16 | chsts->chstat0_l);
offset = EE_AUDIO_SPDIFOUT_B_CHSTS4 - EE_AUDIO_SPDIFOUT_CHSTS4;
reg = EE_AUDIO_SPDIFOUT_CHSTS4 + offset * spdif_id;
audiobus_write(reg, chsts->chstat1_l << 16 | chsts->chstat0_l);
offset = EE_AUDIO_SPDIFOUT_B_CHSTS5 - EE_AUDIO_SPDIFOUT_CHSTS5;
reg = EE_AUDIO_SPDIFOUT_CHSTS5 + offset * spdif_id;
audiobus_write(reg, chsts->chstat1_l << 16 | chsts->chstat0_l);
offset = EE_AUDIO_SPDIFOUT_B_CHSTS6 - EE_AUDIO_SPDIFOUT_CHSTS6;
reg = EE_AUDIO_SPDIFOUT_CHSTS6 + offset * spdif_id;
audiobus_write(reg, chsts->chstat1_r << 16 | chsts->chstat0_r);
offset = EE_AUDIO_SPDIFOUT_B_CHSTS7 - EE_AUDIO_SPDIFOUT_CHSTS7;
reg = EE_AUDIO_SPDIFOUT_CHSTS7 + offset * spdif_id;
audiobus_write(reg, chsts->chstat1_r << 16 | chsts->chstat0_r);
offset = EE_AUDIO_SPDIFOUT_B_CHSTS8 - EE_AUDIO_SPDIFOUT_CHSTS8;
reg = EE_AUDIO_SPDIFOUT_CHSTS8 + offset * spdif_id;
audiobus_write(reg, chsts->chstat1_r << 16 | chsts->chstat0_r);
offset = EE_AUDIO_SPDIFOUT_B_CHSTS9 - EE_AUDIO_SPDIFOUT_CHSTS9;
reg = EE_AUDIO_SPDIFOUT_CHSTS9 + offset * spdif_id;
audiobus_write(reg, chsts->chstat1_r << 16 | chsts->chstat0_r);
offset = EE_AUDIO_SPDIFOUT_B_CHSTSA - EE_AUDIO_SPDIFOUT_CHSTSA;
reg = EE_AUDIO_SPDIFOUT_CHSTSA + offset * spdif_id;
audiobus_write(reg, chsts->chstat1_r << 16 | chsts->chstat0_r);
offset = EE_AUDIO_SPDIFOUT_B_CHSTSB - EE_AUDIO_SPDIFOUT_CHSTSB;
reg = EE_AUDIO_SPDIFOUT_CHSTSB + offset * spdif_id;
audiobus_write(reg, chsts->chstat1_r << 16 | chsts->chstat0_r);
}
void spdifout_play_with_zerodata(unsigned int spdif_id, bool reenable)
{
pr_debug("%s, spdif id:%d enable:%d\n",
__func__,
spdif_id,
spdifout_is_enable(spdif_id));
if (!spdifout_is_enable(spdif_id)) {
unsigned int frddr_index = 0;
unsigned int bitwidth = 32;
unsigned int sample_rate = 48000;
unsigned int src0_sel = 4; /* spdif b */
struct iec958_chsts chsts;
struct snd_pcm_substream substream;
struct snd_pcm_runtime runtime;
substream.runtime = &runtime;
runtime.rate = sample_rate;
runtime.format = SNDRV_PCM_FORMAT_S16_LE;
runtime.channels = 2;
runtime.sample_bits = 16;
/* check whether fix to spdif a */
if (spdif_id == 0)
src0_sel = 3;
/* spdif clk */
//spdifout_clk_ctrl(spdif_id, true);
/* spdif to hdmitx */
spdifout_to_hdmitx_ctrl(spdif_id);
/* spdif ctrl */
spdifout_fifo_ctrl(spdif_id,
frddr_index, bitwidth, runtime.channels, 0);
/* channel status info */
spdif_get_channel_status_info(&chsts, sample_rate);
spdif_set_channel_status_info(&chsts, spdif_id);
/* notify hdmitx audio */
aout_notifier_call_chain(0x1, &substream);
/* init frddr to output zero data. */
frddr_init_without_mngr(frddr_index, src0_sel);
/* spdif enable */
spdifout_enable(spdif_id, true, reenable);
}
}
void spdifout_play_with_zerodata_free(unsigned int spdif_id)
{
pr_debug("%s, spdif id:%d\n",
__func__,
spdif_id);
/* free frddr, then frddr in mngr */
frddr_deinit_without_mngr(spdif_id);
}