static int msm_dai_q6_auxpcm_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); int rc = 0; mutex_lock(&aux_pcm_mutex); if (aux_pcm_count == 2) { dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count is 2. Just" " return.\n", __func__, dai->id); mutex_unlock(&aux_pcm_mutex); return 0; } else if (aux_pcm_count > 2) { dev_err(dai->dev, "%s(): ERROR: dai->id %d" " aux_pcm_count = %d > 2\n", __func__, dai->id, aux_pcm_count); mutex_unlock(&aux_pcm_mutex); return 0; } aux_pcm_count++; if (aux_pcm_count == 2) { dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count = %d after " " increment\n", __func__, dai->id, aux_pcm_count); mutex_unlock(&aux_pcm_mutex); return 0; } pr_debug("%s:dai->id:%d aux_pcm_count = %d. opening afe\n", __func__, dai->id, aux_pcm_count); rc = afe_q6_interface_prepare(); if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "fail to open AFE APR\n"); /* * For AUX PCM Interface the below sequence of clk * settings and afe_open is a strict requirement. * * Also using afe_open instead of afe_port_start_nowait * to make sure the port is open before deasserting the * clock line. This is required because pcm register is * not written before clock deassert. Hence the hw does * not get updated with new setting if the below clock * assert/deasset and afe_open sequence is not followed. */ afe_open(PCM_RX, &dai_data->port_config, dai_data->rate); afe_open(PCM_TX, &dai_data->port_config, dai_data->rate); mutex_unlock(&aux_pcm_mutex); return rc; }
static int msm_dai_q6_auxpcm_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); int rc = 0; struct msm_dai_auxpcm_pdata *auxpcm_pdata = (struct msm_dai_auxpcm_pdata *) dai->dev->platform_data; if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { rc = afe_q6_interface_prepare(); if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "fail to open AFE APR\n"); rc = afe_q6_interface_prepare(); if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "fail to open AFE APR\n"); pr_debug("%s:dai->id:%d dai_data->status_mask = %ld\n", __func__, dai->id, *dai_data->status_mask); /* * For AUX PCM Interface the below sequence of clk * settings and afe_open is a strict requirement. * * Also using afe_open instead of afe_port_start_nowait * to make sure the port is open before deasserting the * clock line. This is required because pcm register is * not written before clock deassert. Hence the hw does * not get updated with new setting if the below clock * assert/deasset and afe_open sequence is not followed. */ clk_reset(pcm_clk, CLK_RESET_ASSERT); afe_open(dai->id, &dai_data->port_config, dai_data->rate); set_bit(STATUS_PORT_STARTED, dai_data->status_mask); afe_open(PCM_TX, &dai_data->port_config, dai_data->rate); rc = clk_set_rate(pcm_clk, auxpcm_pdata->pcm_clk_rate); if (rc < 0) { pr_err("%s: clk_set_rate failed\n", __func__); return rc; } clk_enable(pcm_clk); clk_reset(pcm_clk, CLK_RESET_DEASSERT); } return rc; }
static int snddev_hdmi_open(struct msm_snddev_info *dev_info) { int rc = 0; union afe_port_config afe_config; struct snddev_hdmi_data *snddev_hdmi_data; if (!dev_info) { pr_err("msm_snddev_info is null\n"); return -EINVAL; } snddev_hdmi_data = dev_info->private_data; mutex_lock(&snddev_hdmi_lock); if (snddev_hdmi_active) { pr_err("HDMI snddev already active\n"); mutex_unlock(&snddev_hdmi_lock); return -EBUSY; } if (snddev_hdmi_data->on_apps) { snddev_hdmi_active = 1; pr_debug("%s open done\n", dev_info->name); mutex_unlock(&snddev_hdmi_lock); return 0; } afe_config.hdmi.channel_mode = snddev_hdmi_data->channel_mode; afe_config.hdmi.bitwidth = 16; afe_config.hdmi.data_type = 0; rc = afe_open(snddev_hdmi_data->copp_id, &afe_config, dev_info->sample_rate); if (rc < 0) { pr_err("afe_open failed\n"); mutex_unlock(&snddev_hdmi_lock); return -EINVAL; } snddev_hdmi_active = 1; pr_debug("%s open done\n", dev_info->name); mutex_unlock(&snddev_hdmi_lock); return 0; }
static int afe_start(struct pcm *pcm) { union afe_port_config port_config; port_config.rtproxy.num_ch = pcm->channel_count; pr_debug("channel %d entered,port: %d,rate: %d\n", port_config.rtproxy.num_ch, RT_PROXY_DAI_001_TX, pcm->sample_rate); port_config.rtproxy.bitwidth = 16; /* Q6 only supports 16 */ port_config.rtproxy.interleaved = 1; port_config.rtproxy.frame_sz = pcm->buffer_size; port_config.rtproxy.jitter = port_config.rtproxy.frame_sz/2; port_config.rtproxy.lw_mark = 0; port_config.rtproxy.hw_mark = 0; port_config.rtproxy.rsvd = 0; afe_open(RT_PROXY_DAI_001_TX, &port_config, pcm->sample_rate); return 0; }
static int snddev_ecodec_open(struct msm_snddev_info *dev_info) { int rc; struct snddev_ecodec_drv_state *drv = &snddev_ecodec_drv; union afe_port_config afe_config; pr_debug("%s\n", __func__); mutex_lock(&drv->dev_lock); if (dev_info->opened) { pr_err("%s: ERROR: %s already opened\n", __func__, dev_info->name); mutex_unlock(&drv->dev_lock); return -EBUSY; } if (drv->ref_cnt != 0) { pr_debug("%s: opened %s\n", __func__, dev_info->name); drv->ref_cnt++; mutex_unlock(&drv->dev_lock); return 0; } pr_info("%s: opening %s\n", __func__, dev_info->name); rc = aux_pcm_gpios_request(); if (rc < 0) { pr_err("%s: GPIO request failed\n", __func__); return rc; } clk_reset(drv->ecodec_clk, CLK_RESET_ASSERT); afe_config.pcm.mode = AFE_PCM_CFG_MODE_PCM; afe_config.pcm.sync = AFE_PCM_CFG_SYNC_INT; afe_config.pcm.frame = AFE_PCM_CFG_FRM_256BPF; afe_config.pcm.quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD; afe_config.pcm.slot = 0; afe_config.pcm.data = AFE_PCM_CFG_CDATAOE_MASTER; rc = afe_open(PCM_RX, &afe_config, ECODEC_SAMPLE_RATE); if (rc < 0) { pr_err("%s: afe open failed for PCM_RX\n", __func__); goto err_rx_afe; } rc = afe_open(PCM_TX, &afe_config, ECODEC_SAMPLE_RATE); if (rc < 0) { pr_err("%s: afe open failed for PCM_TX\n", __func__); goto err_tx_afe; } rc = clk_set_rate(drv->ecodec_clk, 2048000); if (rc < 0) { pr_err("%s: clk_set_rate failed\n", __func__); goto err_clk; } clk_prepare_enable(drv->ecodec_clk); clk_reset(drv->ecodec_clk, CLK_RESET_DEASSERT); drv->ref_cnt++; mutex_unlock(&drv->dev_lock); return 0; err_clk: afe_close(PCM_TX); err_tx_afe: afe_close(PCM_RX); err_rx_afe: aux_pcm_gpios_free(); mutex_unlock(&drv->dev_lock); return -ENODEV; }
static int snddev_icodec_open_tx(struct snddev_icodec_state *icodec) { int trc; int afe_channel_mode; union afe_port_config afe_config; struct snddev_icodec_drv_state *drv = &snddev_icodec_drv;; pm_qos_update_request(&drv->tx_pm_qos_req, msm_cpuidle_get_deep_idle_latency()); if (drv->snddev_vreg) vreg_mode_vote(drv->snddev_vreg, 1, SNDDEV_HIGH_POWER_MODE); /* Reuse pamp_on for TX platform-specific setup */ if (icodec->data->pamp_on) { if (icodec->data->pamp_on()) { pr_err("%s: Error turning on tx power\n", __func__); goto error_pamp; } } msm_snddev_tx_mclk_request(); drv->tx_osrclk = clk_get_sys(NULL, "i2s_mic_osr_clk"); if (IS_ERR(drv->tx_osrclk)) pr_err("%s master clock Error\n", __func__); trc = clk_set_rate(drv->tx_osrclk, SNDDEV_ICODEC_CLK_RATE(icodec->sample_rate)); if (IS_ERR_VALUE(trc)) { pr_err("ERROR setting m clock1\n"); goto error_invalid_freq; } clk_prepare_enable(drv->tx_osrclk); drv->tx_bitclk = clk_get_sys(NULL, "i2s_mic_bit_clk"); if (IS_ERR(drv->tx_bitclk)) pr_err("%s clock Error\n", __func__); /* Master clock = Sample Rate * OSR rate bit clock * OSR Rate bit clock = bit/sample * channel master * clock / bit clock = divider value = 8 */ if (msm_codec_i2s_slave_mode) { pr_info("%s: configuring bit clock for slave mode\n", __func__); trc = clk_set_rate(drv->tx_bitclk, 0); } else trc = clk_set_rate(drv->tx_bitclk, 8); clk_prepare_enable(drv->tx_bitclk); /* Enable ADIE */ trc = adie_codec_open(icodec->data->profile, &icodec->adie_path); if (IS_ERR_VALUE(trc)) pr_err("%s: adie codec open failed\n", __func__); else adie_codec_setpath(icodec->adie_path, icodec->sample_rate, 256); switch (icodec->data->channel_mode) { case 2: afe_channel_mode = MSM_AFE_STEREO; break; case 1: default: afe_channel_mode = MSM_AFE_MONO; break; } afe_config.mi2s.channel = afe_channel_mode; afe_config.mi2s.bitwidth = 16; afe_config.mi2s.line = 1; afe_config.mi2s.format = MSM_AFE_I2S_FORMAT_LPCM; if (msm_codec_i2s_slave_mode) afe_config.mi2s.ws = 0; else afe_config.mi2s.ws = 1; trc = afe_open(icodec->data->copp_id, &afe_config, icodec->sample_rate); if (icodec->adie_path) { adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_READY); adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_ANALOG_READY); } if (msm_codec_i2s_slave_mode) adie_codec_set_master_mode(icodec->adie_path, 1); else adie_codec_set_master_mode(icodec->adie_path, 0); icodec->enabled = 1; pm_qos_update_request(&drv->tx_pm_qos_req, PM_QOS_DEFAULT_VALUE); return 0; error_invalid_freq: if (icodec->data->pamp_off) icodec->data->pamp_off(); pr_err("%s: encounter error\n", __func__); error_pamp: pm_qos_update_request(&drv->tx_pm_qos_req, PM_QOS_DEFAULT_VALUE); return -ENODEV; }
static int snddev_icodec_open_rx(struct snddev_icodec_state *icodec) { int trc; int afe_channel_mode; union afe_port_config afe_config; struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; pm_qos_update_request(&drv->rx_pm_qos_req, msm_cpuidle_get_deep_idle_latency()); if (drv->snddev_vreg) { if (!strcmp(icodec->data->name, "headset_stereo_rx")) vreg_mode_vote(drv->snddev_vreg, 1, SNDDEV_LOW_POWER_MODE); else vreg_mode_vote(drv->snddev_vreg, 1, SNDDEV_HIGH_POWER_MODE); } msm_snddev_rx_mclk_request(); drv->rx_osrclk = clk_get_sys(NULL, "i2s_spkr_osr_clk"); if (IS_ERR(drv->rx_osrclk)) pr_err("%s master clock Error\n", __func__); trc = clk_set_rate(drv->rx_osrclk, SNDDEV_ICODEC_CLK_RATE(icodec->sample_rate)); if (IS_ERR_VALUE(trc)) { pr_err("ERROR setting m clock1\n"); goto error_invalid_freq; } clk_prepare_enable(drv->rx_osrclk); drv->rx_bitclk = clk_get_sys(NULL, "i2s_spkr_bit_clk"); if (IS_ERR(drv->rx_bitclk)) pr_err("%s clock Error\n", __func__); /* Master clock = Sample Rate * OSR rate bit clock * OSR Rate bit clock = bit/sample * channel master * clock / bit clock = divider value = 8 */ if (msm_codec_i2s_slave_mode) { pr_info("%s: configuring bit clock for slave mode\n", __func__); trc = clk_set_rate(drv->rx_bitclk, 0); } else trc = clk_set_rate(drv->rx_bitclk, 8); if (IS_ERR_VALUE(trc)) { pr_err("ERROR setting m clock1\n"); goto error_adie; } clk_prepare_enable(drv->rx_bitclk); if (icodec->data->voltage_on) icodec->data->voltage_on(); /* Configure ADIE */ trc = adie_codec_open(icodec->data->profile, &icodec->adie_path); if (IS_ERR_VALUE(trc)) pr_err("%s: adie codec open failed\n", __func__); else adie_codec_setpath(icodec->adie_path, icodec->sample_rate, 256); /* OSR default to 256, can be changed for power optimization * If OSR is to be changed, need clock API for setting the divider */ switch (icodec->data->channel_mode) { case 2: afe_channel_mode = MSM_AFE_STEREO; break; case 1: default: afe_channel_mode = MSM_AFE_MONO; break; } afe_config.mi2s.channel = afe_channel_mode; afe_config.mi2s.bitwidth = 16; afe_config.mi2s.line = 1; afe_config.mi2s.format = MSM_AFE_I2S_FORMAT_LPCM; if (msm_codec_i2s_slave_mode) afe_config.mi2s.ws = 0; else afe_config.mi2s.ws = 1; trc = afe_open(icodec->data->copp_id, &afe_config, icodec->sample_rate); if (trc < 0) pr_err("%s: afe open failed, trc = %d\n", __func__, trc); /* Enable ADIE */ if (icodec->adie_path) { adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_READY); adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_ANALOG_READY); } if (msm_codec_i2s_slave_mode) adie_codec_set_master_mode(icodec->adie_path, 1); else adie_codec_set_master_mode(icodec->adie_path, 0); /* Enable power amplifier */ if (icodec->data->pamp_on) { if (icodec->data->pamp_on()) { pr_err("%s: Error turning on rx power\n", __func__); goto error_pamp; } } icodec->enabled = 1; pm_qos_update_request(&drv->rx_pm_qos_req, PM_QOS_DEFAULT_VALUE); return 0; error_pamp: error_adie: clk_disable_unprepare(drv->rx_osrclk); error_invalid_freq: pr_err("%s: encounter error\n", __func__); pm_qos_update_request(&drv->rx_pm_qos_req, PM_QOS_DEFAULT_VALUE); return -ENODEV; }
static int snddev_mi2s_open(struct msm_snddev_info *dev_info) { int rc = 0; union afe_port_config afe_config; u8 channels; u8 num_of_sd_lines = 0; struct snddev_mi2s_drv_state *drv = &snddev_mi2s_drv; struct snddev_mi2s_data *snddev_mi2s_data = dev_info->private_data; if (!dev_info) { pr_err("%s: msm_snddev_info is null\n", __func__); return -EINVAL; } drv->tx_osrclk = clk_get_sys(NULL, "mi2s_osr_clk"); if (IS_ERR(drv->tx_osrclk)) pr_err("%s master clock Error\n", __func__); rc = clk_set_rate(drv->tx_osrclk, SNDDEV_MI2S_CLK_RATE(dev_info->sample_rate)); if (IS_ERR_VALUE(rc)) { pr_err("ERROR setting osr clock\n"); return -ENODEV; } clk_prepare_enable(drv->tx_osrclk); drv->tx_bitclk = clk_get_sys(NULL, "mi2s_bit_clk"); if (IS_ERR(drv->tx_bitclk)) pr_err("%s clock Error\n", __func__); rc = clk_set_rate(drv->tx_bitclk, 8); if (IS_ERR_VALUE(rc)) { pr_err("ERROR setting bit clock\n"); clk_disable_unprepare(drv->tx_osrclk); return -ENODEV; } clk_prepare_enable(drv->tx_bitclk); afe_config.mi2s.bitwidth = 16; if (snddev_mi2s_data->channel_mode == 1) channels = AFE_MI2S_MONO; else if (snddev_mi2s_data->channel_mode == 2) channels = AFE_MI2S_STEREO; else if (snddev_mi2s_data->channel_mode == 4) channels = AFE_MI2S_4CHANNELS; else if (snddev_mi2s_data->channel_mode == 6) channels = AFE_MI2S_6CHANNELS; else if (snddev_mi2s_data->channel_mode == 8) channels = AFE_MI2S_8CHANNELS; else { pr_err("ERROR: Invalid MI2S channel mode\n"); goto error_invalid_data; } num_of_sd_lines = num_of_bits_set(snddev_mi2s_data->sd_lines); switch (num_of_sd_lines) { case 1: switch (snddev_mi2s_data->sd_lines) { case MI2S_SD0: afe_config.mi2s.line = AFE_I2S_SD0; break; case MI2S_SD1: afe_config.mi2s.line = AFE_I2S_SD1; break; case MI2S_SD2: afe_config.mi2s.line = AFE_I2S_SD2; break; case MI2S_SD3: afe_config.mi2s.line = AFE_I2S_SD3; break; default: pr_err("%s: invalid SD line\n", __func__); goto error_invalid_data; } if (channels != AFE_MI2S_STEREO && channels != AFE_MI2S_MONO) { pr_err("%s: for one SD line, channel " "must be 1 or 2\n", __func__); goto error_invalid_data; } afe_config.mi2s.channel = channels; break; case 2: switch (snddev_mi2s_data->sd_lines) { case MI2S_SD0 | MI2S_SD1: afe_config.mi2s.line = AFE_I2S_QUAD01; break; case MI2S_SD2 | MI2S_SD3: afe_config.mi2s.line = AFE_I2S_QUAD23; break; default: pr_err("%s: invalid SD line\n", __func__); goto error_invalid_data; } if (channels != AFE_MI2S_4CHANNELS) { pr_err("%s: for two SD lines, channel " "must be 1 and 2 or 3 and 4\n", __func__); goto error_invalid_data; } break; case 3: switch (snddev_mi2s_data->sd_lines) { case MI2S_SD0 | MI2S_SD1 | MI2S_SD2: afe_config.mi2s.line = AFE_I2S_6CHS; break; default: pr_err("%s: invalid SD lines\n", __func__); goto error_invalid_data; } if (channels != AFE_MI2S_6CHANNELS) { pr_err("%s: for three SD lines, lines " "must be 1, 2, and 3\n", __func__); goto error_invalid_data; } break; case 4: switch (snddev_mi2s_data->sd_lines) { case MI2S_SD0 | MI2S_SD1 | MI2S_SD2 | MI2S_SD3: afe_config.mi2s.line = AFE_I2S_8CHS; break; default: pr_err("%s: invalid SD lines\n", __func__); goto error_invalid_data; } if (channels != AFE_MI2S_8CHANNELS) { pr_err("%s: for four SD lines, lines " "must be 1, 2, 3, and 4\n", __func__); goto error_invalid_data; } break; default: pr_err("%s: invalid SD lines\n", __func__); goto error_invalid_data; } afe_config.mi2s.ws = 1; afe_config.mi2s.format = MSM_AFE_I2S_FORMAT_LPCM; rc = afe_open(snddev_mi2s_data->copp_id, &afe_config, dev_info->sample_rate); if (rc < 0) { pr_err("%s: afe_open failed\n", __func__); goto error_invalid_data; } rc = mi2s_gpios_request(); if (rc < 0) { pr_err("%s: GPIO request failed\n", __func__); return rc; } pr_info("%s: afe_open done\n", __func__); return rc; error_invalid_data: clk_disable_unprepare(drv->tx_bitclk); clk_disable_unprepare(drv->tx_osrclk); return -EINVAL; }
static int msm_dai_q6_auxpcm_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); int rc = 0; struct msm_dai_auxpcm_pdata *auxpcm_pdata = (struct msm_dai_auxpcm_pdata *) dai->dev->platform_data; unsigned long pcm_clk_rate; mutex_lock(&aux_pcm_mutex); if (aux_pcm_count == 2) { dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count is 2. Just" " return.\n", __func__, dai->id); mutex_unlock(&aux_pcm_mutex); return 0; } else if (aux_pcm_count > 2) { dev_err(dai->dev, "%s(): ERROR: dai->id %d" " aux_pcm_count = %d > 2\n", __func__, dai->id, aux_pcm_count); mutex_unlock(&aux_pcm_mutex); return 0; } aux_pcm_count++; if (aux_pcm_count == 2) { dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count = %d after " " increment\n", __func__, dai->id, aux_pcm_count); mutex_unlock(&aux_pcm_mutex); return 0; } pr_debug("%s:dai->id:%d aux_pcm_count = %d. opening afe\n", __func__, dai->id, aux_pcm_count); rc = afe_q6_interface_prepare(); if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "fail to open AFE APR\n"); /* * For AUX PCM Interface the below sequence of clk * settings and afe_open is a strict requirement. * * Also using afe_open instead of afe_port_start_nowait * to make sure the port is open before deasserting the * clock line. This is required because pcm register is * not written before clock deassert. Hence the hw does * not get updated with new setting if the below clock * assert/deasset and afe_open sequence is not followed. */ clk_reset(pcm_clk, CLK_RESET_ASSERT); afe_open(PCM_RX, &dai_data->port_config, dai_data->rate); afe_open(PCM_TX, &dai_data->port_config, dai_data->rate); if (dai_data->rate == 8000) { pcm_clk_rate = auxpcm_pdata->mode_8k.pcm_clk_rate; } else if (dai_data->rate == 16000) { pcm_clk_rate = auxpcm_pdata->mode_8k.pcm_clk_rate; } else { dev_err(dai->dev, "%s: Invalid AUX PCM rate %d\n", __func__, dai_data->rate); return -EINVAL; } rc = clk_set_rate(pcm_clk, pcm_clk_rate); if (rc < 0) { pr_err("%s: clk_set_rate failed\n", __func__); return rc; } clk_prepare_enable(pcm_clk); clk_reset(pcm_clk, CLK_RESET_DEASSERT); mutex_unlock(&aux_pcm_mutex); return rc; }
static int snddev_icodec_open_tx(struct snddev_icodec_state *icodec) { int trc; int rc_clk; int afe_channel_mode; union afe_port_config afe_config; struct snddev_icodec_drv_state *drv = &snddev_icodec_drv;; wake_lock(&drv->tx_idlelock); if (drv->snddev_vreg) vreg_mode_vote(drv->snddev_vreg, 1, SNDDEV_HIGH_POWER_MODE); if (support_aic3254_use_mclk) { rc_clk = snddev_icodec_rxclk_enable(icodec, 1); if (IS_ERR_VALUE(rc_clk)) { pr_aud_err("%s Enable RX master clock Error\n", \ __func__); goto error_invalid_osrclk; } } msm_snddev_tx_mclk_request(); drv->tx_osrclk = clk_get(0, "i2s_mic_osr_clk"); if (IS_ERR(drv->tx_osrclk)) { pr_aud_err("%s master clock Error\n", __func__); goto error_invalid_osrclk; } trc = clk_set_rate(drv->tx_osrclk, SNDDEV_ICODEC_CLK_RATE(icodec->sample_rate)); if (IS_ERR_VALUE(trc)) { pr_aud_err("ERROR setting m clock1\n"); goto error_invalid_freq; } clk_enable(drv->tx_osrclk); drv->tx_bitclk = clk_get(0, "i2s_mic_bit_clk"); if (IS_ERR(drv->tx_bitclk)) { pr_aud_err("%s clock Error\n", __func__); goto error_invalid_bitclk; } /* *************************************** * 1. CPU MASTER MODE: * Master clock = Sample Rate * OSR rate bit clock * OSR Rate bit clock = bit/sample * channel master * clock / bit clock = divider value = 8 * * 2. CPU SLAVE MODE: * bitclk = 0 * *************************************** */ if (msm_codec_i2s_slave_mode) { pr_debug("%s: configuring bit clock for slave mode\n", __func__); trc = clk_set_rate(drv->tx_bitclk, 0); } else trc = clk_set_rate(drv->tx_bitclk, 8); clk_enable(drv->tx_bitclk); if (support_aic3254) { if (aic3254_ops->aic3254_set_mode) { if (msm_get_call_state() == 1) aic3254_ops->aic3254_set_mode(AIC3254_CONFIG_TX, icodec->data->aic3254_voc_id); else aic3254_ops->aic3254_set_mode(AIC3254_CONFIG_TX, icodec->data->aic3254_id); } } if (support_adie) { /* Enable ADIE */ trc = adie_codec_open(icodec->data->profile, &icodec->adie_path); if (IS_ERR_VALUE(trc)) pr_aud_err("%s: adie codec open failed\n", __func__); else adie_codec_setpath(icodec->adie_path, icodec->sample_rate, 256); } switch (icodec->data->channel_mode) { case 2: afe_channel_mode = MSM_AFE_STEREO; break; case 1: default: afe_channel_mode = MSM_AFE_MONO; break; } afe_config.mi2s.channel = afe_channel_mode; afe_config.mi2s.bitwidth = 16; afe_config.mi2s.line = 1; if (msm_codec_i2s_slave_mode) afe_config.mi2s.ws = 0; else afe_config.mi2s.ws = 1; trc = afe_open(icodec->data->copp_id, &afe_config, icodec->sample_rate); if (icodec->adie_path && support_adie) { adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_READY); adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_ANALOG_READY); if (msm_codec_i2s_slave_mode) adie_codec_set_master_mode(icodec->adie_path, 1); else adie_codec_set_master_mode(icodec->adie_path, 0); } /* Reuse pamp_on for TX platform-specific setup */ if (icodec->data->pamp_on) icodec->data->pamp_on(1); icodec->enabled = 1; wake_unlock(&drv->tx_idlelock); return 0; error_invalid_bitclk: clk_disable(drv->tx_osrclk); error_invalid_freq: error_invalid_osrclk: if (icodec->data->pamp_on) icodec->data->pamp_on(0); msm_snddev_tx_mclk_free(); pr_aud_err("%s: encounter error\n", __func__); wake_unlock(&drv->tx_idlelock); return -ENODEV; }
static int snddev_ecodec_open(struct msm_snddev_info *dev_info) { int rc; struct snddev_ecodec_drv_state *drv = &snddev_ecodec_drv; union afe_port_config afe_config; #ifdef CONFIG_PANTECH_AUDIO_PRESTO_AUDIENCE2020 // jmlee struct snddev_ecodec_state *ecodec; //int i; #endif pr_debug("%s\n", __func__); mutex_lock(&drv->dev_lock); if (dev_info->opened) { pr_err("%s: ERROR: %s already opened\n", __func__, dev_info->name); mutex_unlock(&drv->dev_lock); return -EBUSY; } if (drv->ref_cnt != 0) { pr_debug("%s: opened %s\n", __func__, dev_info->name); drv->ref_cnt++; mutex_unlock(&drv->dev_lock); return 0; } pr_info("%s: opening %s\n", __func__, dev_info->name); rc = aux_pcm_gpios_request(); if (rc < 0) { pr_err("%s: GPIO request failed\n", __func__); return rc; } clk_reset(drv->ecodec_clk, CLK_RESET_ASSERT); afe_config.pcm.mode = AFE_PCM_CFG_MODE_PCM; afe_config.pcm.sync = AFE_PCM_CFG_SYNC_INT; afe_config.pcm.frame = AFE_PCM_CFG_FRM_256BPF; afe_config.pcm.quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD; afe_config.pcm.slot = 0; afe_config.pcm.data = AFE_PCM_CFG_CDATAOE_MASTER; rc = afe_open(PCM_RX, &afe_config, ECODEC_SAMPLE_RATE); if (rc < 0) { pr_err("%s: afe open failed for PCM_RX\n", __func__); goto err_rx_afe; } rc = afe_open(PCM_TX, &afe_config, ECODEC_SAMPLE_RATE); if (rc < 0) { pr_err("%s: afe open failed for PCM_TX\n", __func__); goto err_tx_afe; } rc = clk_set_rate(drv->ecodec_clk, 2048000); if (rc < 0) { pr_err("%s: clk_set_rate failed\n", __func__); goto err_clk; } clk_enable(drv->ecodec_clk); clk_reset(drv->ecodec_clk, CLK_RESET_DEASSERT); drv->ref_cnt++; mutex_unlock(&drv->dev_lock); #ifdef CONFIG_PANTECH_AUDIO_PRESTO_AUDIENCE2020 // jmlee /* audience enable */ ecodec = dev_info->private_data; if ((ecodec->data->pamp_on) && (!ecodec_audience_enable)) { ecodec->data->pamp_on(); ecodec_audience_enable = 1; /* Enable mic bias */ //for (i = 0; i < ecodec->data->pmctl_id_sz; i++) { // pmic_hsed_enable(ecodec->data->pmctl_id[i], // PM_HSED_ENABLE_PWM_TCXO); //} } #endif return 0; err_clk: afe_close(PCM_TX); err_tx_afe: afe_close(PCM_RX); err_rx_afe: aux_pcm_gpios_free(); mutex_unlock(&drv->dev_lock); return -ENODEV; }
static int snddev_icodec_open_rx(struct snddev_icodec_state *icodec) { int trc; int rc_clk; int afe_channel_mode; union afe_port_config afe_config; struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; wake_lock(&drv->rx_idlelock); if (drv->snddev_vreg) { if (!strcmp(icodec->data->name, "headset_stereo_rx")) vreg_mode_vote(drv->snddev_vreg, 1, SNDDEV_LOW_POWER_MODE); else vreg_mode_vote(drv->snddev_vreg, 1, SNDDEV_HIGH_POWER_MODE); } if (support_aic3254_use_mclk) { rc_clk = snddev_icodec_rxclk_enable(icodec, 1); if (IS_ERR_VALUE(rc_clk)) { pr_aud_err("%s Enable RX master clock Error\n", \ __func__); goto error_invalid_freq; } } else { msm_snddev_rx_mclk_request(); drv->rx_osrclk = clk_get(0, "i2s_spkr_osr_clk"); if (IS_ERR(drv->rx_osrclk)) pr_aud_err("%s master clock Error\n", __func__); trc = clk_set_rate(drv->rx_osrclk, SNDDEV_ICODEC_CLK_RATE(icodec->sample_rate)); if (IS_ERR_VALUE(trc)) { pr_aud_err("ERROR setting m clock1\n"); goto error_invalid_freq; } clk_enable(drv->rx_osrclk); } drv->rx_bitclk = clk_get(0, "i2s_spkr_bit_clk"); if (IS_ERR(drv->rx_bitclk)) pr_aud_err("%s clock Error\n", __func__); /* *************************************** * 1. CPU MASTER MODE: * Master clock = Sample Rate * OSR rate bit clock * OSR Rate bit clock = bit/sample * channel master * clock / bit clock = divider value = 8 * * 2. CPU SLAVE MODE: * bitclk = 0 * *************************************** */ if (msm_codec_i2s_slave_mode) { pr_debug("%s: configuring bit clock for slave mode\n", __func__); trc = clk_set_rate(drv->rx_bitclk, 0); } else trc = clk_set_rate(drv->rx_bitclk, 8); if (IS_ERR_VALUE(trc)) { pr_aud_err("ERROR setting m clock1\n"); goto error_adie; } clk_enable(drv->rx_bitclk); if (icodec->data->voltage_on) icodec->data->voltage_on(1); if (support_aic3254) { if (aic3254_ops->aic3254_set_mode) { if (msm_get_call_state() == 1) aic3254_ops->aic3254_set_mode(AIC3254_CONFIG_RX, icodec->data->aic3254_voc_id); else aic3254_ops->aic3254_set_mode(AIC3254_CONFIG_RX, icodec->data->aic3254_id); } } if (support_adie) { /* Configure ADIE */ trc = adie_codec_open(icodec->data->profile, &icodec->adie_path); if (IS_ERR_VALUE(trc)) pr_aud_err("%s: adie codec open failed\n", __func__); else adie_codec_setpath(icodec->adie_path, icodec->sample_rate, 256); /* OSR default to 256, can be changed for power optimization * If OSR is to be changed, need clock API for setting the divider */ } switch (icodec->data->channel_mode) { case 2: afe_channel_mode = MSM_AFE_STEREO; break; case 1: default: afe_channel_mode = MSM_AFE_MONO; break; } afe_config.mi2s.channel = afe_channel_mode; afe_config.mi2s.bitwidth = 16; afe_config.mi2s.line = 1; if (msm_codec_i2s_slave_mode) afe_config.mi2s.ws = 0; else afe_config.mi2s.ws = 1; trc = afe_open(icodec->data->copp_id, &afe_config, icodec->sample_rate); if (trc < 0) pr_aud_err("%s: afe open failed, trc = %d\n", __func__, trc); if (support_adie) { /* Enable ADIE */ if (icodec->adie_path) { adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_READY); adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_ANALOG_READY); } if (msm_codec_i2s_slave_mode) adie_codec_set_master_mode(icodec->adie_path, 1); else adie_codec_set_master_mode(icodec->adie_path, 0); } /* Enable power amplifier */ if (icodec->data->pamp_on) icodec->data->pamp_on(1); icodec->enabled = 1; wake_unlock(&drv->rx_idlelock); return 0; error_adie: clk_disable(drv->rx_bitclk); clk_disable(drv->rx_osrclk); error_invalid_freq: pr_aud_err("%s: encounter error\n", __func__); msm_snddev_rx_mclk_free(); wake_unlock(&drv->rx_idlelock); return -ENODEV; }