soc-io.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. // SPDX-License-Identifier: GPL-2.0+
  2. //
  3. // soc-io.c -- ASoC register I/O helpers
  4. //
  5. // Copyright 2009-2011 Wolfson Microelectronics PLC.
  6. //
  7. // Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
  8. #include <linux/i2c.h>
  9. #include <linux/spi/spi.h>
  10. #include <linux/regmap.h>
  11. #include <linux/export.h>
  12. #include <sound/soc.h>
  13. /**
  14. * snd_soc_component_read() - Read register value
  15. * @component: Component to read from
  16. * @reg: Register to read
  17. * @val: Pointer to where the read value is stored
  18. *
  19. * Return: 0 on success, a negative error code otherwise.
  20. */
  21. int snd_soc_component_read(struct snd_soc_component *component,
  22. unsigned int reg, unsigned int *val)
  23. {
  24. int ret;
  25. if (component->regmap)
  26. ret = regmap_read(component->regmap, reg, val);
  27. else if (component->driver->read) {
  28. *val = component->driver->read(component, reg);
  29. ret = 0;
  30. }
  31. else
  32. ret = -EIO;
  33. return ret;
  34. }
  35. EXPORT_SYMBOL_GPL(snd_soc_component_read);
  36. unsigned int snd_soc_component_read32(struct snd_soc_component *component,
  37. unsigned int reg)
  38. {
  39. unsigned int val;
  40. int ret;
  41. ret = snd_soc_component_read(component, reg, &val);
  42. if (ret < 0)
  43. return -1;
  44. return val;
  45. }
  46. EXPORT_SYMBOL_GPL(snd_soc_component_read32);
  47. /**
  48. * snd_soc_component_write() - Write register value
  49. * @component: Component to write to
  50. * @reg: Register to write
  51. * @val: Value to write to the register
  52. *
  53. * Return: 0 on success, a negative error code otherwise.
  54. */
  55. int snd_soc_component_write(struct snd_soc_component *component,
  56. unsigned int reg, unsigned int val)
  57. {
  58. if (component->regmap)
  59. return regmap_write(component->regmap, reg, val);
  60. else if (component->driver->write)
  61. return component->driver->write(component, reg, val);
  62. else
  63. return -EIO;
  64. }
  65. EXPORT_SYMBOL_GPL(snd_soc_component_write);
  66. static int snd_soc_component_update_bits_legacy(
  67. struct snd_soc_component *component, unsigned int reg,
  68. unsigned int mask, unsigned int val, bool *change)
  69. {
  70. unsigned int old, new;
  71. int ret;
  72. mutex_lock(&component->io_mutex);
  73. ret = snd_soc_component_read(component, reg, &old);
  74. if (ret < 0)
  75. goto out_unlock;
  76. new = (old & ~mask) | (val & mask);
  77. *change = old != new;
  78. if (*change)
  79. ret = snd_soc_component_write(component, reg, new);
  80. out_unlock:
  81. mutex_unlock(&component->io_mutex);
  82. return ret;
  83. }
  84. /**
  85. * snd_soc_component_update_bits() - Perform read/modify/write cycle
  86. * @component: Component to update
  87. * @reg: Register to update
  88. * @mask: Mask that specifies which bits to update
  89. * @val: New value for the bits specified by mask
  90. *
  91. * Return: 1 if the operation was successful and the value of the register
  92. * changed, 0 if the operation was successful, but the value did not change.
  93. * Returns a negative error code otherwise.
  94. */
  95. int snd_soc_component_update_bits(struct snd_soc_component *component,
  96. unsigned int reg, unsigned int mask, unsigned int val)
  97. {
  98. bool change;
  99. int ret;
  100. if (component->regmap)
  101. ret = regmap_update_bits_check(component->regmap, reg, mask,
  102. val, &change);
  103. else
  104. ret = snd_soc_component_update_bits_legacy(component, reg,
  105. mask, val, &change);
  106. if (ret < 0)
  107. return ret;
  108. return change;
  109. }
  110. EXPORT_SYMBOL_GPL(snd_soc_component_update_bits);
  111. /**
  112. * snd_soc_component_update_bits_async() - Perform asynchronous
  113. * read/modify/write cycle
  114. * @component: Component to update
  115. * @reg: Register to update
  116. * @mask: Mask that specifies which bits to update
  117. * @val: New value for the bits specified by mask
  118. *
  119. * This function is similar to snd_soc_component_update_bits(), but the update
  120. * operation is scheduled asynchronously. This means it may not be completed
  121. * when the function returns. To make sure that all scheduled updates have been
  122. * completed snd_soc_component_async_complete() must be called.
  123. *
  124. * Return: 1 if the operation was successful and the value of the register
  125. * changed, 0 if the operation was successful, but the value did not change.
  126. * Returns a negative error code otherwise.
  127. */
  128. int snd_soc_component_update_bits_async(struct snd_soc_component *component,
  129. unsigned int reg, unsigned int mask, unsigned int val)
  130. {
  131. bool change;
  132. int ret;
  133. if (component->regmap)
  134. ret = regmap_update_bits_check_async(component->regmap, reg,
  135. mask, val, &change);
  136. else
  137. ret = snd_soc_component_update_bits_legacy(component, reg,
  138. mask, val, &change);
  139. if (ret < 0)
  140. return ret;
  141. return change;
  142. }
  143. EXPORT_SYMBOL_GPL(snd_soc_component_update_bits_async);
  144. /**
  145. * snd_soc_component_async_complete() - Ensure asynchronous I/O has completed
  146. * @component: Component for which to wait
  147. *
  148. * This function blocks until all asynchronous I/O which has previously been
  149. * scheduled using snd_soc_component_update_bits_async() has completed.
  150. */
  151. void snd_soc_component_async_complete(struct snd_soc_component *component)
  152. {
  153. if (component->regmap)
  154. regmap_async_complete(component->regmap);
  155. }
  156. EXPORT_SYMBOL_GPL(snd_soc_component_async_complete);
  157. /**
  158. * snd_soc_component_test_bits - Test register for change
  159. * @component: component
  160. * @reg: Register to test
  161. * @mask: Mask that specifies which bits to test
  162. * @value: Value to test against
  163. *
  164. * Tests a register with a new value and checks if the new value is
  165. * different from the old value.
  166. *
  167. * Return: 1 for change, otherwise 0.
  168. */
  169. int snd_soc_component_test_bits(struct snd_soc_component *component,
  170. unsigned int reg, unsigned int mask, unsigned int value)
  171. {
  172. unsigned int old, new;
  173. int ret;
  174. ret = snd_soc_component_read(component, reg, &old);
  175. if (ret < 0)
  176. return ret;
  177. new = (old & ~mask) | value;
  178. return old != new;
  179. }
  180. EXPORT_SYMBOL_GPL(snd_soc_component_test_bits);