| .. | .. |
|---|
| 112 | 112 | return 0; |
|---|
| 113 | 113 | } |
|---|
| 114 | 114 | |
|---|
| 115 | | -static int axg_spdifin_startup(struct snd_pcm_substream *substream, |
|---|
| 116 | | - struct snd_soc_dai *dai) |
|---|
| 117 | | -{ |
|---|
| 118 | | - struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai); |
|---|
| 119 | | - int ret; |
|---|
| 120 | | - |
|---|
| 121 | | - ret = clk_prepare_enable(priv->refclk); |
|---|
| 122 | | - if (ret) { |
|---|
| 123 | | - dev_err(dai->dev, |
|---|
| 124 | | - "failed to enable spdifin reference clock\n"); |
|---|
| 125 | | - return ret; |
|---|
| 126 | | - } |
|---|
| 127 | | - |
|---|
| 128 | | - regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, |
|---|
| 129 | | - SPDIFIN_CTRL0_EN); |
|---|
| 130 | | - |
|---|
| 131 | | - return 0; |
|---|
| 132 | | -} |
|---|
| 133 | | - |
|---|
| 134 | | -static void axg_spdifin_shutdown(struct snd_pcm_substream *substream, |
|---|
| 135 | | - struct snd_soc_dai *dai) |
|---|
| 136 | | -{ |
|---|
| 137 | | - struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai); |
|---|
| 138 | | - |
|---|
| 139 | | - regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, 0); |
|---|
| 140 | | - clk_disable_unprepare(priv->refclk); |
|---|
| 141 | | -} |
|---|
| 142 | | - |
|---|
| 143 | 115 | static void axg_spdifin_write_mode_param(struct regmap *map, int mode, |
|---|
| 144 | 116 | unsigned int val, |
|---|
| 145 | 117 | unsigned int num_per_reg, |
|---|
| .. | .. |
|---|
| 251 | 223 | ret = axg_spdifin_sample_mode_config(dai, priv); |
|---|
| 252 | 224 | if (ret) { |
|---|
| 253 | 225 | dev_err(dai->dev, "mode configuration failed\n"); |
|---|
| 254 | | - clk_disable_unprepare(priv->pclk); |
|---|
| 255 | | - return ret; |
|---|
| 226 | + goto pclk_err; |
|---|
| 256 | 227 | } |
|---|
| 257 | 228 | |
|---|
| 229 | + ret = clk_prepare_enable(priv->refclk); |
|---|
| 230 | + if (ret) { |
|---|
| 231 | + dev_err(dai->dev, |
|---|
| 232 | + "failed to enable spdifin reference clock\n"); |
|---|
| 233 | + goto pclk_err; |
|---|
| 234 | + } |
|---|
| 235 | + |
|---|
| 236 | + regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, |
|---|
| 237 | + SPDIFIN_CTRL0_EN); |
|---|
| 238 | + |
|---|
| 258 | 239 | return 0; |
|---|
| 240 | + |
|---|
| 241 | +pclk_err: |
|---|
| 242 | + clk_disable_unprepare(priv->pclk); |
|---|
| 243 | + return ret; |
|---|
| 259 | 244 | } |
|---|
| 260 | 245 | |
|---|
| 261 | 246 | static int axg_spdifin_dai_remove(struct snd_soc_dai *dai) |
|---|
| 262 | 247 | { |
|---|
| 263 | 248 | struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai); |
|---|
| 264 | 249 | |
|---|
| 250 | + regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, 0); |
|---|
| 251 | + clk_disable_unprepare(priv->refclk); |
|---|
| 265 | 252 | clk_disable_unprepare(priv->pclk); |
|---|
| 266 | 253 | return 0; |
|---|
| 267 | 254 | } |
|---|
| 268 | 255 | |
|---|
| 269 | 256 | static const struct snd_soc_dai_ops axg_spdifin_ops = { |
|---|
| 270 | 257 | .prepare = axg_spdifin_prepare, |
|---|
| 271 | | - .startup = axg_spdifin_startup, |
|---|
| 272 | | - .shutdown = axg_spdifin_shutdown, |
|---|
| 273 | 258 | }; |
|---|
| 274 | 259 | |
|---|
| 275 | 260 | static int axg_spdifin_iec958_info(struct snd_kcontrol *kcontrol, |
|---|