0001
0002
0003
0004
0005
0006
0007
0008 #ifndef __SIMPLE_CARD_UTILS_H
0009 #define __SIMPLE_CARD_UTILS_H
0010
0011 #include <linux/clk.h>
0012 #include <sound/soc.h>
0013
0014 #define asoc_simple_init_hp(card, sjack, prefix) \
0015 asoc_simple_init_jack(card, sjack, 1, prefix, NULL)
0016 #define asoc_simple_init_mic(card, sjack, prefix) \
0017 asoc_simple_init_jack(card, sjack, 0, prefix, NULL)
0018
0019 struct asoc_simple_tdm_width_map {
0020 u8 sample_bits;
0021 u8 slot_count;
0022 u16 slot_width;
0023 };
0024
0025 struct asoc_simple_dai {
0026 const char *name;
0027 unsigned int sysclk;
0028 int clk_direction;
0029 int slots;
0030 int slot_width;
0031 unsigned int tx_slot_mask;
0032 unsigned int rx_slot_mask;
0033 struct clk *clk;
0034 bool clk_fixed;
0035 struct asoc_simple_tdm_width_map *tdm_width_map;
0036 int n_tdm_widths;
0037 };
0038
0039 struct asoc_simple_data {
0040 u32 convert_rate;
0041 u32 convert_channels;
0042 };
0043
0044 struct asoc_simple_jack {
0045 struct snd_soc_jack jack;
0046 struct snd_soc_jack_pin pin;
0047 struct snd_soc_jack_gpio gpio;
0048 };
0049
0050 struct prop_nums {
0051 int cpus;
0052 int codecs;
0053 int platforms;
0054 };
0055
0056 struct asoc_simple_priv {
0057 struct snd_soc_card snd_card;
0058 struct simple_dai_props {
0059 struct asoc_simple_dai *cpu_dai;
0060 struct asoc_simple_dai *codec_dai;
0061 struct snd_soc_dai_link_component *cpus;
0062 struct snd_soc_dai_link_component *codecs;
0063 struct snd_soc_dai_link_component *platforms;
0064 struct asoc_simple_data adata;
0065 struct snd_soc_codec_conf *codec_conf;
0066 struct prop_nums num;
0067 unsigned int mclk_fs;
0068 } *dai_props;
0069 struct asoc_simple_jack hp_jack;
0070 struct asoc_simple_jack mic_jack;
0071 struct snd_soc_dai_link *dai_link;
0072 struct asoc_simple_dai *dais;
0073 struct snd_soc_dai_link_component *dlcs;
0074 struct snd_soc_dai_link_component dummy;
0075 struct snd_soc_codec_conf *codec_conf;
0076 struct gpio_desc *pa_gpio;
0077 const struct snd_soc_ops *ops;
0078 unsigned int dpcm_selectable:1;
0079 unsigned int force_dpcm:1;
0080 };
0081 #define simple_priv_to_card(priv) (&(priv)->snd_card)
0082 #define simple_priv_to_props(priv, i) ((priv)->dai_props + (i))
0083 #define simple_priv_to_dev(priv) (simple_priv_to_card(priv)->dev)
0084 #define simple_priv_to_link(priv, i) (simple_priv_to_card(priv)->dai_link + (i))
0085
0086 #define simple_props_to_dlc_cpu(props, i) ((props)->cpus + i)
0087 #define simple_props_to_dlc_codec(props, i) ((props)->codecs + i)
0088 #define simple_props_to_dlc_platform(props, i) ((props)->platforms + i)
0089
0090 #define simple_props_to_dai_cpu(props, i) ((props)->cpu_dai + i)
0091 #define simple_props_to_dai_codec(props, i) ((props)->codec_dai + i)
0092 #define simple_props_to_codec_conf(props, i) ((props)->codec_conf + i)
0093
0094 #define for_each_prop_dlc_cpus(props, i, cpu) \
0095 for ((i) = 0; \
0096 ((i) < (props)->num.cpus) && \
0097 ((cpu) = simple_props_to_dlc_cpu(props, i)); \
0098 (i)++)
0099 #define for_each_prop_dlc_codecs(props, i, codec) \
0100 for ((i) = 0; \
0101 ((i) < (props)->num.codecs) && \
0102 ((codec) = simple_props_to_dlc_codec(props, i)); \
0103 (i)++)
0104 #define for_each_prop_dlc_platforms(props, i, platform) \
0105 for ((i) = 0; \
0106 ((i) < (props)->num.platforms) && \
0107 ((platform) = simple_props_to_dlc_platform(props, i)); \
0108 (i)++)
0109 #define for_each_prop_codec_conf(props, i, conf) \
0110 for ((i) = 0; \
0111 ((i) < (props)->num.codecs) && \
0112 (props)->codec_conf && \
0113 ((conf) = simple_props_to_codec_conf(props, i)); \
0114 (i)++)
0115
0116 #define for_each_prop_dai_cpu(props, i, cpu) \
0117 for ((i) = 0; \
0118 ((i) < (props)->num.cpus) && \
0119 ((cpu) = simple_props_to_dai_cpu(props, i)); \
0120 (i)++)
0121 #define for_each_prop_dai_codec(props, i, codec) \
0122 for ((i) = 0; \
0123 ((i) < (props)->num.codecs) && \
0124 ((codec) = simple_props_to_dai_codec(props, i)); \
0125 (i)++)
0126
0127 #define SNDRV_MAX_LINKS 512
0128
0129 struct link_info {
0130 int link;
0131 int cpu;
0132 struct prop_nums num[SNDRV_MAX_LINKS];
0133 };
0134
0135 int asoc_simple_parse_daifmt(struct device *dev,
0136 struct device_node *node,
0137 struct device_node *codec,
0138 char *prefix,
0139 unsigned int *retfmt);
0140 int asoc_simple_parse_tdm_width_map(struct device *dev, struct device_node *np,
0141 struct asoc_simple_dai *dai);
0142
0143 __printf(3, 4)
0144 int asoc_simple_set_dailink_name(struct device *dev,
0145 struct snd_soc_dai_link *dai_link,
0146 const char *fmt, ...);
0147 int asoc_simple_parse_card_name(struct snd_soc_card *card,
0148 char *prefix);
0149
0150 int asoc_simple_parse_clk(struct device *dev,
0151 struct device_node *node,
0152 struct asoc_simple_dai *simple_dai,
0153 struct snd_soc_dai_link_component *dlc);
0154 int asoc_simple_startup(struct snd_pcm_substream *substream);
0155 void asoc_simple_shutdown(struct snd_pcm_substream *substream);
0156 int asoc_simple_hw_params(struct snd_pcm_substream *substream,
0157 struct snd_pcm_hw_params *params);
0158 int asoc_simple_dai_init(struct snd_soc_pcm_runtime *rtd);
0159 int asoc_simple_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
0160 struct snd_pcm_hw_params *params);
0161
0162 #define asoc_simple_parse_tdm(np, dai) \
0163 snd_soc_of_parse_tdm_slot(np, &(dai)->tx_slot_mask, \
0164 &(dai)->rx_slot_mask, \
0165 &(dai)->slots, \
0166 &(dai)->slot_width);
0167
0168 void asoc_simple_canonicalize_platform(struct snd_soc_dai_link_component *platforms,
0169 struct snd_soc_dai_link_component *cpus);
0170 void asoc_simple_canonicalize_cpu(struct snd_soc_dai_link_component *cpus,
0171 int is_single_links);
0172
0173 void asoc_simple_clean_reference(struct snd_soc_card *card);
0174
0175 void asoc_simple_convert_fixup(struct asoc_simple_data *data,
0176 struct snd_pcm_hw_params *params);
0177 void asoc_simple_parse_convert(struct device_node *np, char *prefix,
0178 struct asoc_simple_data *data);
0179
0180 int asoc_simple_parse_routing(struct snd_soc_card *card,
0181 char *prefix);
0182 int asoc_simple_parse_widgets(struct snd_soc_card *card,
0183 char *prefix);
0184 int asoc_simple_parse_pin_switches(struct snd_soc_card *card,
0185 char *prefix);
0186
0187 int asoc_simple_init_jack(struct snd_soc_card *card,
0188 struct asoc_simple_jack *sjack,
0189 int is_hp, char *prefix, char *pin);
0190 int asoc_simple_init_priv(struct asoc_simple_priv *priv,
0191 struct link_info *li);
0192 int asoc_simple_remove(struct platform_device *pdev);
0193
0194 int asoc_graph_card_probe(struct snd_soc_card *card);
0195 int asoc_graph_is_ports0(struct device_node *port);
0196
0197 #ifdef DEBUG
0198 static inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv,
0199 char *name,
0200 struct asoc_simple_dai *dai)
0201 {
0202 struct device *dev = simple_priv_to_dev(priv);
0203
0204
0205 if (!dai)
0206 return;
0207
0208 if (dai->name)
0209 dev_dbg(dev, "%s dai name = %s\n",
0210 name, dai->name);
0211
0212 if (dai->slots)
0213 dev_dbg(dev, "%s slots = %d\n", name, dai->slots);
0214 if (dai->slot_width)
0215 dev_dbg(dev, "%s slot width = %d\n", name, dai->slot_width);
0216 if (dai->tx_slot_mask)
0217 dev_dbg(dev, "%s tx slot mask = %d\n", name, dai->tx_slot_mask);
0218 if (dai->rx_slot_mask)
0219 dev_dbg(dev, "%s rx slot mask = %d\n", name, dai->rx_slot_mask);
0220 if (dai->clk)
0221 dev_dbg(dev, "%s clk %luHz\n", name, clk_get_rate(dai->clk));
0222 if (dai->sysclk)
0223 dev_dbg(dev, "%s sysclk = %dHz\n",
0224 name, dai->sysclk);
0225 if (dai->clk || dai->sysclk)
0226 dev_dbg(dev, "%s direction = %s\n",
0227 name, dai->clk_direction ? "OUT" : "IN");
0228 }
0229
0230 static inline void asoc_simple_debug_info(struct asoc_simple_priv *priv)
0231 {
0232 struct snd_soc_card *card = simple_priv_to_card(priv);
0233 struct device *dev = simple_priv_to_dev(priv);
0234
0235 int i;
0236
0237 if (card->name)
0238 dev_dbg(dev, "Card Name: %s\n", card->name);
0239
0240 for (i = 0; i < card->num_links; i++) {
0241 struct simple_dai_props *props = simple_priv_to_props(priv, i);
0242 struct snd_soc_dai_link *link = simple_priv_to_link(priv, i);
0243 struct asoc_simple_dai *dai;
0244 struct snd_soc_codec_conf *cnf;
0245 int j;
0246
0247 dev_dbg(dev, "DAI%d\n", i);
0248
0249 dev_dbg(dev, "cpu num = %d\n", link->num_cpus);
0250 for_each_prop_dai_cpu(props, j, dai)
0251 asoc_simple_debug_dai(priv, "cpu", dai);
0252 dev_dbg(dev, "codec num = %d\n", link->num_codecs);
0253 for_each_prop_dai_codec(props, j, dai)
0254 asoc_simple_debug_dai(priv, "codec", dai);
0255
0256 if (link->name)
0257 dev_dbg(dev, "dai name = %s\n", link->name);
0258 if (link->dai_fmt)
0259 dev_dbg(dev, "dai format = %04x\n", link->dai_fmt);
0260 if (props->adata.convert_rate)
0261 dev_dbg(dev, "convert_rate = %d\n", props->adata.convert_rate);
0262 if (props->adata.convert_channels)
0263 dev_dbg(dev, "convert_channels = %d\n", props->adata.convert_channels);
0264 for_each_prop_codec_conf(props, j, cnf)
0265 if (cnf->name_prefix)
0266 dev_dbg(dev, "name prefix = %s\n", cnf->name_prefix);
0267 if (props->mclk_fs)
0268 dev_dbg(dev, "mclk-fs = %d\n", props->mclk_fs);
0269 }
0270 }
0271 #else
0272 #define asoc_simple_debug_info(priv)
0273 #endif
0274
0275 #endif