File Index
Files and directories
Sign in
FILE

simple_card_utils.h

File preview with syntax highlighting.

linux-6.19.14/include/sound/simple_card_utils.h C
  1/* SPDX-License-Identifier: GPL-2.0
  2 *
  3 * simple_card_utils.h
  4 *
  5 * Copyright (c) 2016 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
  6 */
  7
  8#ifndef __SIMPLE_CARD_UTILS_H
  9#define __SIMPLE_CARD_UTILS_H
 10
 11#include <linux/clk.h>
 12#include <sound/soc.h>
 13
 14#define simple_util_init_hp(card, sjack, prefix)		\
 15	simple_util_init_jack(card, sjack, 1, prefix, NULL)
 16#define simple_util_init_mic(card, sjack, prefix)		\
 17	simple_util_init_jack(card, sjack, 0, prefix, NULL)
 18
 19struct simple_util_tdm_width_map {
 20	u8 sample_bits;
 21	u8 slot_count;
 22	u16 slot_width;
 23};
 24
 25struct simple_util_dai {
 26	const char *name;
 27	unsigned int sysclk;
 28	int clk_direction;
 29	int slots;
 30	int slot_width;
 31	unsigned int tx_slot_mask;
 32	unsigned int rx_slot_mask;
 33	struct clk *clk;
 34	bool clk_fixed;
 35	struct simple_util_tdm_width_map *tdm_width_map;
 36	int n_tdm_widths;
 37};
 38
 39struct simple_util_data {
 40	u32 convert_rate;
 41	u32 convert_channels;
 42	const char *convert_sample_format;
 43};
 44
 45struct simple_util_jack {
 46	struct snd_soc_jack jack;
 47	struct snd_soc_jack_pin pin;
 48	struct snd_soc_jack_gpio gpio;
 49};
 50
 51struct prop_nums {
 52	int cpus;
 53	int codecs;
 54	int platforms;
 55};
 56
 57struct simple_util_priv {
 58	struct snd_soc_card snd_card;
 59	struct simple_dai_props {
 60		struct simple_util_dai *cpu_dai;
 61		struct simple_util_dai *codec_dai;
 62		struct simple_util_data adata;
 63		struct snd_soc_codec_conf *codec_conf;
 64		struct prop_nums num;
 65		unsigned int mclk_fs;
 66	} *dai_props;
 67	struct simple_util_jack hp_jack;
 68	struct simple_util_jack mic_jack;
 69	struct snd_soc_jack *aux_jacks;
 70	struct snd_soc_dai_link *dai_link;
 71	struct simple_util_dai *dais;
 72	struct snd_soc_dai_link_component *dlcs;
 73	struct snd_soc_codec_conf *codec_conf;
 74	struct gpio_desc *pa_gpio;
 75	const struct snd_soc_ops *ops;
 76	unsigned int dpcm_selectable:1;
 77	unsigned int force_dpcm:1;
 78};
 79#define simple_priv_to_card(priv)	(&(priv)->snd_card)
 80#define simple_priv_to_props(priv, i)	((priv)->dai_props + (i))
 81#define simple_priv_to_dev(priv)	(simple_priv_to_card(priv)->dev)
 82#define simple_priv_to_link(priv, i)	(simple_priv_to_card(priv)->dai_link + (i))
 83
 84#define simple_props_to_dlc_cpu(props, i)	((props)->cpus + i)
 85#define simple_props_to_dlc_codec(props, i)	((props)->codecs + i)
 86#define simple_props_to_dlc_platform(props, i)	((props)->platforms + i)
 87
 88#define simple_props_to_dai_cpu(props, i)	((props)->cpu_dai + i)
 89#define simple_props_to_dai_codec(props, i)	((props)->codec_dai + i)
 90#define simple_props_to_codec_conf(props, i)	((props)->codec_conf + i)
 91
 92/* has the same effect as simple_priv_to_props(). Preferred over
 93 * simple_priv_to_props() when dealing with PCM runtime data as
 94 * the ID stored in rtd->id may not be a valid array index.
 95 */
 96#define runtime_simple_priv_to_props(priv, rtd)				\
 97	((priv)->dai_props + ((rtd)->dai_link - (priv)->dai_link))
 98
 99#define for_each_prop_dlc_cpus(props, i, cpu)				\
100	for ((i) = 0;							\
101	     ((i) < (props)->num.cpus) &&				\
102		     ((cpu) = simple_props_to_dlc_cpu(props, i));	\
103	     (i)++)
104#define for_each_prop_dlc_codecs(props, i, codec)			\
105	for ((i) = 0;							\
106	     ((i) < (props)->num.codecs) &&				\
107		     ((codec) = simple_props_to_dlc_codec(props, i));	\
108	     (i)++)
109#define for_each_prop_dlc_platforms(props, i, platform)			\
110	for ((i) = 0;							\
111	     ((i) < (props)->num.platforms) &&				\
112		     ((platform) = simple_props_to_dlc_platform(props, i)); \
113	     (i)++)
114#define for_each_prop_codec_conf(props, i, conf)			\
115	for ((i) = 0;							\
116	     ((i) < (props)->num.codecs) &&				\
117		     (props)->codec_conf &&				\
118		     ((conf) = simple_props_to_codec_conf(props, i));	\
119	     (i)++)
120
121#define for_each_prop_dai_cpu(props, i, cpu)				\
122	for ((i) = 0;							\
123	     ((i) < (props)->num.cpus) &&				\
124		     ((cpu) = simple_props_to_dai_cpu(props, i));	\
125	     (i)++)
126#define for_each_prop_dai_codec(props, i, codec)			\
127	for ((i) = 0;							\
128	     ((i) < (props)->num.codecs) &&				\
129		     ((codec) = simple_props_to_dai_codec(props, i));	\
130	     (i)++)
131
132#define SNDRV_MAX_LINKS 512
133
134struct link_info {
135	int link; /* number of link */
136	int cpu;  /* turn for CPU / Codec */
137	struct prop_nums num[SNDRV_MAX_LINKS];
138};
139
140int simple_util_parse_daifmt(struct device *dev,
141			     struct device_node *node,
142			     struct device_node *codec,
143			     char *prefix,
144			     unsigned int *retfmt);
145int simple_util_parse_tdm_width_map(struct simple_util_priv *priv, struct device_node *np,
146				    struct simple_util_dai *dai);
147
148__printf(3, 4)
149int simple_util_set_dailink_name(struct simple_util_priv *priv,
150				 struct snd_soc_dai_link *dai_link,
151				 const char *fmt, ...);
152int simple_util_parse_card_name(struct simple_util_priv *priv,
153				char *prefix);
154
155int simple_util_parse_clk(struct device *dev,
156			  struct device_node *node,
157			  struct simple_util_dai *simple_dai,
158			  struct snd_soc_dai_link_component *dlc);
159int simple_util_startup(struct snd_pcm_substream *substream);
160void simple_util_shutdown(struct snd_pcm_substream *substream);
161int simple_util_hw_params(struct snd_pcm_substream *substream,
162			  struct snd_pcm_hw_params *params);
163int simple_util_dai_init(struct snd_soc_pcm_runtime *rtd);
164int simple_util_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
165				   struct snd_pcm_hw_params *params);
166
167#define simple_util_parse_tdm(np, dai)				\
168	snd_soc_of_parse_tdm_slot(np,	&(dai)->tx_slot_mask,	\
169					&(dai)->rx_slot_mask,	\
170					&(dai)->slots,		\
171					&(dai)->slot_width);
172
173void simple_util_canonicalize_platform(struct snd_soc_dai_link_component *platforms,
174				       struct snd_soc_dai_link_component *cpus);
175void simple_util_canonicalize_cpu(struct snd_soc_dai_link_component *cpus,
176				  int is_single_links);
177
178void simple_util_clean_reference(struct snd_soc_card *card);
179
180void simple_util_parse_convert(struct device_node *np, char *prefix,
181			       struct simple_util_data *data);
182bool simple_util_is_convert_required(const struct simple_util_data *data);
183
184int simple_util_get_sample_fmt(struct simple_util_data *data);
185
186int simple_util_parse_routing(struct snd_soc_card *card,
187				      char *prefix);
188int simple_util_parse_widgets(struct snd_soc_card *card,
189				      char *prefix);
190int simple_util_parse_pin_switches(struct snd_soc_card *card,
191				   char *prefix);
192
193int simple_util_init_jack(struct snd_soc_card *card,
194			       struct simple_util_jack *sjack,
195			       int is_hp, char *prefix, char *pin);
196int simple_util_init_aux_jacks(struct simple_util_priv *priv,
197				char *prefix);
198int simple_util_init_priv(struct simple_util_priv *priv,
199			       struct link_info *li);
200void simple_util_remove(struct platform_device *pdev);
201
202int graph_util_card_probe(struct snd_soc_card *card);
203int graph_util_is_ports0(struct device_node *port);
204int graph_util_parse_dai(struct simple_util_priv *priv, struct device_node *ep,
205			 struct snd_soc_dai_link_component *dlc, int *is_single_link);
206
207void graph_util_parse_link_direction(struct device_node *np,
208				    bool *is_playback_only, bool *is_capture_only);
209void graph_util_parse_trigger_order(struct simple_util_priv *priv,
210				    struct device_node *np,
211				    enum snd_soc_trigger_order *trigger_start,
212				    enum snd_soc_trigger_order *trigger_stop);
213
214#ifdef DEBUG
215static inline void simple_util_debug_dai(struct simple_util_priv *priv,
216					 char *name,
217					 struct simple_util_dai *dai)
218{
219	struct device *dev = simple_priv_to_dev(priv);
220
221	/* dai might be NULL */
222	if (!dai)
223		return;
224
225	if (dai->name)
226		dev_dbg(dev, "%s dai name = %s\n",
227			name, dai->name);
228
229	if (dai->slots)
230		dev_dbg(dev, "%s slots = %d\n", name, dai->slots);
231	if (dai->slot_width)
232		dev_dbg(dev, "%s slot width = %d\n", name, dai->slot_width);
233	if (dai->tx_slot_mask)
234		dev_dbg(dev, "%s tx slot mask = %d\n", name, dai->tx_slot_mask);
235	if (dai->rx_slot_mask)
236		dev_dbg(dev, "%s rx slot mask = %d\n", name, dai->rx_slot_mask);
237	if (dai->clk)
238		dev_dbg(dev, "%s clk %luHz\n", name, clk_get_rate(dai->clk));
239	if (dai->sysclk)
240		dev_dbg(dev, "%s sysclk = %dHz\n",
241			name, dai->sysclk);
242	if (dai->clk || dai->sysclk)
243		dev_dbg(dev, "%s direction = %s\n",
244			name, dai->clk_direction ? "OUT" : "IN");
245}
246
247static inline void simple_util_debug_info(struct simple_util_priv *priv)
248{
249	struct snd_soc_card *card = simple_priv_to_card(priv);
250	struct device *dev = simple_priv_to_dev(priv);
251
252	int i;
253
254	if (card->name)
255		dev_dbg(dev, "Card Name: %s\n", card->name);
256
257	for (i = 0; i < card->num_links; i++) {
258		struct simple_dai_props *props = simple_priv_to_props(priv, i);
259		struct snd_soc_dai_link *link = simple_priv_to_link(priv, i);
260		struct simple_util_dai *dai;
261		struct snd_soc_codec_conf *cnf;
262		int j;
263
264		dev_dbg(dev, "DAI%d\n", i);
265
266		dev_dbg(dev, "cpu num = %d\n", link->num_cpus);
267		for_each_prop_dai_cpu(props, j, dai)
268			simple_util_debug_dai(priv, "cpu", dai);
269		dev_dbg(dev, "codec num = %d\n", link->num_codecs);
270		for_each_prop_dai_codec(props, j, dai)
271			simple_util_debug_dai(priv, "codec", dai);
272
273		if (link->name)
274			dev_dbg(dev, "link name = %s\n", link->name);
275		if (link->dai_fmt)
276			dev_dbg(dev, "link format = %04x\n", link->dai_fmt);
277		if (link->playback_only)
278			dev_dbg(dev, "link has playback_only");
279		if (link->capture_only)
280			dev_dbg(dev, "link has capture_only");
281		if (props->adata.convert_rate)
282			dev_dbg(dev, "convert_rate = %d\n", props->adata.convert_rate);
283		if (props->adata.convert_channels)
284			dev_dbg(dev, "convert_channels = %d\n", props->adata.convert_channels);
285		for_each_prop_codec_conf(props, j, cnf)
286			if (cnf->name_prefix)
287				dev_dbg(dev, "name prefix = %s\n", cnf->name_prefix);
288		if (props->mclk_fs)
289			dev_dbg(dev, "mclk-fs = %d\n", props->mclk_fs);
290	}
291}
292#else
293#define  simple_util_debug_info(priv)
294#endif /* DEBUG */
295
296#endif /* __SIMPLE_CARD_UTILS_H */
~/ Read-only file preview.