diff options
Diffstat (limited to 'sound/soc/codecs/da7219.c')
-rw-r--r-- | sound/soc/codecs/da7219.c | 85 |
1 files changed, 70 insertions, 15 deletions
diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c index e46e9f4bc994..b1df4bb36105 100644 --- a/sound/soc/codecs/da7219.c +++ b/sound/soc/codecs/da7219.c @@ -423,7 +423,7 @@ static int da7219_tonegen_freq_get(struct snd_kcontrol *kcontrol, struct soc_mixer_control *mixer_ctrl = (struct soc_mixer_control *) kcontrol->private_value; unsigned int reg = mixer_ctrl->reg; - u16 val; + __le16 val; int ret; mutex_lock(&da7219->ctrl_lock); @@ -450,7 +450,7 @@ static int da7219_tonegen_freq_put(struct snd_kcontrol *kcontrol, struct soc_mixer_control *mixer_ctrl = (struct soc_mixer_control *) kcontrol->private_value; unsigned int reg = mixer_ctrl->reg; - u16 val; + __le16 val; int ret; /* @@ -838,7 +838,7 @@ static int da7219_dai_event(struct snd_soc_dapm_widget *w, ++i; msleep(50); } - } while ((i < DA7219_SRM_CHECK_RETRIES) & (!srm_lock)); + } while ((i < DA7219_SRM_CHECK_RETRIES) && (!srm_lock)); if (!srm_lock) dev_warn(component->dev, "SRM failed to lock\n"); @@ -1396,7 +1396,7 @@ static int da7219_set_dai_tdm_slot(struct snd_soc_dai *dai, struct snd_soc_component *component = dai->component; struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); u8 dai_bclks_per_wclk; - u16 offset; + __le16 offset; u32 frame_size; /* No channels enabled so disable TDM, revert to 64-bit frames */ @@ -1767,7 +1767,7 @@ static int da7219_dai_clks_prepare(struct clk_hw *hw) { struct da7219_priv *da7219 = container_of(hw, struct da7219_priv, dai_clks_hw); - struct snd_soc_component *component = da7219->aad->component; + struct snd_soc_component *component = da7219->component; snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE, DA7219_DAI_CLK_EN_MASK, @@ -1780,7 +1780,7 @@ static void da7219_dai_clks_unprepare(struct clk_hw *hw) { struct da7219_priv *da7219 = container_of(hw, struct da7219_priv, dai_clks_hw); - struct snd_soc_component *component = da7219->aad->component; + struct snd_soc_component *component = da7219->component; snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE, DA7219_DAI_CLK_EN_MASK, 0); @@ -1790,7 +1790,7 @@ static int da7219_dai_clks_is_prepared(struct clk_hw *hw) { struct da7219_priv *da7219 = container_of(hw, struct da7219_priv, dai_clks_hw); - struct snd_soc_component *component = da7219->aad->component; + struct snd_soc_component *component = da7219->component; u8 clk_reg; clk_reg = snd_soc_component_read32(component, DA7219_DAI_CLK_MODE); @@ -1798,13 +1798,50 @@ static int da7219_dai_clks_is_prepared(struct clk_hw *hw) return !!(clk_reg & DA7219_DAI_CLK_EN_MASK); } +static unsigned long da7219_dai_clks_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct da7219_priv *da7219 = + container_of(hw, struct da7219_priv, dai_clks_hw); + struct snd_soc_component *component = da7219->component; + u8 fs = snd_soc_component_read32(component, DA7219_SR); + + switch (fs & DA7219_SR_MASK) { + case DA7219_SR_8000: + return 8000; + case DA7219_SR_11025: + return 11025; + case DA7219_SR_12000: + return 12000; + case DA7219_SR_16000: + return 16000; + case DA7219_SR_22050: + return 22050; + case DA7219_SR_24000: + return 24000; + case DA7219_SR_32000: + return 32000; + case DA7219_SR_44100: + return 44100; + case DA7219_SR_48000: + return 48000; + case DA7219_SR_88200: + return 88200; + case DA7219_SR_96000: + return 96000; + default: + return 0; + } +} + static const struct clk_ops da7219_dai_clks_ops = { .prepare = da7219_dai_clks_prepare, .unprepare = da7219_dai_clks_unprepare, .is_prepared = da7219_dai_clks_is_prepared, + .recalc_rate = da7219_dai_clks_recalc_rate, }; -static void da7219_register_dai_clks(struct snd_soc_component *component) +static int da7219_register_dai_clks(struct snd_soc_component *component) { struct device *dev = component->dev; struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); @@ -1812,18 +1849,27 @@ static void da7219_register_dai_clks(struct snd_soc_component *component) struct clk_init_data init = {}; struct clk *dai_clks; struct clk_lookup *dai_clks_lookup; + const char *parent_name; + + if (da7219->mclk) { + parent_name = __clk_get_name(da7219->mclk); + init.parent_names = &parent_name; + init.num_parents = 1; + } else { + init.parent_names = NULL; + init.num_parents = 0; + } - init.parent_names = NULL; - init.num_parents = 0; init.name = pdata->dai_clks_name; init.ops = &da7219_dai_clks_ops; + init.flags = CLK_GET_RATE_NOCACHE; da7219->dai_clks_hw.init = &init; dai_clks = devm_clk_register(dev, &da7219->dai_clks_hw); if (IS_ERR(dai_clks)) { dev_warn(dev, "Failed to register DAI clocks: %ld\n", PTR_ERR(dai_clks)); - return; + return PTR_ERR(dai_clks); } da7219->dai_clks = dai_clks; @@ -1835,13 +1881,18 @@ static void da7219_register_dai_clks(struct snd_soc_component *component) dai_clks_lookup = clkdev_create(dai_clks, pdata->dai_clks_name, "%s", dev_name(dev)); if (!dai_clks_lookup) - dev_warn(dev, "Failed to create DAI clkdev"); + return -ENOMEM; else da7219->dai_clks_lookup = dai_clks_lookup; } + + return 0; } #else -static inline void da7219_register_dai_clks(struct snd_soc_component *component) {} +static inline int da7219_register_dai_clks(struct snd_soc_component *component) +{ + return 0; +} #endif /* CONFIG_COMMON_CLK */ static void da7219_handle_pdata(struct snd_soc_component *component) @@ -1854,8 +1905,6 @@ static void da7219_handle_pdata(struct snd_soc_component *component) da7219->wakeup_source = pdata->wakeup_source; - da7219_register_dai_clks(component); - /* Mic Bias voltages */ switch (pdata->micbias_lvl) { case DA7219_MICBIAS_1_6V: @@ -1901,6 +1950,7 @@ static int da7219_probe(struct snd_soc_component *component) unsigned int rev; int ret; + da7219->component = component; mutex_init(&da7219->ctrl_lock); mutex_init(&da7219->pll_lock); @@ -1947,6 +1997,11 @@ static int da7219_probe(struct snd_soc_component *component) } } + /* Register CCF DAI clock control */ + ret = da7219_register_dai_clks(component); + if (ret) + return ret; + /* Default PC counter to free-running */ snd_soc_component_update_bits(component, DA7219_PC_COUNT, DA7219_PC_FREERUN_MASK, DA7219_PC_FREERUN_MASK); |