hdac_ext_bus.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * hdac-ext-bus.c - HD-audio extended core bus functions.
  4. *
  5. * Copyright (C) 2014-2015 Intel Corp
  6. * Author: Jeeja KP <[email protected]>
  7. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  8. *
  9. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  10. */
  11. #include <linux/module.h>
  12. #include <linux/slab.h>
  13. #include <linux/io.h>
  14. #include <sound/hdaudio_ext.h>
  15. MODULE_DESCRIPTION("HDA extended core");
  16. MODULE_LICENSE("GPL v2");
  17. /**
  18. * snd_hdac_ext_bus_init - initialize a HD-audio extended bus
  19. * @bus: the pointer to HDAC bus object
  20. * @dev: device pointer
  21. * @ops: bus verb operators
  22. * @ext_ops: operators used for ASoC HDA codec drivers
  23. *
  24. * Returns 0 if successful, or a negative error code.
  25. */
  26. int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev,
  27. const struct hdac_bus_ops *ops,
  28. const struct hdac_ext_bus_ops *ext_ops)
  29. {
  30. int ret;
  31. ret = snd_hdac_bus_init(bus, dev, ops);
  32. if (ret < 0)
  33. return ret;
  34. bus->ext_ops = ext_ops;
  35. /* FIXME:
  36. * Currently only one bus is supported, if there is device with more
  37. * buses, bus->idx should be greater than 0, but there needs to be a
  38. * reliable way to always assign same number.
  39. */
  40. bus->idx = 0;
  41. bus->cmd_dma_state = true;
  42. return 0;
  43. }
  44. EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_init);
  45. /**
  46. * snd_hdac_ext_bus_exit - clean up a HD-audio extended bus
  47. * @bus: the pointer to HDAC bus object
  48. */
  49. void snd_hdac_ext_bus_exit(struct hdac_bus *bus)
  50. {
  51. snd_hdac_bus_exit(bus);
  52. WARN_ON(!list_empty(&bus->hlink_list));
  53. }
  54. EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_exit);
  55. /**
  56. * snd_hdac_ext_bus_device_remove - remove HD-audio extended codec base devices
  57. *
  58. * @bus: the pointer to HDAC bus object
  59. */
  60. void snd_hdac_ext_bus_device_remove(struct hdac_bus *bus)
  61. {
  62. struct hdac_device *codec, *__codec;
  63. /*
  64. * we need to remove all the codec devices objects created in the
  65. * snd_hdac_ext_bus_device_init
  66. */
  67. list_for_each_entry_safe(codec, __codec, &bus->codec_list, list) {
  68. snd_hdac_device_unregister(codec);
  69. put_device(&codec->dev);
  70. }
  71. }
  72. EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_device_remove);
  73. #define dev_to_hdac(dev) (container_of((dev), \
  74. struct hdac_device, dev))
  75. static inline struct hdac_driver *get_hdrv(struct device *dev)
  76. {
  77. struct hdac_driver *hdrv = drv_to_hdac_driver(dev->driver);
  78. return hdrv;
  79. }
  80. static inline struct hdac_device *get_hdev(struct device *dev)
  81. {
  82. struct hdac_device *hdev = dev_to_hdac_dev(dev);
  83. return hdev;
  84. }
  85. static int hda_ext_drv_probe(struct device *dev)
  86. {
  87. return (get_hdrv(dev))->probe(get_hdev(dev));
  88. }
  89. static int hdac_ext_drv_remove(struct device *dev)
  90. {
  91. return (get_hdrv(dev))->remove(get_hdev(dev));
  92. }
  93. static void hdac_ext_drv_shutdown(struct device *dev)
  94. {
  95. return (get_hdrv(dev))->shutdown(get_hdev(dev));
  96. }
  97. /**
  98. * snd_hda_ext_driver_register - register a driver for ext hda devices
  99. *
  100. * @drv: ext hda driver structure
  101. */
  102. int snd_hda_ext_driver_register(struct hdac_driver *drv)
  103. {
  104. drv->type = HDA_DEV_ASOC;
  105. drv->driver.bus = &snd_hda_bus_type;
  106. /* we use default match */
  107. if (drv->probe)
  108. drv->driver.probe = hda_ext_drv_probe;
  109. if (drv->remove)
  110. drv->driver.remove = hdac_ext_drv_remove;
  111. if (drv->shutdown)
  112. drv->driver.shutdown = hdac_ext_drv_shutdown;
  113. return driver_register(&drv->driver);
  114. }
  115. EXPORT_SYMBOL_GPL(snd_hda_ext_driver_register);
  116. /**
  117. * snd_hda_ext_driver_unregister - unregister a driver for ext hda devices
  118. *
  119. * @drv: ext hda driver structure
  120. */
  121. void snd_hda_ext_driver_unregister(struct hdac_driver *drv)
  122. {
  123. driver_unregister(&drv->driver);
  124. }
  125. EXPORT_SYMBOL_GPL(snd_hda_ext_driver_unregister);