4. hda设备中的pcm文件 (第三部分)

4.2.3 azx_probe_work

回顾一下azx_create中最后部分的一行代码:

INIT_DELAYED_WORK(&hda->probe_work, azx_probe_work);

初始化了一个延时work。

再回到azx_probe的最后部分:

if (schedule_probe)
	schedule_delayed_work(&hda->probe_work, 0);

azx_probe_work被放到了延时处理的消息列表中去执行。

static void azx_probe_work(struct work_struct *work)
{
	struct hda_intel *hda = container_of(work, struct hda_intel, probe_work.work);
	azx_probe_continue(&hda->chip);
}

azx_probe_work是通过azx_probe_continue来完成任务的。

static int azx_probe_continue(struct azx *chip)
{
	struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
	struct hdac_bus *bus = azx_bus(chip);
	struct pci_dev *pci = chip->pci;
	int dev = chip->dev_index;
	int err;

	.......
	err = azx_first_init(chip);
	if (err < 0)
		goto out_free;

    ......

	/* create codec instances */
	if (bus->codec_mask) {
		err = azx_probe_codecs(chip, azx_max_codecs[chip->driver_type]);
		if (err < 0)
			goto out_free;
	}

    ......
	complete_all(&hda->probe_wait);
	to_hda_bus(bus)->bus_probing = 0;
	hda->probe_retry = 0;
	return 0;
}

这段代码中我去除了一些针对特殊设备的特殊处理,以及在初始化失败后尝试再次启动延时work的相关代码。只是想照着主线,推进我们的理解。

这时候我们要面对的就是两个函数azx_first_init和azx_probe_codecs。

4.2.3.1 azx_first_init

static int azx_first_init(struct azx *chip)
{
	int dev = chip->dev_index;
	struct pci_dev *pci = chip->pci;
	struct snd_card *card = chip->card;
	struct hdac_bus *bus = azx_bus(chip);
	int err;
	unsigned short gcap;
	unsigned int dma_bits = 64;

#if BITS_PER_LONG != 64
	/* Fix up base address on ULI M5461 */
	if (chip->driver_type == AZX_DRIVER_ULI) {
		u16 tmp3;
		pci_read_config_word(pci, 0x40, &tmp3);
		pci_write_config_word(pci, 0x40, tmp3 | 0x10);
		pci_write_config_dword(pci, PCI_BASE_ADDRESS_1, 0);
	}
#endif
    // 以下三个函数用来分配和获取IO空间
	err = pcim_iomap_regions(pci, 1 << 0, "ICH HD audio");
	if (err < 0)
		return err;

	bus->addr = pci_resource_start(pci, 0);
	bus->remap_addr = pcim_iomap_table(pci)[0];

	if (chip->driver_type == AZX_DRIVER_SKL)
		snd_hdac_bus_parse_capabilities(bus);

	/*
	 * Some Intel CPUs has always running timer (ART) feature and
	 * controller may have Global time sync reporting capability, so
	 * check both of these before declaring synchronized time reporting
	 * capability SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME
	 */
// gts_present是针对get_time_info的特殊处理,在中断的时候同步硬件信息,后续讲到读取音频的时候会用到。
	chip->gts_present = false;

#ifdef CONFIG_X86
	if (bus->ppcap && boot_cpu_has(X86_FEATURE_ART))
		chip->gts_present = true;
#endif

	if (chip->msi) {
		if (chip->driver_caps & AZX_DCAPS_NO_MSI64) {
			dev_dbg(card->dev, "Disabling 64bit MSI\n");
			pci->no_64bit_msi = true;
		}
		if (pci_enable_msi(pci) < 0)
			chip->msi = 0;
	}

//设置过后,才能从pci总线发送消息到设备
	pci_set_master(pci);

// 读取GCAP 注存器信息
	gcap = 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值