void holiday_imic_pamp_on_with_audience(int en) { int ret, call_state=0; pr_aud_info("%s %d\n", __func__, en); call_state = msm_get_call_state(); if (en) { ret = pm8058_micbias_enable(OTHC_MICBIAS_0, OTHC_SIGNAL_ALWAYS_ON); if (ret) pr_aud_err("%s: Enabling int mic power failed\n", __func__); /* select internal mic path */ if (call_state) { gpio_set_value(PM8058_GPIO_PM_TO_SYS(HOLIDAY_AUD_MIC_SEL2), 0); ret = pm8058_micbias_enable(OTHC_MICBIAS_1, OTHC_SIGNAL_ALWAYS_ON); if (ret) pr_aud_err("%s: Enabling back mic power failed\n", __func__); } else { if (!force_a1026_on) gpio_set_value(PM8058_GPIO_PM_TO_SYS(HOLIDAY_AUD_MIC_SEL2), 1); } } else { ret = pm8058_micbias_enable(OTHC_MICBIAS_0, OTHC_SIGNAL_OFF); if (ret) pr_aud_err("%s: Enabling int mic power failed\n", __func__); if (call_state) { ret = pm8058_micbias_enable(OTHC_MICBIAS_1, OTHC_SIGNAL_OFF); if (ret) pr_aud_err("%s: Enabling back mic power failed\n", __func__); } } }
void holiday_snddev_emic_pamp_on(int en) { int call_state = 0; pr_aud_info("%s (support_audience, en)=(%d, %d)\n", __func__, support_audience, en); call_state = msm_get_call_state(); /* external micbias should be controlled by headset driver with HOLIDAY_mic_enable turn on with headset plugged in and turn off when headset unplugged. */ if (en) { /* select internal mic path */ gpio_set_value(PM8058_GPIO_PM_TO_SYS(HOLIDAY_AUD_MIC_SEL1), 1); if (support_audience) { if (call_state) gpio_set_value(PM8058_GPIO_PM_TO_SYS(HOLIDAY_AUD_MIC_SEL2), 0); else gpio_set_value(PM8058_GPIO_PM_TO_SYS(HOLIDAY_AUD_MIC_SEL2), 1); } } }
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_icodec_open_tx(struct snddev_icodec_state *icodec) { int trc; struct msm_afe_config afe_config; struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; printk("%s(): +++\n", __func__); wake_lock(&drv->tx_idlelock); /* Reuse pamp_on for TX platform-specific setup */ if (icodec->data->pamp_on) icodec->data->pamp_on(1); //HTC_AUD_START #ifndef CONFIG_CODEC_AIC3008 //HTC_AUD_END /* enable MI2S TX master block */ /* enable MI2S TX bit clock */ trc = clk_set_rate(drv->tx_mclk, SNDDEV_ICODEC_CLK_RATE(icodec->sample_rate)); if (IS_ERR_VALUE(trc)) goto error_invalid_freq; clk_enable(drv->tx_mclk); clk_enable(drv->tx_sclk); //HTC_AUD_START #endif //HTC_AUD_END /* Set MI2S */ mi2s_set_codec_input_path((icodec->data->channel_mode == REAL_STEREO_CHANNEL_MODE ? MI2S_CHAN_STEREO : (icodec->data->channel_mode == 2 ? MI2S_CHAN_STEREO : MI2S_CHAN_MONO_RAW)), WT_16_BIT); /* Enable External Codec A3254 */ 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) { /* Configure ADIE */ trc = adie_codec_open(icodec->data->profile, &icodec->adie_path); if (IS_ERR_VALUE(trc)) goto error_adie; /* Enable ADIE */ adie_codec_setpath(icodec->adie_path, icodec->sample_rate, 256); if (adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_READY)) { /* icodec->adie_path->profile = NULL; */ goto error_adie; } if (adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_ANALOG_READY)) { /* icodec->adie_path->profile = NULL; */ goto error_adie; } } /* Start AFE */ afe_config.sample_rate = icodec->sample_rate / 1000; afe_config.channel_mode = icodec->data->channel_mode; afe_config.volume = AFE_VOLUME_UNITY; trc = afe_enable(AFE_HW_PATH_CODEC_TX, &afe_config); if (IS_ERR_VALUE(trc)) goto error_afe; icodec->enabled = 1; wake_unlock(&drv->tx_idlelock); printk("%s(): ---\n", __func__); return 0; error_afe: if (support_adie) { adie_codec_close(icodec->adie_path); icodec->adie_path = NULL; } error_adie: //HTC_CSP_START #ifndef CONFIG_CODEC_AIC3008 clk_disable(drv->tx_sclk); clk_disable(drv->tx_mclk); #endif //HTC_CSP_END //HTC_AUD_START #ifndef CONFIG_CODEC_AIC3008 //HTC_AUD_END error_invalid_freq: if (icodec->data->pamp_on) icodec->data->pamp_on(0); MM_AUD_ERR("%s: encounter error\n", __func__); wake_unlock(&drv->tx_idlelock); printk("%s(): ---\n", __func__); //HTC_AUD_START #endif //HTC_AUD_END return -ENODEV; }
static int snddev_icodec_open_rx(struct snddev_icodec_state *icodec) { int trc; struct msm_afe_config afe_config; struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; struct lpa_codec_config lpa_config; printk("%s(): +++\n", __func__); wake_lock(&drv->rx_idlelock); //HTC_AUD_START #ifndef CONFIG_CODEC_AIC3008 //HTC_AUD_END /* enable MI2S RX master block */ /* enable MI2S RX bit clock */ trc = clk_set_rate(drv->rx_mclk, SNDDEV_ICODEC_CLK_RATE(icodec->sample_rate)); if (IS_ERR_VALUE(trc)) goto error_invalid_freq; clk_enable(drv->rx_mclk); clk_enable(drv->rx_sclk); //HTC_AUD_START #endif //HTC_AUD_END /* clk_set_rate(drv->lpa_codec_clk, 1); */ /* Remove if use pcom */ clk_enable(drv->lpa_p_clk); clk_enable(drv->lpa_codec_clk); clk_enable(drv->lpa_core_clk); /* Enable LPA sub system */ drv->lpa = lpa_get(); if (!drv->lpa) goto error_lpa; lpa_config.sample_rate = icodec->sample_rate; lpa_config.sample_width = 16; lpa_config.output_interface = LPA_OUTPUT_INTF_WB_CODEC; lpa_config.num_channels = icodec->data->channel_mode; lpa_cmd_codec_config(drv->lpa, &lpa_config); /* Set audio interconnect reg to LPA */ audio_interct_codec(AUDIO_INTERCT_LPA); /* Enable qtr headset amplifier */ if (icodec->data->pre_pamp_on) icodec->data->pre_pamp_on(1); /* Set MI2S */ mi2s_set_codec_output_path((icodec->data->channel_mode == 2 ? MI2S_CHAN_STEREO : MI2S_CHAN_MONO_PACKED), WT_16_BIT); if (!support_aic3254) { if (support_adie) { /* Configure ADIE */ trc = adie_codec_open(icodec->data->profile, &icodec->adie_path); if (IS_ERR_VALUE(trc)) goto error_adie; /* OSR default to 256, can be changed for power optimization If OSR is to be changed, need clock API for setting the divider */ adie_codec_setpath(icodec->adie_path, icodec->sample_rate, 256); } } else { 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); } } /* Start AFE */ afe_config.sample_rate = icodec->sample_rate / 1000; afe_config.channel_mode = icodec->data->channel_mode; afe_config.volume = AFE_VOLUME_UNITY; trc = afe_enable(AFE_HW_PATH_CODEC_RX, &afe_config); if (IS_ERR_VALUE(trc)) goto error_afe; lpa_cmd_enable_codec(drv->lpa, 1); if (!support_aic3254) { if (support_adie) { /* Enable ADIE */ if (adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_READY)) { /* icodec->adie_path->profile = NULL; */ goto error_adie; } if (adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_ANALOG_READY)) { /* icodec->adie_path->profile = NULL; */ goto error_adie; } } } /* Enable power amplifier */ if (icodec->data->pamp_on) icodec->data->pamp_on(1); icodec->enabled = 1; wake_unlock(&drv->rx_idlelock); printk("%s(): ---\n", __func__); return 0; error_afe: if (!support_aic3254) { if (support_adie) { adie_codec_close(icodec->adie_path); icodec->adie_path = NULL; } } error_adie: lpa_put(drv->lpa); error_lpa: clk_disable(drv->lpa_p_clk); clk_disable(drv->lpa_codec_clk); clk_disable(drv->lpa_core_clk); //HTC_CSP_START #ifndef CONFIG_CODEC_AIC3008 clk_disable(drv->rx_sclk); clk_disable(drv->rx_mclk); #endif //HTC_CSP_END //HTC_AUD_START #ifndef CONFIG_CODEC_AIC3008 //HTC_AUD_END error_invalid_freq: MM_AUD_ERR("%s: encounter error\n", __func__); wake_unlock(&drv->rx_idlelock); printk("%s(): ---\n", __func__); //HTC_AUD_START #endif //HTC_AUD_END return -ENODEV; }
static int msm_device_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int rc = 0; int set = 0; struct msm_audio_route_config route_cfg; struct msm_snddev_info *dev_info; struct msm_snddev_info *dst_dev_info; struct msm_snddev_info *src_dev_info; int tx_freq = 0; int rx_freq = 0; u32 set_freq = 0; set = ucontrol->value.integer.value[0]; route_cfg.dev_id = ucontrol->id.numid - device_index; dev_info = audio_dev_ctrl_find_dev(route_cfg.dev_id); if (IS_ERR(dev_info)) { MM_AUD_ERR("pass invalid dev_id\n"); rc = PTR_ERR(dev_info); return rc; } MM_INFO("device %s set %d\n", dev_info->name, set); pr_aud_info("[ALSA] msm_en_device (dev %s, id %d, enable %d, opened %d)\n", dev_info->name, route_cfg.dev_id, set, dev_info->opened); if (set) { if (!dev_info->opened) { set_freq = dev_info->sample_rate; if (!msm_device_is_voice(route_cfg.dev_id) && msm_get_call_state()) { msm_get_voc_freq(&tx_freq, &rx_freq); if (dev_info->capability & SNDDEV_CAP_TX) set_freq = tx_freq; if (dev_info->capability & SNDDEV_CAP_RX) set_freq = rx_freq; if (set_freq == 0) set_freq = dev_info->sample_rate; } else set_freq = dev_info->sample_rate; MM_AUD_INFO("device freq =%d\n", set_freq); rc = dev_info->dev_ops.set_freq(dev_info, set_freq); if (rc < 0) { MM_AUD_ERR("device freq failed!\n"); return rc; } dev_info->set_sample_rate = rc; rc = 0; rc = dev_info->dev_ops.open(dev_info); if (rc < 0) { MM_AUD_ERR("Enabling %s failed", dev_info->name); return rc; } dev_info->opened = 1; broadcast_event(AUDDEV_EVT_DEV_RDY, route_cfg.dev_id, SESSION_IGNORE); if ((route_cfg.dev_id == src_dev) || (route_cfg.dev_id == dst_dev)) { dst_dev_info = audio_dev_ctrl_find_dev( dst_dev); if (IS_ERR(dst_dev_info)) { pr_err("dst_dev:%s:pass invalid" "dev_id\n", __func__); rc = PTR_ERR(dst_dev_info); return rc; } src_dev_info = audio_dev_ctrl_find_dev( src_dev); if (IS_ERR(src_dev_info)) { pr_err("src_dev:%s:pass invalid" "dev_id\n", __func__); rc = PTR_ERR(src_dev_info); return rc; } if ((dst_dev_info->opened) && (src_dev_info->opened)) { pr_debug("%d: Enable afe_loopback\n", __LINE__); afe_loopback(LOOPBACK_ENABLE, dst_dev_info->copp_id, src_dev_info->copp_id); loopback_status = 1; } } } } else { if (dev_info->opened) { broadcast_event(AUDDEV_EVT_REL_PENDING, route_cfg.dev_id, SESSION_IGNORE); rc = dev_info->dev_ops.close(dev_info); if (rc < 0) { MM_AUD_ERR("Snd device failed close!\n"); return rc; } else { dev_info->opened = 0; broadcast_event(AUDDEV_EVT_DEV_RLS, route_cfg.dev_id, SESSION_IGNORE); } if (loopback_status == 1) { if ((route_cfg.dev_id == src_dev) || (route_cfg.dev_id == dst_dev)) { dst_dev_info = audio_dev_ctrl_find_dev( dst_dev); if (IS_ERR(dst_dev_info)) { pr_err("dst_dev:%s:pass invalid" "dev_id\n", __func__); rc = PTR_ERR(dst_dev_info); return rc; } src_dev_info = audio_dev_ctrl_find_dev( src_dev); if (IS_ERR(src_dev_info)) { pr_err("src_dev:%s:pass invalid" "dev_id\n", __func__); rc = PTR_ERR(src_dev_info); return rc; } pr_debug("%d: Disable afe_loopback\n", __LINE__); afe_loopback(LOOPBACK_DISABLE, dst_dev_info->copp_id, src_dev_info->copp_id); loopback_status = 0; } } } } return rc; }
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; }