sound/hda/codecs/side-codecs/tas2781_hda_i2c.c
Source file repositories/reference/linux-study-clean/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c
File Facts
- System
- Linux kernel
- Corpus path
sound/hda/codecs/side-codecs/tas2781_hda_i2c.c- Extension
.c- Size
- 22763 bytes
- Lines
- 828
- Domain
- Driver Families
- Bucket
- sound/hda
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/unaligned.hlinux/acpi.hlinux/crc8.hlinux/crc32.hlinux/efi.hlinux/firmware.hlinux/i2c.hlinux/mod_devicetable.hlinux/module.hlinux/pci_ids.hlinux/pm_runtime.hlinux/regmap.hsound/hda_codec.hsound/soc.hsound/tas2781.hsound/tas2781-comlib-i2c.hsound/tlv.hsound/tas2770-tlv.hsound/tas2781-tlv.hsound/tas5825-tlv.hhda_local.hhda_auto_parser.hhda_component.hhda_jack.h../generic.htas2781_hda.h
Detected Declarations
struct tas2781_hda_i2c_privenum device_chip_idfunction tas2781_get_i2c_resfunction tas2781_read_acpifunction tas2781_hda_playback_hookfunction scoped_guardfunction scoped_guardfunction tas2781_amp_getvolfunction tas2781_amp_putvolfunction tas2781_force_fwload_getfunction tas2781_force_fwload_putfunction tas2563_save_calibrationfunction tas2781_hda_remove_controlsfunction tasdev_add_kcontrolsfunction tasdevice_dspfw_initfunction tasdev_fw_readyfunction tas2781_hda_bindfunction tas2781_hda_unbindfunction tas2781_hda_i2c_probefunction tas2781_hda_i2c_removefunction tas2781_runtime_suspendfunction tas2781_runtime_resumefunction tas2781_system_suspendfunction tas2781_system_resume
Annotated Snippet
struct tas2781_hda_i2c_priv {
struct snd_kcontrol *snd_ctls[2];
int (*save_calibration)(struct tas2781_hda *h);
int hda_chip_id;
};
static int tas2781_get_i2c_res(struct acpi_resource *ares, void *data)
{
struct tasdevice_priv *tas_priv = data;
struct acpi_resource_i2c_serialbus *sb;
if (i2c_acpi_get_i2c_resource(ares, &sb)) {
if (tas_priv->ndev < TASDEVICE_MAX_CHANNELS &&
sb->slave_address != tas_priv->global_addr) {
tas_priv->tasdevice[tas_priv->ndev].dev_addr =
(unsigned int)sb->slave_address;
tas_priv->ndev++;
}
}
return 1;
}
static const struct acpi_gpio_params speakerid_gpios = { 0, 0, false };
static const struct acpi_gpio_mapping tas2781_speaker_id_gpios[] = {
{ "speakerid-gpios", &speakerid_gpios, 1 },
{ }
};
static int tas2781_read_acpi(struct tasdevice_priv *p, const char *hid)
{
struct gpio_desc *speaker_id;
struct acpi_device *adev;
struct device *physdev;
LIST_HEAD(resources);
const char *sub;
uint32_t subid;
int ret;
adev = acpi_dev_get_first_match_dev(hid, NULL, -1);
if (!adev) {
dev_err(p->dev,
"Failed to find an ACPI device for %s\n", hid);
return -ENODEV;
}
physdev = get_device(acpi_get_first_physical_node(adev));
ret = acpi_dev_get_resources(adev, &resources, tas2781_get_i2c_res, p);
if (ret < 0) {
dev_err(p->dev, "Failed to get ACPI resource.\n");
goto err;
}
sub = acpi_get_subsystem_id(ACPI_HANDLE(physdev));
if (IS_ERR(sub)) {
/* No subsys id in older tas2563 projects. */
if (!strncmp(hid, "INT8866", sizeof("INT8866"))) {
p->speaker_id = -1;
goto end_2563;
}
dev_err(p->dev, "Failed to get SUBSYS ID.\n");
ret = PTR_ERR(sub);
goto err;
}
/* Speaker id was needed for ASUS projects. */
ret = kstrtou32(sub, 16, &subid);
if (!ret && upper_16_bits(subid) == PCI_VENDOR_ID_ASUSTEK) {
ret = acpi_dev_add_driver_gpios(adev, tas2781_speaker_id_gpios);
if (ret < 0) {
dev_err(p->dev, "Failed to add driver gpio %d.\n",
ret);
p->speaker_id = -1;
goto end_2563;
}
speaker_id = fwnode_gpiod_get_index(acpi_fwnode_handle(adev),
"speakerid", 0, GPIOD_IN, NULL);
if (!IS_ERR(speaker_id)) {
p->speaker_id = gpiod_get_value_cansleep(speaker_id);
dev_dbg(p->dev, "Got speaker id gpio from ACPI: %d.\n",
p->speaker_id);
gpiod_put(speaker_id);
} else {
p->speaker_id = -1;
ret = PTR_ERR(speaker_id);
dev_err(p->dev, "Get speaker id gpio failed %d.\n",
ret);
}
acpi_dev_remove_driver_gpios(adev);
Annotation
- Immediate include surface: `linux/unaligned.h`, `linux/acpi.h`, `linux/crc8.h`, `linux/crc32.h`, `linux/efi.h`, `linux/firmware.h`, `linux/i2c.h`, `linux/mod_devicetable.h`.
- Detected declarations: `struct tas2781_hda_i2c_priv`, `enum device_chip_id`, `function tas2781_get_i2c_res`, `function tas2781_read_acpi`, `function tas2781_hda_playback_hook`, `function scoped_guard`, `function scoped_guard`, `function tas2781_amp_getvol`, `function tas2781_amp_putvol`, `function tas2781_force_fwload_get`.
- Atlas domain: Driver Families / sound/hda.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.