cxd2880_spi_device.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * cxd2880_spi_device.c
  4. * Sony CXD2880 DVB-T2/T tuner + demodulator driver
  5. * SPI access functions
  6. *
  7. * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation
  8. */
  9. #include <linux/spi/spi.h>
  10. #include "cxd2880_spi_device.h"
  11. static int cxd2880_spi_device_write(struct cxd2880_spi *spi,
  12. const u8 *data, u32 size)
  13. {
  14. struct cxd2880_spi_device *spi_device = NULL;
  15. struct spi_message msg;
  16. struct spi_transfer tx;
  17. int result = 0;
  18. if (!spi || !spi->user || !data || size == 0)
  19. return -EINVAL;
  20. spi_device = spi->user;
  21. memset(&tx, 0, sizeof(tx));
  22. tx.tx_buf = data;
  23. tx.len = size;
  24. spi_message_init(&msg);
  25. spi_message_add_tail(&tx, &msg);
  26. result = spi_sync(spi_device->spi, &msg);
  27. if (result < 0)
  28. return -EIO;
  29. return 0;
  30. }
  31. static int cxd2880_spi_device_write_read(struct cxd2880_spi *spi,
  32. const u8 *tx_data,
  33. u32 tx_size,
  34. u8 *rx_data,
  35. u32 rx_size)
  36. {
  37. struct cxd2880_spi_device *spi_device = NULL;
  38. int result = 0;
  39. if (!spi || !spi->user || !tx_data ||
  40. !tx_size || !rx_data || !rx_size)
  41. return -EINVAL;
  42. spi_device = spi->user;
  43. result = spi_write_then_read(spi_device->spi, tx_data,
  44. tx_size, rx_data, rx_size);
  45. if (result < 0)
  46. return -EIO;
  47. return 0;
  48. }
  49. int
  50. cxd2880_spi_device_initialize(struct cxd2880_spi_device *spi_device,
  51. enum cxd2880_spi_mode mode,
  52. u32 speed_hz)
  53. {
  54. int result = 0;
  55. struct spi_device *spi = spi_device->spi;
  56. switch (mode) {
  57. case CXD2880_SPI_MODE_0:
  58. spi->mode = SPI_MODE_0;
  59. break;
  60. case CXD2880_SPI_MODE_1:
  61. spi->mode = SPI_MODE_1;
  62. break;
  63. case CXD2880_SPI_MODE_2:
  64. spi->mode = SPI_MODE_2;
  65. break;
  66. case CXD2880_SPI_MODE_3:
  67. spi->mode = SPI_MODE_3;
  68. break;
  69. default:
  70. return -EINVAL;
  71. }
  72. spi->max_speed_hz = speed_hz;
  73. spi->bits_per_word = 8;
  74. result = spi_setup(spi);
  75. if (result != 0) {
  76. pr_err("spi_setup failed %d\n", result);
  77. return -EINVAL;
  78. }
  79. return 0;
  80. }
  81. int cxd2880_spi_device_create_spi(struct cxd2880_spi *spi,
  82. struct cxd2880_spi_device *spi_device)
  83. {
  84. if (!spi || !spi_device)
  85. return -EINVAL;
  86. spi->read = NULL;
  87. spi->write = cxd2880_spi_device_write;
  88. spi->write_read = cxd2880_spi_device_write_read;
  89. spi->flags = 0;
  90. spi->user = spi_device;
  91. return 0;
  92. }