| .. | .. |
|---|
| 57 | 57 | static int mt8173_rt5650_hw_params(struct snd_pcm_substream *substream, |
|---|
| 58 | 58 | struct snd_pcm_hw_params *params) |
|---|
| 59 | 59 | { |
|---|
| 60 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
|---|
| 60 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
|---|
| 61 | 61 | unsigned int mclk_clock; |
|---|
| 62 | + struct snd_soc_dai *codec_dai; |
|---|
| 62 | 63 | int i, ret; |
|---|
| 63 | 64 | |
|---|
| 64 | 65 | switch (mt8173_rt5650_priv.pll_from) { |
|---|
| .. | .. |
|---|
| 76 | 77 | break; |
|---|
| 77 | 78 | } |
|---|
| 78 | 79 | |
|---|
| 79 | | - for (i = 0; i < rtd->num_codecs; i++) { |
|---|
| 80 | | - struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; |
|---|
| 81 | | - |
|---|
| 80 | + for_each_rtd_codec_dais(rtd, i, codec_dai) { |
|---|
| 82 | 81 | /* pll from mclk */ |
|---|
| 83 | 82 | ret = snd_soc_dai_set_pll(codec_dai, 0, 0, mclk_clock, |
|---|
| 84 | 83 | params_rate(params) * 512); |
|---|
| .. | .. |
|---|
| 99 | 98 | .hw_params = mt8173_rt5650_hw_params, |
|---|
| 100 | 99 | }; |
|---|
| 101 | 100 | |
|---|
| 102 | | -static struct snd_soc_jack mt8173_rt5650_jack; |
|---|
| 101 | +static struct snd_soc_jack mt8173_rt5650_jack, mt8173_rt5650_hdmi_jack; |
|---|
| 103 | 102 | |
|---|
| 104 | 103 | static int mt8173_rt5650_init(struct snd_soc_pcm_runtime *runtime) |
|---|
| 105 | 104 | { |
|---|
| 106 | 105 | struct snd_soc_card *card = runtime->card; |
|---|
| 107 | | - struct snd_soc_component *component = runtime->codec_dais[0]->component; |
|---|
| 108 | | - const char *codec_capture_dai = runtime->codec_dais[1]->name; |
|---|
| 106 | + struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; |
|---|
| 107 | + const char *codec_capture_dai = asoc_rtd_to_codec(runtime, 1)->name; |
|---|
| 109 | 108 | int ret; |
|---|
| 110 | 109 | |
|---|
| 111 | 110 | rt5645_sel_asrc_clk_src(component, |
|---|
| .. | .. |
|---|
| 145 | 144 | &mt8173_rt5650_jack); |
|---|
| 146 | 145 | } |
|---|
| 147 | 146 | |
|---|
| 148 | | -static struct snd_soc_dai_link_component mt8173_rt5650_codecs[] = { |
|---|
| 149 | | - { |
|---|
| 150 | | - /* Playback */ |
|---|
| 151 | | - .dai_name = "rt5645-aif1", |
|---|
| 152 | | - }, |
|---|
| 153 | | - { |
|---|
| 154 | | - /* Capture */ |
|---|
| 155 | | - .dai_name = "rt5645-aif1", |
|---|
| 156 | | - }, |
|---|
| 157 | | -}; |
|---|
| 147 | +static int mt8173_rt5650_hdmi_init(struct snd_soc_pcm_runtime *rtd) |
|---|
| 148 | +{ |
|---|
| 149 | + int ret; |
|---|
| 150 | + |
|---|
| 151 | + ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, |
|---|
| 152 | + &mt8173_rt5650_hdmi_jack, NULL, 0); |
|---|
| 153 | + if (ret) |
|---|
| 154 | + return ret; |
|---|
| 155 | + |
|---|
| 156 | + return snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component, |
|---|
| 157 | + &mt8173_rt5650_hdmi_jack, NULL); |
|---|
| 158 | +} |
|---|
| 158 | 159 | |
|---|
| 159 | 160 | enum { |
|---|
| 160 | 161 | DAI_LINK_PLAYBACK, |
|---|
| .. | .. |
|---|
| 164 | 165 | DAI_LINK_HDMI_I2S, |
|---|
| 165 | 166 | }; |
|---|
| 166 | 167 | |
|---|
| 168 | +SND_SOC_DAILINK_DEFS(playback, |
|---|
| 169 | + DAILINK_COMP_ARRAY(COMP_CPU("DL1")), |
|---|
| 170 | + DAILINK_COMP_ARRAY(COMP_DUMMY()), |
|---|
| 171 | + DAILINK_COMP_ARRAY(COMP_EMPTY())); |
|---|
| 172 | + |
|---|
| 173 | +SND_SOC_DAILINK_DEFS(capture, |
|---|
| 174 | + DAILINK_COMP_ARRAY(COMP_CPU("VUL")), |
|---|
| 175 | + DAILINK_COMP_ARRAY(COMP_DUMMY()), |
|---|
| 176 | + DAILINK_COMP_ARRAY(COMP_EMPTY())); |
|---|
| 177 | + |
|---|
| 178 | +SND_SOC_DAILINK_DEFS(hdmi_pcm, |
|---|
| 179 | + DAILINK_COMP_ARRAY(COMP_CPU("HDMI")), |
|---|
| 180 | + DAILINK_COMP_ARRAY(COMP_DUMMY()), |
|---|
| 181 | + DAILINK_COMP_ARRAY(COMP_EMPTY())); |
|---|
| 182 | + |
|---|
| 183 | +SND_SOC_DAILINK_DEFS(codec, |
|---|
| 184 | + DAILINK_COMP_ARRAY(COMP_CPU("I2S")), |
|---|
| 185 | + DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "rt5645-aif1"), /* Playback */ |
|---|
| 186 | + COMP_CODEC(NULL, "rt5645-aif1")),/* Capture */ |
|---|
| 187 | + DAILINK_COMP_ARRAY(COMP_EMPTY())); |
|---|
| 188 | + |
|---|
| 189 | +SND_SOC_DAILINK_DEFS(hdmi_be, |
|---|
| 190 | + DAILINK_COMP_ARRAY(COMP_CPU("HDMIO")), |
|---|
| 191 | + DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "i2s-hifi")), |
|---|
| 192 | + DAILINK_COMP_ARRAY(COMP_EMPTY())); |
|---|
| 193 | + |
|---|
| 167 | 194 | /* Digital audio interface glue - connects codec <---> CPU */ |
|---|
| 168 | 195 | static struct snd_soc_dai_link mt8173_rt5650_dais[] = { |
|---|
| 169 | 196 | /* Front End DAI links */ |
|---|
| 170 | 197 | [DAI_LINK_PLAYBACK] = { |
|---|
| 171 | 198 | .name = "rt5650 Playback", |
|---|
| 172 | 199 | .stream_name = "rt5650 Playback", |
|---|
| 173 | | - .cpu_dai_name = "DL1", |
|---|
| 174 | | - .codec_name = "snd-soc-dummy", |
|---|
| 175 | | - .codec_dai_name = "snd-soc-dummy-dai", |
|---|
| 176 | 200 | .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, |
|---|
| 177 | 201 | .dynamic = 1, |
|---|
| 178 | 202 | .dpcm_playback = 1, |
|---|
| 203 | + SND_SOC_DAILINK_REG(playback), |
|---|
| 179 | 204 | }, |
|---|
| 180 | 205 | [DAI_LINK_CAPTURE] = { |
|---|
| 181 | 206 | .name = "rt5650 Capture", |
|---|
| 182 | 207 | .stream_name = "rt5650 Capture", |
|---|
| 183 | | - .cpu_dai_name = "VUL", |
|---|
| 184 | | - .codec_name = "snd-soc-dummy", |
|---|
| 185 | | - .codec_dai_name = "snd-soc-dummy-dai", |
|---|
| 186 | 208 | .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, |
|---|
| 187 | 209 | .dynamic = 1, |
|---|
| 188 | 210 | .dpcm_capture = 1, |
|---|
| 211 | + SND_SOC_DAILINK_REG(capture), |
|---|
| 189 | 212 | }, |
|---|
| 190 | 213 | [DAI_LINK_HDMI] = { |
|---|
| 191 | 214 | .name = "HDMI", |
|---|
| 192 | 215 | .stream_name = "HDMI PCM", |
|---|
| 193 | | - .cpu_dai_name = "HDMI", |
|---|
| 194 | | - .codec_name = "snd-soc-dummy", |
|---|
| 195 | | - .codec_dai_name = "snd-soc-dummy-dai", |
|---|
| 196 | 216 | .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, |
|---|
| 197 | 217 | .dynamic = 1, |
|---|
| 198 | 218 | .dpcm_playback = 1, |
|---|
| 219 | + SND_SOC_DAILINK_REG(hdmi_pcm), |
|---|
| 199 | 220 | }, |
|---|
| 200 | 221 | /* Back End DAI links */ |
|---|
| 201 | 222 | [DAI_LINK_CODEC_I2S] = { |
|---|
| 202 | 223 | .name = "Codec", |
|---|
| 203 | | - .cpu_dai_name = "I2S", |
|---|
| 204 | 224 | .no_pcm = 1, |
|---|
| 205 | | - .codecs = mt8173_rt5650_codecs, |
|---|
| 206 | | - .num_codecs = 2, |
|---|
| 207 | 225 | .init = mt8173_rt5650_init, |
|---|
| 208 | 226 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
|---|
| 209 | 227 | SND_SOC_DAIFMT_CBS_CFS, |
|---|
| .. | .. |
|---|
| 211 | 229 | .ignore_pmdown_time = 1, |
|---|
| 212 | 230 | .dpcm_playback = 1, |
|---|
| 213 | 231 | .dpcm_capture = 1, |
|---|
| 232 | + SND_SOC_DAILINK_REG(codec), |
|---|
| 214 | 233 | }, |
|---|
| 215 | 234 | [DAI_LINK_HDMI_I2S] = { |
|---|
| 216 | 235 | .name = "HDMI BE", |
|---|
| 217 | | - .cpu_dai_name = "HDMIO", |
|---|
| 218 | 236 | .no_pcm = 1, |
|---|
| 219 | | - .codec_dai_name = "i2s-hifi", |
|---|
| 220 | 237 | .dpcm_playback = 1, |
|---|
| 238 | + .init = mt8173_rt5650_hdmi_init, |
|---|
| 239 | + SND_SOC_DAILINK_REG(hdmi_be), |
|---|
| 221 | 240 | }, |
|---|
| 222 | 241 | }; |
|---|
| 223 | 242 | |
|---|
| .. | .. |
|---|
| 240 | 259 | struct device_node *platform_node; |
|---|
| 241 | 260 | struct device_node *np; |
|---|
| 242 | 261 | const char *codec_capture_dai; |
|---|
| 262 | + struct snd_soc_dai_link *dai_link; |
|---|
| 243 | 263 | int i, ret; |
|---|
| 244 | 264 | |
|---|
| 245 | 265 | platform_node = of_parse_phandle(pdev->dev.of_node, |
|---|
| .. | .. |
|---|
| 249 | 269 | return -EINVAL; |
|---|
| 250 | 270 | } |
|---|
| 251 | 271 | |
|---|
| 252 | | - for (i = 0; i < card->num_links; i++) { |
|---|
| 253 | | - if (mt8173_rt5650_dais[i].platform_name) |
|---|
| 272 | + for_each_card_prelinks(card, i, dai_link) { |
|---|
| 273 | + if (dai_link->platforms->name) |
|---|
| 254 | 274 | continue; |
|---|
| 255 | | - mt8173_rt5650_dais[i].platform_of_node = platform_node; |
|---|
| 275 | + dai_link->platforms->of_node = platform_node; |
|---|
| 256 | 276 | } |
|---|
| 257 | 277 | |
|---|
| 258 | | - mt8173_rt5650_codecs[0].of_node = |
|---|
| 278 | + mt8173_rt5650_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node = |
|---|
| 259 | 279 | of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 0); |
|---|
| 260 | | - if (!mt8173_rt5650_codecs[0].of_node) { |
|---|
| 280 | + if (!mt8173_rt5650_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node) { |
|---|
| 261 | 281 | dev_err(&pdev->dev, |
|---|
| 262 | 282 | "Property 'audio-codec' missing or invalid\n"); |
|---|
| 263 | | - return -EINVAL; |
|---|
| 283 | + ret = -EINVAL; |
|---|
| 284 | + goto put_platform_node; |
|---|
| 264 | 285 | } |
|---|
| 265 | | - mt8173_rt5650_codecs[1].of_node = mt8173_rt5650_codecs[0].of_node; |
|---|
| 286 | + mt8173_rt5650_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node = |
|---|
| 287 | + mt8173_rt5650_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node; |
|---|
| 266 | 288 | |
|---|
| 267 | 289 | np = of_get_child_by_name(pdev->dev.of_node, "codec-capture"); |
|---|
| 268 | 290 | if (np) { |
|---|
| .. | .. |
|---|
| 272 | 294 | dev_err(&pdev->dev, |
|---|
| 273 | 295 | "%s codec_capture_dai name fail %d\n", |
|---|
| 274 | 296 | __func__, ret); |
|---|
| 275 | | - return ret; |
|---|
| 297 | + goto put_platform_node; |
|---|
| 276 | 298 | } |
|---|
| 277 | | - mt8173_rt5650_codecs[1].dai_name = codec_capture_dai; |
|---|
| 299 | + mt8173_rt5650_dais[DAI_LINK_CODEC_I2S].codecs[1].dai_name = |
|---|
| 300 | + codec_capture_dai; |
|---|
| 278 | 301 | } |
|---|
| 279 | 302 | |
|---|
| 280 | 303 | if (device_property_present(&pdev->dev, "mediatek,mclk")) { |
|---|
| .. | .. |
|---|
| 288 | 311 | } |
|---|
| 289 | 312 | } |
|---|
| 290 | 313 | |
|---|
| 291 | | - mt8173_rt5650_dais[DAI_LINK_HDMI_I2S].codec_of_node = |
|---|
| 314 | + mt8173_rt5650_dais[DAI_LINK_HDMI_I2S].codecs->of_node = |
|---|
| 292 | 315 | of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 1); |
|---|
| 293 | | - if (!mt8173_rt5650_dais[DAI_LINK_HDMI_I2S].codec_of_node) { |
|---|
| 316 | + if (!mt8173_rt5650_dais[DAI_LINK_HDMI_I2S].codecs->of_node) { |
|---|
| 294 | 317 | dev_err(&pdev->dev, |
|---|
| 295 | 318 | "Property 'audio-codec' missing or invalid\n"); |
|---|
| 296 | | - return -EINVAL; |
|---|
| 319 | + ret = -EINVAL; |
|---|
| 320 | + goto put_platform_node; |
|---|
| 297 | 321 | } |
|---|
| 298 | 322 | card->dev = &pdev->dev; |
|---|
| 299 | 323 | |
|---|
| .. | .. |
|---|
| 302 | 326 | dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", |
|---|
| 303 | 327 | __func__, ret); |
|---|
| 304 | 328 | |
|---|
| 329 | +put_platform_node: |
|---|
| 305 | 330 | of_node_put(platform_node); |
|---|
| 306 | 331 | return ret; |
|---|
| 307 | 332 | } |
|---|