Skip to content

Commit 28a09d9

Browse files
Shenghao-Dingtiwai
authored andcommitted
ALSA: hda/tas2781: Create an independent lib to save the shared parts for both SPI and I2C driver
Some common parts, such as struct tas2781_hda{...} and some audio kcontrols are moved into an independent lib for code cleanup. Signed-off-by: Shenghao Ding <shenghao-ding@ti.com> Link: https://patch.msgid.link/20250507045813.151-1-shenghao-ding@ti.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent 845b997 commit 28a09d9

6 files changed

Lines changed: 405 additions & 457 deletions

File tree

sound/pci/hda/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,17 @@ config SND_HDA_SCODEC_CS35L56_SPI
180180
Say Y or M here to include CS35L56 amplifier support with
181181
SPI control.
182182

183+
config SND_HDA_SCODEC_TAS2781
184+
tristate
185+
select SND_HDA_GENERIC
186+
183187
config SND_HDA_SCODEC_TAS2781_I2C
184188
tristate "Build TAS2781 HD-audio side codec support for I2C Bus"
185189
depends on I2C
186190
depends on ACPI
187191
depends on EFI
188192
depends on SND_SOC
193+
select SND_HDA_SCODEC_TAS2781
189194
select SND_SOC_TAS2781_COMLIB_I2C
190195
select SND_SOC_TAS2781_FMWLIB
191196
select CRC32
@@ -202,6 +207,8 @@ config SND_HDA_SCODEC_TAS2781_SPI
202207
depends on ACPI
203208
depends on EFI
204209
depends on SND_SOC
210+
select SND_HDA_SCODEC_TAS2781
211+
select SND_SOC_TAS2781_COMLIB
205212
select SND_SOC_TAS2781_FMWLIB
206213
select CRC8
207214
select CRC32

sound/pci/hda/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ snd-hda-scodec-cs35l56-y := cs35l56_hda.o
3838
snd-hda-scodec-cs35l56-i2c-y := cs35l56_hda_i2c.o
3939
snd-hda-scodec-cs35l56-spi-y := cs35l56_hda_spi.o
4040
snd-hda-scodec-component-y := hda_component.o
41+
snd-hda-scodec-tas2781-y := tas2781_hda.o
4142
snd-hda-scodec-tas2781-i2c-y := tas2781_hda_i2c.o
4243
snd-hda-scodec-tas2781-spi-y := tas2781_hda_spi.o
4344

@@ -70,6 +71,7 @@ obj-$(CONFIG_SND_HDA_SCODEC_CS35L56) += snd-hda-scodec-cs35l56.o
7071
obj-$(CONFIG_SND_HDA_SCODEC_CS35L56_I2C) += snd-hda-scodec-cs35l56-i2c.o
7172
obj-$(CONFIG_SND_HDA_SCODEC_CS35L56_SPI) += snd-hda-scodec-cs35l56-spi.o
7273
obj-$(CONFIG_SND_HDA_SCODEC_COMPONENT) += snd-hda-scodec-component.o
74+
obj-$(CONFIG_SND_HDA_SCODEC_TAS2781) += snd-hda-scodec-tas2781.o
7375
obj-$(CONFIG_SND_HDA_SCODEC_TAS2781_I2C) += snd-hda-scodec-tas2781-i2c.o
7476
obj-$(CONFIG_SND_HDA_SCODEC_TAS2781_SPI) += snd-hda-scodec-tas2781-spi.o
7577

sound/pci/hda/tas2781_hda.c

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
//
3+
// TAS2781 HDA Shared Lib for I2C&SPI driver
4+
//
5+
// Copyright 2025 Texas Instruments, Inc.
6+
//
7+
// Author: Shenghao Ding <shenghao-ding@ti.com>
8+
9+
#include <linux/component.h>
10+
#include <linux/crc8.h>
11+
#include <linux/crc32.h>
12+
#include <linux/efi.h>
13+
#include <linux/firmware.h>
14+
#include <linux/i2c.h>
15+
#include <linux/pm_runtime.h>
16+
#include <sound/soc.h>
17+
#include <sound/tas2781.h>
18+
19+
#include "tas2781_hda.h"
20+
21+
void tas2781_hda_remove(struct device *dev,
22+
const struct component_ops *ops)
23+
{
24+
struct tas2781_hda *tas_hda = dev_get_drvdata(dev);
25+
26+
component_del(tas_hda->dev, ops);
27+
28+
pm_runtime_get_sync(tas_hda->dev);
29+
pm_runtime_disable(tas_hda->dev);
30+
31+
pm_runtime_put_noidle(tas_hda->dev);
32+
33+
tasdevice_remove(tas_hda->priv);
34+
}
35+
EXPORT_SYMBOL_NS_GPL(tas2781_hda_remove, "SND_HDA_SCODEC_TAS2781");
36+
37+
int tasdevice_info_profile(struct snd_kcontrol *kcontrol,
38+
struct snd_ctl_elem_info *uinfo)
39+
{
40+
struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
41+
42+
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
43+
uinfo->count = 1;
44+
uinfo->value.integer.min = 0;
45+
uinfo->value.integer.max = tas_priv->rcabin.ncfgs - 1;
46+
47+
return 0;
48+
}
49+
EXPORT_SYMBOL_NS_GPL(tasdevice_info_profile, "SND_HDA_SCODEC_TAS2781");
50+
51+
int tasdevice_info_programs(struct snd_kcontrol *kcontrol,
52+
struct snd_ctl_elem_info *uinfo)
53+
{
54+
struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
55+
56+
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
57+
uinfo->count = 1;
58+
uinfo->value.integer.min = 0;
59+
uinfo->value.integer.max = tas_priv->fmw->nr_programs - 1;
60+
61+
return 0;
62+
}
63+
EXPORT_SYMBOL_NS_GPL(tasdevice_info_programs, "SND_HDA_SCODEC_TAS2781");
64+
65+
int tasdevice_info_config(struct snd_kcontrol *kcontrol,
66+
struct snd_ctl_elem_info *uinfo)
67+
{
68+
struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
69+
struct tasdevice_fw *tas_fw = tas_priv->fmw;
70+
71+
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
72+
uinfo->count = 1;
73+
uinfo->value.integer.min = 0;
74+
uinfo->value.integer.max = tas_fw->nr_configurations - 1;
75+
76+
return 0;
77+
}
78+
EXPORT_SYMBOL_NS_GPL(tasdevice_info_config, "SND_HDA_SCODEC_TAS2781");
79+
80+
int tasdevice_get_profile_id(struct snd_kcontrol *kcontrol,
81+
struct snd_ctl_elem_value *ucontrol)
82+
{
83+
struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
84+
85+
ucontrol->value.integer.value[0] = tas_priv->rcabin.profile_cfg_id;
86+
87+
dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d\n", __func__,
88+
kcontrol->id.name, tas_priv->rcabin.profile_cfg_id);
89+
90+
return 0;
91+
}
92+
EXPORT_SYMBOL_NS_GPL(tasdevice_get_profile_id, "SND_HDA_SCODEC_TAS2781");
93+
94+
int tasdevice_set_profile_id(struct snd_kcontrol *kcontrol,
95+
struct snd_ctl_elem_value *ucontrol)
96+
{
97+
struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
98+
int profile_id = ucontrol->value.integer.value[0];
99+
int max = tas_priv->rcabin.ncfgs - 1;
100+
int val, ret = 0;
101+
102+
val = clamp(profile_id, 0, max);
103+
104+
guard(mutex)(&tas_priv->codec_lock);
105+
106+
dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d -> %d\n", __func__,
107+
kcontrol->id.name, tas_priv->rcabin.profile_cfg_id, val);
108+
109+
if (tas_priv->rcabin.profile_cfg_id != val) {
110+
tas_priv->rcabin.profile_cfg_id = val;
111+
ret = 1;
112+
}
113+
114+
return ret;
115+
}
116+
EXPORT_SYMBOL_NS_GPL(tasdevice_set_profile_id, "SND_HDA_SCODEC_TAS2781");
117+
118+
int tasdevice_program_get(struct snd_kcontrol *kcontrol,
119+
struct snd_ctl_elem_value *ucontrol)
120+
{
121+
struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
122+
123+
ucontrol->value.integer.value[0] = tas_priv->cur_prog;
124+
125+
dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d\n", __func__,
126+
kcontrol->id.name, tas_priv->cur_prog);
127+
128+
return 0;
129+
}
130+
EXPORT_SYMBOL_NS_GPL(tasdevice_program_get, "SND_HDA_SCODEC_TAS2781");
131+
132+
int tasdevice_program_put(struct snd_kcontrol *kcontrol,
133+
struct snd_ctl_elem_value *ucontrol)
134+
{
135+
struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
136+
struct tasdevice_fw *tas_fw = tas_priv->fmw;
137+
int nr_program = ucontrol->value.integer.value[0];
138+
int max = tas_fw->nr_programs - 1;
139+
int val, ret = 0;
140+
141+
val = clamp(nr_program, 0, max);
142+
143+
guard(mutex)(&tas_priv->codec_lock);
144+
145+
dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d -> %d\n", __func__,
146+
kcontrol->id.name, tas_priv->cur_prog, val);
147+
148+
if (tas_priv->cur_prog != val) {
149+
tas_priv->cur_prog = val;
150+
ret = 1;
151+
}
152+
153+
return ret;
154+
}
155+
EXPORT_SYMBOL_NS_GPL(tasdevice_program_put, "SND_HDA_SCODEC_TAS2781");
156+
157+
int tasdevice_config_get(struct snd_kcontrol *kcontrol,
158+
struct snd_ctl_elem_value *ucontrol)
159+
{
160+
struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
161+
162+
ucontrol->value.integer.value[0] = tas_priv->cur_conf;
163+
164+
dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d\n", __func__,
165+
kcontrol->id.name, tas_priv->cur_conf);
166+
167+
return 0;
168+
}
169+
EXPORT_SYMBOL_NS_GPL(tasdevice_config_get, "SND_HDA_SCODEC_TAS2781");
170+
171+
int tasdevice_config_put(struct snd_kcontrol *kcontrol,
172+
struct snd_ctl_elem_value *ucontrol)
173+
{
174+
struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
175+
struct tasdevice_fw *tas_fw = tas_priv->fmw;
176+
int nr_config = ucontrol->value.integer.value[0];
177+
int max = tas_fw->nr_configurations - 1;
178+
int val, ret = 0;
179+
180+
val = clamp(nr_config, 0, max);
181+
182+
guard(mutex)(&tas_priv->codec_lock);
183+
184+
dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d -> %d\n", __func__,
185+
kcontrol->id.name, tas_priv->cur_conf, val);
186+
187+
if (tas_priv->cur_conf != val) {
188+
tas_priv->cur_conf = val;
189+
ret = 1;
190+
}
191+
192+
return ret;
193+
}
194+
EXPORT_SYMBOL_NS_GPL(tasdevice_config_put, "SND_HDA_SCODEC_TAS2781");
195+
196+
MODULE_DESCRIPTION("TAS2781 HDA Driver");
197+
MODULE_LICENSE("GPL");
198+
MODULE_AUTHOR("Shenghao Ding, TI, <shenghao-ding@ti.com>");

sound/pci/hda/tas2781_hda.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,35 @@
4444
.private_value = xdata, \
4545
}
4646

47+
struct tas2781_hda {
48+
struct device *dev;
49+
struct tasdevice_priv *priv;
50+
struct snd_kcontrol *dsp_prog_ctl;
51+
struct snd_kcontrol *dsp_conf_ctl;
52+
struct snd_kcontrol *prof_ctl;
53+
enum device_catlog_id catlog_id;
54+
void *hda_priv;
55+
};
56+
57+
void tas2781_hda_remove(struct device *dev,
58+
const struct component_ops *ops);
59+
int tasdevice_info_profile(struct snd_kcontrol *kctl,
60+
struct snd_ctl_elem_info *uctl);
61+
int tasdevice_info_programs(struct snd_kcontrol *kctl,
62+
struct snd_ctl_elem_info *uctl);
63+
int tasdevice_info_config(struct snd_kcontrol *kctl,
64+
struct snd_ctl_elem_info *uctl);
65+
int tasdevice_set_profile_id(struct snd_kcontrol *kctl,
66+
struct snd_ctl_elem_value *uctl);
67+
int tasdevice_get_profile_id(struct snd_kcontrol *kctl,
68+
struct snd_ctl_elem_value *uctl);
69+
int tasdevice_program_get(struct snd_kcontrol *kctl,
70+
struct snd_ctl_elem_value *uctl);
71+
int tasdevice_program_put(struct snd_kcontrol *kctl,
72+
struct snd_ctl_elem_value *uctl);
73+
int tasdevice_config_put(struct snd_kcontrol *kctl,
74+
struct snd_ctl_elem_value *uctl);
75+
int tasdevice_config_get(struct snd_kcontrol *kctl,
76+
struct snd_ctl_elem_value *uctl);
77+
4778
#endif

0 commit comments

Comments
 (0)