894 lines · c
1// SPDX-License-Identifier: GPL-2.02//3// mt8183-da7219-max98357.c4// -- MT8183-DA7219-MAX98357 ALSA SoC machine driver5//6// Copyright (c) 2018 MediaTek Inc.7// Author: Shunli Wang <shunli.wang@mediatek.com>8 9#include <linux/input.h>10#include <linux/module.h>11#include <linux/of.h>12#include <linux/pinctrl/consumer.h>13#include <sound/jack.h>14#include <sound/pcm_params.h>15#include <sound/soc.h>16 17#include "../../codecs/da7219.h"18#include "../../codecs/rt1015.h"19#include "../common/mtk-afe-platform-driver.h"20#include "mt8183-afe-common.h"21 22#define DA7219_CODEC_DAI "da7219-hifi"23#define DA7219_DEV_NAME "da7219.5-001a"24#define RT1015_CODEC_DAI "rt1015-aif"25#define RT1015_DEV0_NAME "rt1015.6-0028"26#define RT1015_DEV1_NAME "rt1015.6-0029"27 28struct mt8183_da7219_max98357_priv {29 struct snd_soc_jack headset_jack, hdmi_jack;30};31 32static struct snd_soc_jack_pin mt8183_da7219_max98357_jack_pins[] = {33 {34 .pin = "Headphones",35 .mask = SND_JACK_HEADPHONE,36 },37 {38 .pin = "Headset Mic",39 .mask = SND_JACK_MICROPHONE,40 },41 {42 .pin = "Line Out",43 .mask = SND_JACK_LINEOUT,44 },45};46 47static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream,48 struct snd_pcm_hw_params *params)49{50 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);51 unsigned int rate = params_rate(params);52 unsigned int mclk_fs_ratio = 128;53 unsigned int mclk_fs = rate * mclk_fs_ratio;54 55 return snd_soc_dai_set_sysclk(snd_soc_rtd_to_cpu(rtd, 0),56 0, mclk_fs, SND_SOC_CLOCK_OUT);57}58 59static const struct snd_soc_ops mt8183_mt6358_i2s_ops = {60 .hw_params = mt8183_mt6358_i2s_hw_params,61};62 63static int mt8183_da7219_i2s_hw_params(struct snd_pcm_substream *substream,64 struct snd_pcm_hw_params *params)65{66 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);67 struct snd_soc_dai *codec_dai;68 unsigned int rate = params_rate(params);69 unsigned int mclk_fs_ratio = 256;70 unsigned int mclk_fs = rate * mclk_fs_ratio;71 unsigned int freq;72 int ret = 0, j;73 74 ret = snd_soc_dai_set_sysclk(snd_soc_rtd_to_cpu(rtd, 0), 0,75 mclk_fs, SND_SOC_CLOCK_OUT);76 if (ret < 0)77 dev_err(rtd->dev, "failed to set cpu dai sysclk\n");78 79 for_each_rtd_codec_dais(rtd, j, codec_dai) {80 if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {81 ret = snd_soc_dai_set_sysclk(codec_dai,82 DA7219_CLKSRC_MCLK,83 mclk_fs,84 SND_SOC_CLOCK_IN);85 if (ret < 0)86 dev_err(rtd->dev, "failed to set sysclk\n");87 88 if ((rate % 8000) == 0)89 freq = DA7219_PLL_FREQ_OUT_98304;90 else91 freq = DA7219_PLL_FREQ_OUT_90316;92 93 ret = snd_soc_dai_set_pll(codec_dai, 0,94 DA7219_SYSCLK_PLL_SRM,95 0, freq);96 if (ret)97 dev_err(rtd->dev, "failed to start PLL: %d\n",98 ret);99 }100 }101 102 return ret;103}104 105static int mt8183_da7219_hw_free(struct snd_pcm_substream *substream)106{107 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);108 struct snd_soc_dai *codec_dai;109 int ret = 0, j;110 111 for_each_rtd_codec_dais(rtd, j, codec_dai) {112 if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {113 ret = snd_soc_dai_set_pll(codec_dai,114 0, DA7219_SYSCLK_MCLK, 0, 0);115 if (ret < 0) {116 dev_err(rtd->dev, "failed to stop PLL: %d\n",117 ret);118 break;119 }120 }121 }122 123 return ret;124}125 126static const struct snd_soc_ops mt8183_da7219_i2s_ops = {127 .hw_params = mt8183_da7219_i2s_hw_params,128 .hw_free = mt8183_da7219_hw_free,129};130 131static int132mt8183_da7219_rt1015_i2s_hw_params(struct snd_pcm_substream *substream,133 struct snd_pcm_hw_params *params)134{135 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);136 unsigned int rate = params_rate(params);137 struct snd_soc_dai *codec_dai;138 int ret = 0, i;139 140 for_each_rtd_codec_dais(rtd, i, codec_dai) {141 if (!strcmp(codec_dai->component->name, RT1015_DEV0_NAME) ||142 !strcmp(codec_dai->component->name, RT1015_DEV1_NAME)) {143 ret = snd_soc_dai_set_pll(codec_dai, 0,144 RT1015_PLL_S_BCLK,145 rate * 64, rate * 256);146 if (ret) {147 dev_err(rtd->dev, "failed to set pll\n");148 return ret;149 }150 151 ret = snd_soc_dai_set_sysclk(codec_dai,152 RT1015_SCLK_S_PLL,153 rate * 256,154 SND_SOC_CLOCK_IN);155 if (ret) {156 dev_err(rtd->dev, "failed to set sysclk\n");157 return ret;158 }159 }160 }161 162 return mt8183_da7219_i2s_hw_params(substream, params);163}164 165static const struct snd_soc_ops mt8183_da7219_rt1015_i2s_ops = {166 .hw_params = mt8183_da7219_rt1015_i2s_hw_params,167 .hw_free = mt8183_da7219_hw_free,168};169 170static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,171 struct snd_pcm_hw_params *params)172{173 /* fix BE i2s format to S32_LE, clean param mask first */174 snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),175 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);176 177 params_set_format(params, SNDRV_PCM_FORMAT_S32_LE);178 179 return 0;180}181 182static int mt8183_rt1015_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,183 struct snd_pcm_hw_params *params)184{185 /* fix BE i2s format to S24_LE, clean param mask first */186 snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),187 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);188 189 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);190 191 return 0;192}193 194static int195mt8183_da7219_max98357_startup(196 struct snd_pcm_substream *substream)197{198 static const unsigned int rates[] = {199 48000,200 };201 static const struct snd_pcm_hw_constraint_list constraints_rates = {202 .count = ARRAY_SIZE(rates),203 .list = rates,204 .mask = 0,205 };206 static const unsigned int channels[] = {207 2,208 };209 static const struct snd_pcm_hw_constraint_list constraints_channels = {210 .count = ARRAY_SIZE(channels),211 .list = channels,212 .mask = 0,213 };214 215 struct snd_pcm_runtime *runtime = substream->runtime;216 217 snd_pcm_hw_constraint_list(runtime, 0,218 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);219 runtime->hw.channels_max = 2;220 snd_pcm_hw_constraint_list(runtime, 0,221 SNDRV_PCM_HW_PARAM_CHANNELS,222 &constraints_channels);223 224 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;225 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);226 227 return 0;228}229 230static const struct snd_soc_ops mt8183_da7219_max98357_ops = {231 .startup = mt8183_da7219_max98357_startup,232};233 234static int235mt8183_da7219_max98357_bt_sco_startup(236 struct snd_pcm_substream *substream)237{238 static const unsigned int rates[] = {239 8000, 16000240 };241 static const struct snd_pcm_hw_constraint_list constraints_rates = {242 .count = ARRAY_SIZE(rates),243 .list = rates,244 .mask = 0,245 };246 static const unsigned int channels[] = {247 1,248 };249 static const struct snd_pcm_hw_constraint_list constraints_channels = {250 .count = ARRAY_SIZE(channels),251 .list = channels,252 .mask = 0,253 };254 255 struct snd_pcm_runtime *runtime = substream->runtime;256 257 snd_pcm_hw_constraint_list(runtime, 0,258 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);259 runtime->hw.channels_max = 1;260 snd_pcm_hw_constraint_list(runtime, 0,261 SNDRV_PCM_HW_PARAM_CHANNELS,262 &constraints_channels);263 264 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;265 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);266 267 return 0;268}269 270static const struct snd_soc_ops mt8183_da7219_max98357_bt_sco_ops = {271 .startup = mt8183_da7219_max98357_bt_sco_startup,272};273 274/* FE */275SND_SOC_DAILINK_DEFS(playback1,276 DAILINK_COMP_ARRAY(COMP_CPU("DL1")),277 DAILINK_COMP_ARRAY(COMP_DUMMY()),278 DAILINK_COMP_ARRAY(COMP_EMPTY()));279 280SND_SOC_DAILINK_DEFS(playback2,281 DAILINK_COMP_ARRAY(COMP_CPU("DL2")),282 DAILINK_COMP_ARRAY(COMP_DUMMY()),283 DAILINK_COMP_ARRAY(COMP_EMPTY()));284 285SND_SOC_DAILINK_DEFS(playback3,286 DAILINK_COMP_ARRAY(COMP_CPU("DL3")),287 DAILINK_COMP_ARRAY(COMP_DUMMY()),288 DAILINK_COMP_ARRAY(COMP_EMPTY()));289 290SND_SOC_DAILINK_DEFS(capture1,291 DAILINK_COMP_ARRAY(COMP_CPU("UL1")),292 DAILINK_COMP_ARRAY(COMP_DUMMY()),293 DAILINK_COMP_ARRAY(COMP_EMPTY()));294 295SND_SOC_DAILINK_DEFS(capture2,296 DAILINK_COMP_ARRAY(COMP_CPU("UL2")),297 DAILINK_COMP_ARRAY(COMP_DUMMY()),298 DAILINK_COMP_ARRAY(COMP_EMPTY()));299 300SND_SOC_DAILINK_DEFS(capture3,301 DAILINK_COMP_ARRAY(COMP_CPU("UL3")),302 DAILINK_COMP_ARRAY(COMP_DUMMY()),303 DAILINK_COMP_ARRAY(COMP_EMPTY()));304 305SND_SOC_DAILINK_DEFS(capture_mono,306 DAILINK_COMP_ARRAY(COMP_CPU("UL_MONO_1")),307 DAILINK_COMP_ARRAY(COMP_DUMMY()),308 DAILINK_COMP_ARRAY(COMP_EMPTY()));309 310SND_SOC_DAILINK_DEFS(playback_hdmi,311 DAILINK_COMP_ARRAY(COMP_CPU("HDMI")),312 DAILINK_COMP_ARRAY(COMP_DUMMY()),313 DAILINK_COMP_ARRAY(COMP_EMPTY()));314 315/* BE */316SND_SOC_DAILINK_DEFS(primary_codec,317 DAILINK_COMP_ARRAY(COMP_CPU("ADDA")),318 DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound", "mt6358-snd-codec-aif1")),319 DAILINK_COMP_ARRAY(COMP_EMPTY()));320 321SND_SOC_DAILINK_DEFS(pcm1,322 DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")),323 DAILINK_COMP_ARRAY(COMP_DUMMY()),324 DAILINK_COMP_ARRAY(COMP_EMPTY()));325 326SND_SOC_DAILINK_DEFS(pcm2,327 DAILINK_COMP_ARRAY(COMP_CPU("PCM 2")),328 DAILINK_COMP_ARRAY(COMP_DUMMY()),329 DAILINK_COMP_ARRAY(COMP_EMPTY()));330 331SND_SOC_DAILINK_DEFS(i2s0,332 DAILINK_COMP_ARRAY(COMP_CPU("I2S0")),333 DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),334 DAILINK_COMP_ARRAY(COMP_EMPTY()));335 336SND_SOC_DAILINK_DEFS(i2s1,337 DAILINK_COMP_ARRAY(COMP_CPU("I2S1")),338 DAILINK_COMP_ARRAY(COMP_DUMMY()),339 DAILINK_COMP_ARRAY(COMP_EMPTY()));340 341SND_SOC_DAILINK_DEFS(i2s2,342 DAILINK_COMP_ARRAY(COMP_CPU("I2S2")),343 DAILINK_COMP_ARRAY(COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),344 DAILINK_COMP_ARRAY(COMP_EMPTY()));345 346SND_SOC_DAILINK_DEFS(i2s3_max98357a,347 DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),348 DAILINK_COMP_ARRAY(COMP_CODEC("max98357a", "HiFi"),349 COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),350 DAILINK_COMP_ARRAY(COMP_EMPTY()));351 352SND_SOC_DAILINK_DEFS(i2s3_rt1015,353 DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),354 DAILINK_COMP_ARRAY(COMP_CODEC(RT1015_DEV0_NAME, RT1015_CODEC_DAI),355 COMP_CODEC(RT1015_DEV1_NAME, RT1015_CODEC_DAI),356 COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),357 DAILINK_COMP_ARRAY(COMP_EMPTY()));358 359SND_SOC_DAILINK_DEFS(i2s3_rt1015p,360 DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),361 DAILINK_COMP_ARRAY(COMP_CODEC("rt1015p", "HiFi"),362 COMP_CODEC(DA7219_DEV_NAME, DA7219_CODEC_DAI)),363 DAILINK_COMP_ARRAY(COMP_EMPTY()));364 365SND_SOC_DAILINK_DEFS(i2s5,366 DAILINK_COMP_ARRAY(COMP_CPU("I2S5")),367 DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm")),368 DAILINK_COMP_ARRAY(COMP_EMPTY()));369 370SND_SOC_DAILINK_DEFS(tdm,371 DAILINK_COMP_ARRAY(COMP_CPU("TDM")),372 DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "i2s-hifi")),373 DAILINK_COMP_ARRAY(COMP_EMPTY()));374 375static int mt8183_da7219_max98357_hdmi_init(struct snd_soc_pcm_runtime *rtd)376{377 struct mt8183_da7219_max98357_priv *priv =378 snd_soc_card_get_drvdata(rtd->card);379 int ret;380 381 ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,382 &priv->hdmi_jack);383 if (ret)384 return ret;385 386 return snd_soc_component_set_jack(snd_soc_rtd_to_codec(rtd, 0)->component,387 &priv->hdmi_jack, NULL);388}389 390static int mt8183_bt_init(struct snd_soc_pcm_runtime *rtd)391{392 struct snd_soc_component *cmpnt_afe =393 snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);394 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);395 int ret;396 397 ret = mt8183_dai_i2s_set_share(afe, "I2S5", "I2S0");398 if (ret) {399 dev_err(rtd->dev, "Failed to set up shared clocks\n");400 return ret;401 }402 return 0;403}404 405static int mt8183_da7219_init(struct snd_soc_pcm_runtime *rtd)406{407 struct snd_soc_component *cmpnt_afe =408 snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);409 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);410 int ret;411 412 ret = mt8183_dai_i2s_set_share(afe, "I2S2", "I2S3");413 if (ret) {414 dev_err(rtd->dev, "Failed to set up shared clocks\n");415 return ret;416 }417 return 0;418}419 420static struct snd_soc_dai_link mt8183_da7219_dai_links[] = {421 /* FE */422 {423 .name = "Playback_1",424 .stream_name = "Playback_1",425 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,426 SND_SOC_DPCM_TRIGGER_PRE},427 .dynamic = 1,428 .dpcm_playback = 1,429 .ops = &mt8183_da7219_max98357_ops,430 SND_SOC_DAILINK_REG(playback1),431 },432 {433 .name = "Playback_2",434 .stream_name = "Playback_2",435 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,436 SND_SOC_DPCM_TRIGGER_PRE},437 .dynamic = 1,438 .dpcm_playback = 1,439 .ops = &mt8183_da7219_max98357_bt_sco_ops,440 SND_SOC_DAILINK_REG(playback2),441 },442 {443 .name = "Playback_3",444 .stream_name = "Playback_3",445 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,446 SND_SOC_DPCM_TRIGGER_PRE},447 .dynamic = 1,448 .dpcm_playback = 1,449 SND_SOC_DAILINK_REG(playback3),450 },451 {452 .name = "Capture_1",453 .stream_name = "Capture_1",454 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,455 SND_SOC_DPCM_TRIGGER_PRE},456 .dynamic = 1,457 .dpcm_capture = 1,458 .ops = &mt8183_da7219_max98357_bt_sco_ops,459 SND_SOC_DAILINK_REG(capture1),460 },461 {462 .name = "Capture_2",463 .stream_name = "Capture_2",464 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,465 SND_SOC_DPCM_TRIGGER_PRE},466 .dynamic = 1,467 .dpcm_capture = 1,468 SND_SOC_DAILINK_REG(capture2),469 },470 {471 .name = "Capture_3",472 .stream_name = "Capture_3",473 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,474 SND_SOC_DPCM_TRIGGER_PRE},475 .dynamic = 1,476 .dpcm_capture = 1,477 .ops = &mt8183_da7219_max98357_ops,478 SND_SOC_DAILINK_REG(capture3),479 },480 {481 .name = "Capture_Mono_1",482 .stream_name = "Capture_Mono_1",483 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,484 SND_SOC_DPCM_TRIGGER_PRE},485 .dynamic = 1,486 .dpcm_capture = 1,487 SND_SOC_DAILINK_REG(capture_mono),488 },489 {490 .name = "Playback_HDMI",491 .stream_name = "Playback_HDMI",492 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,493 SND_SOC_DPCM_TRIGGER_PRE},494 .dynamic = 1,495 .dpcm_playback = 1,496 SND_SOC_DAILINK_REG(playback_hdmi),497 },498 /* BE */499 {500 .name = "Primary Codec",501 .no_pcm = 1,502 .dpcm_playback = 1,503 .dpcm_capture = 1,504 .ignore_suspend = 1,505 SND_SOC_DAILINK_REG(primary_codec),506 },507 {508 .name = "PCM 1",509 .no_pcm = 1,510 .dpcm_playback = 1,511 .dpcm_capture = 1,512 .ignore_suspend = 1,513 SND_SOC_DAILINK_REG(pcm1),514 },515 {516 .name = "PCM 2",517 .no_pcm = 1,518 .dpcm_playback = 1,519 .dpcm_capture = 1,520 .ignore_suspend = 1,521 SND_SOC_DAILINK_REG(pcm2),522 },523 {524 .name = "I2S0",525 .no_pcm = 1,526 .dpcm_capture = 1,527 .ignore_suspend = 1,528 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,529 .ops = &mt8183_mt6358_i2s_ops,530 SND_SOC_DAILINK_REG(i2s0),531 },532 {533 .name = "I2S1",534 .no_pcm = 1,535 .dpcm_playback = 1,536 .ignore_suspend = 1,537 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,538 .ops = &mt8183_mt6358_i2s_ops,539 SND_SOC_DAILINK_REG(i2s1),540 },541 {542 .name = "I2S2",543 .no_pcm = 1,544 .dpcm_capture = 1,545 .ignore_suspend = 1,546 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,547 .ops = &mt8183_da7219_i2s_ops,548 .init = &mt8183_da7219_init,549 SND_SOC_DAILINK_REG(i2s2),550 },551 {552 .name = "I2S3",553 .no_pcm = 1,554 .dpcm_playback = 1,555 .ignore_suspend = 1,556 },557 {558 .name = "I2S5",559 .no_pcm = 1,560 .dpcm_playback = 1,561 .ignore_suspend = 1,562 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,563 .ops = &mt8183_mt6358_i2s_ops,564 .init = &mt8183_bt_init,565 SND_SOC_DAILINK_REG(i2s5),566 },567 {568 .name = "TDM",569 .no_pcm = 1,570 .dai_fmt = SND_SOC_DAIFMT_I2S |571 SND_SOC_DAIFMT_IB_IF |572 SND_SOC_DAIFMT_CBM_CFM,573 .dpcm_playback = 1,574 .ignore_suspend = 1,575 .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,576 .ignore = 1,577 .init = mt8183_da7219_max98357_hdmi_init,578 SND_SOC_DAILINK_REG(tdm),579 },580};581 582static int583mt8183_da7219_max98357_headset_init(struct snd_soc_component *component)584{585 int ret;586 struct mt8183_da7219_max98357_priv *priv =587 snd_soc_card_get_drvdata(component->card);588 589 /* Enable Headset and 4 Buttons Jack detection */590 ret = snd_soc_card_jack_new_pins(component->card,591 "Headset Jack",592 SND_JACK_HEADSET |593 SND_JACK_BTN_0 | SND_JACK_BTN_1 |594 SND_JACK_BTN_2 | SND_JACK_BTN_3 |595 SND_JACK_LINEOUT,596 &priv->headset_jack,597 mt8183_da7219_max98357_jack_pins,598 ARRAY_SIZE(mt8183_da7219_max98357_jack_pins));599 if (ret)600 return ret;601 602 snd_jack_set_key(603 priv->headset_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);604 snd_jack_set_key(605 priv->headset_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);606 snd_jack_set_key(607 priv->headset_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);608 snd_jack_set_key(609 priv->headset_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);610 611 snd_soc_component_set_jack(component, &priv->headset_jack, NULL);612 613 return 0;614}615 616static struct snd_soc_aux_dev mt8183_da7219_max98357_headset_dev = {617 .dlc = COMP_EMPTY(),618 .init = mt8183_da7219_max98357_headset_init,619};620 621static struct snd_soc_codec_conf mt6358_codec_conf[] = {622 {623 .dlc = COMP_CODEC_CONF("mt6358-sound"),624 .name_prefix = "Mt6358",625 },626};627 628static const struct snd_kcontrol_new mt8183_da7219_max98357_snd_controls[] = {629 SOC_DAPM_PIN_SWITCH("Headphones"),630 SOC_DAPM_PIN_SWITCH("Headset Mic"),631 SOC_DAPM_PIN_SWITCH("Speakers"),632 SOC_DAPM_PIN_SWITCH("Line Out"),633};634 635static const636struct snd_soc_dapm_widget mt8183_da7219_max98357_dapm_widgets[] = {637 SND_SOC_DAPM_HP("Headphones", NULL),638 SND_SOC_DAPM_MIC("Headset Mic", NULL),639 SND_SOC_DAPM_SPK("Speakers", NULL),640 SND_SOC_DAPM_SPK("Line Out", NULL),641 SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL",642 "aud_tdm_out_on", "aud_tdm_out_off"),643};644 645static const struct snd_soc_dapm_route mt8183_da7219_max98357_dapm_routes[] = {646 {"Speakers", NULL, "Speaker"},647 {"I2S Playback", NULL, "TDM_OUT_PINCTRL"},648};649 650static struct snd_soc_card mt8183_da7219_max98357_card = {651 .name = "mt8183_da7219_max98357",652 .owner = THIS_MODULE,653 .controls = mt8183_da7219_max98357_snd_controls,654 .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls),655 .dapm_widgets = mt8183_da7219_max98357_dapm_widgets,656 .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets),657 .dapm_routes = mt8183_da7219_max98357_dapm_routes,658 .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes),659 .dai_link = mt8183_da7219_dai_links,660 .num_links = ARRAY_SIZE(mt8183_da7219_dai_links),661 .aux_dev = &mt8183_da7219_max98357_headset_dev,662 .num_aux_devs = 1,663 .codec_conf = mt6358_codec_conf,664 .num_configs = ARRAY_SIZE(mt6358_codec_conf),665};666 667static struct snd_soc_codec_conf mt8183_da7219_rt1015_codec_conf[] = {668 {669 .dlc = COMP_CODEC_CONF("mt6358-sound"),670 .name_prefix = "Mt6358",671 },672 {673 .dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME),674 .name_prefix = "Left",675 },676 {677 .dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME),678 .name_prefix = "Right",679 },680};681 682static const struct snd_kcontrol_new mt8183_da7219_rt1015_snd_controls[] = {683 SOC_DAPM_PIN_SWITCH("Headphones"),684 SOC_DAPM_PIN_SWITCH("Headset Mic"),685 SOC_DAPM_PIN_SWITCH("Left Spk"),686 SOC_DAPM_PIN_SWITCH("Right Spk"),687 SOC_DAPM_PIN_SWITCH("Line Out"),688};689 690static const691struct snd_soc_dapm_widget mt8183_da7219_rt1015_dapm_widgets[] = {692 SND_SOC_DAPM_HP("Headphones", NULL),693 SND_SOC_DAPM_MIC("Headset Mic", NULL),694 SND_SOC_DAPM_SPK("Left Spk", NULL),695 SND_SOC_DAPM_SPK("Right Spk", NULL),696 SND_SOC_DAPM_LINE("Line Out", NULL),697 SND_SOC_DAPM_PINCTRL("TDM_OUT_PINCTRL",698 "aud_tdm_out_on", "aud_tdm_out_off"),699};700 701static const struct snd_soc_dapm_route mt8183_da7219_rt1015_dapm_routes[] = {702 {"Left Spk", NULL, "Left SPO"},703 {"Right Spk", NULL, "Right SPO"},704 {"I2S Playback", NULL, "TDM_OUT_PINCTRL"},705};706 707static struct snd_soc_card mt8183_da7219_rt1015_card = {708 .name = "mt8183_da7219_rt1015",709 .owner = THIS_MODULE,710 .controls = mt8183_da7219_rt1015_snd_controls,711 .num_controls = ARRAY_SIZE(mt8183_da7219_rt1015_snd_controls),712 .dapm_widgets = mt8183_da7219_rt1015_dapm_widgets,713 .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_widgets),714 .dapm_routes = mt8183_da7219_rt1015_dapm_routes,715 .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_rt1015_dapm_routes),716 .dai_link = mt8183_da7219_dai_links,717 .num_links = ARRAY_SIZE(mt8183_da7219_dai_links),718 .aux_dev = &mt8183_da7219_max98357_headset_dev,719 .num_aux_devs = 1,720 .codec_conf = mt8183_da7219_rt1015_codec_conf,721 .num_configs = ARRAY_SIZE(mt8183_da7219_rt1015_codec_conf),722};723 724static struct snd_soc_card mt8183_da7219_rt1015p_card = {725 .name = "mt8183_da7219_rt1015p",726 .owner = THIS_MODULE,727 .controls = mt8183_da7219_max98357_snd_controls,728 .num_controls = ARRAY_SIZE(mt8183_da7219_max98357_snd_controls),729 .dapm_widgets = mt8183_da7219_max98357_dapm_widgets,730 .num_dapm_widgets = ARRAY_SIZE(mt8183_da7219_max98357_dapm_widgets),731 .dapm_routes = mt8183_da7219_max98357_dapm_routes,732 .num_dapm_routes = ARRAY_SIZE(mt8183_da7219_max98357_dapm_routes),733 .dai_link = mt8183_da7219_dai_links,734 .num_links = ARRAY_SIZE(mt8183_da7219_dai_links),735 .aux_dev = &mt8183_da7219_max98357_headset_dev,736 .num_aux_devs = 1,737 .codec_conf = mt6358_codec_conf,738 .num_configs = ARRAY_SIZE(mt6358_codec_conf),739};740 741static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev)742{743 struct snd_soc_card *card;744 struct device_node *platform_node, *hdmi_codec;745 struct snd_soc_dai_link *dai_link;746 struct mt8183_da7219_max98357_priv *priv;747 struct pinctrl *pinctrl;748 int ret, i;749 750 platform_node = of_parse_phandle(pdev->dev.of_node,751 "mediatek,platform", 0);752 if (!platform_node) {753 dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");754 return -EINVAL;755 }756 757 card = (struct snd_soc_card *)of_device_get_match_data(&pdev->dev);758 if (!card) {759 ret = -EINVAL;760 goto put_platform_node;761 }762 763 card->dev = &pdev->dev;764 765 hdmi_codec = of_parse_phandle(pdev->dev.of_node,766 "mediatek,hdmi-codec", 0);767 768 for_each_card_prelinks(card, i, dai_link) {769 if (strcmp(dai_link->name, "I2S3") == 0) {770 if (card == &mt8183_da7219_max98357_card) {771 dai_link->be_hw_params_fixup =772 mt8183_i2s_hw_params_fixup;773 dai_link->ops = &mt8183_da7219_i2s_ops;774 dai_link->cpus = i2s3_max98357a_cpus;775 dai_link->num_cpus =776 ARRAY_SIZE(i2s3_max98357a_cpus);777 dai_link->codecs = i2s3_max98357a_codecs;778 dai_link->num_codecs =779 ARRAY_SIZE(i2s3_max98357a_codecs);780 dai_link->platforms = i2s3_max98357a_platforms;781 dai_link->num_platforms =782 ARRAY_SIZE(i2s3_max98357a_platforms);783 } else if (card == &mt8183_da7219_rt1015_card) {784 dai_link->be_hw_params_fixup =785 mt8183_rt1015_i2s_hw_params_fixup;786 dai_link->ops = &mt8183_da7219_rt1015_i2s_ops;787 dai_link->cpus = i2s3_rt1015_cpus;788 dai_link->num_cpus =789 ARRAY_SIZE(i2s3_rt1015_cpus);790 dai_link->codecs = i2s3_rt1015_codecs;791 dai_link->num_codecs =792 ARRAY_SIZE(i2s3_rt1015_codecs);793 dai_link->platforms = i2s3_rt1015_platforms;794 dai_link->num_platforms =795 ARRAY_SIZE(i2s3_rt1015_platforms);796 } else if (card == &mt8183_da7219_rt1015p_card) {797 dai_link->be_hw_params_fixup =798 mt8183_rt1015_i2s_hw_params_fixup;799 dai_link->ops = &mt8183_da7219_i2s_ops;800 dai_link->cpus = i2s3_rt1015p_cpus;801 dai_link->num_cpus =802 ARRAY_SIZE(i2s3_rt1015p_cpus);803 dai_link->codecs = i2s3_rt1015p_codecs;804 dai_link->num_codecs =805 ARRAY_SIZE(i2s3_rt1015p_codecs);806 dai_link->platforms = i2s3_rt1015p_platforms;807 dai_link->num_platforms =808 ARRAY_SIZE(i2s3_rt1015p_platforms);809 }810 }811 812 if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) {813 dai_link->codecs->of_node = hdmi_codec;814 dai_link->ignore = 0;815 }816 817 if (!dai_link->platforms->name)818 dai_link->platforms->of_node = platform_node;819 }820 821 mt8183_da7219_max98357_headset_dev.dlc.of_node =822 of_parse_phandle(pdev->dev.of_node,823 "mediatek,headset-codec", 0);824 if (!mt8183_da7219_max98357_headset_dev.dlc.of_node) {825 dev_err(&pdev->dev,826 "Property 'mediatek,headset-codec' missing/invalid\n");827 ret = -EINVAL;828 goto put_hdmi_codec;829 }830 831 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);832 if (!priv) {833 ret = -ENOMEM;834 goto put_hdmi_codec;835 }836 837 snd_soc_card_set_drvdata(card, priv);838 839 pinctrl = devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT);840 if (IS_ERR(pinctrl)) {841 ret = PTR_ERR(pinctrl);842 dev_err(&pdev->dev, "%s failed to select default state %d\n",843 __func__, ret);844 goto put_hdmi_codec;845 }846 847 ret = devm_snd_soc_register_card(&pdev->dev, card);848 849 850put_hdmi_codec:851 of_node_put(hdmi_codec);852put_platform_node:853 of_node_put(platform_node);854 return ret;855}856 857#ifdef CONFIG_OF858static const struct of_device_id mt8183_da7219_max98357_dt_match[] = {859 {860 .compatible = "mediatek,mt8183_da7219_max98357",861 .data = &mt8183_da7219_max98357_card,862 },863 {864 .compatible = "mediatek,mt8183_da7219_rt1015",865 .data = &mt8183_da7219_rt1015_card,866 },867 {868 .compatible = "mediatek,mt8183_da7219_rt1015p",869 .data = &mt8183_da7219_rt1015p_card,870 },871 {}872};873MODULE_DEVICE_TABLE(of, mt8183_da7219_max98357_dt_match);874#endif875 876static struct platform_driver mt8183_da7219_max98357_driver = {877 .driver = {878 .name = "mt8183_da7219",879#ifdef CONFIG_OF880 .of_match_table = mt8183_da7219_max98357_dt_match,881#endif882 .pm = &snd_soc_pm_ops,883 },884 .probe = mt8183_da7219_max98357_dev_probe,885};886 887module_platform_driver(mt8183_da7219_max98357_driver);888 889/* Module information */890MODULE_DESCRIPTION("MT8183-DA7219-MAX98357 ALSA SoC machine driver");891MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>");892MODULE_LICENSE("GPL v2");893MODULE_ALIAS("mt8183_da7219_max98357 soc card");894