sound/pci/bt87x.c

Source file repositories/reference/linux-study-clean/sound/pci/bt87x.c

File Facts

System
Linux kernel
Corpus path
sound/pci/bt87x.c
Extension
.c
Size
28258 bytes
Lines
919
Domain
Driver Families
Bucket
sound/pci
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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.

Dependency Surface

Detected Declarations

Annotated Snippet

static struct pci_driver driver;

/* return the id of the card, or a negative value if it's on the denylist */
static int snd_bt87x_detect_card(struct pci_dev *pci)
{
	int i;
	const struct pci_device_id *supported;

	supported = pci_match_id(snd_bt87x_ids, pci);
	if (supported && supported->driver_data > 0)
		return supported->driver_data;

	for (i = 0; i < ARRAY_SIZE(denylist); ++i)
		if (denylist[i].subvendor == pci->subsystem_vendor &&
		    denylist[i].subdevice == pci->subsystem_device) {
			dev_dbg(&pci->dev,
				"card %#04x-%#04x:%#04x has no audio\n",
				    pci->device, pci->subsystem_vendor, pci->subsystem_device);
			return -EBUSY;
		}

	dev_info(&pci->dev, "unknown card %#04x-%#04x:%#04x\n",
		   pci->device, pci->subsystem_vendor, pci->subsystem_device);
	dev_info(&pci->dev, "please mail id, board name, and, "
		   "if it works, the correct digital_rate option to "
		   "<alsa-devel@alsa-project.org>\n");
	return SND_BT87X_BOARD_UNKNOWN;
}

static int __snd_bt87x_probe(struct pci_dev *pci,
			     const struct pci_device_id *pci_id)
{
	static int dev;
	struct snd_card *card;
	struct snd_bt87x *chip;
	int err;
	enum snd_bt87x_boardid boardid;

	if (!pci_id->driver_data) {
		err = snd_bt87x_detect_card(pci);
		if (err < 0)
			return -ENODEV;
		boardid = err;
	} else
		boardid = pci_id->driver_data;

	if (dev >= SNDRV_CARDS)
		return -ENODEV;
	if (!enable[dev]) {
		++dev;
		return -ENOENT;
	}

	err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
				sizeof(*chip), &card);
	if (err < 0)
		return err;
	chip = card->private_data;

	err = snd_bt87x_create(card, pci);
	if (err < 0)
		return err;

	memcpy(&chip->board, &snd_bt87x_boards[boardid], sizeof(chip->board));

	if (!chip->board.no_digital) {
		if (digital_rate[dev] > 0)
			chip->board.dig_rate = digital_rate[dev];

		chip->reg_control |= chip->board.digital_fmt;

		err = snd_bt87x_pcm(chip, DEVICE_DIGITAL, "Bt87x Digital");
		if (err < 0)
			return err;
	}
	if (!chip->board.no_analog) {
		err = snd_bt87x_pcm(chip, DEVICE_ANALOG, "Bt87x Analog");
		if (err < 0)
			return err;
		err = snd_ctl_add(card, snd_ctl_new1(
				  &snd_bt87x_capture_volume, chip));
		if (err < 0)
			return err;
		err = snd_ctl_add(card, snd_ctl_new1(
				  &snd_bt87x_capture_boost, chip));
		if (err < 0)
			return err;
		err = snd_ctl_add(card, snd_ctl_new1(
				  &snd_bt87x_capture_source, chip));
		if (err < 0)

Annotation

Implementation Notes