162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci *
362306a36Sopenharmony_ci * linux/sound/soc-dai.h -- ALSA SoC Layer
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright:	2005-2008 Wolfson Microelectronics. PLC.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Digital Audio Interface (DAI) API.
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#ifndef __LINUX_SND_SOC_DAI_H
1162306a36Sopenharmony_ci#define __LINUX_SND_SOC_DAI_H
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <linux/list.h>
1562306a36Sopenharmony_ci#include <sound/asoc.h>
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_cistruct snd_pcm_substream;
1862306a36Sopenharmony_cistruct snd_soc_dapm_widget;
1962306a36Sopenharmony_cistruct snd_compr_stream;
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci/*
2262306a36Sopenharmony_ci * DAI hardware audio formats.
2362306a36Sopenharmony_ci *
2462306a36Sopenharmony_ci * Describes the physical PCM data formating and clocking. Add new formats
2562306a36Sopenharmony_ci * to the end.
2662306a36Sopenharmony_ci */
2762306a36Sopenharmony_ci#define SND_SOC_DAIFMT_I2S		SND_SOC_DAI_FORMAT_I2S
2862306a36Sopenharmony_ci#define SND_SOC_DAIFMT_RIGHT_J		SND_SOC_DAI_FORMAT_RIGHT_J
2962306a36Sopenharmony_ci#define SND_SOC_DAIFMT_LEFT_J		SND_SOC_DAI_FORMAT_LEFT_J
3062306a36Sopenharmony_ci#define SND_SOC_DAIFMT_DSP_A		SND_SOC_DAI_FORMAT_DSP_A
3162306a36Sopenharmony_ci#define SND_SOC_DAIFMT_DSP_B		SND_SOC_DAI_FORMAT_DSP_B
3262306a36Sopenharmony_ci#define SND_SOC_DAIFMT_AC97		SND_SOC_DAI_FORMAT_AC97
3362306a36Sopenharmony_ci#define SND_SOC_DAIFMT_PDM		SND_SOC_DAI_FORMAT_PDM
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci/* left and right justified also known as MSB and LSB respectively */
3662306a36Sopenharmony_ci#define SND_SOC_DAIFMT_MSB		SND_SOC_DAIFMT_LEFT_J
3762306a36Sopenharmony_ci#define SND_SOC_DAIFMT_LSB		SND_SOC_DAIFMT_RIGHT_J
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci/* Describes the possible PCM format */
4062306a36Sopenharmony_ci/*
4162306a36Sopenharmony_ci * use SND_SOC_DAI_FORMAT_xx as eash shift.
4262306a36Sopenharmony_ci * see
4362306a36Sopenharmony_ci *	snd_soc_runtime_get_dai_fmt()
4462306a36Sopenharmony_ci */
4562306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_FORMAT_SHIFT	0
4662306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_FORMAT_MASK	(0xFFFF << SND_SOC_POSSIBLE_DAIFMT_FORMAT_SHIFT)
4762306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_I2S		(1 << SND_SOC_DAI_FORMAT_I2S)
4862306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_RIGHT_J		(1 << SND_SOC_DAI_FORMAT_RIGHT_J)
4962306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_LEFT_J		(1 << SND_SOC_DAI_FORMAT_LEFT_J)
5062306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_DSP_A		(1 << SND_SOC_DAI_FORMAT_DSP_A)
5162306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_DSP_B		(1 << SND_SOC_DAI_FORMAT_DSP_B)
5262306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_AC97		(1 << SND_SOC_DAI_FORMAT_AC97)
5362306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_PDM		(1 << SND_SOC_DAI_FORMAT_PDM)
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci/*
5662306a36Sopenharmony_ci * DAI Clock gating.
5762306a36Sopenharmony_ci *
5862306a36Sopenharmony_ci * DAI bit clocks can be gated (disabled) when the DAI is not
5962306a36Sopenharmony_ci * sending or receiving PCM data in a frame. This can be used to save power.
6062306a36Sopenharmony_ci */
6162306a36Sopenharmony_ci#define SND_SOC_DAIFMT_CONT		(1 << 4) /* continuous clock */
6262306a36Sopenharmony_ci#define SND_SOC_DAIFMT_GATED		(0 << 4) /* clock is gated */
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci/* Describes the possible PCM format */
6562306a36Sopenharmony_ci/*
6662306a36Sopenharmony_ci * define GATED -> CONT. GATED will be selected if both are selected.
6762306a36Sopenharmony_ci * see
6862306a36Sopenharmony_ci *	snd_soc_runtime_get_dai_fmt()
6962306a36Sopenharmony_ci */
7062306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_CLOCK_SHIFT	16
7162306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_CLOCK_MASK	(0xFFFF	<< SND_SOC_POSSIBLE_DAIFMT_CLOCK_SHIFT)
7262306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_GATED		(0x1ULL	<< SND_SOC_POSSIBLE_DAIFMT_CLOCK_SHIFT)
7362306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_CONT		(0x2ULL	<< SND_SOC_POSSIBLE_DAIFMT_CLOCK_SHIFT)
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci/*
7662306a36Sopenharmony_ci * DAI hardware signal polarity.
7762306a36Sopenharmony_ci *
7862306a36Sopenharmony_ci * Specifies whether the DAI can also support inverted clocks for the specified
7962306a36Sopenharmony_ci * format.
8062306a36Sopenharmony_ci *
8162306a36Sopenharmony_ci * BCLK:
8262306a36Sopenharmony_ci * - "normal" polarity means signal is available at rising edge of BCLK
8362306a36Sopenharmony_ci * - "inverted" polarity means signal is available at falling edge of BCLK
8462306a36Sopenharmony_ci *
8562306a36Sopenharmony_ci * FSYNC "normal" polarity depends on the frame format:
8662306a36Sopenharmony_ci * - I2S: frame consists of left then right channel data. Left channel starts
8762306a36Sopenharmony_ci *      with falling FSYNC edge, right channel starts with rising FSYNC edge.
8862306a36Sopenharmony_ci * - Left/Right Justified: frame consists of left then right channel data.
8962306a36Sopenharmony_ci *      Left channel starts with rising FSYNC edge, right channel starts with
9062306a36Sopenharmony_ci *      falling FSYNC edge.
9162306a36Sopenharmony_ci * - DSP A/B: Frame starts with rising FSYNC edge.
9262306a36Sopenharmony_ci * - AC97: Frame starts with rising FSYNC edge.
9362306a36Sopenharmony_ci *
9462306a36Sopenharmony_ci * "Negative" FSYNC polarity is the one opposite of "normal" polarity.
9562306a36Sopenharmony_ci */
9662306a36Sopenharmony_ci#define SND_SOC_DAIFMT_NB_NF		(0 << 8) /* normal bit clock + frame */
9762306a36Sopenharmony_ci#define SND_SOC_DAIFMT_NB_IF		(2 << 8) /* normal BCLK + inv FRM */
9862306a36Sopenharmony_ci#define SND_SOC_DAIFMT_IB_NF		(3 << 8) /* invert BCLK + nor FRM */
9962306a36Sopenharmony_ci#define SND_SOC_DAIFMT_IB_IF		(4 << 8) /* invert BCLK + FRM */
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci/* Describes the possible PCM format */
10262306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_INV_SHIFT	32
10362306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_INV_MASK	(0xFFFFULL << SND_SOC_POSSIBLE_DAIFMT_INV_SHIFT)
10462306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_NB_NF		(0x1ULL    << SND_SOC_POSSIBLE_DAIFMT_INV_SHIFT)
10562306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_NB_IF		(0x2ULL    << SND_SOC_POSSIBLE_DAIFMT_INV_SHIFT)
10662306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_IB_NF		(0x4ULL    << SND_SOC_POSSIBLE_DAIFMT_INV_SHIFT)
10762306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_IB_IF		(0x8ULL    << SND_SOC_POSSIBLE_DAIFMT_INV_SHIFT)
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci/*
11062306a36Sopenharmony_ci * DAI hardware clock providers/consumers
11162306a36Sopenharmony_ci *
11262306a36Sopenharmony_ci * This is wrt the codec, the inverse is true for the interface
11362306a36Sopenharmony_ci * i.e. if the codec is clk and FRM provider then the interface is
11462306a36Sopenharmony_ci * clk and frame consumer.
11562306a36Sopenharmony_ci */
11662306a36Sopenharmony_ci#define SND_SOC_DAIFMT_CBP_CFP		(1 << 12) /* codec clk provider & frame provider */
11762306a36Sopenharmony_ci#define SND_SOC_DAIFMT_CBC_CFP		(2 << 12) /* codec clk consumer & frame provider */
11862306a36Sopenharmony_ci#define SND_SOC_DAIFMT_CBP_CFC		(3 << 12) /* codec clk provider & frame consumer */
11962306a36Sopenharmony_ci#define SND_SOC_DAIFMT_CBC_CFC		(4 << 12) /* codec clk consumer & frame consumer */
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci/* previous definitions kept for backwards-compatibility, do not use in new contributions */
12262306a36Sopenharmony_ci#define SND_SOC_DAIFMT_CBM_CFM		SND_SOC_DAIFMT_CBP_CFP
12362306a36Sopenharmony_ci#define SND_SOC_DAIFMT_CBS_CFM		SND_SOC_DAIFMT_CBC_CFP
12462306a36Sopenharmony_ci#define SND_SOC_DAIFMT_CBM_CFS		SND_SOC_DAIFMT_CBP_CFC
12562306a36Sopenharmony_ci#define SND_SOC_DAIFMT_CBS_CFS		SND_SOC_DAIFMT_CBC_CFC
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci/* when passed to set_fmt directly indicate if the device is provider or consumer */
12862306a36Sopenharmony_ci#define SND_SOC_DAIFMT_BP_FP		SND_SOC_DAIFMT_CBP_CFP
12962306a36Sopenharmony_ci#define SND_SOC_DAIFMT_BC_FP		SND_SOC_DAIFMT_CBC_CFP
13062306a36Sopenharmony_ci#define SND_SOC_DAIFMT_BP_FC		SND_SOC_DAIFMT_CBP_CFC
13162306a36Sopenharmony_ci#define SND_SOC_DAIFMT_BC_FC		SND_SOC_DAIFMT_CBC_CFC
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci/* Describes the possible PCM format */
13462306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT	48
13562306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_MASK	(0xFFFFULL << SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT)
13662306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_CBP_CFP			(0x1ULL    << SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT)
13762306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_CBC_CFP			(0x2ULL    << SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT)
13862306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_CBP_CFC			(0x4ULL    << SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT)
13962306a36Sopenharmony_ci#define SND_SOC_POSSIBLE_DAIFMT_CBC_CFC			(0x8ULL    << SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT)
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci#define SND_SOC_DAIFMT_FORMAT_MASK		0x000f
14262306a36Sopenharmony_ci#define SND_SOC_DAIFMT_CLOCK_MASK		0x00f0
14362306a36Sopenharmony_ci#define SND_SOC_DAIFMT_INV_MASK			0x0f00
14462306a36Sopenharmony_ci#define SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK	0xf000
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci#define SND_SOC_DAIFMT_MASTER_MASK	SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci/*
14962306a36Sopenharmony_ci * Master Clock Directions
15062306a36Sopenharmony_ci */
15162306a36Sopenharmony_ci#define SND_SOC_CLOCK_IN		0
15262306a36Sopenharmony_ci#define SND_SOC_CLOCK_OUT		1
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci#define SND_SOC_STD_AC97_FMTS (SNDRV_PCM_FMTBIT_S8 |\
15562306a36Sopenharmony_ci			       SNDRV_PCM_FMTBIT_S16_LE |\
15662306a36Sopenharmony_ci			       SNDRV_PCM_FMTBIT_S16_BE |\
15762306a36Sopenharmony_ci			       SNDRV_PCM_FMTBIT_S20_3LE |\
15862306a36Sopenharmony_ci			       SNDRV_PCM_FMTBIT_S20_3BE |\
15962306a36Sopenharmony_ci			       SNDRV_PCM_FMTBIT_S20_LE |\
16062306a36Sopenharmony_ci			       SNDRV_PCM_FMTBIT_S20_BE |\
16162306a36Sopenharmony_ci			       SNDRV_PCM_FMTBIT_S24_3LE |\
16262306a36Sopenharmony_ci			       SNDRV_PCM_FMTBIT_S24_3BE |\
16362306a36Sopenharmony_ci                               SNDRV_PCM_FMTBIT_S32_LE |\
16462306a36Sopenharmony_ci                               SNDRV_PCM_FMTBIT_S32_BE)
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_cistruct snd_soc_dai_driver;
16762306a36Sopenharmony_cistruct snd_soc_dai;
16862306a36Sopenharmony_cistruct snd_ac97_bus_ops;
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci/* Digital Audio Interface clocking API.*/
17162306a36Sopenharmony_ciint snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
17262306a36Sopenharmony_ci	unsigned int freq, int dir);
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ciint snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
17562306a36Sopenharmony_ci	int div_id, int div);
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ciint snd_soc_dai_set_pll(struct snd_soc_dai *dai,
17862306a36Sopenharmony_ci	int pll_id, int source, unsigned int freq_in, unsigned int freq_out);
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ciint snd_soc_dai_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio);
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci/* Digital Audio interface formatting */
18362306a36Sopenharmony_ciint snd_soc_dai_get_fmt_max_priority(struct snd_soc_pcm_runtime *rtd);
18462306a36Sopenharmony_ciu64 snd_soc_dai_get_fmt(struct snd_soc_dai *dai, int priority);
18562306a36Sopenharmony_ciint snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt);
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_ciint snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
18862306a36Sopenharmony_ci	unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width);
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ciint snd_soc_dai_set_channel_map(struct snd_soc_dai *dai,
19162306a36Sopenharmony_ci	unsigned int tx_num, unsigned int *tx_slot,
19262306a36Sopenharmony_ci	unsigned int rx_num, unsigned int *rx_slot);
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ciint snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate);
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci/* Digital Audio Interface mute */
19762306a36Sopenharmony_ciint snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute,
19862306a36Sopenharmony_ci			     int direction);
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ciint snd_soc_dai_get_channel_map(struct snd_soc_dai *dai,
20262306a36Sopenharmony_ci		unsigned int *tx_num, unsigned int *tx_slot,
20362306a36Sopenharmony_ci		unsigned int *rx_num, unsigned int *rx_slot);
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ciint snd_soc_dai_is_dummy(struct snd_soc_dai *dai);
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ciint snd_soc_dai_hw_params(struct snd_soc_dai *dai,
20862306a36Sopenharmony_ci			  struct snd_pcm_substream *substream,
20962306a36Sopenharmony_ci			  struct snd_pcm_hw_params *params);
21062306a36Sopenharmony_civoid snd_soc_dai_hw_free(struct snd_soc_dai *dai,
21162306a36Sopenharmony_ci			 struct snd_pcm_substream *substream,
21262306a36Sopenharmony_ci			 int rollback);
21362306a36Sopenharmony_ciint snd_soc_dai_startup(struct snd_soc_dai *dai,
21462306a36Sopenharmony_ci			struct snd_pcm_substream *substream);
21562306a36Sopenharmony_civoid snd_soc_dai_shutdown(struct snd_soc_dai *dai,
21662306a36Sopenharmony_ci			  struct snd_pcm_substream *substream, int rollback);
21762306a36Sopenharmony_civoid snd_soc_dai_suspend(struct snd_soc_dai *dai);
21862306a36Sopenharmony_civoid snd_soc_dai_resume(struct snd_soc_dai *dai);
21962306a36Sopenharmony_ciint snd_soc_dai_compress_new(struct snd_soc_dai *dai,
22062306a36Sopenharmony_ci			     struct snd_soc_pcm_runtime *rtd, int num);
22162306a36Sopenharmony_cibool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream);
22262306a36Sopenharmony_civoid snd_soc_dai_link_set_capabilities(struct snd_soc_dai_link *dai_link);
22362306a36Sopenharmony_civoid snd_soc_dai_action(struct snd_soc_dai *dai,
22462306a36Sopenharmony_ci			int stream, int action);
22562306a36Sopenharmony_cistatic inline void snd_soc_dai_activate(struct snd_soc_dai *dai,
22662306a36Sopenharmony_ci					int stream)
22762306a36Sopenharmony_ci{
22862306a36Sopenharmony_ci	snd_soc_dai_action(dai, stream,  1);
22962306a36Sopenharmony_ci}
23062306a36Sopenharmony_cistatic inline void snd_soc_dai_deactivate(struct snd_soc_dai *dai,
23162306a36Sopenharmony_ci					  int stream)
23262306a36Sopenharmony_ci{
23362306a36Sopenharmony_ci	snd_soc_dai_action(dai, stream, -1);
23462306a36Sopenharmony_ci}
23562306a36Sopenharmony_ciint snd_soc_dai_active(struct snd_soc_dai *dai);
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ciint snd_soc_pcm_dai_probe(struct snd_soc_pcm_runtime *rtd, int order);
23862306a36Sopenharmony_ciint snd_soc_pcm_dai_remove(struct snd_soc_pcm_runtime *rtd, int order);
23962306a36Sopenharmony_ciint snd_soc_pcm_dai_new(struct snd_soc_pcm_runtime *rtd);
24062306a36Sopenharmony_ciint snd_soc_pcm_dai_prepare(struct snd_pcm_substream *substream);
24162306a36Sopenharmony_ciint snd_soc_pcm_dai_trigger(struct snd_pcm_substream *substream, int cmd,
24262306a36Sopenharmony_ci			    int rollback);
24362306a36Sopenharmony_ciint snd_soc_pcm_dai_bespoke_trigger(struct snd_pcm_substream *substream,
24462306a36Sopenharmony_ci				    int cmd);
24562306a36Sopenharmony_civoid snd_soc_pcm_dai_delay(struct snd_pcm_substream *substream,
24662306a36Sopenharmony_ci			   snd_pcm_sframes_t *cpu_delay, snd_pcm_sframes_t *codec_delay);
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ciint snd_soc_dai_compr_startup(struct snd_soc_dai *dai,
24962306a36Sopenharmony_ci			      struct snd_compr_stream *cstream);
25062306a36Sopenharmony_civoid snd_soc_dai_compr_shutdown(struct snd_soc_dai *dai,
25162306a36Sopenharmony_ci				struct snd_compr_stream *cstream,
25262306a36Sopenharmony_ci				int rollback);
25362306a36Sopenharmony_ciint snd_soc_dai_compr_trigger(struct snd_soc_dai *dai,
25462306a36Sopenharmony_ci			      struct snd_compr_stream *cstream, int cmd);
25562306a36Sopenharmony_ciint snd_soc_dai_compr_set_params(struct snd_soc_dai *dai,
25662306a36Sopenharmony_ci				 struct snd_compr_stream *cstream,
25762306a36Sopenharmony_ci				 struct snd_compr_params *params);
25862306a36Sopenharmony_ciint snd_soc_dai_compr_get_params(struct snd_soc_dai *dai,
25962306a36Sopenharmony_ci				 struct snd_compr_stream *cstream,
26062306a36Sopenharmony_ci				 struct snd_codec *params);
26162306a36Sopenharmony_ciint snd_soc_dai_compr_ack(struct snd_soc_dai *dai,
26262306a36Sopenharmony_ci			  struct snd_compr_stream *cstream,
26362306a36Sopenharmony_ci			  size_t bytes);
26462306a36Sopenharmony_ciint snd_soc_dai_compr_pointer(struct snd_soc_dai *dai,
26562306a36Sopenharmony_ci			      struct snd_compr_stream *cstream,
26662306a36Sopenharmony_ci			      struct snd_compr_tstamp *tstamp);
26762306a36Sopenharmony_ciint snd_soc_dai_compr_set_metadata(struct snd_soc_dai *dai,
26862306a36Sopenharmony_ci				   struct snd_compr_stream *cstream,
26962306a36Sopenharmony_ci				   struct snd_compr_metadata *metadata);
27062306a36Sopenharmony_ciint snd_soc_dai_compr_get_metadata(struct snd_soc_dai *dai,
27162306a36Sopenharmony_ci				   struct snd_compr_stream *cstream,
27262306a36Sopenharmony_ci				   struct snd_compr_metadata *metadata);
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ciconst char *snd_soc_dai_name_get(struct snd_soc_dai *dai);
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_cistruct snd_soc_dai_ops {
27762306a36Sopenharmony_ci	/* DAI driver callbacks */
27862306a36Sopenharmony_ci	int (*probe)(struct snd_soc_dai *dai);
27962306a36Sopenharmony_ci	int (*remove)(struct snd_soc_dai *dai);
28062306a36Sopenharmony_ci	/* compress dai */
28162306a36Sopenharmony_ci	int (*compress_new)(struct snd_soc_pcm_runtime *rtd, int num);
28262306a36Sopenharmony_ci	/* Optional Callback used at pcm creation*/
28362306a36Sopenharmony_ci	int (*pcm_new)(struct snd_soc_pcm_runtime *rtd,
28462306a36Sopenharmony_ci		       struct snd_soc_dai *dai);
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci	/*
28762306a36Sopenharmony_ci	 * DAI clocking configuration, all optional.
28862306a36Sopenharmony_ci	 * Called by soc_card drivers, normally in their hw_params.
28962306a36Sopenharmony_ci	 */
29062306a36Sopenharmony_ci	int (*set_sysclk)(struct snd_soc_dai *dai,
29162306a36Sopenharmony_ci		int clk_id, unsigned int freq, int dir);
29262306a36Sopenharmony_ci	int (*set_pll)(struct snd_soc_dai *dai, int pll_id, int source,
29362306a36Sopenharmony_ci		unsigned int freq_in, unsigned int freq_out);
29462306a36Sopenharmony_ci	int (*set_clkdiv)(struct snd_soc_dai *dai, int div_id, int div);
29562306a36Sopenharmony_ci	int (*set_bclk_ratio)(struct snd_soc_dai *dai, unsigned int ratio);
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci	/*
29862306a36Sopenharmony_ci	 * DAI format configuration
29962306a36Sopenharmony_ci	 * Called by soc_card drivers, normally in their hw_params.
30062306a36Sopenharmony_ci	 */
30162306a36Sopenharmony_ci	int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt);
30262306a36Sopenharmony_ci	int (*xlate_tdm_slot_mask)(unsigned int slots,
30362306a36Sopenharmony_ci		unsigned int *tx_mask, unsigned int *rx_mask);
30462306a36Sopenharmony_ci	int (*set_tdm_slot)(struct snd_soc_dai *dai,
30562306a36Sopenharmony_ci		unsigned int tx_mask, unsigned int rx_mask,
30662306a36Sopenharmony_ci		int slots, int slot_width);
30762306a36Sopenharmony_ci	int (*set_channel_map)(struct snd_soc_dai *dai,
30862306a36Sopenharmony_ci		unsigned int tx_num, unsigned int *tx_slot,
30962306a36Sopenharmony_ci		unsigned int rx_num, unsigned int *rx_slot);
31062306a36Sopenharmony_ci	int (*get_channel_map)(struct snd_soc_dai *dai,
31162306a36Sopenharmony_ci			unsigned int *tx_num, unsigned int *tx_slot,
31262306a36Sopenharmony_ci			unsigned int *rx_num, unsigned int *rx_slot);
31362306a36Sopenharmony_ci	int (*set_tristate)(struct snd_soc_dai *dai, int tristate);
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci	int (*set_stream)(struct snd_soc_dai *dai,
31662306a36Sopenharmony_ci			  void *stream, int direction);
31762306a36Sopenharmony_ci	void *(*get_stream)(struct snd_soc_dai *dai, int direction);
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_ci	/*
32062306a36Sopenharmony_ci	 * DAI digital mute - optional.
32162306a36Sopenharmony_ci	 * Called by soc-core to minimise any pops.
32262306a36Sopenharmony_ci	 */
32362306a36Sopenharmony_ci	int (*mute_stream)(struct snd_soc_dai *dai, int mute, int stream);
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci	/*
32662306a36Sopenharmony_ci	 * ALSA PCM audio operations - all optional.
32762306a36Sopenharmony_ci	 * Called by soc-core during audio PCM operations.
32862306a36Sopenharmony_ci	 */
32962306a36Sopenharmony_ci	int (*startup)(struct snd_pcm_substream *,
33062306a36Sopenharmony_ci		struct snd_soc_dai *);
33162306a36Sopenharmony_ci	void (*shutdown)(struct snd_pcm_substream *,
33262306a36Sopenharmony_ci		struct snd_soc_dai *);
33362306a36Sopenharmony_ci	int (*hw_params)(struct snd_pcm_substream *,
33462306a36Sopenharmony_ci		struct snd_pcm_hw_params *, struct snd_soc_dai *);
33562306a36Sopenharmony_ci	int (*hw_free)(struct snd_pcm_substream *,
33662306a36Sopenharmony_ci		struct snd_soc_dai *);
33762306a36Sopenharmony_ci	int (*prepare)(struct snd_pcm_substream *,
33862306a36Sopenharmony_ci		struct snd_soc_dai *);
33962306a36Sopenharmony_ci	/*
34062306a36Sopenharmony_ci	 * NOTE: Commands passed to the trigger function are not necessarily
34162306a36Sopenharmony_ci	 * compatible with the current state of the dai. For example this
34262306a36Sopenharmony_ci	 * sequence of commands is possible: START STOP STOP.
34362306a36Sopenharmony_ci	 * So do not unconditionally use refcounting functions in the trigger
34462306a36Sopenharmony_ci	 * function, e.g. clk_enable/disable.
34562306a36Sopenharmony_ci	 */
34662306a36Sopenharmony_ci	int (*trigger)(struct snd_pcm_substream *, int,
34762306a36Sopenharmony_ci		struct snd_soc_dai *);
34862306a36Sopenharmony_ci	int (*bespoke_trigger)(struct snd_pcm_substream *, int,
34962306a36Sopenharmony_ci		struct snd_soc_dai *);
35062306a36Sopenharmony_ci	/*
35162306a36Sopenharmony_ci	 * For hardware based FIFO caused delay reporting.
35262306a36Sopenharmony_ci	 * Optional.
35362306a36Sopenharmony_ci	 */
35462306a36Sopenharmony_ci	snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *,
35562306a36Sopenharmony_ci		struct snd_soc_dai *);
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_ci	/*
35862306a36Sopenharmony_ci	 * Format list for auto selection.
35962306a36Sopenharmony_ci	 * Format will be increased if priority format was
36062306a36Sopenharmony_ci	 * not selected.
36162306a36Sopenharmony_ci	 * see
36262306a36Sopenharmony_ci	 *	snd_soc_dai_get_fmt()
36362306a36Sopenharmony_ci	 */
36462306a36Sopenharmony_ci	u64 *auto_selectable_formats;
36562306a36Sopenharmony_ci	int num_auto_selectable_formats;
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci	/* probe ordering - for components with runtime dependencies */
36862306a36Sopenharmony_ci	int probe_order;
36962306a36Sopenharmony_ci	int remove_order;
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci	/* bit field */
37262306a36Sopenharmony_ci	unsigned int no_capture_mute:1;
37362306a36Sopenharmony_ci	unsigned int mute_unmute_on_trigger:1;
37462306a36Sopenharmony_ci};
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_cistruct snd_soc_cdai_ops {
37762306a36Sopenharmony_ci	/*
37862306a36Sopenharmony_ci	 * for compress ops
37962306a36Sopenharmony_ci	 */
38062306a36Sopenharmony_ci	int (*startup)(struct snd_compr_stream *,
38162306a36Sopenharmony_ci			struct snd_soc_dai *);
38262306a36Sopenharmony_ci	int (*shutdown)(struct snd_compr_stream *,
38362306a36Sopenharmony_ci			struct snd_soc_dai *);
38462306a36Sopenharmony_ci	int (*set_params)(struct snd_compr_stream *,
38562306a36Sopenharmony_ci			struct snd_compr_params *, struct snd_soc_dai *);
38662306a36Sopenharmony_ci	int (*get_params)(struct snd_compr_stream *,
38762306a36Sopenharmony_ci			struct snd_codec *, struct snd_soc_dai *);
38862306a36Sopenharmony_ci	int (*set_metadata)(struct snd_compr_stream *,
38962306a36Sopenharmony_ci			struct snd_compr_metadata *, struct snd_soc_dai *);
39062306a36Sopenharmony_ci	int (*get_metadata)(struct snd_compr_stream *,
39162306a36Sopenharmony_ci			struct snd_compr_metadata *, struct snd_soc_dai *);
39262306a36Sopenharmony_ci	int (*trigger)(struct snd_compr_stream *, int,
39362306a36Sopenharmony_ci			struct snd_soc_dai *);
39462306a36Sopenharmony_ci	int (*pointer)(struct snd_compr_stream *,
39562306a36Sopenharmony_ci			struct snd_compr_tstamp *, struct snd_soc_dai *);
39662306a36Sopenharmony_ci	int (*ack)(struct snd_compr_stream *, size_t,
39762306a36Sopenharmony_ci			struct snd_soc_dai *);
39862306a36Sopenharmony_ci};
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ci/*
40162306a36Sopenharmony_ci * Digital Audio Interface Driver.
40262306a36Sopenharmony_ci *
40362306a36Sopenharmony_ci * Describes the Digital Audio Interface in terms of its ALSA, DAI and AC97
40462306a36Sopenharmony_ci * operations and capabilities. Codec and platform drivers will register this
40562306a36Sopenharmony_ci * structure for every DAI they have.
40662306a36Sopenharmony_ci *
40762306a36Sopenharmony_ci * This structure covers the clocking, formating and ALSA operations for each
40862306a36Sopenharmony_ci * interface.
40962306a36Sopenharmony_ci */
41062306a36Sopenharmony_cistruct snd_soc_dai_driver {
41162306a36Sopenharmony_ci	/* DAI description */
41262306a36Sopenharmony_ci	const char *name;
41362306a36Sopenharmony_ci	unsigned int id;
41462306a36Sopenharmony_ci	unsigned int base;
41562306a36Sopenharmony_ci	struct snd_soc_dobj dobj;
41662306a36Sopenharmony_ci	struct of_phandle_args *dai_args;
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_ci	/* ops */
41962306a36Sopenharmony_ci	const struct snd_soc_dai_ops *ops;
42062306a36Sopenharmony_ci	const struct snd_soc_cdai_ops *cops;
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci	/* DAI capabilities */
42362306a36Sopenharmony_ci	struct snd_soc_pcm_stream capture;
42462306a36Sopenharmony_ci	struct snd_soc_pcm_stream playback;
42562306a36Sopenharmony_ci	unsigned int symmetric_rate:1;
42662306a36Sopenharmony_ci	unsigned int symmetric_channels:1;
42762306a36Sopenharmony_ci	unsigned int symmetric_sample_bits:1;
42862306a36Sopenharmony_ci};
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_ci/* for Playback/Capture */
43162306a36Sopenharmony_cistruct snd_soc_dai_stream {
43262306a36Sopenharmony_ci	struct snd_soc_dapm_widget *widget;
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_ci	unsigned int active;	/* usage count */
43562306a36Sopenharmony_ci	unsigned int tdm_mask;	/* CODEC TDM slot masks and params (for fixup) */
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_ci	void *dma_data;		/* DAI DMA data */
43862306a36Sopenharmony_ci};
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci/*
44162306a36Sopenharmony_ci * Digital Audio Interface runtime data.
44262306a36Sopenharmony_ci *
44362306a36Sopenharmony_ci * Holds runtime data for a DAI.
44462306a36Sopenharmony_ci */
44562306a36Sopenharmony_cistruct snd_soc_dai {
44662306a36Sopenharmony_ci	const char *name;
44762306a36Sopenharmony_ci	int id;
44862306a36Sopenharmony_ci	struct device *dev;
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_ci	/* driver ops */
45162306a36Sopenharmony_ci	struct snd_soc_dai_driver *driver;
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_ci	/* DAI runtime info */
45462306a36Sopenharmony_ci	struct snd_soc_dai_stream stream[SNDRV_PCM_STREAM_LAST + 1];
45562306a36Sopenharmony_ci
45662306a36Sopenharmony_ci	/* Symmetry data - only valid if symmetry is being enforced */
45762306a36Sopenharmony_ci	unsigned int rate;
45862306a36Sopenharmony_ci	unsigned int channels;
45962306a36Sopenharmony_ci	unsigned int sample_bits;
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_ci	/* parent platform/codec */
46262306a36Sopenharmony_ci	struct snd_soc_component *component;
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_ci	struct list_head list;
46562306a36Sopenharmony_ci
46662306a36Sopenharmony_ci	/* function mark */
46762306a36Sopenharmony_ci	struct snd_pcm_substream *mark_startup;
46862306a36Sopenharmony_ci	struct snd_pcm_substream *mark_hw_params;
46962306a36Sopenharmony_ci	struct snd_pcm_substream *mark_trigger;
47062306a36Sopenharmony_ci	struct snd_compr_stream  *mark_compr_startup;
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci	/* bit field */
47362306a36Sopenharmony_ci	unsigned int probed:1;
47462306a36Sopenharmony_ci};
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_cistatic inline struct snd_soc_pcm_stream *
47762306a36Sopenharmony_cisnd_soc_dai_get_pcm_stream(const struct snd_soc_dai *dai, int stream)
47862306a36Sopenharmony_ci{
47962306a36Sopenharmony_ci	return (stream == SNDRV_PCM_STREAM_PLAYBACK) ?
48062306a36Sopenharmony_ci		&dai->driver->playback : &dai->driver->capture;
48162306a36Sopenharmony_ci}
48262306a36Sopenharmony_ci
48362306a36Sopenharmony_ci#define snd_soc_dai_get_widget_playback(dai)	snd_soc_dai_get_widget(dai, SNDRV_PCM_STREAM_PLAYBACK)
48462306a36Sopenharmony_ci#define snd_soc_dai_get_widget_capture(dai)	snd_soc_dai_get_widget(dai, SNDRV_PCM_STREAM_CAPTURE)
48562306a36Sopenharmony_cistatic inline
48662306a36Sopenharmony_cistruct snd_soc_dapm_widget *snd_soc_dai_get_widget(struct snd_soc_dai *dai, int stream)
48762306a36Sopenharmony_ci{
48862306a36Sopenharmony_ci	return dai->stream[stream].widget;
48962306a36Sopenharmony_ci}
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_ci#define snd_soc_dai_set_widget_playback(dai, widget)	snd_soc_dai_set_widget(dai, SNDRV_PCM_STREAM_PLAYBACK, widget)
49262306a36Sopenharmony_ci#define snd_soc_dai_set_widget_capture(dai,  widget)	snd_soc_dai_set_widget(dai, SNDRV_PCM_STREAM_CAPTURE,  widget)
49362306a36Sopenharmony_cistatic inline
49462306a36Sopenharmony_civoid snd_soc_dai_set_widget(struct snd_soc_dai *dai, int stream, struct snd_soc_dapm_widget *widget)
49562306a36Sopenharmony_ci{
49662306a36Sopenharmony_ci	dai->stream[stream].widget = widget;
49762306a36Sopenharmony_ci}
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci#define snd_soc_dai_dma_data_get_playback(dai)	snd_soc_dai_dma_data_get(dai, SNDRV_PCM_STREAM_PLAYBACK)
50062306a36Sopenharmony_ci#define snd_soc_dai_dma_data_get_capture(dai)	snd_soc_dai_dma_data_get(dai, SNDRV_PCM_STREAM_CAPTURE)
50162306a36Sopenharmony_ci#define snd_soc_dai_get_dma_data(dai, ss)	snd_soc_dai_dma_data_get(dai, ss->stream)
50262306a36Sopenharmony_cistatic inline void *snd_soc_dai_dma_data_get(const struct snd_soc_dai *dai, int stream)
50362306a36Sopenharmony_ci{
50462306a36Sopenharmony_ci	return dai->stream[stream].dma_data;
50562306a36Sopenharmony_ci}
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_ci#define snd_soc_dai_dma_data_set_playback(dai, data)	snd_soc_dai_dma_data_set(dai, SNDRV_PCM_STREAM_PLAYBACK, data)
50862306a36Sopenharmony_ci#define snd_soc_dai_dma_data_set_capture(dai,  data)	snd_soc_dai_dma_data_set(dai, SNDRV_PCM_STREAM_CAPTURE,  data)
50962306a36Sopenharmony_ci#define snd_soc_dai_set_dma_data(dai, ss, data)		snd_soc_dai_dma_data_set(dai, ss->stream, data)
51062306a36Sopenharmony_cistatic inline void snd_soc_dai_dma_data_set(struct snd_soc_dai *dai, int stream, void *data)
51162306a36Sopenharmony_ci{
51262306a36Sopenharmony_ci	dai->stream[stream].dma_data = data;
51362306a36Sopenharmony_ci}
51462306a36Sopenharmony_ci
51562306a36Sopenharmony_cistatic inline void snd_soc_dai_init_dma_data(struct snd_soc_dai *dai, void *playback, void *capture)
51662306a36Sopenharmony_ci{
51762306a36Sopenharmony_ci	snd_soc_dai_dma_data_set_playback(dai, playback);
51862306a36Sopenharmony_ci	snd_soc_dai_dma_data_set_capture(dai,  capture);
51962306a36Sopenharmony_ci}
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_cistatic inline unsigned int snd_soc_dai_tdm_mask_get(struct snd_soc_dai *dai, int stream)
52262306a36Sopenharmony_ci{
52362306a36Sopenharmony_ci	return dai->stream[stream].tdm_mask;
52462306a36Sopenharmony_ci}
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_cistatic inline void snd_soc_dai_tdm_mask_set(struct snd_soc_dai *dai, int stream,
52762306a36Sopenharmony_ci					    unsigned int tdm_mask)
52862306a36Sopenharmony_ci{
52962306a36Sopenharmony_ci	dai->stream[stream].tdm_mask = tdm_mask;
53062306a36Sopenharmony_ci}
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_cistatic inline unsigned int snd_soc_dai_stream_active(struct snd_soc_dai *dai, int stream)
53362306a36Sopenharmony_ci{
53462306a36Sopenharmony_ci	/* see snd_soc_dai_action() for setup */
53562306a36Sopenharmony_ci	return dai->stream[stream].active;
53662306a36Sopenharmony_ci}
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_cistatic inline void snd_soc_dai_set_drvdata(struct snd_soc_dai *dai,
53962306a36Sopenharmony_ci		void *data)
54062306a36Sopenharmony_ci{
54162306a36Sopenharmony_ci	dev_set_drvdata(dai->dev, data);
54262306a36Sopenharmony_ci}
54362306a36Sopenharmony_ci
54462306a36Sopenharmony_cistatic inline void *snd_soc_dai_get_drvdata(struct snd_soc_dai *dai)
54562306a36Sopenharmony_ci{
54662306a36Sopenharmony_ci	return dev_get_drvdata(dai->dev);
54762306a36Sopenharmony_ci}
54862306a36Sopenharmony_ci
54962306a36Sopenharmony_ci/**
55062306a36Sopenharmony_ci * snd_soc_dai_set_stream() - Configures a DAI for stream operation
55162306a36Sopenharmony_ci * @dai: DAI
55262306a36Sopenharmony_ci * @stream: STREAM (opaque structure depending on DAI type)
55362306a36Sopenharmony_ci * @direction: Stream direction(Playback/Capture)
55462306a36Sopenharmony_ci * Some subsystems, such as SoundWire, don't have a notion of direction and we reuse
55562306a36Sopenharmony_ci * the ASoC stream direction to configure sink/source ports.
55662306a36Sopenharmony_ci * Playback maps to source ports and Capture for sink ports.
55762306a36Sopenharmony_ci *
55862306a36Sopenharmony_ci * This should be invoked with NULL to clear the stream set previously.
55962306a36Sopenharmony_ci * Returns 0 on success, a negative error code otherwise.
56062306a36Sopenharmony_ci */
56162306a36Sopenharmony_cistatic inline int snd_soc_dai_set_stream(struct snd_soc_dai *dai,
56262306a36Sopenharmony_ci					 void *stream, int direction)
56362306a36Sopenharmony_ci{
56462306a36Sopenharmony_ci	if (dai->driver->ops->set_stream)
56562306a36Sopenharmony_ci		return dai->driver->ops->set_stream(dai, stream, direction);
56662306a36Sopenharmony_ci	else
56762306a36Sopenharmony_ci		return -ENOTSUPP;
56862306a36Sopenharmony_ci}
56962306a36Sopenharmony_ci
57062306a36Sopenharmony_ci/**
57162306a36Sopenharmony_ci * snd_soc_dai_get_stream() - Retrieves stream from DAI
57262306a36Sopenharmony_ci * @dai: DAI
57362306a36Sopenharmony_ci * @direction: Stream direction(Playback/Capture)
57462306a36Sopenharmony_ci *
57562306a36Sopenharmony_ci * This routine only retrieves that was previously configured
57662306a36Sopenharmony_ci * with snd_soc_dai_get_stream()
57762306a36Sopenharmony_ci *
57862306a36Sopenharmony_ci * Returns pointer to stream or an ERR_PTR value, e.g.
57962306a36Sopenharmony_ci * ERR_PTR(-ENOTSUPP) if callback is not supported;
58062306a36Sopenharmony_ci */
58162306a36Sopenharmony_cistatic inline void *snd_soc_dai_get_stream(struct snd_soc_dai *dai,
58262306a36Sopenharmony_ci					   int direction)
58362306a36Sopenharmony_ci{
58462306a36Sopenharmony_ci	if (dai->driver->ops->get_stream)
58562306a36Sopenharmony_ci		return dai->driver->ops->get_stream(dai, direction);
58662306a36Sopenharmony_ci	else
58762306a36Sopenharmony_ci		return ERR_PTR(-ENOTSUPP);
58862306a36Sopenharmony_ci}
58962306a36Sopenharmony_ci
59062306a36Sopenharmony_ci#endif
591