dp_utils.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (c) 2024, The Linux Foundation. All rights reserved.
  4. */
  5. #include <linux/types.h>
  6. #include "dp_utils.h"
  7. #define DP_SDP_HEADER_SIZE 8
  8. u8 dp_utils_get_g0_value(u8 data)
  9. {
  10. u8 c[4];
  11. u8 g[4];
  12. u8 ret_data = 0;
  13. u8 i;
  14. for (i = 0; i < 4; i++)
  15. c[i] = (data >> i) & 0x01;
  16. g[0] = c[3];
  17. g[1] = c[0] ^ c[3];
  18. g[2] = c[1];
  19. g[3] = c[2];
  20. for (i = 0; i < 4; i++)
  21. ret_data = ((g[i] & 0x01) << i) | ret_data;
  22. return ret_data;
  23. }
  24. u8 dp_utils_get_g1_value(u8 data)
  25. {
  26. u8 c[4];
  27. u8 g[4];
  28. u8 ret_data = 0;
  29. u8 i;
  30. for (i = 0; i < 4; i++)
  31. c[i] = (data >> i) & 0x01;
  32. g[0] = c[0] ^ c[3];
  33. g[1] = c[0] ^ c[1] ^ c[3];
  34. g[2] = c[1] ^ c[2];
  35. g[3] = c[2] ^ c[3];
  36. for (i = 0; i < 4; i++)
  37. ret_data = ((g[i] & 0x01) << i) | ret_data;
  38. return ret_data;
  39. }
  40. u8 dp_utils_calculate_parity(u32 data)
  41. {
  42. u8 x0 = 0;
  43. u8 x1 = 0;
  44. u8 ci = 0;
  45. u8 iData = 0;
  46. u8 i = 0;
  47. u8 parity_byte;
  48. u8 num_byte = (data & 0xFF00) > 0 ? 8 : 2;
  49. for (i = 0; i < num_byte; i++) {
  50. iData = (data >> i * 4) & 0xF;
  51. ci = iData ^ x1;
  52. x1 = x0 ^ dp_utils_get_g1_value(ci);
  53. x0 = dp_utils_get_g0_value(ci);
  54. }
  55. parity_byte = x1 | (x0 << 4);
  56. return parity_byte;
  57. }
  58. ssize_t dp_utils_pack_sdp_header(struct dp_sdp_header *sdp_header, u32 *header_buff)
  59. {
  60. size_t length;
  61. length = sizeof(header_buff);
  62. if (length < DP_SDP_HEADER_SIZE)
  63. return -ENOSPC;
  64. header_buff[0] = FIELD_PREP(HEADER_0_MASK, sdp_header->HB0) |
  65. FIELD_PREP(PARITY_0_MASK, dp_utils_calculate_parity(sdp_header->HB0)) |
  66. FIELD_PREP(HEADER_1_MASK, sdp_header->HB1) |
  67. FIELD_PREP(PARITY_1_MASK, dp_utils_calculate_parity(sdp_header->HB1));
  68. header_buff[1] = FIELD_PREP(HEADER_2_MASK, sdp_header->HB2) |
  69. FIELD_PREP(PARITY_2_MASK, dp_utils_calculate_parity(sdp_header->HB2)) |
  70. FIELD_PREP(HEADER_3_MASK, sdp_header->HB3) |
  71. FIELD_PREP(PARITY_3_MASK, dp_utils_calculate_parity(sdp_header->HB3));
  72. return length;
  73. }