歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> ALSA在Linux3.1上的一些改進

ALSA在Linux3.1上的一些改進

日期:2017/3/1 10:34:49   编辑:Linux編程

Android邁進了4.0,相應的Linux內核也進入了3.x時代。之後的一個工作估計要將2.6.32的驅動移植到3.x上面來。因此趁現在有空,看看alsa在這方面有什麼改動。

總的來說,架構大的改動是不大可能的。codec中幾個關鍵結構體沒有大的變化,如snd_soc_dai_ops、snd_soc_dai_driver(相當於2.6.32中的snd_soc_dai),倒是以前的snd_soc_codec_device重定義為snd_soc_codec_driver,這個算是最明顯的。


注冊用結構體-snd_soc_codec_driver


2.6.32:

[cpp]
  1. /* codec device */
  2. struct snd_soc_codec_device {
  3. int (*probe)(struct platform_device *pdev);
  4. int (*remove)(struct platform_device *pdev);
  5. int (*suspend)(struct platform_device *pdev, pm_message_t state);
  6. int (*resume)(struct platform_device *pdev);
  7. };
3.1.1: [cpp]
  1. /* codec driver */
  2. struct snd_soc_codec_driver {
  3. /* driver ops */
  4. int (*probe)(struct snd_soc_codec *);
  5. int (*remove)(struct snd_soc_codec *);
  6. int (*suspend)(struct snd_soc_codec *,
  7. pm_message_t state);
  8. int (*resume)(struct snd_soc_codec *);
  9. /* Default control and setup, added after probe() is run */
  10. const struct snd_kcontrol_new *controls;
  11. int num_controls;
  12. const struct snd_soc_dapm_widget *dapm_widgets;
  13. int num_dapm_widgets;
  14. const struct snd_soc_dapm_route *dapm_routes;
  15. int num_dapm_routes;
  16. /* codec wide operations */
  17. int (*set_sysclk)(struct snd_soc_codec *codec,
  18. int clk_id, unsigned int freq, int dir);
  19. int (*set_pll)(struct snd_soc_codec *codec, int pll_id, int source,
  20. unsigned int freq_in, unsigned int freq_out);
  21. /* codec IO */
  22. unsigned int (*read)(struct snd_soc_codec *, unsigned int);
  23. int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
  24. int (*display_register)(struct snd_soc_codec *, char *,
  25. size_t, unsigned int);
  26. int (*volatile_register)(struct snd_soc_codec *, unsigned int);
  27. int (*readable_register)(struct snd_soc_codec *, unsigned int);
  28. int (*writable_register)(struct snd_soc_codec *, unsigned int);
  29. short reg_cache_size;
  30. short reg_cache_step;
  31. short reg_word_size;
  32. const void *reg_cache_default;
  33. short reg_access_size;
  34. const struct snd_soc_reg_access *reg_access_default;
  35. enum snd_soc_compress_type compress_type;
  36. /* codec bias level */
  37. int (*set_bias_level)(struct snd_soc_codec *,
  38. enum snd_soc_bias_level level);
  39. void (*seq_notifier)(struct snd_soc_dapm_context *,
  40. enum snd_soc_dapm_type, int);
  41. /* probe ordering - for components with runtime dependencies */
  42. int probe_order;
  43. int remove_order;
  44. };

位於snd_soc_codec_driver中的一些codec IO成員函數和set_bias_level回調函數原來都放在另外一個結構體snd_soc_codec中,現在放置在這裡了,這是根據源碼結構調整的結果。事實真正需要設置的成員也不是很多,如下:

[cpp]
  1. static struct snd_soc_codec_driver soc_codec_dev_wm9713 = {
  2. .probe = wm9713_soc_probe,
  3. .remove = wm9713_soc_remove,
  4. .suspend = wm9713_soc_suspend,
  5. .resume = wm9713_soc_resume,
  6. .read = ac97_read,
  7. .write = ac97_write,
  8. .set_bias_level = wm9713_set_bias_level,
  9. .reg_cache_size = ARRAY_SIZE(wm9713_reg),
  10. .reg_word_size = sizeof(u16),
  11. .reg_cache_step = 2,
  12. .reg_cache_default = wm9713_reg,
  13. .dapm_widgets = wm9713_dapm_widgets,
  14. .num_dapm_widgets = ARRAY_SIZE(wm9713_dapm_widgets),
  15. .dapm_routes = wm9713_audio_map,
  16. .num_dapm_routes = ARRAY_SIZE(wm9713_audio_map),
  17. };

probe、remove、suspend、resume相信不用累述了,volatile_register函數判斷指定的寄存器是否volatile,reg_cache_size一般為寄存器數目,reg_word_size為寄存器的字長,reg_cache_default為寄存器默認值配置表。

而dapm_widgets、dapm_routes就比較“犀利”了。之前的dapm widgets和routes分別通過函數snd_soc_dapm_new_controls和snd_soc_dapm_add_routes來注冊的(當然現在還保留這些接口),現在則可以填入到這個結構體,在soc-core裡注冊,省了不少功夫:

[cpp]
  1. static int soc_probe_codec(struct snd_soc_card *card,
  2. struct snd_soc_codec *codec)
  3. {
  4. //...
  5. if (driver->dapm_widgets)
  6. snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets,
  7. driver->num_dapm_widgets);
  8. //...
  9. if (driver->controls)
  10. snd_soc_add_controls(codec, driver->controls,
  11. driver->num_controls);
  12. if (driver->dapm_routes)
  13. snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes,
  14. driver->num_dapm_routes);
  15. //...
  16. }


同時可看到dirver ops的函數參數有所不同了,以前是struct platform_device *pdev,現在改為struct snd_soc_codec *codec,這個與codec的注冊函數snd_soc_register_codec和設備的drvdata有關,之後會逐一分析。

Copyright © Linux教程網 All Rights Reserved