// Copyright 2021 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

#include "pw_spi/linux_spi.h"

#include <fcntl.h>
#include <linux/spi/spidev.h>
#include <linux/types.h>
#include <sys/ioctl.h>
#include <unistd.h>

#include <cstring>

#include "pw_log/log.h"
#include "pw_spi/chip_selector.h"
#include "pw_spi/device.h"
#include "pw_spi/initiator.h"
#include "pw_status/try.h"

namespace pw::spi {

LinuxInitiator::~LinuxInitiator() {
  if (fd_ >= 0) {
    close(fd_);
  }
}

Status LinuxInitiator::Configure(const Config& config) {
  // Map clock polarity/phase to Linux userspace equivalents
  uint32_t mode = 0;
  if (config.polarity == ClockPolarity::kActiveLow) {
    mode |= SPI_CPOL;  // Clock polarity -- signal is high when idle
  }
  if (config.phase == ClockPhase::kFallingEdge) {
    mode |= SPI_CPHA;  // Clock phase -- latch on falling edge
  }
  if (ioctl(fd_, SPI_IOC_WR_MODE32, &mode) < 0) {
    PW_LOG_ERROR("Unable to set SPI mode");
    return Status::InvalidArgument();
  }

  // Configure LSB/MSB first
  uint8_t lsb_first = 0;
  if (config.bit_order == BitOrder::kLsbFirst) {
    lsb_first = 1;  // non-zero value indicates LSB first
  }
  if (ioctl(fd_, SPI_IOC_WR_LSB_FIRST, &lsb_first) < 0) {
    PW_LOG_ERROR("Unable to set SPI LSB");
    return Status::InvalidArgument();
  }

  // Configure bits-per-word
  uint8_t bits_per_word = config.bits_per_word();
  if (ioctl(fd_, SPI_IOC_WR_BITS_PER_WORD, &bits_per_word) < 0) {
    PW_LOG_ERROR("Unable to set SPI Bits Per Word");
    return Status::InvalidArgument();
  }

  // Configure maximum bus speed
  if (ioctl(fd_, SPI_IOC_WR_MAX_SPEED_HZ, &max_speed_hz_) < 0) {
    PW_LOG_ERROR("Unable to set SPI Max Speed");
    return Status::InvalidArgument();
  }

  return OkStatus();
}

Status LinuxInitiator::WriteRead(ConstByteSpan write_buffer,
                                 ByteSpan read_buffer) {
  // Configure a full-duplex transfer using ioctl()
  struct spi_ioc_transfer transaction[2];
  memset(transaction, 0, sizeof(transaction));
  transaction[0].tx_buf = reinterpret_cast<uintptr_t>(write_buffer.data());
  transaction[0].len = write_buffer.size();

  transaction[1].rx_buf = reinterpret_cast<uintptr_t>(read_buffer.data());
  transaction[1].len = read_buffer.size();

  if (ioctl(fd_, SPI_IOC_MESSAGE(2), transaction) < 0) {
    PW_LOG_ERROR("Unable to perform SPI transfer");
    return Status::Unknown();
  }

  return OkStatus();
}

Status LinuxChipSelector::SetActive(bool /*active*/) {
  // Note: For Linux' SPI userspace support, chip-select control is not exposed
  // directly to the user.  This limits our ability to use the SPI HAL to do
  // composite (multi read-write) transactions with the PW SPI HAL, as Linux
  // performs composite transactions with a single ioctl() call using an array
  // of descriptors provided as a parameter -- there's no way of separating
  // individual operations from userspace.  This could be addressed with a
  // direct "Composite" transaction HAL API, or by using a raw GPIO
  // to control of chip select from userspace (which is not common practice).
  return OkStatus();
}

}  // namespace pw::spi
