Loading sound/soc/codecs/ak4613.c +54 −36 Original line number Diff line number Diff line Loading @@ -74,16 +74,6 @@ #define DFS_DOUBLE_SPEED (1 << 2) #define DFS_QUAD_SPEED (2 << 2) struct ak4613_priv { struct mutex lock; unsigned int fmt; u8 fmt_ctrl; u8 oc; u8 ic; int cnt; }; struct ak4613_formats { unsigned int width; unsigned int fmt; Loading @@ -94,6 +84,16 @@ struct ak4613_interface { struct ak4613_formats playback; }; struct ak4613_priv { struct mutex lock; const struct ak4613_interface *iface; unsigned int fmt; u8 oc; u8 ic; int cnt; }; /* * Playback Volume * Loading Loading @@ -128,7 +128,7 @@ static const struct reg_default ak4613_reg[] = { { 0x14, 0x00 }, { 0x15, 0x00 }, { 0x16, 0x00 }, }; #define AUDIO_IFACE_IDX_TO_VAL(i) (i << 3) #define AUDIO_IFACE_TO_VAL(fmts) ((fmts - ak4613_iface) << 3) #define AUDIO_IFACE(b, fmt) { b, SND_SOC_DAIFMT_##fmt } static const struct ak4613_interface ak4613_iface[] = { /* capture */ /* playback */ Loading Loading @@ -242,7 +242,7 @@ static void ak4613_dai_shutdown(struct snd_pcm_substream *substream, priv->cnt = 0; } if (!priv->cnt) priv->fmt_ctrl = NO_FMT; priv->iface = NULL; mutex_unlock(&priv->lock); } Loading @@ -267,13 +267,35 @@ static int ak4613_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return 0; } static bool ak4613_dai_fmt_matching(const struct ak4613_interface *iface, int is_play, unsigned int fmt, unsigned int width) { const struct ak4613_formats *fmts; fmts = (is_play) ? &iface->playback : &iface->capture; if (fmts->fmt != fmt) return false; if (fmt == SND_SOC_DAIFMT_RIGHT_J) { if (fmts->width != width) return false; } else { if (fmts->width < width) return false; } return true; } static int ak4613_dai_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec); const struct ak4613_formats *fmts; const struct ak4613_interface *iface; struct device *dev = codec->dev; unsigned int width = params_width(params); unsigned int fmt = priv->fmt; Loading Loading @@ -307,33 +329,27 @@ static int ak4613_dai_hw_params(struct snd_pcm_substream *substream, * It doesn't support TDM at this point */ fmt_ctrl = NO_FMT; for (i = 0; i < ARRAY_SIZE(ak4613_iface); i++) { fmts = (is_play) ? &ak4613_iface[i].playback : &ak4613_iface[i].capture; if (fmts->fmt != fmt) continue; ret = -EINVAL; iface = NULL; if (fmt == SND_SOC_DAIFMT_RIGHT_J) { if (fmts->width != width) continue; mutex_lock(&priv->lock); if (priv->iface) { if (ak4613_dai_fmt_matching(priv->iface, is_play, fmt, width)) iface = priv->iface; } else { if (fmts->width < width) for (i = ARRAY_SIZE(ak4613_iface); i >= 0; i--) { if (!ak4613_dai_fmt_matching(ak4613_iface + i, is_play, fmt, width)) continue; } fmt_ctrl = AUDIO_IFACE_IDX_TO_VAL(i); iface = ak4613_iface + i; break; } } ret = -EINVAL; if (fmt_ctrl == NO_FMT) goto hw_params_end; mutex_lock(&priv->lock); if ((priv->fmt_ctrl == NO_FMT) || (priv->fmt_ctrl == fmt_ctrl)) { priv->fmt_ctrl = fmt_ctrl; if ((priv->iface == NULL) || (priv->iface == iface)) { priv->iface = iface; priv->cnt++; ret = 0; } Loading @@ -342,6 +358,8 @@ static int ak4613_dai_hw_params(struct snd_pcm_substream *substream, if (ret < 0) goto hw_params_end; fmt_ctrl = AUDIO_IFACE_TO_VAL(iface); snd_soc_update_bits(codec, CTRL1, FMT_MASK, fmt_ctrl); snd_soc_write(codec, CTRL2, ctrl2); Loading Loading @@ -487,7 +505,7 @@ static int ak4613_i2c_probe(struct i2c_client *i2c, ak4613_parse_of(priv, dev); priv->fmt_ctrl = NO_FMT; priv->iface = NULL; priv->cnt = 0; mutex_init(&priv->lock); Loading Loading
sound/soc/codecs/ak4613.c +54 −36 Original line number Diff line number Diff line Loading @@ -74,16 +74,6 @@ #define DFS_DOUBLE_SPEED (1 << 2) #define DFS_QUAD_SPEED (2 << 2) struct ak4613_priv { struct mutex lock; unsigned int fmt; u8 fmt_ctrl; u8 oc; u8 ic; int cnt; }; struct ak4613_formats { unsigned int width; unsigned int fmt; Loading @@ -94,6 +84,16 @@ struct ak4613_interface { struct ak4613_formats playback; }; struct ak4613_priv { struct mutex lock; const struct ak4613_interface *iface; unsigned int fmt; u8 oc; u8 ic; int cnt; }; /* * Playback Volume * Loading Loading @@ -128,7 +128,7 @@ static const struct reg_default ak4613_reg[] = { { 0x14, 0x00 }, { 0x15, 0x00 }, { 0x16, 0x00 }, }; #define AUDIO_IFACE_IDX_TO_VAL(i) (i << 3) #define AUDIO_IFACE_TO_VAL(fmts) ((fmts - ak4613_iface) << 3) #define AUDIO_IFACE(b, fmt) { b, SND_SOC_DAIFMT_##fmt } static const struct ak4613_interface ak4613_iface[] = { /* capture */ /* playback */ Loading Loading @@ -242,7 +242,7 @@ static void ak4613_dai_shutdown(struct snd_pcm_substream *substream, priv->cnt = 0; } if (!priv->cnt) priv->fmt_ctrl = NO_FMT; priv->iface = NULL; mutex_unlock(&priv->lock); } Loading @@ -267,13 +267,35 @@ static int ak4613_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return 0; } static bool ak4613_dai_fmt_matching(const struct ak4613_interface *iface, int is_play, unsigned int fmt, unsigned int width) { const struct ak4613_formats *fmts; fmts = (is_play) ? &iface->playback : &iface->capture; if (fmts->fmt != fmt) return false; if (fmt == SND_SOC_DAIFMT_RIGHT_J) { if (fmts->width != width) return false; } else { if (fmts->width < width) return false; } return true; } static int ak4613_dai_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec); const struct ak4613_formats *fmts; const struct ak4613_interface *iface; struct device *dev = codec->dev; unsigned int width = params_width(params); unsigned int fmt = priv->fmt; Loading Loading @@ -307,33 +329,27 @@ static int ak4613_dai_hw_params(struct snd_pcm_substream *substream, * It doesn't support TDM at this point */ fmt_ctrl = NO_FMT; for (i = 0; i < ARRAY_SIZE(ak4613_iface); i++) { fmts = (is_play) ? &ak4613_iface[i].playback : &ak4613_iface[i].capture; if (fmts->fmt != fmt) continue; ret = -EINVAL; iface = NULL; if (fmt == SND_SOC_DAIFMT_RIGHT_J) { if (fmts->width != width) continue; mutex_lock(&priv->lock); if (priv->iface) { if (ak4613_dai_fmt_matching(priv->iface, is_play, fmt, width)) iface = priv->iface; } else { if (fmts->width < width) for (i = ARRAY_SIZE(ak4613_iface); i >= 0; i--) { if (!ak4613_dai_fmt_matching(ak4613_iface + i, is_play, fmt, width)) continue; } fmt_ctrl = AUDIO_IFACE_IDX_TO_VAL(i); iface = ak4613_iface + i; break; } } ret = -EINVAL; if (fmt_ctrl == NO_FMT) goto hw_params_end; mutex_lock(&priv->lock); if ((priv->fmt_ctrl == NO_FMT) || (priv->fmt_ctrl == fmt_ctrl)) { priv->fmt_ctrl = fmt_ctrl; if ((priv->iface == NULL) || (priv->iface == iface)) { priv->iface = iface; priv->cnt++; ret = 0; } Loading @@ -342,6 +358,8 @@ static int ak4613_dai_hw_params(struct snd_pcm_substream *substream, if (ret < 0) goto hw_params_end; fmt_ctrl = AUDIO_IFACE_TO_VAL(iface); snd_soc_update_bits(codec, CTRL1, FMT_MASK, fmt_ctrl); snd_soc_write(codec, CTRL2, ctrl2); Loading Loading @@ -487,7 +505,7 @@ static int ak4613_i2c_probe(struct i2c_client *i2c, ak4613_parse_of(priv, dev); priv->fmt_ctrl = NO_FMT; priv->iface = NULL; priv->cnt = 0; mutex_init(&priv->lock); Loading