Linux ALSA声卡驱动详细分析(3)

2019-01-27 16:59

22. strncpy(card->driver, dev->dev.driver->name, sizeof(card->driver)); 23.

24. ////(4)////

25. ret = pxa2xx_pcm_new(card, &pxa2xx_ac97_pcm_client, &pxa2xx_ac97_pcm); 26. if (ret) 27. goto err; 28. ////(2)////

29. ret = pxa2xx_ac97_hw_probe(dev); 30. if (ret) 31. goto err; 32.

33. ////(4)////

34. ret = snd_ac97_bus(card, 0, &pxa2xx_ac97_ops, NULL, &ac97_bus); 35. if (ret)

36. goto err_remove;

37. memset(&ac97_template, 0, sizeof(ac97_template));

38. ret = snd_ac97_mixer(ac97_bus, &ac97_template, &pxa2xx_ac97_ac97); 39. if (ret)

40. goto err_remove; 41. ////(3)////

42. snprintf(card->shortname, sizeof(card->shortname), 43. \, snd_ac97_get_short_name(pxa2xx_ac97_ac97)); 44. snprintf(card->longname, sizeof(card->longname),

45. \, dev->dev.driver->name, card->mixername); 46.

47. if (pdata && pdata->codec_pdata[0])

48. snd_ac97_dev_add_pdata(ac97_bus->codec[0], pdata->codec_pdata[0]); 49. snd_card_set_dev(card, &dev->dev); 50. ////(5)////

51. ret = snd_card_register(card); 52. if (ret == 0) {

53. platform_set_drvdata(dev, card); 54. return 0; 55. } 56.

57. err_remove:

58. pxa2xx_ac97_hw_remove(dev); 59. err:

60. if (card)

61. snd_card_free(card); 62. err_dev: 63. return ret; 64. } 65.

11

66. static int __devexit pxa2xx_ac97_remove(struct platform_device *dev) 67. {

68. struct snd_card *card = platform_get_drvdata(dev); 69.

70. if (card) {

71. snd_card_free(card);

72. platform_set_drvdata(dev, NULL); 73. pxa2xx_ac97_hw_remove(dev); 74. } 75.

76. return 0; 77. } 78.

79. static struct platform_driver pxa2xx_ac97_driver = { 80. .probe = pxa2xx_ac97_probe,

81. .remove = __devexit_p(pxa2xx_ac97_remove), 82. .driver = {

83. .name = \, 84. .owner = THIS_MODULE, 85. #ifdef CONFIG_PM

86. .pm = &pxa2xx_ac97_pm_ops, 87. #endif 88. }, 89. }; 90.

91. static int __init pxa2xx_ac97_init(void) 92. {

93. return platform_driver_register(&pxa2xx_ac97_driver); 94. } 95.

96. static void __exit pxa2xx_ac97_exit(void) 97. {

98. platform_driver_unregister(&pxa2xx_ac97_driver); 99. } 100.

101. module_init(pxa2xx_ac97_init); 102. module_exit(pxa2xx_ac97_exit); 103.

104. MODULE_AUTHOR(\);

105. MODULE_DESCRIPTION(\);

驱动程序通常由probe回调函数开始,对一下2.1中的步骤,是否有相似之处? 经过以上的创建步骤之后,声卡的逻辑结构如下图所示:

12

图 2.2.1 声卡的软件逻辑结构

下面的章节里我们分别讨论一下snd_card_create()和snd_card_register()这两个函数。

3. snd_card_create()

snd_card_create()在/sound/core/init.c中定义。 [cpp] view plain copy

1. /**

2. * snd_card_create - create and initialize a soundcard structure

3. * @idx: card index (address) [0 ... (SNDRV_CARDS-1)] 4. * @xid: card identification (ASCII string) 5. * @module: top level module for locking

6. * @extra_size: allocate this extra size after the main soundcard structure

7. * @card_ret: the pointer to store the created card instance 8. *

9. * Creates and initializes a soundcard structure. 10. *

11. * The function allocates snd_card instance via kzalloc with the given

12. * space for the driver to use freely. The allocated struct is stored

13. * in the given card_ret pointer. 14. *

13

15. * Returns zero if successful or a negative error code.

16. */

17. int snd_card_create(int idx, const char *xid,

18. struct module *module, int extra_size, 19. struct snd_card **card_ret)

首先,根据extra_size参数的大小分配内存,该内存区可以作为芯片的专有数据使用(见前面的介绍): [c-sharp] view plain copy 1. card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL); 2. if (!card)

3. return -ENOMEM; 拷贝声卡的ID字符串: [c-sharp] view plain copy 1. if (xid)

2. strlcpy(card->id, xid, sizeof(card->id)); 如果传入的声卡编号为-1,自动分配一个索引编号: [c-sharp] view plain copy 1. if (idx < 0) {

2. for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++)

3. /* idx == -1 == 0xffff means: take any free slot */

4. if (~snd_cards_lock & idx & 1<

5. if (module_slot_match(module, idx2)) { 6. idx = idx2; 7. break; 8. } 9. } 10. }

11. if (idx < 0) {

12. for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++)

13. /* idx == -1 == 0xffff means: take any free slot */

14. if (~snd_cards_lock & idx & 1<

14

16. idx = idx2; 17. break; 18. } 19. } 20. }

初始化snd_card结构中必要的字段: [c-sharp] view plain copy 1. card->number = idx; 2. card->module = module;

3. INIT_LIST_HEAD(&card->devices); 4. init_rwsem(&card->controls_rwsem); 5. rwlock_init(&card->ctl_files_rwlock); 6. INIT_LIST_HEAD(&card->controls); 7. INIT_LIST_HEAD(&card->ctl_files); 8. spin_lock_init(&card->files_lock); 9. INIT_LIST_HEAD(&card->files_list);

10. init_waitqueue_head(&card->shutdown_sleep); 11. #ifdef CONFIG_PM

12. mutex_init(&card->power_lock);

13. init_waitqueue_head(&card->power_sleep); 14. #endif 建立逻辑设备:Control [c-sharp] view plain copy 1. /* the control interface cannot be accessed from the user space until */

2. /* snd_cards_bitmask and snd_cards are set with snd_card_register */

3. err = snd_ctl_create(card);

建立proc文件中的info节点:通常就是/proc/asound/card0 [c-sharp] view plain copy 1. err = snd_info_card_create(card); 把第一步分配的内存指针放入private_data字段中: [c-sharp] view plain copy 15


Linux ALSA声卡驱动详细分析(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:乡镇2014年上半年工作总结 - 0

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: