sound/usb/hiface/chip.c
Source file repositories/reference/linux-study-clean/sound/usb/hiface/chip.c
File Facts
- System
- Linux kernel
- Corpus path
sound/usb/hiface/chip.c- Extension
.c- Size
- 6783 bytes
- Lines
- 272
- Domain
- Driver Families
- Bucket
- sound/usb
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/slab.hsound/initval.hchip.hpcm.h
Detected Declarations
struct hiface_vendor_quirkfunction hiface_chip_createfunction hiface_chip_probefunction hiface_chip_disconnectfunction USB_DEVICE
Annotated Snippet
struct hiface_vendor_quirk {
const char *device_name;
u8 extra_freq;
};
static int hiface_chip_create(struct usb_interface *intf,
struct usb_device *device, int idx,
const struct hiface_vendor_quirk *quirk,
struct hiface_chip **rchip)
{
struct snd_card *card = NULL;
struct hiface_chip *chip;
int ret;
int len;
*rchip = NULL;
/* if we are here, card can be registered in alsa. */
ret = snd_card_new(&intf->dev, index[idx], id[idx], THIS_MODULE,
sizeof(*chip), &card);
if (ret < 0) {
dev_err(&device->dev, "cannot create alsa card.\n");
return ret;
}
strscpy(card->driver, DRIVER_NAME, sizeof(card->driver));
if (quirk && quirk->device_name)
strscpy(card->shortname, quirk->device_name, sizeof(card->shortname));
else
strscpy(card->shortname, "M2Tech generic audio", sizeof(card->shortname));
strlcat(card->longname, card->shortname, sizeof(card->longname));
len = strlcat(card->longname, " at ", sizeof(card->longname));
if (len < sizeof(card->longname))
usb_make_path(device, card->longname + len,
sizeof(card->longname) - len);
chip = card->private_data;
chip->dev = device;
chip->card = card;
*rchip = chip;
return 0;
}
static int hiface_chip_probe(struct usb_interface *intf,
const struct usb_device_id *usb_id)
{
const struct hiface_vendor_quirk *quirk = (struct hiface_vendor_quirk *)usb_id->driver_info;
int ret;
int i;
struct hiface_chip *chip;
struct usb_device *device = interface_to_usbdev(intf);
ret = usb_set_interface(device, 0, 0);
if (ret != 0) {
dev_err(&device->dev, "can't set first interface for " CARD_NAME " device.\n");
return -EIO;
}
/* check whether the card is already registered */
chip = NULL;
guard(mutex)(®ister_mutex);
for (i = 0; i < SNDRV_CARDS; i++)
if (enable[i])
break;
if (i >= SNDRV_CARDS) {
dev_err(&device->dev, "no available " CARD_NAME " audio device\n");
return -ENODEV;
}
ret = hiface_chip_create(intf, device, i, quirk, &chip);
if (ret < 0)
return ret;
ret = hiface_pcm_init(chip, quirk ? quirk->extra_freq : 0);
if (ret < 0)
goto err_chip_destroy;
ret = snd_card_register(chip->card);
if (ret < 0) {
dev_err(&device->dev, "cannot register " CARD_NAME " card\n");
goto err_chip_destroy;
}
usb_set_intfdata(intf, chip);
return 0;
Annotation
- Immediate include surface: `linux/module.h`, `linux/slab.h`, `sound/initval.h`, `chip.h`, `pcm.h`.
- Detected declarations: `struct hiface_vendor_quirk`, `function hiface_chip_create`, `function hiface_chip_probe`, `function hiface_chip_disconnect`, `function USB_DEVICE`.
- Atlas domain: Driver Families / sound/usb.
- 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.