Advertisement
Guest User

Untitled

a guest
May 30th, 2023
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.17 KB | None | 0 0
  1. /* NEW DEFINES FOR REGS */
  2.  
  3. #define ALVIUM_REG_SIZE_SHIFT 8
  4. #define ALVIUM_REG_ADDR_MASK 0xff
  5.  
  6. #define ALVIUM_REG_8BIT(n) ((1U << ALVIUM_REG_SIZE_SHIFT) | (n))
  7. #define ALVIUM_REG_16BIT(n) ((2U << ALVIUM_REG_SIZE_SHIFT) | (n))
  8. #define ALVIUM_REG_32BIT(n) ((4U << ALVIUM_REG_SIZE_SHIFT) | (n))
  9. #define ALVIUM_REG_64BIT(n) ((8U << ALVIUM_REG_SIZE_SHIFT) | (n))
  10.  
  11. #define ALVIUM_BCRM_EXPOSURE_AUTO_8RW ALVIUM_REG_8BIT(0x01a0)
  12. #define ALVIUM_BCRM_REG_ADDR ALVIUM_REG_16BIT(0x0014)
  13. #define ALVIUM_BCRM_REG_VERSION ALVIUM_REG_32BIT(0x0000)
  14. #define ALVIUM_BCRM_DEVICE_FIRMWARE_VERSION ALVIUM_REG_64BIT(0x0010)
  15. #define ALVIUM_BCRM_WRITE_HANDSHAKE_8RW ALVIUM_REG_8BIT(0x0018)
  16.  
  17. /* NEW READ FUNCTION */
  18.  
  19. static int __always_unused alvium_read(struct alvium_dev *alvium,
  20. u16 addr, void *val)
  21. {
  22. struct i2c_client *client = alvium->i2c_client;
  23. struct i2c_msg msgs[2] = {0};
  24. u8 addr_buf[2] = {0};
  25. u8 *data_buf = NULL;
  26. u16 reg = 0;
  27. u32 len = 0;
  28. int ret;
  29.  
  30. reg = (addr & ALVIUM_REG_ADDR_MASK);
  31. len = (addr >> ALVIUM_REG_SIZE_SHIFT);
  32.  
  33. if (WARN_ON(len > 8))
  34. return -EINVAL;
  35.  
  36. data_buf = kmalloc_array(len,
  37. sizeof(u8),
  38. GFP_KERNEL);
  39.  
  40. put_unaligned_be16(reg, addr_buf);
  41.  
  42. msgs[0].addr = client->addr;
  43. msgs[0].flags = 0;
  44. msgs[0].len = ARRAY_SIZE(addr_buf);
  45. msgs[0].buf = addr_buf;
  46.  
  47. msgs[1].addr = client->addr;
  48. msgs[1].flags = I2C_M_RD;
  49. msgs[1].len = len;
  50. msgs[1].buf = data_buf;
  51.  
  52. ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
  53. if (ret != ARRAY_SIZE(msgs))
  54. return -EIO;
  55.  
  56. switch (len) {
  57. case 1:
  58. *(u8 *)val = data_buf[0];
  59. break;
  60. case 2:
  61. *(u16 *)val = get_unaligned_be16(data_buf);
  62. break;
  63. case 4:
  64. *(u32 *)val = get_unaligned_be32(data_buf);
  65. break;
  66. case 8:
  67. *(u64 *)val = get_unaligned_be64(data_buf);
  68. break;
  69. default:
  70. return -EINVAL;
  71. }
  72.  
  73. return 0;
  74. }
  75.  
  76. /* NEW WRITE FUNCTION */
  77.  
  78. static int __always_unused alvium_write(struct alvium_dev *alvium,
  79. u16 addr, void *val)
  80. {
  81. struct i2c_client *client = alvium->i2c_client;
  82. struct i2c_msg msgs[2] = {0};
  83. u8 addr_buf[2] = {0};
  84. u8 *data_buf = NULL;
  85. u16 reg = 0;
  86. u32 len = 0;
  87. int ret;
  88.  
  89. reg = (addr & ALVIUM_REG_ADDR_MASK);
  90. len = (addr >> ALVIUM_REG_SIZE_SHIFT);
  91.  
  92. if (WARN_ON(len > 8))
  93. return -EINVAL;
  94.  
  95. data_buf = kmalloc_array(len,
  96. sizeof(u8),
  97. GFP_KERNEL);
  98.  
  99. put_unaligned_be16(reg, addr_buf);
  100.  
  101. switch (len) {
  102. case 1:
  103. data_buf = val;
  104. break;
  105. case 2:
  106. put_unaligned_be16(*(u64 *)val, data_buf);
  107. break;
  108. case 4:
  109. put_unaligned_be32(*(u32 *)val, data_buf);
  110. break;
  111. case 8:
  112. put_unaligned_be64(*(u16 *)val, data_buf);
  113. break;
  114. default:
  115. return -EINVAL;
  116. }
  117.  
  118. msgs[0].addr = client->addr;
  119. msgs[0].flags = 0;
  120. msgs[0].len = ARRAY_SIZE(addr_buf);
  121. msgs[0].buf = addr_buf;
  122.  
  123. msgs[1].addr = client->addr;
  124. msgs[1].flags = 0;
  125. msgs[1].len = len;
  126. msgs[1].buf = data_buf;
  127.  
  128. ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
  129. if (ret != ARRAY_SIZE(msgs))
  130. return -EIO;
  131.  
  132. return 0;
  133. }
  134.  
  135.  
  136. # USAGE
  137. ret = alvium_read(alvium, ALVIUM_BCRM_REG_VERSION, &tmp);
  138. ret = alvium_write(alvium, ALVIUM_BCRM_WRITE_HANDSHAKE_8RW, &test);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement