1
linux/sound/soc/intel/boards/cht_bsw_max98090_ti.c

649 lines
16 KiB
C
Raw Permalink Normal View History

// SPDX-License-Identifier: GPL-2.0-only
/*
* cht-bsw-max98090.c - ASoc Machine driver for Intel Cherryview-based
* platforms Cherrytrail and Braswell, with max98090 & TI codec.
*
* Copyright (C) 2015 Intel Corp
* Author: Fang, Yang A <yang.a.fang@intel.com>
* This file is modified from cht_bsw_rt5645.c
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#include <linux/dmi.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/clk.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include <sound/jack.h>
#include "../../codecs/max98090.h"
#include "../atom/sst-atom-controls.h"
#include "../../codecs/ts3a227e.h"
#define CHT_PLAT_CLK_3_HZ 19200000
#define CHT_CODEC_DAI "HiFi"
#define QUIRK_PMC_PLT_CLK_0 0x01
struct cht_mc_private {
struct clk *mclk;
struct snd_soc_jack jack;
bool ts3a227e_present;
ASoC: Intel: cht_bsw_max98090_ti: Enable codec clock once and keep it enabled Users have been seeing sound stability issues with max98090 codecs since: commit 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") At first that commit broke sound for Chromebook Swanky and Clapper models, the problem was that the machine-driver has been controlling the wrong clock on those models since support for them was added. This was hidden by clk-pmc-atom.c keeping the actual clk on unconditionally. With the machine-driver controlling the proper clock, sound works again but we are seeing bug reports describing it as: low volume, "sounds like played at 10x speed" and instable. When these issues are hit the following message is seen in dmesg: "max98090 i2c-193C9890:00: PLL unlocked". Attempts have been made to fix this by inserting a delay between enabling the clk and enabling and checking the pll, but this has not helped. It seems that at least on boards which use pmc_plt_clk_0 as clock, if we ever disable the clk, the pll looses its lock and after that we get various issues. This commit fixes this by enabling the clock once at probe time on these boards. In essence this restores the old behavior of clk-pmc-atom.c always keeping the clk on on these boards. Fixes: 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") Reported-by: Mogens Jensen <mogens-jensen@protonmail.com> Reported-by: Dean Wallace <duffydack73@gmail.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
2019-04-02 03:20:49 -07:00
int quirks;
};
static int platform_clock_control(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event)
{
struct snd_soc_dapm_context *dapm = w->dapm;
struct snd_soc_card *card = dapm->card;
struct snd_soc_dai *codec_dai;
struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card);
int ret;
ASoC: Intel: cht_bsw_max98090_ti: Enable codec clock once and keep it enabled Users have been seeing sound stability issues with max98090 codecs since: commit 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") At first that commit broke sound for Chromebook Swanky and Clapper models, the problem was that the machine-driver has been controlling the wrong clock on those models since support for them was added. This was hidden by clk-pmc-atom.c keeping the actual clk on unconditionally. With the machine-driver controlling the proper clock, sound works again but we are seeing bug reports describing it as: low volume, "sounds like played at 10x speed" and instable. When these issues are hit the following message is seen in dmesg: "max98090 i2c-193C9890:00: PLL unlocked". Attempts have been made to fix this by inserting a delay between enabling the clk and enabling and checking the pll, but this has not helped. It seems that at least on boards which use pmc_plt_clk_0 as clock, if we ever disable the clk, the pll looses its lock and after that we get various issues. This commit fixes this by enabling the clock once at probe time on these boards. In essence this restores the old behavior of clk-pmc-atom.c always keeping the clk on on these boards. Fixes: 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") Reported-by: Mogens Jensen <mogens-jensen@protonmail.com> Reported-by: Dean Wallace <duffydack73@gmail.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
2019-04-02 03:20:49 -07:00
/* See the comment in snd_cht_mc_probe() */
if (ctx->quirks & QUIRK_PMC_PLT_CLK_0)
return 0;
codec_dai = snd_soc_card_get_codec_dai(card, CHT_CODEC_DAI);
if (!codec_dai) {
dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n");
return -EIO;
}
if (SND_SOC_DAPM_EVENT_ON(event)) {
ret = clk_prepare_enable(ctx->mclk);
if (ret < 0) {
dev_err(card->dev,
"could not configure MCLK state");
return ret;
}
} else {
clk_disable_unprepare(ctx->mclk);
}
return 0;
}
static const struct snd_soc_dapm_widget cht_dapm_widgets[] = {
SND_SOC_DAPM_HP("Headphone", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL),
SND_SOC_DAPM_MIC("Int Mic", NULL),
SND_SOC_DAPM_SPK("Ext Spk", NULL),
SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
platform_clock_control, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMD),
};
static const struct snd_soc_dapm_route cht_audio_map[] = {
{"IN34", NULL, "Headset Mic"},
{"Headset Mic", NULL, "MICBIAS"},
{"DMICL", NULL, "Int Mic"},
{"Headphone", NULL, "HPL"},
{"Headphone", NULL, "HPR"},
{"Ext Spk", NULL, "SPKL"},
{"Ext Spk", NULL, "SPKR"},
{"HiFi Playback", NULL, "ssp2 Tx"},
{"ssp2 Tx", NULL, "codec_out0"},
{"ssp2 Tx", NULL, "codec_out1"},
{"codec_in0", NULL, "ssp2 Rx" },
{"codec_in1", NULL, "ssp2 Rx" },
{"ssp2 Rx", NULL, "HiFi Capture"},
{"Headphone", NULL, "Platform Clock"},
{"Headset Mic", NULL, "Platform Clock"},
{"Int Mic", NULL, "Platform Clock"},
{"Ext Spk", NULL, "Platform Clock"},
};
static const struct snd_kcontrol_new cht_mc_controls[] = {
SOC_DAPM_PIN_SWITCH("Headphone"),
SOC_DAPM_PIN_SWITCH("Headset Mic"),
SOC_DAPM_PIN_SWITCH("Int Mic"),
SOC_DAPM_PIN_SWITCH("Ext Spk"),
};
static int cht_aif1_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
int ret;
ret = snd_soc_dai_set_sysclk(codec_dai, M98090_REG_SYSTEM_CLOCK,
CHT_PLAT_CLK_3_HZ, SND_SOC_CLOCK_IN);
if (ret < 0) {
dev_err(rtd->dev, "can't set codec sysclk: %d\n", ret);
return ret;
}
return 0;
}
static int cht_ti_jack_event(struct notifier_block *nb,
unsigned long event, void *data)
{
struct snd_soc_jack *jack = (struct snd_soc_jack *)data;
struct snd_soc_dapm_context *dapm = &jack->card->dapm;
if (event & SND_JACK_MICROPHONE) {
snd_soc_dapm_force_enable_pin(dapm, "SHDN");
snd_soc_dapm_force_enable_pin(dapm, "MICBIAS");
snd_soc_dapm_sync(dapm);
} else {
snd_soc_dapm_disable_pin(dapm, "MICBIAS");
snd_soc_dapm_disable_pin(dapm, "SHDN");
snd_soc_dapm_sync(dapm);
}
return 0;
}
static struct notifier_block cht_jack_nb = {
.notifier_call = cht_ti_jack_event,
};
static struct snd_soc_jack_pin hs_jack_pins[] = {
{
.pin = "Headphone",
.mask = SND_JACK_HEADPHONE,
},
{
.pin = "Headset Mic",
.mask = SND_JACK_MICROPHONE,
},
};
static struct snd_soc_jack_gpio hs_jack_gpios[] = {
{
.name = "hp",
.report = SND_JACK_HEADPHONE | SND_JACK_LINEOUT,
.debounce_time = 200,
},
{
.name = "mic",
.invert = 1,
.report = SND_JACK_MICROPHONE,
.debounce_time = 200,
},
};
static const struct acpi_gpio_params hp_gpios = { 0, 0, false };
static const struct acpi_gpio_params mic_gpios = { 1, 0, false };
static const struct acpi_gpio_mapping acpi_max98090_gpios[] = {
{ "hp-gpios", &hp_gpios, 1 },
{ "mic-gpios", &mic_gpios, 1 },
{},
};
static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
{
int ret;
int jack_type;
struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card);
struct snd_soc_jack *jack = &ctx->jack;
if (ctx->ts3a227e_present) {
/*
* The jack has already been created in the
* cht_max98090_headset_init() function.
*/
snd_soc_jack_notifier_register(jack, &cht_jack_nb);
return 0;
}
jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE;
ret = snd_soc_card_jack_new_pins(runtime->card, "Headset Jack",
jack_type, jack,
hs_jack_pins,
ARRAY_SIZE(hs_jack_pins));
if (ret) {
dev_err(runtime->dev, "Headset Jack creation failed %d\n", ret);
return ret;
}
ret = snd_soc_jack_add_gpiods(runtime->card->dev->parent, jack,
ARRAY_SIZE(hs_jack_gpios),
hs_jack_gpios);
if (ret) {
/*
* flag error but don't bail if jack detect is broken
* due to platform issues or bad BIOS/configuration
*/
dev_err(runtime->dev,
"jack detection gpios not added, error %d\n", ret);
}
ASoC: Intel: cht_bsw_max98090_ti: Enable codec clock once and keep it enabled Users have been seeing sound stability issues with max98090 codecs since: commit 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") At first that commit broke sound for Chromebook Swanky and Clapper models, the problem was that the machine-driver has been controlling the wrong clock on those models since support for them was added. This was hidden by clk-pmc-atom.c keeping the actual clk on unconditionally. With the machine-driver controlling the proper clock, sound works again but we are seeing bug reports describing it as: low volume, "sounds like played at 10x speed" and instable. When these issues are hit the following message is seen in dmesg: "max98090 i2c-193C9890:00: PLL unlocked". Attempts have been made to fix this by inserting a delay between enabling the clk and enabling and checking the pll, but this has not helped. It seems that at least on boards which use pmc_plt_clk_0 as clock, if we ever disable the clk, the pll looses its lock and after that we get various issues. This commit fixes this by enabling the clock once at probe time on these boards. In essence this restores the old behavior of clk-pmc-atom.c always keeping the clk on on these boards. Fixes: 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") Reported-by: Mogens Jensen <mogens-jensen@protonmail.com> Reported-by: Dean Wallace <duffydack73@gmail.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
2019-04-02 03:20:49 -07:00
/* See the comment in snd_cht_mc_probe() */
if (ctx->quirks & QUIRK_PMC_PLT_CLK_0)
return 0;
/*
* The firmware might enable the clock at
* boot (this information may or may not
* be reflected in the enable clock register).
* To change the rate we must disable the clock
* first to cover these cases. Due to common
* clock framework restrictions that do not allow
* to disable a clock that has not been enabled,
* we need to enable the clock first.
*/
ret = clk_prepare_enable(ctx->mclk);
if (!ret)
clk_disable_unprepare(ctx->mclk);
ret = clk_set_rate(ctx->mclk, CHT_PLAT_CLK_3_HZ);
if (ret)
dev_err(runtime->dev, "unable to set MCLK rate\n");
return ret;
}
static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
struct snd_interval *rate = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_RATE);
struct snd_interval *channels = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
int ret = 0;
unsigned int fmt = 0;
ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 16);
if (ret < 0) {
dev_err(rtd->dev, "can't set cpu_dai slot fmt: %d\n", ret);
return ret;
}
fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP;
ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), fmt);
if (ret < 0) {
dev_err(rtd->dev, "can't set cpu_dai set fmt: %d\n", ret);
return ret;
}
/* The DSP will convert the FE rate to 48k, stereo, 24bits */
rate->min = rate->max = 48000;
channels->min = channels->max = 2;
/* set SSP2 to 16-bit */
params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
return 0;
}
static int cht_aif1_startup(struct snd_pcm_substream *substream)
{
return snd_pcm_hw_constraint_single(substream->runtime,
SNDRV_PCM_HW_PARAM_RATE, 48000);
}
static int cht_max98090_headset_init(struct snd_soc_component *component)
{
struct snd_soc_card *card = component->card;
struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card);
struct snd_soc_jack *jack = &ctx->jack;
int jack_type;
int ret;
/*
* TI supports 4 buttons headset detection
* KEY_MEDIA
* KEY_VOICECOMMAND
* KEY_VOLUMEUP
* KEY_VOLUMEDOWN
*/
jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE |
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
SND_JACK_BTN_2 | SND_JACK_BTN_3;
ret = snd_soc_card_jack_new(card, "Headset Jack", jack_type, jack);
if (ret) {
dev_err(card->dev, "Headset Jack creation failed %d\n", ret);
return ret;
}
return ts3a227e_enable_jack_detect(component, jack);
}
ASoC: constify snd_soc_ops structures Check for snd_soc_ops structures that are only stored in the ops field of a snd_soc_dai_link structure. This field is declared const, so snd_soc_ops structures that have this property can be declared as const also. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // <smpl> @r disable optional_qualifier@ identifier i; position p; @@ static struct snd_soc_ops i@p = { ... }; @ok1@ identifier r.i; struct snd_soc_dai_link e; position p; @@ e.ops = &i@p; @ok2@ identifier r.i, e; position p; @@ struct snd_soc_dai_link e[] = { ..., { .ops = &i@p, }, ..., }; @bad@ position p != {r.p,ok1.p,ok2.p}; identifier r.i; struct snd_soc_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct snd_soc_ops i = { ... }; // </smpl> The effect on the layout of the .o files is shown by the following output of the size command, first before then after the transformation: text data bss dec hex filename 4500 696 0 5196 144c sound/soc/generic/simple-card.o 4564 632 0 5196 144c sound/soc/generic/simple-card.o text data bss dec hex filename 3018 608 0 3626 e2a sound/soc/generic/simple-scu-card.o 3074 544 0 3618 e22 sound/soc/generic/simple-scu-card.o text data bss dec hex filename 4148 2448 768 7364 1cc4 sound/soc/intel/boards/bdw-rt5677.o 4212 2384 768 7364 1cc4 sound/soc/intel/boards/bdw-rt5677.o text data bss dec hex filename 5403 4628 384 10415 28af sound/soc/intel/boards/bxt_da7219_max98357a.o 5531 4516 384 10431 28bf sound/soc/intel/boards/bxt_da7219_max98357a.o text data bss dec hex filename 5275 4496 384 10155 27ab sound/soc/intel/boards/bxt_rt298.o 5403 4368 384 10155 27ab sound/soc/intel/boards/bxt_rt298.o text data bss dec hex filename 10017 2344 48 12409 3079 sound/soc/intel/boards/bytcr_rt5640.o 10145 2232 48 12425 3089 sound/soc/intel/boards/bytcr_rt5640.o text data bss dec hex filename 3719 2356 0 6075 17bb sound/soc/intel/boards/bytcr_rt5651.o 3847 2244 0 6091 17cb sound/soc/intel/boards/bytcr_rt5651.o text data bss dec hex filename 3598 2392 0 5990 1766 sound/soc/intel/boards/cht_bsw_max98090_ti.o 3726 2280 0 6006 1776 sound/soc/intel/boards/cht_bsw_max98090_ti.o text data bss dec hex filename 5343 3624 16 8983 2317 sound/soc/intel/boards/cht_bsw_rt5645.o 5471 3496 16 8983 2317 sound/soc/intel/boards/cht_bsw_rt5645.o text data bss dec hex filename 4662 2592 384 7638 1dd6 sound/soc/intel/boards/cht_bsw_rt5672.o 4790 2464 384 7638 1dd6 sound/soc/intel/boards/cht_bsw_rt5672.o text data bss dec hex filename 1595 2528 0 4123 101b sound/soc/intel/boards/haswell.o 1659 2472 0 4131 1023 sound/soc/intel/boards/haswell.o text data bss dec hex filename 6272 4760 416 11448 2cb8 sound/soc/intel/boards/skl_nau88l25_max98357a.o 6464 4568 416 11448 2cb8 sound/soc/intel/boards/skl_nau88l25_max98357a.o text data bss dec hex filename 7075 4888 416 12379 305b sound/soc/intel/boards/skl_nau88l25_ssm4567.o 7267 4696 416 12379 305b sound/soc/intel/boards/skl_nau88l25_ssm4567.o text data bss dec hex filename 5659 4496 384 10539 292b sound/soc/intel/boards/skl_rt286.o 5787 4368 384 10539 292b sound/soc/intel/boards/skl_rt286.o text data bss dec hex filename 1721 2048 0 3769 eb9 sound/soc/kirkwood/armada-370-db.o 1769 1976 0 3745 ea1 sound/soc/kirkwood/armada-370-db.o text data bss dec hex filename 1363 1792 0 3155 c53 sound/soc/mxs/mxs-sgtl5000.o 1427 1728 0 3155 c53 sound/soc/mxs/mxs-sgtl5000.o Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: Mark Brown <broonie@kernel.org>
2016-10-15 07:55:49 -07:00
static const struct snd_soc_ops cht_aif1_ops = {
.startup = cht_aif1_startup,
};
ASoC: constify snd_soc_ops structures Check for snd_soc_ops structures that are only stored in the ops field of a snd_soc_dai_link structure. This field is declared const, so snd_soc_ops structures that have this property can be declared as const also. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // <smpl> @r disable optional_qualifier@ identifier i; position p; @@ static struct snd_soc_ops i@p = { ... }; @ok1@ identifier r.i; struct snd_soc_dai_link e; position p; @@ e.ops = &i@p; @ok2@ identifier r.i, e; position p; @@ struct snd_soc_dai_link e[] = { ..., { .ops = &i@p, }, ..., }; @bad@ position p != {r.p,ok1.p,ok2.p}; identifier r.i; struct snd_soc_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct snd_soc_ops i = { ... }; // </smpl> The effect on the layout of the .o files is shown by the following output of the size command, first before then after the transformation: text data bss dec hex filename 4500 696 0 5196 144c sound/soc/generic/simple-card.o 4564 632 0 5196 144c sound/soc/generic/simple-card.o text data bss dec hex filename 3018 608 0 3626 e2a sound/soc/generic/simple-scu-card.o 3074 544 0 3618 e22 sound/soc/generic/simple-scu-card.o text data bss dec hex filename 4148 2448 768 7364 1cc4 sound/soc/intel/boards/bdw-rt5677.o 4212 2384 768 7364 1cc4 sound/soc/intel/boards/bdw-rt5677.o text data bss dec hex filename 5403 4628 384 10415 28af sound/soc/intel/boards/bxt_da7219_max98357a.o 5531 4516 384 10431 28bf sound/soc/intel/boards/bxt_da7219_max98357a.o text data bss dec hex filename 5275 4496 384 10155 27ab sound/soc/intel/boards/bxt_rt298.o 5403 4368 384 10155 27ab sound/soc/intel/boards/bxt_rt298.o text data bss dec hex filename 10017 2344 48 12409 3079 sound/soc/intel/boards/bytcr_rt5640.o 10145 2232 48 12425 3089 sound/soc/intel/boards/bytcr_rt5640.o text data bss dec hex filename 3719 2356 0 6075 17bb sound/soc/intel/boards/bytcr_rt5651.o 3847 2244 0 6091 17cb sound/soc/intel/boards/bytcr_rt5651.o text data bss dec hex filename 3598 2392 0 5990 1766 sound/soc/intel/boards/cht_bsw_max98090_ti.o 3726 2280 0 6006 1776 sound/soc/intel/boards/cht_bsw_max98090_ti.o text data bss dec hex filename 5343 3624 16 8983 2317 sound/soc/intel/boards/cht_bsw_rt5645.o 5471 3496 16 8983 2317 sound/soc/intel/boards/cht_bsw_rt5645.o text data bss dec hex filename 4662 2592 384 7638 1dd6 sound/soc/intel/boards/cht_bsw_rt5672.o 4790 2464 384 7638 1dd6 sound/soc/intel/boards/cht_bsw_rt5672.o text data bss dec hex filename 1595 2528 0 4123 101b sound/soc/intel/boards/haswell.o 1659 2472 0 4131 1023 sound/soc/intel/boards/haswell.o text data bss dec hex filename 6272 4760 416 11448 2cb8 sound/soc/intel/boards/skl_nau88l25_max98357a.o 6464 4568 416 11448 2cb8 sound/soc/intel/boards/skl_nau88l25_max98357a.o text data bss dec hex filename 7075 4888 416 12379 305b sound/soc/intel/boards/skl_nau88l25_ssm4567.o 7267 4696 416 12379 305b sound/soc/intel/boards/skl_nau88l25_ssm4567.o text data bss dec hex filename 5659 4496 384 10539 292b sound/soc/intel/boards/skl_rt286.o 5787 4368 384 10539 292b sound/soc/intel/boards/skl_rt286.o text data bss dec hex filename 1721 2048 0 3769 eb9 sound/soc/kirkwood/armada-370-db.o 1769 1976 0 3745 ea1 sound/soc/kirkwood/armada-370-db.o text data bss dec hex filename 1363 1792 0 3155 c53 sound/soc/mxs/mxs-sgtl5000.o 1427 1728 0 3155 c53 sound/soc/mxs/mxs-sgtl5000.o Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: Mark Brown <broonie@kernel.org>
2016-10-15 07:55:49 -07:00
static const struct snd_soc_ops cht_be_ssp2_ops = {
.hw_params = cht_aif1_hw_params,
};
static struct snd_soc_aux_dev cht_max98090_headset_dev = {
.dlc = COMP_AUX("i2c-104C227E:00"),
.init = cht_max98090_headset_init,
};
SND_SOC_DAILINK_DEF(dummy,
DAILINK_COMP_ARRAY(COMP_DUMMY()));
SND_SOC_DAILINK_DEF(media,
DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai")));
SND_SOC_DAILINK_DEF(deepbuffer,
DAILINK_COMP_ARRAY(COMP_CPU("deepbuffer-cpu-dai")));
SND_SOC_DAILINK_DEF(ssp2_port,
DAILINK_COMP_ARRAY(COMP_CPU("ssp2-port")));
SND_SOC_DAILINK_DEF(ssp2_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-193C9890:00", "HiFi")));
SND_SOC_DAILINK_DEF(platform,
DAILINK_COMP_ARRAY(COMP_PLATFORM("sst-mfld-platform")));
static struct snd_soc_dai_link cht_dailink[] = {
[MERR_DPCM_AUDIO] = {
.name = "Audio Port",
.stream_name = "Audio",
.nonatomic = true,
.dynamic = 1,
.dpcm_playback = 1,
.dpcm_capture = 1,
.ops = &cht_aif1_ops,
SND_SOC_DAILINK_REG(media, dummy, platform),
},
[MERR_DPCM_DEEP_BUFFER] = {
.name = "Deep-Buffer Audio Port",
.stream_name = "Deep-Buffer Audio",
.nonatomic = true,
.dynamic = 1,
.dpcm_playback = 1,
.ops = &cht_aif1_ops,
SND_SOC_DAILINK_REG(deepbuffer, dummy, platform),
},
/* back ends */
{
.name = "SSP2-Codec",
.id = 0,
.no_pcm = 1,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBC_CFC,
.init = cht_codec_init,
.be_hw_params_fixup = cht_codec_fixup,
.dpcm_playback = 1,
.dpcm_capture = 1,
.ops = &cht_be_ssp2_ops,
SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
},
};
/* use space before codec name to simplify card ID, and simplify driver name */
#define SOF_CARD_NAME "bytcht max98090" /* card name will be 'sof-bytcht max98090 */
#define SOF_DRIVER_NAME "SOF"
#define CARD_NAME "chtmax98090"
#define DRIVER_NAME NULL /* card name will be used for driver name */
/* SoC card */
static struct snd_soc_card snd_soc_card_cht = {
.owner = THIS_MODULE,
.dai_link = cht_dailink,
.num_links = ARRAY_SIZE(cht_dailink),
.aux_dev = &cht_max98090_headset_dev,
.num_aux_devs = 1,
.dapm_widgets = cht_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(cht_dapm_widgets),
.dapm_routes = cht_audio_map,
.num_dapm_routes = ARRAY_SIZE(cht_audio_map),
.controls = cht_mc_controls,
.num_controls = ARRAY_SIZE(cht_mc_controls),
};
static const struct dmi_system_id cht_max98090_quirk_table[] = {
{
/* Banjo model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Banjo"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Candy model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Candy"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Clapper model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Clapper"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Cyan model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Cyan"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Enguarde model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Enguarde"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Glimmer model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Glimmer"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Gnawty model Chromebook (Acer Chromebook CB3-111) */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Gnawty"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Heli model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Heli"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Kip model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Kip"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Ninja model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Ninja"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Orco model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Orco"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Quawks model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Quawks"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Rambi model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Rambi"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Squawks model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Squawks"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Sumo model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Sumo"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Swanky model Chromebook (Toshiba Chromebook 2) */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Swanky"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Winky model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Winky"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{}
};
static int snd_cht_mc_probe(struct platform_device *pdev)
{
const struct dmi_system_id *dmi_id;
struct device *dev = &pdev->dev;
int ret_val = 0;
struct cht_mc_private *drv;
const char *mclk_name;
struct snd_soc_acpi_mach *mach;
const char *platform_name;
bool sof_parent;
drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL);
if (!drv)
return -ENOMEM;
ASoC: Intel: cht_bsw_max98090_ti: Enable codec clock once and keep it enabled Users have been seeing sound stability issues with max98090 codecs since: commit 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") At first that commit broke sound for Chromebook Swanky and Clapper models, the problem was that the machine-driver has been controlling the wrong clock on those models since support for them was added. This was hidden by clk-pmc-atom.c keeping the actual clk on unconditionally. With the machine-driver controlling the proper clock, sound works again but we are seeing bug reports describing it as: low volume, "sounds like played at 10x speed" and instable. When these issues are hit the following message is seen in dmesg: "max98090 i2c-193C9890:00: PLL unlocked". Attempts have been made to fix this by inserting a delay between enabling the clk and enabling and checking the pll, but this has not helped. It seems that at least on boards which use pmc_plt_clk_0 as clock, if we ever disable the clk, the pll looses its lock and after that we get various issues. This commit fixes this by enabling the clock once at probe time on these boards. In essence this restores the old behavior of clk-pmc-atom.c always keeping the clk on on these boards. Fixes: 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") Reported-by: Mogens Jensen <mogens-jensen@protonmail.com> Reported-by: Dean Wallace <duffydack73@gmail.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
2019-04-02 03:20:49 -07:00
dmi_id = dmi_first_match(cht_max98090_quirk_table);
if (dmi_id)
drv->quirks = (unsigned long)dmi_id->driver_data;
drv->ts3a227e_present = acpi_dev_found("104C227E");
if (!drv->ts3a227e_present) {
/* no need probe TI jack detection chip */
snd_soc_card_cht.aux_dev = NULL;
snd_soc_card_cht.num_aux_devs = 0;
ret_val = devm_acpi_dev_add_driver_gpios(dev->parent,
acpi_max98090_gpios);
if (ret_val)
dev_dbg(dev, "Unable to add GPIO mapping table\n");
}
/* override platform name, if required */
snd_soc_card_cht.dev = dev;
mach = dev->platform_data;
platform_name = mach->mach_params.platform;
ret_val = snd_soc_fixup_dai_links_platform_name(&snd_soc_card_cht,
platform_name);
if (ret_val)
return ret_val;
/* register the soc card */
snd_soc_card_set_drvdata(&snd_soc_card_cht, drv);
ASoC: Intel: cht_bsw_max98090_ti: Enable codec clock once and keep it enabled Users have been seeing sound stability issues with max98090 codecs since: commit 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") At first that commit broke sound for Chromebook Swanky and Clapper models, the problem was that the machine-driver has been controlling the wrong clock on those models since support for them was added. This was hidden by clk-pmc-atom.c keeping the actual clk on unconditionally. With the machine-driver controlling the proper clock, sound works again but we are seeing bug reports describing it as: low volume, "sounds like played at 10x speed" and instable. When these issues are hit the following message is seen in dmesg: "max98090 i2c-193C9890:00: PLL unlocked". Attempts have been made to fix this by inserting a delay between enabling the clk and enabling and checking the pll, but this has not helped. It seems that at least on boards which use pmc_plt_clk_0 as clock, if we ever disable the clk, the pll looses its lock and after that we get various issues. This commit fixes this by enabling the clock once at probe time on these boards. In essence this restores the old behavior of clk-pmc-atom.c always keeping the clk on on these boards. Fixes: 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") Reported-by: Mogens Jensen <mogens-jensen@protonmail.com> Reported-by: Dean Wallace <duffydack73@gmail.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
2019-04-02 03:20:49 -07:00
if (drv->quirks & QUIRK_PMC_PLT_CLK_0)
mclk_name = "pmc_plt_clk_0";
else
mclk_name = "pmc_plt_clk_3";
drv->mclk = devm_clk_get(dev, mclk_name);
if (IS_ERR(drv->mclk)) {
dev_err(dev,
"Failed to get MCLK from %s: %ld\n",
mclk_name, PTR_ERR(drv->mclk));
return PTR_ERR(drv->mclk);
}
ASoC: Intel: cht_bsw_max98090_ti: Enable codec clock once and keep it enabled Users have been seeing sound stability issues with max98090 codecs since: commit 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") At first that commit broke sound for Chromebook Swanky and Clapper models, the problem was that the machine-driver has been controlling the wrong clock on those models since support for them was added. This was hidden by clk-pmc-atom.c keeping the actual clk on unconditionally. With the machine-driver controlling the proper clock, sound works again but we are seeing bug reports describing it as: low volume, "sounds like played at 10x speed" and instable. When these issues are hit the following message is seen in dmesg: "max98090 i2c-193C9890:00: PLL unlocked". Attempts have been made to fix this by inserting a delay between enabling the clk and enabling and checking the pll, but this has not helped. It seems that at least on boards which use pmc_plt_clk_0 as clock, if we ever disable the clk, the pll looses its lock and after that we get various issues. This commit fixes this by enabling the clock once at probe time on these boards. In essence this restores the old behavior of clk-pmc-atom.c always keeping the clk on on these boards. Fixes: 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") Reported-by: Mogens Jensen <mogens-jensen@protonmail.com> Reported-by: Dean Wallace <duffydack73@gmail.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
2019-04-02 03:20:49 -07:00
/*
* Boards which have the MAX98090's clk connected to clk_0 do not seem
* to like it if we muck with the clock. If we disable the clock when
* it is unused we get "max98090 i2c-193C9890:00: PLL unlocked" errors
* and the PLL never seems to lock again.
* So for these boards we enable it here once and leave it at that.
*/
if (drv->quirks & QUIRK_PMC_PLT_CLK_0) {
ret_val = clk_prepare_enable(drv->mclk);
if (ret_val < 0) {
dev_err(dev, "MCLK enable error: %d\n", ret_val);
ASoC: Intel: cht_bsw_max98090_ti: Enable codec clock once and keep it enabled Users have been seeing sound stability issues with max98090 codecs since: commit 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") At first that commit broke sound for Chromebook Swanky and Clapper models, the problem was that the machine-driver has been controlling the wrong clock on those models since support for them was added. This was hidden by clk-pmc-atom.c keeping the actual clk on unconditionally. With the machine-driver controlling the proper clock, sound works again but we are seeing bug reports describing it as: low volume, "sounds like played at 10x speed" and instable. When these issues are hit the following message is seen in dmesg: "max98090 i2c-193C9890:00: PLL unlocked". Attempts have been made to fix this by inserting a delay between enabling the clk and enabling and checking the pll, but this has not helped. It seems that at least on boards which use pmc_plt_clk_0 as clock, if we ever disable the clk, the pll looses its lock and after that we get various issues. This commit fixes this by enabling the clock once at probe time on these boards. In essence this restores the old behavior of clk-pmc-atom.c always keeping the clk on on these boards. Fixes: 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") Reported-by: Mogens Jensen <mogens-jensen@protonmail.com> Reported-by: Dean Wallace <duffydack73@gmail.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
2019-04-02 03:20:49 -07:00
return ret_val;
}
}
sof_parent = snd_soc_acpi_sof_parent(dev);
/* set card and driver name */
if (sof_parent) {
snd_soc_card_cht.name = SOF_CARD_NAME;
snd_soc_card_cht.driver_name = SOF_DRIVER_NAME;
} else {
snd_soc_card_cht.name = CARD_NAME;
snd_soc_card_cht.driver_name = DRIVER_NAME;
}
/* set pm ops */
if (sof_parent)
dev->driver->pm = &snd_soc_pm_ops;
ret_val = devm_snd_soc_register_card(dev, &snd_soc_card_cht);
if (ret_val) {
dev_err(dev,
"snd_soc_register_card failed %d\n", ret_val);
return ret_val;
}
platform_set_drvdata(pdev, &snd_soc_card_cht);
return ret_val;
}
static void snd_cht_mc_remove(struct platform_device *pdev)
ASoC: Intel: cht_bsw_max98090_ti: Enable codec clock once and keep it enabled Users have been seeing sound stability issues with max98090 codecs since: commit 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") At first that commit broke sound for Chromebook Swanky and Clapper models, the problem was that the machine-driver has been controlling the wrong clock on those models since support for them was added. This was hidden by clk-pmc-atom.c keeping the actual clk on unconditionally. With the machine-driver controlling the proper clock, sound works again but we are seeing bug reports describing it as: low volume, "sounds like played at 10x speed" and instable. When these issues are hit the following message is seen in dmesg: "max98090 i2c-193C9890:00: PLL unlocked". Attempts have been made to fix this by inserting a delay between enabling the clk and enabling and checking the pll, but this has not helped. It seems that at least on boards which use pmc_plt_clk_0 as clock, if we ever disable the clk, the pll looses its lock and after that we get various issues. This commit fixes this by enabling the clock once at probe time on these boards. In essence this restores the old behavior of clk-pmc-atom.c always keeping the clk on on these boards. Fixes: 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL") Reported-by: Mogens Jensen <mogens-jensen@protonmail.com> Reported-by: Dean Wallace <duffydack73@gmail.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
2019-04-02 03:20:49 -07:00
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card);
if (ctx->quirks & QUIRK_PMC_PLT_CLK_0)
clk_disable_unprepare(ctx->mclk);
}
static struct platform_driver snd_cht_mc_driver = {
.driver = {
.name = "cht-bsw-max98090",
},
.probe = snd_cht_mc_probe,
.remove = snd_cht_mc_remove,
};
module_platform_driver(snd_cht_mc_driver)
MODULE_DESCRIPTION("ASoC Intel(R) Braswell Machine driver");
MODULE_AUTHOR("Fang, Yang A <yang.a.fang@intel.com>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:cht-bsw-max98090");