static int msm_dai_stub_add_route(struct snd_soc_dai *dai) { struct snd_soc_dapm_route intercon; struct snd_soc_dapm_context *dapm; if (!dai || !dai->driver) { pr_err("%s Invalid params\n", __func__); return -EINVAL; } dapm = snd_soc_component_get_dapm(dai->component); memset(&intercon, 0 , sizeof(intercon)); if (dai->driver->playback.stream_name && dai->driver->playback.aif_name) { dev_dbg(dai->dev, "%s add route for widget %s", __func__, dai->driver->playback.stream_name); intercon.source = dai->driver->playback.aif_name; intercon.sink = dai->driver->playback.stream_name; dev_dbg(dai->dev, "%s src %s sink %s\n", __func__, intercon.source, intercon.sink); snd_soc_dapm_add_routes(dapm, &intercon, 1); } if (dai->driver->capture.stream_name && dai->driver->capture.aif_name) { dev_dbg(dai->dev, "%s add route for widget %s", __func__, dai->driver->capture.stream_name); intercon.sink = dai->driver->capture.aif_name; intercon.source = dai->driver->capture.stream_name; dev_dbg(dai->dev, "%s src %s sink %s\n", __func__, intercon.source, intercon.sink); snd_soc_dapm_add_routes(dapm, &intercon, 1); } return 0; }
int adau17x1_add_widgets(struct snd_soc_component *component) { struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); struct adau *adau = snd_soc_component_get_drvdata(component); int ret; ret = snd_soc_add_component_controls(component, adau17x1_controls, ARRAY_SIZE(adau17x1_controls)); if (ret) return ret; ret = snd_soc_dapm_new_controls(dapm, adau17x1_dapm_widgets, ARRAY_SIZE(adau17x1_dapm_widgets)); if (ret) return ret; if (adau17x1_has_dsp(adau)) { ret = snd_soc_dapm_new_controls(dapm, adau17x1_dsp_dapm_widgets, ARRAY_SIZE(adau17x1_dsp_dapm_widgets)); if (ret) return ret; if (!adau->sigmadsp) return 0; ret = sigmadsp_attach(adau->sigmadsp, component); if (ret) { dev_err(component->dev, "Failed to attach firmware: %d\n", ret); return ret; } } return 0; }
static int sun8i_codec_add_mic2(struct snd_soc_component *cmpnt) { struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cmpnt); struct device *dev = cmpnt->dev; int ret; ret = snd_soc_add_component_controls(cmpnt, sun8i_codec_mic2_controls, ARRAY_SIZE(sun8i_codec_mic2_controls)); if (ret) { dev_err(dev, "Failed to add MIC2 controls: %d\n", ret); return ret; } ret = snd_soc_dapm_new_controls(dapm, sun8i_codec_mic2_widgets, ARRAY_SIZE(sun8i_codec_mic2_widgets)); if (ret) { dev_err(dev, "Failed to add MIC2 DAPM widgets: %d\n", ret); return ret; } ret = snd_soc_dapm_add_routes(dapm, sun8i_codec_mic2_routes, ARRAY_SIZE(sun8i_codec_mic2_routes)); if (ret) { dev_err(dev, "Failed to add MIC2 DAPM routes: %d\n", ret); return ret; } return 0; }
static int txsrc_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int val = ucontrol->value.enumerated.item[0] << e->shift_l; unsigned int mask = 1 << e->shift_l; unsigned int txpwr; if (val != 0 && val != mask) return -EINVAL; snd_soc_dapm_mutex_lock(dapm); if (snd_soc_component_test_bits(component, e->reg, mask, val)) { /* save the current power state of the transmitter */ txpwr = snd_soc_component_read32(component, WM8804_PWRDN) & 0x4; /* power down the transmitter */ snd_soc_component_update_bits(component, WM8804_PWRDN, 0x4, 0x4); /* set the tx source */ snd_soc_component_update_bits(component, e->reg, mask, val); /* restore the transmitter's configuration */ snd_soc_component_update_bits(component, WM8804_PWRDN, 0x4, txpwr); } snd_soc_dapm_mutex_unlock(dapm); return 0; }
static int sun8i_codec_add_hmic(struct snd_soc_component *cmpnt) { struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cmpnt); struct device *dev = cmpnt->dev; int ret; ret = snd_soc_dapm_new_controls(dapm, sun8i_codec_hmic_widgets, ARRAY_SIZE(sun8i_codec_hmic_widgets)); if (ret) dev_err(dev, "Failed to add Mic3 DAPM widgets: %d\n", ret); return ret; }
static int adau17x1_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir) { struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(dai->component); struct adau *adau = snd_soc_component_get_drvdata(dai->component); bool is_pll; bool was_pll; switch (clk_id) { case ADAU17X1_CLK_SRC_MCLK: is_pll = false; break; case ADAU17X1_CLK_SRC_PLL_AUTO: if (!adau->mclk) return -EINVAL; /* Fall-through */ case ADAU17X1_CLK_SRC_PLL: is_pll = true; break; default: return -EINVAL; } switch (adau->clk_src) { case ADAU17X1_CLK_SRC_MCLK: was_pll = false; break; case ADAU17X1_CLK_SRC_PLL: case ADAU17X1_CLK_SRC_PLL_AUTO: was_pll = true; break; default: return -EINVAL; } adau->sysclk = freq; if (is_pll != was_pll) { if (is_pll) { snd_soc_dapm_add_routes(dapm, &adau17x1_dapm_pll_route, 1); } else { snd_soc_dapm_del_routes(dapm, &adau17x1_dapm_pll_route, 1); } } adau->clk_src = clk_id; return 0; }
static int cs35l33_set_hg_data(struct snd_soc_component *component, struct cs35l33_pdata *pdata) { struct cs35l33_hg *hg_config = &pdata->hg_config; struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); struct cs35l33_private *priv = snd_soc_component_get_drvdata(component); if (hg_config->enable_hg_algo) { regmap_update_bits(priv->regmap, CS35L33_HG_MEMLDO_CTL, CS35L33_MEM_DEPTH_MASK, hg_config->mem_depth << CS35L33_MEM_DEPTH_SHIFT); regmap_write(priv->regmap, CS35L33_HG_REL_RATE, hg_config->release_rate); regmap_update_bits(priv->regmap, CS35L33_HG_HEAD, CS35L33_HD_RM_MASK, hg_config->hd_rm << CS35L33_HD_RM_SHIFT); regmap_update_bits(priv->regmap, CS35L33_HG_MEMLDO_CTL, CS35L33_LDO_THLD_MASK, hg_config->ldo_thld << CS35L33_LDO_THLD_SHIFT); regmap_update_bits(priv->regmap, CS35L33_HG_MEMLDO_CTL, CS35L33_LDO_DISABLE_MASK, hg_config->ldo_path_disable << CS35L33_LDO_DISABLE_SHIFT); regmap_update_bits(priv->regmap, CS35L33_LDO_DEL, CS35L33_LDO_ENTRY_DELAY_MASK, hg_config->ldo_entry_delay << CS35L33_LDO_ENTRY_DELAY_SHIFT); if (hg_config->vp_hg_auto) { regmap_update_bits(priv->regmap, CS35L33_HG_EN, CS35L33_VP_HG_AUTO_MASK, CS35L33_VP_HG_AUTO_MASK); snd_soc_dapm_add_routes(dapm, cs35l33_vphg_auto_route, ARRAY_SIZE(cs35l33_vphg_auto_route)); } regmap_update_bits(priv->regmap, CS35L33_HG_EN, CS35L33_VP_HG_MASK, hg_config->vp_hg << CS35L33_VP_HG_SHIFT); regmap_update_bits(priv->regmap, CS35L33_LDO_DEL, CS35L33_VP_HG_RATE_MASK, hg_config->vp_hg_rate << CS35L33_VP_HG_RATE_SHIFT); regmap_update_bits(priv->regmap, CS35L33_LDO_DEL, CS35L33_VP_HG_VA_MASK, hg_config->vp_hg_va << CS35L33_VP_HG_VA_SHIFT); regmap_update_bits(priv->regmap, CS35L33_HG_EN, CS35L33_CLASS_HG_EN_MASK, CS35L33_CLASS_HG_EN_MASK); } return 0; }
int adau17x1_setup_firmware(struct snd_soc_component *component, unsigned int rate) { int ret; int dspsr, dsp_run; struct adau *adau = snd_soc_component_get_drvdata(component); struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); /* Check if sample rate is the same as before. If it is there is no * point in performing the below steps as the call to * sigmadsp_setup(...) will return directly when it finds the sample * rate to be the same as before. By checking this we can prevent an * audiable popping noise which occours when toggling DSP_RUN. */ if (adau->sigmadsp->current_samplerate == rate) return 0; snd_soc_dapm_mutex_lock(dapm); ret = regmap_read(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, &dspsr); if (ret) goto err; ret = regmap_read(adau->regmap, ADAU17X1_DSP_RUN, &dsp_run); if (ret) goto err; regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 1); regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, 0xf); regmap_write(adau->regmap, ADAU17X1_DSP_RUN, 0); ret = sigmadsp_setup(adau->sigmadsp, rate); if (ret) { regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 0); goto err; } regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, dspsr); regmap_write(adau->regmap, ADAU17X1_DSP_RUN, dsp_run); err: snd_soc_dapm_mutex_unlock(dapm); return ret; }
/* * The MUX register for the Capture and Playback MUXs selects either DSP as * source/destination or one of the TDM slots. The TDM slot is selected via * snd_soc_dai_set_tdm_slot(), so we only expose whether to go to the DSP or * directly to the DAI interface with this control. */ static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol); struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); struct adau *adau = snd_soc_component_get_drvdata(component); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct snd_soc_dapm_update update = {}; unsigned int stream = e->shift_l; unsigned int val, change; int reg; if (ucontrol->value.enumerated.item[0] >= e->items) return -EINVAL; switch (ucontrol->value.enumerated.item[0]) { case 0: val = 0; adau->dsp_bypass[stream] = false; break; default: val = (adau->tdm_slot[stream] * 2) + 1; adau->dsp_bypass[stream] = true; break; } if (stream == SNDRV_PCM_STREAM_PLAYBACK) reg = ADAU17X1_SERIAL_INPUT_ROUTE; else reg = ADAU17X1_SERIAL_OUTPUT_ROUTE; change = snd_soc_component_test_bits(component, reg, 0xff, val); if (change) { update.kcontrol = kcontrol; update.mask = 0xff; update.reg = reg; update.val = val; snd_soc_dapm_mux_update_power(dapm, kcontrol, ucontrol->value.enumerated.item[0], e, &update); } return change; }
int snd_soc_component_disable_pin(struct snd_soc_component *component, const char *pin) { struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); char *full_name; int ret; if (!component->name_prefix) return snd_soc_dapm_disable_pin(dapm, pin); full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); if (!full_name) return -ENOMEM; ret = snd_soc_dapm_disable_pin(dapm, full_name); kfree(full_name); return ret; }
int adau17x1_add_routes(struct snd_soc_component *component) { struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); struct adau *adau = snd_soc_component_get_drvdata(component); int ret; ret = snd_soc_dapm_add_routes(dapm, adau17x1_dapm_routes, ARRAY_SIZE(adau17x1_dapm_routes)); if (ret) return ret; if (adau17x1_has_dsp(adau)) { ret = snd_soc_dapm_add_routes(dapm, adau17x1_dsp_dapm_routes, ARRAY_SIZE(adau17x1_dsp_dapm_routes)); } else { ret = snd_soc_dapm_add_routes(dapm, adau17x1_no_dsp_dapm_routes, ARRAY_SIZE(adau17x1_no_dsp_dapm_routes)); } if (adau->clk_src != ADAU17X1_CLK_SRC_MCLK) snd_soc_dapm_add_routes(dapm, &adau17x1_dapm_pll_route, 1); return ret; }
static int cs35l33_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) { struct snd_soc_component *component = dai->component; struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); struct cs35l33_private *priv = snd_soc_component_get_drvdata(component); unsigned int reg, bit_pos, i; int slot, slot_num; if (slot_width != 8) return -EINVAL; /* scan rx_mask for aud slot */ slot = ffs(rx_mask) - 1; if (slot >= 0) { regmap_update_bits(priv->regmap, CS35L33_RX_AUD, CS35L33_X_LOC, slot); dev_dbg(component->dev, "Audio starts from slots %d", slot); } /* * scan tx_mask: vmon(2 slots); imon (2 slots); * vpmon (1 slot) vbstmon (1 slot) */ slot = ffs(tx_mask) - 1; slot_num = 0; for (i = 0; i < 2 ; i++) { /* disable vpmon/vbstmon: enable later if set in tx_mask */ regmap_update_bits(priv->regmap, CS35L33_TX_VPMON + i, CS35L33_X_STATE | CS35L33_X_LOC, CS35L33_X_STATE | CS35L33_X_LOC); } /* disconnect {vp,vbst}_mon routes: eanble later if set in tx_mask*/ snd_soc_dapm_del_routes(dapm, cs35l33_vp_vbst_mon_route, ARRAY_SIZE(cs35l33_vp_vbst_mon_route)); while (slot >= 0) { /* configure VMON_TX_LOC */ if (slot_num == 0) { regmap_update_bits(priv->regmap, CS35L33_TX_VMON, CS35L33_X_STATE | CS35L33_X_LOC, slot); dev_dbg(component->dev, "VMON enabled in slots %d-%d", slot, slot + 1); } /* configure IMON_TX_LOC */ if (slot_num == 3) { regmap_update_bits(priv->regmap, CS35L33_TX_IMON, CS35L33_X_STATE | CS35L33_X_LOC, slot); dev_dbg(component->dev, "IMON enabled in slots %d-%d", slot, slot + 1); } /* configure VPMON_TX_LOC */ if (slot_num == 4) { regmap_update_bits(priv->regmap, CS35L33_TX_VPMON, CS35L33_X_STATE | CS35L33_X_LOC, slot); snd_soc_dapm_add_routes(dapm, &cs35l33_vp_vbst_mon_route[0], 2); dev_dbg(component->dev, "VPMON enabled in slots %d", slot); } /* configure VBSTMON_TX_LOC */ if (slot_num == 5) { regmap_update_bits(priv->regmap, CS35L33_TX_VBSTMON, CS35L33_X_STATE | CS35L33_X_LOC, slot); snd_soc_dapm_add_routes(dapm, &cs35l33_vp_vbst_mon_route[2], 2); dev_dbg(component->dev, "VBSTMON enabled in slots %d", slot); } /* Enable the relevant tx slot */ reg = CS35L33_TX_EN4 - (slot/8); bit_pos = slot - ((slot / 8) * (8)); regmap_update_bits(priv->regmap, reg, 1 << bit_pos, 1 << bit_pos); tx_mask &= ~(1 << slot); slot = ffs(tx_mask) - 1; slot_num++; } return 0; }
static int uda134x_soc_probe(struct snd_soc_component *component) { struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); struct uda134x_priv *uda134x = snd_soc_component_get_drvdata(component); struct uda134x_platform_data *pd = uda134x->pd; const struct snd_soc_dapm_widget *widgets; unsigned num_widgets; int ret; printk(KERN_INFO "UDA134X SoC Audio Codec\n"); switch (pd->model) { case UDA134X_UDA1340: case UDA134X_UDA1341: case UDA134X_UDA1344: case UDA134X_UDA1345: break; default: printk(KERN_ERR "UDA134X SoC codec: " "unsupported model %d\n", pd->model); return -EINVAL; } if (pd->power) pd->power(1); uda134x_reset(component); if (pd->model == UDA134X_UDA1341) { widgets = uda1341_dapm_widgets; num_widgets = ARRAY_SIZE(uda1341_dapm_widgets); } else { widgets = uda1340_dapm_widgets; num_widgets = ARRAY_SIZE(uda1340_dapm_widgets); } ret = snd_soc_dapm_new_controls(dapm, widgets, num_widgets); if (ret) { printk(KERN_ERR "%s failed to register dapm controls: %d", __func__, ret); return ret; } switch (pd->model) { case UDA134X_UDA1340: case UDA134X_UDA1344: ret = snd_soc_add_component_controls(component, uda1340_snd_controls, ARRAY_SIZE(uda1340_snd_controls)); break; case UDA134X_UDA1341: ret = snd_soc_add_component_controls(component, uda1341_snd_controls, ARRAY_SIZE(uda1341_snd_controls)); break; case UDA134X_UDA1345: ret = snd_soc_add_component_controls(component, uda1345_snd_controls, ARRAY_SIZE(uda1345_snd_controls)); break; default: printk(KERN_ERR "%s unknown codec type: %d", __func__, pd->model); return -EINVAL; } if (ret < 0) { printk(KERN_ERR "UDA134X: failed to register controls\n"); return ret; } return 0; }