aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/sound/soc/intel/boards/bytcr_rt5651.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/intel/boards/bytcr_rt5651.c')
-rw-r--r--sound/soc/intel/boards/bytcr_rt5651.c253
1 files changed, 140 insertions, 113 deletions
diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c
index 688b5e0a49e3..67c62844ca2a 100644
--- a/sound/soc/intel/boards/bytcr_rt5651.c
+++ b/sound/soc/intel/boards/bytcr_rt5651.c
@@ -85,6 +85,7 @@ struct byt_rt5651_private {
struct gpio_desc *ext_amp_gpio;
struct gpio_desc *hp_detect;
struct snd_soc_jack jack;
+ struct device *codec_dev;
};
static const struct acpi_gpio_mapping *byt_rt5651_gpios;
@@ -143,7 +144,7 @@ static int byt_rt5651_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai,
/* Configure the PLL before selecting it */
if (!(byt_rt5651_quirk & BYT_RT5651_MCLK_EN)) {
- clk_id = RT5651_PLL1_S_BCLK1,
+ clk_id = RT5651_PLL1_S_BCLK1;
clk_freq = rate * bclk_ratio;
} else {
clk_id = RT5651_PLL1_S_MCLK;
@@ -187,13 +188,10 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
}
if (SND_SOC_DAPM_EVENT_ON(event)) {
- if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) {
- ret = clk_prepare_enable(priv->mclk);
- if (ret < 0) {
- dev_err(card->dev,
- "could not configure MCLK state");
- return ret;
- }
+ ret = clk_prepare_enable(priv->mclk);
+ if (ret < 0) {
+ dev_err(card->dev, "could not configure MCLK state");
+ return ret;
}
ret = byt_rt5651_prepare_and_enable_pll1(codec_dai, 48000, 50);
} else {
@@ -206,8 +204,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
48000 * 512,
SND_SOC_CLOCK_IN);
if (!ret)
- if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN)
- clk_disable_unprepare(priv->mclk);
+ clk_disable_unprepare(priv->mclk);
}
if (ret < 0) {
@@ -347,8 +344,8 @@ static struct snd_soc_jack_pin bytcr_jack_pins[] = {
static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
- struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+ 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);
snd_pcm_format_t format = params_format(params);
int rate = params_rate(params);
int bclk_ratio;
@@ -436,6 +433,19 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = {
BYT_RT5651_MONO_SPEAKER),
},
{
+ /* Jumper EZpad 7 */
+ .callback = byt_rt5651_quirk_cb,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Jumper"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "EZpad"),
+ /* Jumper12x.WJ2012.bsBKRCP05 with the version dropped */
+ DMI_MATCH(DMI_BIOS_VERSION, "Jumper12x.WJ2012.bsBKRCP"),
+ },
+ .driver_data = (void *)(BYT_RT5651_DEFAULT_QUIRKS |
+ BYT_RT5651_IN2_MAP |
+ BYT_RT5651_JD_NOT_INV),
+ },
+ {
/* KIANO SlimNote 14.2 */
.callback = byt_rt5651_quirk_cb,
.matches = {
@@ -514,10 +524,13 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = {
* Note this MUST be called before snd_soc_register_card(), so that the props
* are in place before the codec component driver's probe function parses them.
*/
-static int byt_rt5651_add_codec_device_props(struct device *i2c_dev)
+static int byt_rt5651_add_codec_device_props(struct device *i2c_dev,
+ struct byt_rt5651_private *priv)
{
struct property_entry props[MAX_NO_PROPS] = {};
+ struct fwnode_handle *fwnode;
int cnt = 0;
+ int ret;
props[cnt++] = PROPERTY_ENTRY_U32("realtek,jack-detect-source",
BYT_RT5651_JDSRC(byt_rt5651_quirk));
@@ -534,13 +547,23 @@ static int byt_rt5651_add_codec_device_props(struct device *i2c_dev)
if (byt_rt5651_quirk & BYT_RT5651_JD_NOT_INV)
props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,jack-detect-not-inverted");
- return device_add_properties(i2c_dev, props);
+ fwnode = fwnode_create_software_node(props, NULL);
+ if (IS_ERR(fwnode)) {
+ /* put_device(i2c_dev) is handled in caller */
+ return PTR_ERR(fwnode);
+ }
+
+ ret = device_add_software_node(i2c_dev, to_software_node(fwnode));
+
+ fwnode_handle_put(fwnode);
+
+ return ret;
}
static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
{
struct snd_soc_card *card = runtime->card;
- struct snd_soc_component *codec = asoc_rtd_to_codec(runtime, 0)->component;
+ struct snd_soc_component *codec = snd_soc_rtd_to_codec(runtime, 0)->component;
struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card);
const struct snd_soc_dapm_route *custom_map;
int num_routes;
@@ -602,29 +625,25 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
return ret;
}
- if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) {
- /*
- * 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(priv->mclk);
- if (!ret)
- clk_disable_unprepare(priv->mclk);
+ /*
+ * 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(priv->mclk);
+ if (!ret)
+ clk_disable_unprepare(priv->mclk);
- if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ)
- ret = clk_set_rate(priv->mclk, 25000000);
- else
- ret = clk_set_rate(priv->mclk, 19200000);
+ if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ)
+ ret = clk_set_rate(priv->mclk, 25000000);
+ else
+ ret = clk_set_rate(priv->mclk, 19200000);
- if (ret)
- dev_err(card->dev, "unable to set MCLK rate\n");
- }
+ if (ret)
+ dev_err(card->dev, "unable to set MCLK rate\n");
report = 0;
if (BYT_RT5651_JDSRC(byt_rt5651_quirk))
@@ -633,9 +652,10 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
report = SND_JACK_HEADSET;
if (report) {
- ret = snd_soc_card_jack_new(runtime->card, "Headset",
- report, &priv->jack, bytcr_jack_pins,
- ARRAY_SIZE(bytcr_jack_pins));
+ ret = snd_soc_card_jack_new_pins(runtime->card, "Headset",
+ report, &priv->jack,
+ bytcr_jack_pins,
+ ARRAY_SIZE(bytcr_jack_pins));
if (ret) {
dev_err(runtime->dev, "jack creation failed %d\n", ret);
return ret;
@@ -663,7 +683,7 @@ static int byt_rt5651_codec_fixup(struct snd_soc_pcm_runtime *rtd,
SNDRV_PCM_HW_PARAM_CHANNELS);
int ret, bits;
- /* The DSP will covert the FE rate to 48k, stereo */
+ /* The DSP will convert the FE rate to 48k, stereo */
rate->min = rate->max = 48000;
channels->min = channels->max = 2;
@@ -683,10 +703,10 @@ static int byt_rt5651_codec_fixup(struct snd_soc_pcm_runtime *rtd,
* with explicit setting to I2S 2ch. The word length is set with
* dai_set_tdm_slot() since there is no other API exposed
*/
- ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0),
+ ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0),
SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS
+ SND_SOC_DAIFMT_BP_FP
);
if (ret < 0) {
@@ -694,7 +714,7 @@ static int byt_rt5651_codec_fixup(struct snd_soc_pcm_runtime *rtd,
return ret;
}
- ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits);
+ ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits);
if (ret < 0) {
dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
return ret;
@@ -750,8 +770,6 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = {
.stream_name = "Audio",
.nonatomic = true,
.dynamic = 1,
- .dpcm_playback = 1,
- .dpcm_capture = 1,
.ops = &byt_rt5651_aif1_ops,
SND_SOC_DAILINK_REG(media, dummy, platform),
},
@@ -760,7 +778,7 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = {
.stream_name = "Deep-Buffer Audio",
.nonatomic = true,
.dynamic = 1,
- .dpcm_playback = 1,
+ .playback_only = 1,
.ops = &byt_rt5651_aif1_ops,
SND_SOC_DAILINK_REG(deepbuffer, dummy, platform),
},
@@ -771,11 +789,8 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = {
.id = 0,
.no_pcm = 1,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
- | SND_SOC_DAIFMT_CBS_CFS,
+ | SND_SOC_DAIFMT_CBC_CFC,
.be_hw_params_fixup = byt_rt5651_codec_fixup,
- .nonatomic = true,
- .dpcm_playback = 1,
- .dpcm_capture = 1,
.init = byt_rt5651_init,
.ops = &byt_rt5651_be_ssp2_ops,
SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
@@ -827,14 +842,12 @@ static int byt_rt5651_resume(struct snd_soc_card *card)
return 0;
}
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
/* use space before codec name to simplify card ID, and simplify driver name */
-#define CARD_NAME "bytcht rt5651" /* card name will be 'sof-bytcht rt5651' */
-#define DRIVER_NAME "SOF"
-#else
+#define SOF_CARD_NAME "bytcht rt5651" /* card name will be 'sof-bytcht rt5651' */
+#define SOF_DRIVER_NAME "SOF"
+
#define CARD_NAME "bytcr-rt5651"
#define DRIVER_NAME NULL /* card name will be used for driver name */
-#endif
static struct snd_soc_card byt_rt5651_card = {
.name = CARD_NAME,
@@ -870,30 +883,31 @@ struct acpi_chan_package { /* ACPICA seems to require 64 bit integers */
static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
static const char * const mic_name[] = { "dmic", "in1", "in2", "in12" };
+ struct snd_soc_acpi_mach *mach = dev_get_platdata(dev);
struct byt_rt5651_private *priv;
- struct snd_soc_acpi_mach *mach;
const char *platform_name;
struct acpi_device *adev;
struct device *codec_dev;
+ bool sof_parent;
bool is_bytcr = false;
int ret_val = 0;
int dai_index = 0;
int i;
- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
/* register the soc card */
- byt_rt5651_card.dev = &pdev->dev;
-
- mach = byt_rt5651_card.dev->platform_data;
+ byt_rt5651_card.dev = dev;
snd_soc_card_set_drvdata(&byt_rt5651_card, priv);
/* fix index of codec dai */
for (i = 0; i < ARRAY_SIZE(byt_rt5651_dais); i++) {
- if (!strcmp(byt_rt5651_dais[i].codecs->name,
+ if (byt_rt5651_dais[i].num_codecs &&
+ !strcmp(byt_rt5651_dais[i].codecs->name,
"i2c-10EC5651:00")) {
dai_index = i;
break;
@@ -905,17 +919,17 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
if (adev) {
snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name),
"i2c-%s", acpi_dev_name(adev));
- put_device(&adev->dev);
byt_rt5651_dais[dai_index].codecs->name = byt_rt5651_codec_name;
} else {
- dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id);
- return -ENODEV;
+ dev_err(dev, "Error cannot find '%s' dev\n", mach->id);
+ return -ENOENT;
}
- codec_dev = bus_find_device_by_name(&i2c_bus_type, NULL,
- byt_rt5651_codec_name);
+ codec_dev = acpi_get_first_physical_node(adev);
+ acpi_dev_put(adev);
if (!codec_dev)
return -EPROBE_DEFER;
+ priv->codec_dev = get_device(codec_dev);
/*
* swap SSP0 if bytcr is detected
@@ -935,7 +949,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
* with the codec driver/pdata are non-existent
*/
- struct acpi_chan_package chan_package;
+ struct acpi_chan_package chan_package = { 0 };
/* format specified: 2 64-bit integers */
struct acpi_buffer format = {sizeof("NN"), "NN"};
@@ -956,13 +970,13 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
&pkg_ctx);
if (pkg_found) {
if (chan_package.aif_value == 1) {
- dev_info(&pdev->dev, "BIOS Routing: AIF1 connected\n");
+ dev_info(dev, "BIOS Routing: AIF1 connected\n");
byt_rt5651_quirk |= BYT_RT5651_SSP0_AIF1;
} else if (chan_package.aif_value == 2) {
- dev_info(&pdev->dev, "BIOS Routing: AIF2 connected\n");
+ dev_info(dev, "BIOS Routing: AIF2 connected\n");
byt_rt5651_quirk |= BYT_RT5651_SSP0_AIF2;
} else {
- dev_info(&pdev->dev, "BIOS Routing isn't valid, ignored\n");
+ dev_info(dev, "BIOS Routing isn't valid, ignored\n");
pkg_found = false;
}
}
@@ -977,17 +991,15 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
dmi_check_system(byt_rt5651_quirk_table);
if (quirk_override != -1) {
- dev_info(&pdev->dev, "Overriding quirk 0x%lx => 0x%x\n",
+ dev_info(dev, "Overriding quirk 0x%lx => 0x%x\n",
byt_rt5651_quirk, quirk_override);
byt_rt5651_quirk = quirk_override;
}
/* Must be called before register_card, also see declaration comment. */
- ret_val = byt_rt5651_add_codec_device_props(codec_dev);
- if (ret_val) {
- put_device(codec_dev);
- return ret_val;
- }
+ ret_val = byt_rt5651_add_codec_device_props(codec_dev, priv);
+ if (ret_val)
+ goto err_device;
/* Cherry Trail devices use an external amplifier enable gpio */
if (soc_intel_is_cht() && !byt_rt5651_gpios)
@@ -995,8 +1007,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
if (byt_rt5651_gpios) {
devm_acpi_dev_add_driver_gpios(codec_dev, byt_rt5651_gpios);
- priv->ext_amp_gpio = devm_fwnode_gpiod_get(&pdev->dev,
- codec_dev->fwnode,
+ priv->ext_amp_gpio = devm_fwnode_gpiod_get(dev, codec_dev->fwnode,
"ext-amp-enable",
GPIOD_OUT_LOW,
"speaker-amp");
@@ -1007,16 +1018,13 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
priv->ext_amp_gpio = NULL;
break;
default:
- dev_err(&pdev->dev, "Failed to get ext-amp-enable GPIO: %d\n",
- ret_val);
+ dev_err(dev, "Failed to get ext-amp-enable GPIO: %d\n", ret_val);
fallthrough;
case -EPROBE_DEFER:
- put_device(codec_dev);
- return ret_val;
+ goto err;
}
}
- priv->hp_detect = devm_fwnode_gpiod_get(&pdev->dev,
- codec_dev->fwnode,
+ priv->hp_detect = devm_fwnode_gpiod_get(dev, codec_dev->fwnode,
"hp-detect",
GPIOD_IN,
"hp-detect");
@@ -1027,19 +1035,15 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
priv->hp_detect = NULL;
break;
default:
- dev_err(&pdev->dev, "Failed to get hp-detect GPIO: %d\n",
- ret_val);
+ dev_err(dev, "Failed to get hp-detect GPIO: %d\n", ret_val);
fallthrough;
case -EPROBE_DEFER:
- put_device(codec_dev);
- return ret_val;
+ goto err;
}
}
}
- put_device(codec_dev);
-
- log_quirks(&pdev->dev);
+ log_quirks(dev);
if ((byt_rt5651_quirk & BYT_RT5651_SSP2_AIF2) ||
(byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2))
@@ -1050,21 +1054,18 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
byt_rt5651_dais[dai_index].cpus->dai_name = "ssp0-port";
if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) {
- priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
+ priv->mclk = devm_clk_get_optional(dev, "pmc_plt_clk_3");
if (IS_ERR(priv->mclk)) {
- ret_val = PTR_ERR(priv->mclk);
- dev_err(&pdev->dev,
- "Failed to get MCLK from pmc_plt_clk_3: %d\n",
- ret_val);
- /*
- * Fall back to bit clock usage for -ENOENT (clock not
- * available likely due to missing dependencies), bail
- * for all other errors, including -EPROBE_DEFER
- */
- if (ret_val != -ENOENT)
- return ret_val;
- byt_rt5651_quirk &= ~BYT_RT5651_MCLK_EN;
+ ret_val = dev_err_probe(dev, PTR_ERR(priv->mclk),
+ "Failed to get MCLK from pmc_plt_clk_3\n");
+ goto err;
}
+ /*
+ * Fall back to bit clock usage when clock is not
+ * available likely due to missing dependencies.
+ */
+ if (!priv->mclk)
+ byt_rt5651_quirk &= ~BYT_RT5651_MCLK_EN;
}
snprintf(byt_rt5651_components, sizeof(byt_rt5651_components),
@@ -1085,33 +1086,59 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
byt_rt5651_card.long_name = byt_rt5651_long_name;
#endif
- /* override plaform name, if required */
+ /* override platform name, if required */
platform_name = mach->mach_params.platform;
ret_val = snd_soc_fixup_dai_links_platform_name(&byt_rt5651_card,
platform_name);
if (ret_val)
- return ret_val;
+ goto err;
- ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5651_card);
+ sof_parent = snd_soc_acpi_sof_parent(dev);
+ /* set card and driver name */
+ if (sof_parent) {
+ byt_rt5651_card.name = SOF_CARD_NAME;
+ byt_rt5651_card.driver_name = SOF_DRIVER_NAME;
+ } else {
+ byt_rt5651_card.name = CARD_NAME;
+ byt_rt5651_card.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, &byt_rt5651_card);
if (ret_val) {
- dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n",
- ret_val);
- return ret_val;
+ dev_err(dev, "devm_snd_soc_register_card failed %d\n", ret_val);
+ goto err;
}
platform_set_drvdata(pdev, &byt_rt5651_card);
return ret_val;
+
+err:
+ device_remove_software_node(priv->codec_dev);
+err_device:
+ put_device(priv->codec_dev);
+ return ret_val;
+}
+
+static void snd_byt_rt5651_mc_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card);
+
+ device_remove_software_node(priv->codec_dev);
+ put_device(priv->codec_dev);
}
static struct platform_driver snd_byt_rt5651_mc_driver = {
.driver = {
.name = "bytcr_rt5651",
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
- .pm = &snd_soc_pm_ops,
-#endif
},
.probe = snd_byt_rt5651_mc_probe,
+ .remove = snd_byt_rt5651_mc_remove,
};
module_platform_driver(snd_byt_rt5651_mc_driver);