rl6347a.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * rl6347a.c - RL6347A class device shared support
  3. *
  4. * Copyright 2015 Realtek Semiconductor Corp.
  5. *
  6. * Author: Oder Chiou <oder_chiou@realtek.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. */
  12. #include <linux/module.h>
  13. #include <linux/i2c.h>
  14. #include <linux/regmap.h>
  15. #include "rl6347a.h"
  16. int rl6347a_hw_write(void *context, unsigned int reg, unsigned int value)
  17. {
  18. struct i2c_client *client = context;
  19. struct rl6347a_priv *rl6347a = i2c_get_clientdata(client);
  20. u8 data[4];
  21. int ret, i;
  22. /* handle index registers */
  23. if (reg <= 0xff) {
  24. rl6347a_hw_write(client, RL6347A_COEF_INDEX, reg);
  25. for (i = 0; i < rl6347a->index_cache_size; i++) {
  26. if (reg == rl6347a->index_cache[i].reg) {
  27. rl6347a->index_cache[i].def = value;
  28. break;
  29. }
  30. }
  31. reg = RL6347A_PROC_COEF;
  32. }
  33. data[0] = (reg >> 24) & 0xff;
  34. data[1] = (reg >> 16) & 0xff;
  35. /*
  36. * 4 bit VID: reg should be 0
  37. * 12 bit VID: value should be 0
  38. * So we use an OR operator to handle it rather than use if condition.
  39. */
  40. data[2] = ((reg >> 8) & 0xff) | ((value >> 8) & 0xff);
  41. data[3] = value & 0xff;
  42. ret = i2c_master_send(client, data, 4);
  43. if (ret == 4)
  44. return 0;
  45. else
  46. pr_err("ret=%d\n", ret);
  47. if (ret < 0)
  48. return ret;
  49. else
  50. return -EIO;
  51. }
  52. EXPORT_SYMBOL_GPL(rl6347a_hw_write);
  53. int rl6347a_hw_read(void *context, unsigned int reg, unsigned int *value)
  54. {
  55. struct i2c_client *client = context;
  56. struct i2c_msg xfer[2];
  57. int ret;
  58. __be32 be_reg;
  59. unsigned int index, vid, buf = 0x0;
  60. /* handle index registers */
  61. if (reg <= 0xff) {
  62. rl6347a_hw_write(client, RL6347A_COEF_INDEX, reg);
  63. reg = RL6347A_PROC_COEF;
  64. }
  65. reg = reg | 0x80000;
  66. vid = (reg >> 8) & 0xfff;
  67. if (AC_VERB_GET_AMP_GAIN_MUTE == (vid & 0xf00)) {
  68. index = (reg >> 8) & 0xf;
  69. reg = (reg & ~0xf0f) | index;
  70. }
  71. be_reg = cpu_to_be32(reg);
  72. /* Write register */
  73. xfer[0].addr = client->addr;
  74. xfer[0].flags = 0;
  75. xfer[0].len = 4;
  76. xfer[0].buf = (u8 *)&be_reg;
  77. /* Read data */
  78. xfer[1].addr = client->addr;
  79. xfer[1].flags = I2C_M_RD;
  80. xfer[1].len = 4;
  81. xfer[1].buf = (u8 *)&buf;
  82. ret = i2c_transfer(client->adapter, xfer, 2);
  83. if (ret < 0)
  84. return ret;
  85. else if (ret != 2)
  86. return -EIO;
  87. *value = be32_to_cpu(buf);
  88. return 0;
  89. }
  90. EXPORT_SYMBOL_GPL(rl6347a_hw_read);
  91. MODULE_DESCRIPTION("RL6347A class device shared support");
  92. MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>");
  93. MODULE_LICENSE("GPL v2");