treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / sound / soc / soc-dai.c
blob51031e330179ddb5cf7203b0cc77afaca9ca641d
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // soc-dai.c
4 //
5 // Copyright (C) 2019 Renesas Electronics Corp.
6 // Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
7 //
9 #include <sound/soc.h>
10 #include <sound/soc-dai.h>
12 /**
13 * snd_soc_dai_set_sysclk - configure DAI system or master clock.
14 * @dai: DAI
15 * @clk_id: DAI specific clock ID
16 * @freq: new clock frequency in Hz
17 * @dir: new clock direction - input/output.
19 * Configures the DAI master (MCLK) or system (SYSCLK) clocking.
21 int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
22 unsigned int freq, int dir)
24 if (dai->driver->ops->set_sysclk)
25 return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir);
27 return snd_soc_component_set_sysclk(dai->component, clk_id, 0,
28 freq, dir);
30 EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
32 /**
33 * snd_soc_dai_set_clkdiv - configure DAI clock dividers.
34 * @dai: DAI
35 * @div_id: DAI specific clock divider ID
36 * @div: new clock divisor.
38 * Configures the clock dividers. This is used to derive the best DAI bit and
39 * frame clocks from the system or master clock. It's best to set the DAI bit
40 * and frame clocks as low as possible to save system power.
42 int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
43 int div_id, int div)
45 if (dai->driver->ops->set_clkdiv)
46 return dai->driver->ops->set_clkdiv(dai, div_id, div);
47 else
48 return -EINVAL;
50 EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
52 /**
53 * snd_soc_dai_set_pll - configure DAI PLL.
54 * @dai: DAI
55 * @pll_id: DAI specific PLL ID
56 * @source: DAI specific source for the PLL
57 * @freq_in: PLL input clock frequency in Hz
58 * @freq_out: requested PLL output clock frequency in Hz
60 * Configures and enables PLL to generate output clock based on input clock.
62 int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
63 unsigned int freq_in, unsigned int freq_out)
65 if (dai->driver->ops->set_pll)
66 return dai->driver->ops->set_pll(dai, pll_id, source,
67 freq_in, freq_out);
69 return snd_soc_component_set_pll(dai->component, pll_id, source,
70 freq_in, freq_out);
72 EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
74 /**
75 * snd_soc_dai_set_bclk_ratio - configure BCLK to sample rate ratio.
76 * @dai: DAI
77 * @ratio: Ratio of BCLK to Sample rate.
79 * Configures the DAI for a preset BCLK to sample rate ratio.
81 int snd_soc_dai_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
83 if (dai->driver->ops->set_bclk_ratio)
84 return dai->driver->ops->set_bclk_ratio(dai, ratio);
85 else
86 return -EINVAL;
88 EXPORT_SYMBOL_GPL(snd_soc_dai_set_bclk_ratio);
90 /**
91 * snd_soc_dai_set_fmt - configure DAI hardware audio format.
92 * @dai: DAI
93 * @fmt: SND_SOC_DAIFMT_* format value.
95 * Configures the DAI hardware format and clocking.
97 int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
99 if (dai->driver->ops->set_fmt == NULL)
100 return -ENOTSUPP;
101 return dai->driver->ops->set_fmt(dai, fmt);
103 EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
106 * snd_soc_xlate_tdm_slot - generate tx/rx slot mask.
107 * @slots: Number of slots in use.
108 * @tx_mask: bitmask representing active TX slots.
109 * @rx_mask: bitmask representing active RX slots.
111 * Generates the TDM tx and rx slot default masks for DAI.
113 static int snd_soc_xlate_tdm_slot_mask(unsigned int slots,
114 unsigned int *tx_mask,
115 unsigned int *rx_mask)
117 if (*tx_mask || *rx_mask)
118 return 0;
120 if (!slots)
121 return -EINVAL;
123 *tx_mask = (1 << slots) - 1;
124 *rx_mask = (1 << slots) - 1;
126 return 0;
130 * snd_soc_dai_set_tdm_slot() - Configures a DAI for TDM operation
131 * @dai: The DAI to configure
132 * @tx_mask: bitmask representing active TX slots.
133 * @rx_mask: bitmask representing active RX slots.
134 * @slots: Number of slots in use.
135 * @slot_width: Width in bits for each slot.
137 * This function configures the specified DAI for TDM operation. @slot contains
138 * the total number of slots of the TDM stream and @slot_with the width of each
139 * slot in bit clock cycles. @tx_mask and @rx_mask are bitmasks specifying the
140 * active slots of the TDM stream for the specified DAI, i.e. which slots the
141 * DAI should write to or read from. If a bit is set the corresponding slot is
142 * active, if a bit is cleared the corresponding slot is inactive. Bit 0 maps to
143 * the first slot, bit 1 to the second slot and so on. The first active slot
144 * maps to the first channel of the DAI, the second active slot to the second
145 * channel and so on.
147 * TDM mode can be disabled by passing 0 for @slots. In this case @tx_mask,
148 * @rx_mask and @slot_width will be ignored.
150 * Returns 0 on success, a negative error code otherwise.
152 int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
153 unsigned int tx_mask, unsigned int rx_mask,
154 int slots, int slot_width)
156 if (dai->driver->ops->xlate_tdm_slot_mask)
157 dai->driver->ops->xlate_tdm_slot_mask(slots,
158 &tx_mask, &rx_mask);
159 else
160 snd_soc_xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask);
162 dai->tx_mask = tx_mask;
163 dai->rx_mask = rx_mask;
165 if (dai->driver->ops->set_tdm_slot)
166 return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask,
167 slots, slot_width);
168 else
169 return -ENOTSUPP;
171 EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
174 * snd_soc_dai_set_channel_map - configure DAI audio channel map
175 * @dai: DAI
176 * @tx_num: how many TX channels
177 * @tx_slot: pointer to an array which imply the TX slot number channel
178 * 0~num-1 uses
179 * @rx_num: how many RX channels
180 * @rx_slot: pointer to an array which imply the RX slot number channel
181 * 0~num-1 uses
183 * configure the relationship between channel number and TDM slot number.
185 int snd_soc_dai_set_channel_map(struct snd_soc_dai *dai,
186 unsigned int tx_num, unsigned int *tx_slot,
187 unsigned int rx_num, unsigned int *rx_slot)
189 if (dai->driver->ops->set_channel_map)
190 return dai->driver->ops->set_channel_map(dai, tx_num, tx_slot,
191 rx_num, rx_slot);
192 else
193 return -ENOTSUPP;
195 EXPORT_SYMBOL_GPL(snd_soc_dai_set_channel_map);
198 * snd_soc_dai_get_channel_map - Get DAI audio channel map
199 * @dai: DAI
200 * @tx_num: how many TX channels
201 * @tx_slot: pointer to an array which imply the TX slot number channel
202 * 0~num-1 uses
203 * @rx_num: how many RX channels
204 * @rx_slot: pointer to an array which imply the RX slot number channel
205 * 0~num-1 uses
207 int snd_soc_dai_get_channel_map(struct snd_soc_dai *dai,
208 unsigned int *tx_num, unsigned int *tx_slot,
209 unsigned int *rx_num, unsigned int *rx_slot)
211 if (dai->driver->ops->get_channel_map)
212 return dai->driver->ops->get_channel_map(dai, tx_num, tx_slot,
213 rx_num, rx_slot);
214 else
215 return -ENOTSUPP;
217 EXPORT_SYMBOL_GPL(snd_soc_dai_get_channel_map);
220 * snd_soc_dai_set_tristate - configure DAI system or master clock.
221 * @dai: DAI
222 * @tristate: tristate enable
224 * Tristates the DAI so that others can use it.
226 int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate)
228 if (dai->driver->ops->set_tristate)
229 return dai->driver->ops->set_tristate(dai, tristate);
230 else
231 return -EINVAL;
233 EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate);
236 * snd_soc_dai_digital_mute - configure DAI system or master clock.
237 * @dai: DAI
238 * @mute: mute enable
239 * @direction: stream to mute
241 * Mutes the DAI DAC.
243 int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute,
244 int direction)
246 if (dai->driver->ops->mute_stream)
247 return dai->driver->ops->mute_stream(dai, mute, direction);
248 else if (direction == SNDRV_PCM_STREAM_PLAYBACK &&
249 dai->driver->ops->digital_mute)
250 return dai->driver->ops->digital_mute(dai, mute);
251 else
252 return -ENOTSUPP;
254 EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
256 int snd_soc_dai_hw_params(struct snd_soc_dai *dai,
257 struct snd_pcm_substream *substream,
258 struct snd_pcm_hw_params *params)
260 struct snd_soc_pcm_runtime *rtd = substream->private_data;
261 int ret;
263 /* perform any topology hw_params fixups before DAI */
264 if (rtd->dai_link->be_hw_params_fixup) {
265 ret = rtd->dai_link->be_hw_params_fixup(rtd, params);
266 if (ret < 0) {
267 dev_err(rtd->dev,
268 "ASoC: hw_params topology fixup failed %d\n",
269 ret);
270 return ret;
274 if (dai->driver->ops->hw_params) {
275 ret = dai->driver->ops->hw_params(substream, params, dai);
276 if (ret < 0) {
277 dev_err(dai->dev, "ASoC: can't set %s hw params: %d\n",
278 dai->name, ret);
279 return ret;
283 return 0;
286 void snd_soc_dai_hw_free(struct snd_soc_dai *dai,
287 struct snd_pcm_substream *substream)
289 if (dai->driver->ops->hw_free)
290 dai->driver->ops->hw_free(substream, dai);
293 int snd_soc_dai_startup(struct snd_soc_dai *dai,
294 struct snd_pcm_substream *substream)
296 int ret = 0;
298 if (dai->driver->ops->startup)
299 ret = dai->driver->ops->startup(substream, dai);
301 return ret;
304 void snd_soc_dai_shutdown(struct snd_soc_dai *dai,
305 struct snd_pcm_substream *substream)
307 if (dai->driver->ops->shutdown)
308 dai->driver->ops->shutdown(substream, dai);
311 int snd_soc_dai_prepare(struct snd_soc_dai *dai,
312 struct snd_pcm_substream *substream)
314 int ret = 0;
316 if (dai->driver->ops->prepare)
317 ret = dai->driver->ops->prepare(substream, dai);
319 return ret;
322 int snd_soc_dai_trigger(struct snd_soc_dai *dai,
323 struct snd_pcm_substream *substream,
324 int cmd)
326 int ret = 0;
328 if (dai->driver->ops->trigger)
329 ret = dai->driver->ops->trigger(substream, cmd, dai);
331 return ret;
334 int snd_soc_dai_bespoke_trigger(struct snd_soc_dai *dai,
335 struct snd_pcm_substream *substream,
336 int cmd)
338 int ret = 0;
340 if (dai->driver->ops->bespoke_trigger)
341 ret = dai->driver->ops->bespoke_trigger(substream, cmd, dai);
343 return ret;
346 snd_pcm_sframes_t snd_soc_dai_delay(struct snd_soc_dai *dai,
347 struct snd_pcm_substream *substream)
349 int delay = 0;
351 if (dai->driver->ops->delay)
352 delay = dai->driver->ops->delay(substream, dai);
354 return delay;
357 int snd_soc_dai_probe(struct snd_soc_dai *dai)
359 if (dai->driver->probe)
360 return dai->driver->probe(dai);
361 return 0;
364 int snd_soc_dai_remove(struct snd_soc_dai *dai)
366 if (dai->driver->remove)
367 return dai->driver->remove(dai);
368 return 0;
371 int snd_soc_dai_compress_new(struct snd_soc_dai *dai,
372 struct snd_soc_pcm_runtime *rtd, int num)
374 if (dai->driver->compress_new)
375 return dai->driver->compress_new(rtd, num);
376 return -ENOTSUPP;
380 * snd_soc_dai_stream_valid() - check if a DAI supports the given stream
382 * Returns true if the DAI supports the indicated stream type.
384 bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int dir)
386 struct snd_soc_pcm_stream *stream;
388 if (dir == SNDRV_PCM_STREAM_PLAYBACK)
389 stream = &dai->driver->playback;
390 else
391 stream = &dai->driver->capture;
393 /* If the codec specifies any channels at all, it supports the stream */
394 return stream->channels_min;