diff options
Diffstat (limited to 'drivers/mxc/hdp/API_HDMI_RX_Audio.c')
-rw-r--r-- | drivers/mxc/hdp/API_HDMI_RX_Audio.c | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/drivers/mxc/hdp/API_HDMI_RX_Audio.c b/drivers/mxc/hdp/API_HDMI_RX_Audio.c new file mode 100644 index 000000000000..1d1442c731ff --- /dev/null +++ b/drivers/mxc/hdp/API_HDMI_RX_Audio.c @@ -0,0 +1,191 @@ +/****************************************************************************** + * + * Copyright (C) 2016-2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Copyright 2018 NXP + * + ****************************************************************************** + * + * API_HDMI_RX_Audio.c + * + ****************************************************************************** + */ + +#include "API_HDMI_RX_Audio.h" +#include "sink_aif_encoder.h" +#include "aif_pckt2smp.h" +#include "address.h" +#include "util.h" +#include "API_General.h" + +CDN_API_STATUS CDN_API_RX_AudioAutoConfig( + state_struct *state, + u8 max_ch_num, + u8 i2s_ports_num, + u8 dis_port3, + u8 enc_sample_width, + u8 i2s_sample_width) +{ + u32 regread; + u8 num_of_pairs_of_channels_per_port = max_ch_num / (i2s_ports_num * 2); + u8 enc_size_code; + u8 i2s_size_code; + u8 i2s_port3_dis = (dis_port3 != 0 && i2s_ports_num == 4) ? 1 : 0; + u8 times = 0; + + /* Valid values: 1/2/4. */ + /* 3 ports can be emulated with 'i2s_ports_num = 4' and 'dis_port3 = 1'. */ + if (i2s_ports_num == 0 || i2s_ports_num == 3 || i2s_ports_num > 4) + return CDN_ERR; + + /* 'dis_port3' makes sense only with 4 ports enabled */ + if (dis_port3 != 0 && i2s_ports_num < 4) + return CDN_ERR; + + switch (enc_sample_width) { + case 16: + enc_size_code = 0x0; + break; + case 24: + enc_size_code = 0x1; + break; + case 32: + enc_size_code = 0x2; + break; + default: + return CDN_ERR; + } + + switch (i2s_sample_width) { + case 16: + i2s_size_code = 0x0; + break; + case 24: + i2s_size_code = 0x1; + break; + case 32: + i2s_size_code = 0x2; + break; + default: + return CDN_ERR; + } + + /* Maximum number of channels has to be in range from 2 to 32 */ + if (max_ch_num < 2 || max_ch_num > 32) + return CDN_ERR; + /* Maximum number of channels has to be power of 2 */ + else if (!(max_ch_num * (max_ch_num - 1))) + return CDN_ERR; + /* Each active port shall carry the same number of sub-channels */ + else if (max_ch_num % i2s_ports_num) + return CDN_ERR; + + /* Disable ACR during configuration */ + if (cdn_apb_write(state, ADDR_AIF_ENCODER + (ACR_CFG << 2), F_ACR_SW_RESET(1))) + return CDN_ERR; + + /* Configuring audio FIFO */ + if (cdn_apb_write(state, + ADDR_AIF_ENCODER + ((0x40 + FIFO_CNTL_ADDR) << 2), + F_CFG_FIFO_SW_RST(0) | F_CFG_INDEX_SYNC_EN(1) | + F_CFG_FIFO_DIR(1) | F_CFG_DIS_PORT3(i2s_port3_dis))) + return CDN_ERR; + + /* Configuring audio parameters */ + if (cdn_apb_write(state, + ADDR_AIF_ENCODER + ((0x40 + AUDIO_SINK_CNFG) << 2), + F_ENC_LOW_INDEX_MSB(0) | F_SINK_AUDIO_CH_NUM(max_ch_num - 1) | + F_ENC_SAMPLE_JUST(0x0) | F_ENC_SMPL_WIDTH(enc_size_code) | + F_I2S_ENC_WL_SIZE(i2s_size_code) | F_CNTL_SMPL_ONLY_EN(1) | + F_CNTL_TYPE_OVRD(0x0) | F_CNTL_TYPE_OVRD_EN(0) | + F_I2S_ENC_PORT_EN((1 << i2s_ports_num) - 1) | F_WS_POLARITY(0))) + return CDN_ERR; + + /* Waiting for N value... */ + do { + if (cdn_apb_read(state, + ADDR_AIF_ENCODER + (AIF_ACR_N_ST << 2), ®read)) + return CDN_ERR; + times++; + udelay(10); + } while (!(regread) && times < 100); + + if (times == 100) + return CDN_ERR; + + /* Enable ACR */ + if (cdn_apb_write(state, + ADDR_AIF_ENCODER + (ACR_CFG << 2), F_ACR_SW_RESET(0))) + return CDN_ERR; + + /* Important: */ + /* Write to AIF_ACR_N_OFST_CFG register is interpreted as new N_CTS value. */ + /* The ACR has to be enabled (reset released) to register that event. */ + + if (cdn_apb_write(state, + ADDR_AIF_ENCODER + (AIF_ACR_N_OFST_CFG << 2), + F_ACR_N_OFFSET(regread * (num_of_pairs_of_channels_per_port - 1)))) + return CDN_ERR; + + /* Enable sample decoder */ + if (cdn_apb_write(state, + ADDR_AIF_ENCODER + (PKT2SMPL_CNTL << 2), F_PKT2SMPL_EN(1))) + return CDN_ERR; + + /* Enable I2S encoder */ + if (cdn_apb_write(state, + ADDR_AIF_ENCODER + ((0x40 + AUDIO_SINK_CNTL) << 2), F_I2S_ENC_START(1))) + return CDN_ERR; + + return CDN_OK; + +} + +CDN_API_STATUS CDN_API_RX_AudioAutoConfig_blocking(state_struct *state, + u8 max_ch_num, + u8 i2s_ports_num, + u8 dis_port3, + u8 enc_sample_width, + u8 i2s_sample_width) +{ + internal_block_function(&state->mutex, + CDN_API_RX_AudioAutoConfig(state, + max_ch_num, + i2s_ports_num, + dis_port3, + enc_sample_width, + i2s_sample_width)); +} |