@@ -85,39 +85,66 @@ static const struct snd_soc_dapm_route kabylake_5660_map[] = {
{"Line Out", NULL, "LOUTR"},
{"Line Out", NULL, "LOUTL"},
-
- { "HDMI", NULL, "hif5 Output" },
- { "DP", NULL, "hif6 Output" },
-
/* CODEC BE connections */
{ "AIF1 Playback", NULL, "ssp0 Tx"},
{ "ssp0 Tx", NULL, "codec0_out"},
- { "ssp0 Tx", NULL, "codec1_out"},
{ "codec0_in", NULL, "ssp0 Rx" },
- { "codec1_in", NULL, "ssp0 Rx" },
+
{ "ssp0 Rx", NULL, "AIF1 Capture" },
- { "hifi3", NULL, "iDisp3 Tx"},
- { "iDisp3 Tx", NULL, "iDisp3_out"},
{ "hifi2", NULL, "iDisp2 Tx"},
{ "iDisp2 Tx", NULL, "iDisp2_out"},
{ "hifi1", NULL, "iDisp1 Tx"},
{ "iDisp1 Tx", NULL, "iDisp1_out"},
};
-static const struct acpi_gpio_params lineout_mute_gpio = { 0, 0, true };
+#define GPIO_LINEOUT_MUTE_INDEX 0
+#define GPIO_LINEOUT_DET_INDEX 3
+#define GPIO_LINEIN_DET_INDEX 4
+
+static const struct acpi_gpio_params lineout_mute_gpio = { GPIO_LINEOUT_MUTE_INDEX, 0, true };
+static const struct acpi_gpio_params lineout_det_gpio = { GPIO_LINEOUT_DET_INDEX, 0, false };
+static const struct acpi_gpio_params mic_det_gpio = { GPIO_LINEIN_DET_INDEX, 0, false };
static const struct acpi_gpio_mapping acpi_rt5660_gpios[] = {
{ "lineout-mute-gpios", &lineout_mute_gpio , 1 },
+ { "lineout-det-gpios", &lineout_det_gpio, 1 },
+ { "mic-det-gpios", &mic_det_gpio, 1 },
{ NULL },
};
+static struct snd_soc_jack lineout_jack;
+static struct snd_soc_jack mic_jack;
+
+static struct snd_soc_jack_pin lineout_jack_pin = {
+ .pin = "Line Out",
+ .mask = SND_JACK_LINEOUT,
+};
+
+static struct snd_soc_jack_pin mic_jack_pin = {
+ .pin = "Line In",
+ .mask = SND_JACK_MICROPHONE,
+};
+
+static struct snd_soc_jack_gpio lineout_jack_gpio = {
+ .name = "lineout-det",
+ .report = SND_JACK_LINEOUT,
+ .debounce_time = 200,
+};
+
+static struct snd_soc_jack_gpio mic_jack_gpio = {
+ .name = "mic-det",
+ .report = SND_JACK_MICROPHONE,
+ .debounce_time = 200,
+};
+
static int kabylake_rt5660_codec_init(struct snd_soc_pcm_runtime *rtd)
{
int ret;
struct kbl_rt5660_private *ctx = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
ret = devm_acpi_dev_add_driver_gpios(codec->dev, acpi_rt5660_gpios);
if (ret)
@@ -131,6 +158,33 @@ static int kabylake_rt5660_codec_init(struct snd_soc_pcm_runtime *rtd)
return PTR_ERR(ctx->gpio_lo_mute);
}
+ /* Create and initialize headphone jack */
+ if (!snd_soc_card_jack_new(rtd->card, "Lineout Jack",
+ SND_JACK_LINEOUT, &lineout_jack,
+ &lineout_jack_pin, 1)) {
+ lineout_jack_gpio.gpiod_dev = codec->dev;
+ if (snd_soc_jack_add_gpios(&lineout_jack, 1,
+ &lineout_jack_gpio))
+ dev_err(codec->dev, "Can't add Lineout jack gpio\n");
+ } else {
+ dev_err(codec->dev, "Can't create Lineout jack\n");
+ }
+
+ /* Create and initialize mic jack */
+ if (!snd_soc_card_jack_new(rtd->card, "Mic Jack",
+ SND_JACK_MICROPHONE, &mic_jack,
+ &mic_jack_pin, 1)) {
+ mic_jack_gpio.gpiod_dev = codec->dev;
+ if (snd_soc_jack_add_gpios(&mic_jack, 1, &mic_jack_gpio))
+ dev_err(codec->dev, "Can't add mic jack gpio\n");
+ } else {
+ dev_err(codec->dev, "Can't create mic jack\n");
+ }
+
+ snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
+ snd_soc_dapm_force_enable_pin(dapm, "BST1");
+ snd_soc_dapm_force_enable_pin(dapm, "BST2");
+
return ret;
}
@@ -226,25 +280,17 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_soc_dpcm *dpcm = container_of(
params, struct snd_soc_dpcm, hw_params);
struct snd_soc_dai_link *fe_dai_link = dpcm->fe->dai_link;
- struct snd_soc_dai_link *be_dai_link = dpcm->be->dai_link;
/*
* The ADSP will convert the FE rate to 48k, stereo, 24 bit
*/
if (!strcmp(fe_dai_link->name, "Kbl Audio Port") ||
- !strcmp(fe_dai_link->name, "Kbl Audio Headset Playback") ||
!strcmp(fe_dai_link->name, "Kbl Audio Capture Port")) {
rate->min = rate->max = 48000;
channels->min = channels->max = 2;
snd_mask_none(fmt);
snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE);
}
- /*
- * The speaker on the SSP0 supports S16_LE and not S24_LE.
- * thus changing the mask here
- */
- if (!strcmp(be_dai_link->name, "SSP0-Codec"))
- snd_mask_set(fmt, SNDRV_PCM_FORMAT_S16_LE);
return 0;
}
@@ -257,68 +303,24 @@ static int kabylake_rt5660_hw_params(struct snd_pcm_substream *substream,
int ret;
ret = snd_soc_dai_set_sysclk(codec_dai,
- RT5660_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN);
- if (ret < 0)
- dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
-
- return ret;
-}
-
-static struct snd_soc_ops kabylake_rt5660_ops = {
- .hw_params = kabylake_rt5660_hw_params,
-};
-
-static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- int ret = 0;
-
- ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
+ RT5660_SCLK_S_PLL1, params_rate(params) * 512, SND_SOC_CLOCK_IN);
if (ret < 0) {
- dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
+ dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
return ret;
}
- return ret;
-}
-
-static struct snd_soc_ops kabylake_ssp0_ops = {
- .hw_params = kabylake_ssp0_hw_params,
-};
-
-static unsigned int rates_16000[] = {
- 16000,
-};
-
-static const struct snd_pcm_hw_constraint_list constraints_16000 = {
- .count = ARRAY_SIZE(rates_16000),
- .list = rates_16000,
-};
-
-static const unsigned int ch_mono[] = {
- 1,
-};
-
-static const struct snd_pcm_hw_constraint_list constraints_refcap = {
- .count = ARRAY_SIZE(ch_mono),
- .list = ch_mono,
-};
+ ret = snd_soc_dai_set_pll(codec_dai, 0,
+ RT5660_PLL1_S_BCLK,
+ params_rate(params) * 50,
+ params_rate(params) * 512);
+ if (ret < 0)
+ dev_err(codec_dai->dev, "can't set codec pll: %d\n", ret);
-static int kabylake_refcap_startup(struct snd_pcm_substream *substream)
-{
- substream->runtime->hw.channels_max = 1;
- snd_pcm_hw_constraint_list(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- &constraints_refcap);
-
- return snd_pcm_hw_constraint_list(substream->runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE,
- &constraints_16000);
+ return ret;
}
-static struct snd_soc_ops skylaye_refcap_ops = {
- .startup = kabylake_refcap_startup,
+static struct snd_soc_ops kabylake_rt5660_ops = {
+ .hw_params = kabylake_rt5660_hw_params,
};
/* kabylake digital audio interface glue - connects codec <--> CPU */
BugLink: https://bugs.launchpad.net/bugs/1807334 Add jack detection GPIO and change to use BCLK rather than MCLK for codec. Signed-off-by: Hui Wang <hui.wang@canonical.com> --- sound/soc/intel/boards/kbl_rt5660.c | 146 ++++++++++++++-------------- 1 file changed, 74 insertions(+), 72 deletions(-)