regmap-sdw.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // SPDX-License-Identifier: GPL-2.0
  2. // Copyright(c) 2015-17 Intel Corporation.
  3. #include <linux/device.h>
  4. #include <linux/errno.h>
  5. #include <linux/module.h>
  6. #include <linux/regmap.h>
  7. #include <linux/soundwire/sdw.h>
  8. #include <linux/types.h>
  9. #include "internal.h"
  10. static int regmap_sdw_write(void *context, const void *val_buf, size_t val_size)
  11. {
  12. struct device *dev = context;
  13. struct sdw_slave *slave = dev_to_sdw_dev(dev);
  14. /* First word of buffer contains the destination address */
  15. u32 addr = le32_to_cpu(*(const __le32 *)val_buf);
  16. const u8 *val = val_buf;
  17. return sdw_nwrite_no_pm(slave, addr, val_size - sizeof(addr), val + sizeof(addr));
  18. }
  19. static int regmap_sdw_gather_write(void *context,
  20. const void *reg_buf, size_t reg_size,
  21. const void *val_buf, size_t val_size)
  22. {
  23. struct device *dev = context;
  24. struct sdw_slave *slave = dev_to_sdw_dev(dev);
  25. u32 addr = le32_to_cpu(*(const __le32 *)reg_buf);
  26. return sdw_nwrite_no_pm(slave, addr, val_size, val_buf);
  27. }
  28. static int regmap_sdw_read(void *context,
  29. const void *reg_buf, size_t reg_size,
  30. void *val_buf, size_t val_size)
  31. {
  32. struct device *dev = context;
  33. struct sdw_slave *slave = dev_to_sdw_dev(dev);
  34. u32 addr = le32_to_cpu(*(const __le32 *)reg_buf);
  35. return sdw_nread_no_pm(slave, addr, val_size, val_buf);
  36. }
  37. static const struct regmap_bus regmap_sdw = {
  38. .write = regmap_sdw_write,
  39. .gather_write = regmap_sdw_gather_write,
  40. .read = regmap_sdw_read,
  41. .reg_format_endian_default = REGMAP_ENDIAN_LITTLE,
  42. .val_format_endian_default = REGMAP_ENDIAN_LITTLE,
  43. };
  44. static int regmap_sdw_config_check(const struct regmap_config *config)
  45. {
  46. /* Register addresses are 32 bits wide */
  47. if (config->reg_bits != 32)
  48. return -ENOTSUPP;
  49. if (config->pad_bits != 0)
  50. return -ENOTSUPP;
  51. /* Only bulk writes are supported not multi-register writes */
  52. if (config->can_multi_write)
  53. return -ENOTSUPP;
  54. return 0;
  55. }
  56. struct regmap *__regmap_init_sdw(struct sdw_slave *sdw,
  57. const struct regmap_config *config,
  58. struct lock_class_key *lock_key,
  59. const char *lock_name)
  60. {
  61. int ret;
  62. ret = regmap_sdw_config_check(config);
  63. if (ret)
  64. return ERR_PTR(ret);
  65. return __regmap_init(&sdw->dev, &regmap_sdw,
  66. &sdw->dev, config, lock_key, lock_name);
  67. }
  68. EXPORT_SYMBOL_GPL(__regmap_init_sdw);
  69. struct regmap *__devm_regmap_init_sdw(struct sdw_slave *sdw,
  70. const struct regmap_config *config,
  71. struct lock_class_key *lock_key,
  72. const char *lock_name)
  73. {
  74. int ret;
  75. ret = regmap_sdw_config_check(config);
  76. if (ret)
  77. return ERR_PTR(ret);
  78. return __devm_regmap_init(&sdw->dev, &regmap_sdw,
  79. &sdw->dev, config, lock_key, lock_name);
  80. }
  81. EXPORT_SYMBOL_GPL(__devm_regmap_init_sdw);
  82. MODULE_DESCRIPTION("regmap SoundWire Module");
  83. MODULE_LICENSE("GPL v2");