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_codec_get_dapm(dai->codec); struct adau *adau = snd_soc_codec_get_drvdata(dai->codec); switch (clk_id) { case ADAU17X1_CLK_SRC_MCLK: case ADAU17X1_CLK_SRC_PLL: break; default: return -EINVAL; } adau->sysclk = freq; if (adau->clk_src != clk_id) { if (clk_id == ADAU17X1_CLK_SRC_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 arizona_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir) { struct snd_soc_codec *codec = dai->codec; struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1]; struct snd_soc_dapm_route routes[2]; switch (clk_id) { case ARIZONA_CLK_SYSCLK: case ARIZONA_CLK_ASYNCCLK: break; default: return -EINVAL; } if (clk_id == dai_priv->clk) return 0; if (dai->active) { dev_err(codec->dev, "Can't change clock on active DAI %d\n", dai->id); return -EBUSY; } memset(&routes, 0, sizeof(routes)); routes[0].sink = dai->driver->capture.stream_name; routes[1].sink = dai->driver->playback.stream_name; switch (clk_id) { case ARIZONA_CLK_SYSCLK: routes[0].source = arizona_dai_clk_str(dai_priv->clk); routes[1].source = arizona_dai_clk_str(dai_priv->clk); snd_soc_dapm_del_routes(&codec->dapm, routes, ARRAY_SIZE(routes)); break; default: break; } switch (clk_id) { case ARIZONA_CLK_ASYNCCLK: routes[0].source = arizona_dai_clk_str(clk_id); routes[1].source = arizona_dai_clk_str(clk_id); snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes)); break; default: break; } dai_priv->clk = clk_id; return snd_soc_dapm_sync(&codec->dapm); }
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_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; }