File Index
Files and directories
Sign in
FILE

soc_sdw_maxim.c

File preview with syntax highlighting.

linux-6.19.14/sound/soc/sdw_utils/soc_sdw_maxim.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2// This file incorporates work covered by the following copyright notice:
  3// Copyright (c) 2020 Intel Corporation
  4// Copyright (c) 2024 Advanced Micro Devices, Inc.
  5//
  6// soc_sdw_maxim - Helpers to handle maxim codecs
  7// codec devices from generic machine driver
  8
  9#include <linux/device.h>
 10#include <linux/errno.h>
 11#include <sound/control.h>
 12#include <sound/soc.h>
 13#include <sound/soc-acpi.h>
 14#include <sound/soc-dapm.h>
 15#include <sound/soc_sdw_utils.h>
 16
 17static int maxim_part_id;
 18#define SOC_SDW_PART_ID_MAX98363 0x8363
 19#define SOC_SDW_PART_ID_MAX98373 0x8373
 20
 21static const struct snd_soc_dapm_route max_98373_dapm_routes[] = {
 22	{ "Left Spk", NULL, "Left BE_OUT" },
 23	{ "Right Spk", NULL, "Right BE_OUT" },
 24};
 25
 26int asoc_sdw_maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
 27{
 28	struct snd_soc_card *card = rtd->card;
 29	struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
 30	int ret;
 31
 32	ret = snd_soc_dapm_add_routes(dapm, max_98373_dapm_routes, 2);
 33	if (ret)
 34		dev_err(rtd->dev, "failed to add first SPK map: %d\n", ret);
 35
 36	return ret;
 37}
 38EXPORT_SYMBOL_NS(asoc_sdw_maxim_spk_rtd_init, "SND_SOC_SDW_UTILS");
 39
 40static int asoc_sdw_mx8373_enable_spk_pin(struct snd_pcm_substream *substream, bool enable)
 41{
 42	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 43	struct snd_soc_dai *codec_dai;
 44	struct snd_soc_dai *cpu_dai;
 45	int ret;
 46	int j;
 47
 48	/* set spk pin by playback only */
 49	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
 50		return 0;
 51
 52	cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
 53	for_each_rtd_codec_dais(rtd, j, codec_dai) {
 54		struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(cpu_dai->component);
 55		char pin_name[16];
 56
 57		snprintf(pin_name, ARRAY_SIZE(pin_name), "%s Spk",
 58			 codec_dai->component->name_prefix);
 59
 60		if (enable)
 61			ret = snd_soc_dapm_enable_pin(dapm, pin_name);
 62		else
 63			ret = snd_soc_dapm_disable_pin(dapm, pin_name);
 64
 65		if (!ret)
 66			snd_soc_dapm_sync(dapm);
 67	}
 68
 69	return 0;
 70}
 71
 72static int asoc_sdw_mx8373_prepare(struct snd_pcm_substream *substream)
 73{
 74	int ret;
 75
 76	/* according to soc_pcm_prepare dai link prepare is called first */
 77	ret = asoc_sdw_prepare(substream);
 78	if (ret < 0)
 79		return ret;
 80
 81	return asoc_sdw_mx8373_enable_spk_pin(substream, true);
 82}
 83
 84static int asoc_sdw_mx8373_hw_free(struct snd_pcm_substream *substream)
 85{
 86	int ret;
 87
 88	/* according to soc_pcm_hw_free dai link free is called first */
 89	ret = asoc_sdw_hw_free(substream);
 90	if (ret < 0)
 91		return ret;
 92
 93	return asoc_sdw_mx8373_enable_spk_pin(substream, false);
 94}
 95
 96static const struct snd_soc_ops max_98373_sdw_ops = {
 97	.startup = asoc_sdw_startup,
 98	.prepare = asoc_sdw_mx8373_prepare,
 99	.trigger = asoc_sdw_trigger,
100	.hw_params = asoc_sdw_hw_params,
101	.hw_free = asoc_sdw_mx8373_hw_free,
102	.shutdown = asoc_sdw_shutdown,
103};
104
105static int asoc_sdw_mx8373_sdw_late_probe(struct snd_soc_card *card)
106{
107	struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
108
109	/* Disable Left and Right Spk pin after boot */
110	snd_soc_dapm_disable_pin(dapm, "Left Spk");
111	snd_soc_dapm_disable_pin(dapm, "Right Spk");
112	return snd_soc_dapm_sync(dapm);
113}
114
115int asoc_sdw_maxim_init(struct snd_soc_card *card,
116			struct snd_soc_dai_link *dai_links,
117			struct asoc_sdw_codec_info *info,
118			bool playback)
119{
120	info->amp_num++;
121
122	maxim_part_id = info->part_id;
123	switch (maxim_part_id) {
124	case SOC_SDW_PART_ID_MAX98363:
125		/* Default ops are set in function init_dai_link.
126		 * called as part of function create_sdw_dailink
127		 */
128		break;
129	case SOC_SDW_PART_ID_MAX98373:
130		info->codec_card_late_probe = asoc_sdw_mx8373_sdw_late_probe;
131		dai_links->ops = &max_98373_sdw_ops;
132		break;
133	default:
134		dev_err(card->dev, "Invalid maxim_part_id %#x\n", maxim_part_id);
135		return -EINVAL;
136	}
137	return 0;
138}
139EXPORT_SYMBOL_NS(asoc_sdw_maxim_init, "SND_SOC_SDW_UTILS");
~/ Read-only file preview.