soc-io.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * soc-io.c -- ASoC register I/O helpers
  3. *
  4. * Copyright 2009-2011 Wolfson Microelectronics PLC.
  5. *
  6. * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License as published by the
  10. * Free Software Foundation; either version 2 of the License, or (at your
  11. * option) any later version.
  12. */
  13. #include <linux/i2c.h>
  14. #include <linux/spi/spi.h>
  15. #include <linux/regmap.h>
  16. #include <linux/export.h>
  17. #include <sound/soc.h>
  18. #include <trace/events/asoc.h>
  19. #ifdef CONFIG_REGMAP
  20. static int hw_write(struct snd_soc_codec *codec, unsigned int reg,
  21. unsigned int value)
  22. {
  23. int ret;
  24. if (!snd_soc_codec_volatile_register(codec, reg) &&
  25. reg < codec->driver->reg_cache_size &&
  26. !codec->cache_bypass) {
  27. ret = snd_soc_cache_write(codec, reg, value);
  28. if (ret < 0)
  29. return -1;
  30. }
  31. if (codec->cache_only) {
  32. codec->cache_sync = 1;
  33. return 0;
  34. }
  35. return regmap_write(codec->control_data, reg, value);
  36. }
  37. static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg)
  38. {
  39. int ret;
  40. unsigned int val;
  41. if (reg >= codec->driver->reg_cache_size ||
  42. snd_soc_codec_volatile_register(codec, reg) ||
  43. codec->cache_bypass) {
  44. if (codec->cache_only)
  45. return -1;
  46. ret = regmap_read(codec->control_data, reg, &val);
  47. if (ret == 0)
  48. return val;
  49. else
  50. return -1;
  51. }
  52. ret = snd_soc_cache_read(codec, reg, &val);
  53. if (ret < 0)
  54. return -1;
  55. return val;
  56. }
  57. /* Primitive bulk write support for soc-cache. The data pointed to by
  58. * `data' needs to already be in the form the hardware expects. Any
  59. * data written through this function will not go through the cache as
  60. * it only handles writing to volatile or out of bounds registers.
  61. *
  62. * This is currently only supported for devices using the regmap API
  63. * wrappers.
  64. */
  65. static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec,
  66. unsigned int reg,
  67. const void *data, size_t len)
  68. {
  69. /* To ensure that we don't get out of sync with the cache, check
  70. * whether the base register is volatile or if we've directly asked
  71. * to bypass the cache. Out of bounds registers are considered
  72. * volatile.
  73. */
  74. if (!codec->cache_bypass
  75. && !snd_soc_codec_volatile_register(codec, reg)
  76. && reg < codec->driver->reg_cache_size)
  77. return -EINVAL;
  78. return regmap_raw_write(codec->control_data, reg, data, len);
  79. }
  80. /**
  81. * snd_soc_codec_set_cache_io: Set up standard I/O functions.
  82. *
  83. * @codec: CODEC to configure.
  84. * @addr_bits: Number of bits of register address data.
  85. * @data_bits: Number of bits of data per register.
  86. * @control: Control bus used.
  87. *
  88. * Register formats are frequently shared between many I2C and SPI
  89. * devices. In order to promote code reuse the ASoC core provides
  90. * some standard implementations of CODEC read and write operations
  91. * which can be set up using this function.
  92. *
  93. * The caller is responsible for allocating and initialising the
  94. * actual cache.
  95. *
  96. * Note that at present this code cannot be used by CODECs with
  97. * volatile registers.
  98. */
  99. int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
  100. int addr_bits, int data_bits,
  101. enum snd_soc_control_type control)
  102. {
  103. struct regmap_config config;
  104. int ret;
  105. memset(&config, 0, sizeof(config));
  106. codec->write = hw_write;
  107. codec->read = hw_read;
  108. codec->bulk_write_raw = snd_soc_hw_bulk_write_raw;
  109. config.reg_bits = addr_bits;
  110. config.val_bits = data_bits;
  111. switch (control) {
  112. #if defined(CONFIG_REGMAP_I2C) || defined(CONFIG_REGMAP_I2C_MODULE)
  113. case SND_SOC_I2C:
  114. codec->control_data = regmap_init_i2c(to_i2c_client(codec->dev),
  115. &config);
  116. break;
  117. #endif
  118. #if defined(CONFIG_REGMAP_SPI) || defined(CONFIG_REGMAP_SPI_MODULE)
  119. case SND_SOC_SPI:
  120. codec->control_data = regmap_init_spi(to_spi_device(codec->dev),
  121. &config);
  122. break;
  123. #endif
  124. case SND_SOC_REGMAP:
  125. /* Device has made its own regmap arrangements */
  126. codec->using_regmap = true;
  127. ret = regmap_get_val_bytes(codec->control_data);
  128. /* Errors are legitimate for non-integer byte multiples */
  129. if (ret > 0)
  130. codec->val_bytes = ret;
  131. break;
  132. default:
  133. return -EINVAL;
  134. }
  135. if (IS_ERR(codec->control_data))
  136. return PTR_ERR(codec->control_data);
  137. return 0;
  138. }
  139. EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
  140. #else
  141. int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
  142. int addr_bits, int data_bits,
  143. enum snd_soc_control_type control)
  144. {
  145. return -ENOTSUPP;
  146. }
  147. EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
  148. #endif