summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/da7219.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/da7219.c')
-rw-r--r--sound/soc/codecs/da7219.c85
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);