simple_card_utils.h 6.5 KB
Newer Older
1 2
/* SPDX-License-Identifier: GPL-2.0
 *
3
 * simple_card_utils.h
4 5 6
 *
 * Copyright (c) 2016 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
 */
7

8 9
#ifndef __SIMPLE_CARD_UTILS_H
#define __SIMPLE_CARD_UTILS_H
10 11 12

#include <sound/soc.h>

13 14 15 16
#define asoc_simple_init_hp(card, sjack, prefix) \
	asoc_simple_init_jack(card, sjack, 1, prefix)
#define asoc_simple_init_mic(card, sjack, prefix) \
	asoc_simple_init_jack(card, sjack, 0, prefix)
17

18 19 20
struct asoc_simple_dai {
	const char *name;
	unsigned int sysclk;
21
	int clk_direction;
22 23 24 25 26 27 28
	int slots;
	int slot_width;
	unsigned int tx_slot_mask;
	unsigned int rx_slot_mask;
	struct clk *clk;
};

29
struct asoc_simple_data {
30 31 32 33
	u32 convert_rate;
	u32 convert_channels;
};

34 35 36 37 38 39
struct asoc_simple_jack {
	struct snd_soc_jack jack;
	struct snd_soc_jack_pin pin;
	struct snd_soc_jack_gpio gpio;
};

40 41 42 43 44
struct asoc_simple_priv {
	struct snd_soc_card snd_card;
	struct simple_dai_props {
		struct asoc_simple_dai *cpu_dai;
		struct asoc_simple_dai *codec_dai;
45
		struct snd_soc_dai_link_component cpus;   /* single cpu */
46 47
		struct snd_soc_dai_link_component codecs; /* single codec */
		struct snd_soc_dai_link_component platforms;
48
		struct asoc_simple_data adata;
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
		struct snd_soc_codec_conf *codec_conf;
		unsigned int mclk_fs;
	} *dai_props;
	struct asoc_simple_jack hp_jack;
	struct asoc_simple_jack mic_jack;
	struct snd_soc_dai_link *dai_link;
	struct asoc_simple_dai *dais;
	struct snd_soc_codec_conf *codec_conf;
	struct gpio_desc *pa_gpio;
};
#define simple_priv_to_card(priv)	(&(priv)->snd_card)
#define simple_priv_to_props(priv, i)	((priv)->dai_props + (i))
#define simple_priv_to_dev(priv)	(simple_priv_to_card(priv)->dev)
#define simple_priv_to_link(priv, i)	(simple_priv_to_card(priv)->dai_link + (i))

64 65 66 67 68 69 70
struct link_info {
	int dais; /* number of dai  */
	int link; /* number of link */
	int conf; /* number of codec_conf */
	int cpu;  /* turn for CPU / Codec */
};

71 72 73 74 75
int asoc_simple_parse_daifmt(struct device *dev,
			     struct device_node *node,
			     struct device_node *codec,
			     char *prefix,
			     unsigned int *retfmt);
76
__printf(3, 4)
77 78 79 80 81 82 83
int asoc_simple_set_dailink_name(struct device *dev,
				 struct snd_soc_dai_link *dai_link,
				 const char *fmt, ...);
int asoc_simple_parse_card_name(struct snd_soc_card *card,
				char *prefix);

#define asoc_simple_parse_clk_cpu(dev, node, dai_link, simple_dai)		\
84
	asoc_simple_parse_clk(dev, node, simple_dai, dai_link->cpus)
85
#define asoc_simple_parse_clk_codec(dev, node, dai_link, simple_dai)	\
86
	asoc_simple_parse_clk(dev, node, simple_dai, dai_link->codecs)
87 88 89 90
int asoc_simple_parse_clk(struct device *dev,
			  struct device_node *node,
			  struct asoc_simple_dai *simple_dai,
			  struct snd_soc_dai_link_component *dlc);
91
int asoc_simple_startup(struct snd_pcm_substream *substream);
92
void asoc_simple_shutdown(struct snd_pcm_substream *substream);
93 94
int asoc_simple_hw_params(struct snd_pcm_substream *substream,
			  struct snd_pcm_hw_params *params);
95
int asoc_simple_dai_init(struct snd_soc_pcm_runtime *rtd);
96 97
int asoc_simple_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
				   struct snd_pcm_hw_params *params);
98

99
#define asoc_simple_parse_cpu(node, dai_link, is_single_link)	\
100
	asoc_simple_parse_dai(node, dai_link->cpus, is_single_link)
101
#define asoc_simple_parse_codec(node, dai_link)	\
102
	asoc_simple_parse_dai(node, dai_link->codecs, NULL)
103
#define asoc_simple_parse_platform(node, dai_link)	\
104
	asoc_simple_parse_dai(node, dai_link->platforms, NULL)
105

106
#define asoc_simple_parse_tdm(np, dai)			\
107 108 109 110 111
	snd_soc_of_parse_tdm_slot(np,	&(dai)->tx_slot_mask,	\
					&(dai)->rx_slot_mask,	\
					&(dai)->slots,		\
					&(dai)->slot_width);

112 113
void asoc_simple_canonicalize_platform(struct snd_soc_dai_link *dai_link);
void asoc_simple_canonicalize_cpu(struct snd_soc_dai_link *dai_link,
114
				      int is_single_links);
115

116
int asoc_simple_clean_reference(struct snd_soc_card *card);
117

118
void asoc_simple_convert_fixup(struct asoc_simple_data *data,
119
				      struct snd_pcm_hw_params *params);
120 121 122
void asoc_simple_parse_convert(struct device *dev,
			       struct device_node *np, char *prefix,
			       struct asoc_simple_data *data);
123

124
int asoc_simple_parse_routing(struct snd_soc_card *card,
125
				      char *prefix);
126
int asoc_simple_parse_widgets(struct snd_soc_card *card,
127
				      char *prefix);
128 129
int asoc_simple_parse_pin_switches(struct snd_soc_card *card,
				   char *prefix);
130

131
int asoc_simple_init_jack(struct snd_soc_card *card,
132 133
			       struct asoc_simple_jack *sjack,
			       int is_hp, char *prefix);
134
int asoc_simple_init_priv(struct asoc_simple_priv *priv,
135
			       struct link_info *li);
136 137

#ifdef DEBUG
138 139 140
static inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv,
					 char *name,
					 struct asoc_simple_dai *dai)
141 142 143
{
	struct device *dev = simple_priv_to_dev(priv);

144 145 146 147
	/* dai might be NULL */
	if (!dai)
		return;

148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
	if (dai->name)
		dev_dbg(dev, "%s dai name = %s\n",
			name, dai->name);
	if (dai->sysclk)
		dev_dbg(dev, "%s sysclk = %d\n",
			name, dai->sysclk);

	dev_dbg(dev, "%s direction = %s\n",
		name, dai->clk_direction ? "OUT" : "IN");

	if (dai->slots)
		dev_dbg(dev, "%s slots = %d\n", name, dai->slots);
	if (dai->slot_width)
		dev_dbg(dev, "%s slot width = %d\n", name, dai->slot_width);
	if (dai->tx_slot_mask)
		dev_dbg(dev, "%s tx slot mask = %d\n", name, dai->tx_slot_mask);
	if (dai->rx_slot_mask)
		dev_dbg(dev, "%s rx slot mask = %d\n", name, dai->rx_slot_mask);
	if (dai->clk)
		dev_dbg(dev, "%s clk %luHz\n", name, clk_get_rate(dai->clk));
}

170
static inline void asoc_simple_debug_info(struct asoc_simple_priv *priv)
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
{
	struct snd_soc_card *card = simple_priv_to_card(priv);
	struct device *dev = simple_priv_to_dev(priv);

	int i;

	if (card->name)
		dev_dbg(dev, "Card Name: %s\n", card->name);

	for (i = 0; i < card->num_links; i++) {
		struct simple_dai_props *props = simple_priv_to_props(priv, i);
		struct snd_soc_dai_link *link = simple_priv_to_link(priv, i);

		dev_dbg(dev, "DAI%d\n", i);

		asoc_simple_debug_dai(priv, "cpu", props->cpu_dai);
		asoc_simple_debug_dai(priv, "codec", props->codec_dai);

		if (link->name)
			dev_dbg(dev, "dai name = %s\n", link->name);

		dev_dbg(dev, "dai format = %04x\n", link->dai_fmt);

		if (props->adata.convert_rate)
			dev_dbg(dev, "convert_rate = %d\n",
				props->adata.convert_rate);
		if (props->adata.convert_channels)
			dev_dbg(dev, "convert_channels = %d\n",
				props->adata.convert_channels);
		if (props->codec_conf && props->codec_conf->name_prefix)
			dev_dbg(dev, "name prefix = %s\n",
				props->codec_conf->name_prefix);
		if (props->mclk_fs)
			dev_dbg(dev, "mclk-fs = %d\n",
				props->mclk_fs);
	}
}
#else
#define  asoc_simple_debug_info(priv)
#endif /* DEBUG */

212
#endif /* __SIMPLE_CARD_UTILS_H */