// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "i2c-child.h"

#include <lib/sync/completion.h>
#include <threads.h>
#include <zircon/types.h>

#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/metadata.h>
#include <ddk/metadata/i2c.h>
#include <fbl/alloc_checker.h>
#include <fbl/mutex.h>

namespace i2c {

void I2cChild::Transfer(fidl::VectorView<bool> segments_is_write,
                        fidl::VectorView<fidl::VectorView<uint8_t>> write_segments_data,
                        fidl::VectorView<uint8_t> read_segments_length,
                        TransferCompleter::Sync& completer) {
  if (segments_is_write.count() < 1) {
    completer.ReplyError(ZX_ERR_INVALID_ARGS);
    return;
  }

  auto op_list = std::make_unique<i2c_op_t[]>(segments_is_write.count());
  size_t write_cnt = 0;
  size_t read_cnt = 0;
  for (size_t i = 0; i < segments_is_write.count(); ++i) {
    if (segments_is_write[i]) {
      if (write_cnt >= write_segments_data.count()) {
        completer.ReplyError(ZX_ERR_INVALID_ARGS);
        return;
      }
      op_list[i].data_buffer = write_segments_data[write_cnt].data();
      op_list[i].data_size = write_segments_data[write_cnt].count();
      op_list[i].is_read = false;
      op_list[i].stop = false;
      write_cnt++;
    } else {
      if (read_cnt >= read_segments_length.count()) {
        completer.ReplyError(ZX_ERR_INVALID_ARGS);
        return;
      }
      op_list[i].data_buffer = nullptr;  // unused.
      op_list[i].data_size = read_segments_length[read_cnt];
      op_list[i].is_read = true;
      op_list[i].stop = false;
      read_cnt++;
    }
  }
  op_list[segments_is_write.count() - 1].stop = true;

  if (write_segments_data.count() != write_cnt) {
    completer.ReplyError(ZX_ERR_INVALID_ARGS);
    return;
  }
  if (read_segments_length.count() != read_cnt) {
    completer.ReplyError(ZX_ERR_INVALID_ARGS);
    return;
  }

  struct Ctx {
    sync_completion_t done = {};
    TransferCompleter::Sync* completer;
  } ctx;
  ctx.completer = &completer;
  auto callback = [](void* ctx, zx_status_t status, const i2c_op_t* op_list, size_t op_count) {
    auto ctx2 = static_cast<Ctx*>(ctx);
    if (status == ZX_OK) {
      auto reads = std::make_unique<fidl::VectorView<uint8_t>[]>(op_count);
      for (size_t i = 0; i < op_count; ++i) {
        reads[i].set_data(
            fidl::unowned_ptr(static_cast<uint8_t*>(const_cast<void*>(op_list[i].data_buffer))));
        reads[i].set_count(op_list[i].data_size);
      }
      fidl::VectorView<fidl::VectorView<uint8_t>> all_reads(fidl::unowned_ptr(reads.get()),
                                                            op_count);
      ctx2->completer->ReplySuccess(std::move(all_reads));
    } else {
      ctx2->completer->ReplyError(status);
    }
    sync_completion_signal(&ctx2->done);
  };
  bus_->Transact(address_, op_list.get(), segments_is_write.count(), callback, &ctx);
  sync_completion_wait(&ctx.done, zx::duration::infinite().get());
}

void I2cChild::I2cTransact(const i2c_op_t* op_list, size_t op_count, i2c_transact_callback callback,
                           void* cookie) {
  bus_->Transact(address_, op_list, op_count, callback, cookie);
}

zx_status_t I2cChild::I2cGetMaxTransferSize(size_t* out_size) {
  *out_size = bus_->max_transfer();
  return ZX_OK;
}

zx_status_t I2cChild::I2cGetInterrupt(uint32_t flags, zx::interrupt* out_irq) {
  // This is only used by the Intel I2C driver.
  // TODO: Pass these interrupt numbers from intel-i2c.
  if (address_ == 0xa) {
    // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
    zx_status_t status = zx::interrupt::create(zx::resource(get_root_resource()), 0x1f,
                                               ZX_INTERRUPT_MODE_LEVEL_LOW, out_irq);
    if (status != ZX_OK) {
      return status;
    }
    return ZX_OK;
  } else if (address_ == 0x49) {
    // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
    zx_status_t status = zx::interrupt::create(zx::resource(get_root_resource()), 0x33,
                                               ZX_INTERRUPT_MODE_LEVEL_LOW, out_irq);
    if (status != ZX_OK) {
      return status;
    }
    return ZX_OK;
  } else if (address_ == 0x10) {
    // Acer12
    // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
    zx_status_t status = zx::interrupt::create(zx::resource(get_root_resource()), 0x1f,
                                               ZX_INTERRUPT_MODE_LEVEL_LOW, out_irq);
    if (status != ZX_OK) {
      return status;
    }
    return ZX_OK;
  } else if (address_ == 0x50) {
    // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
    zx_status_t status = zx::interrupt::create(zx::resource(get_root_resource()), 0x18,
                                               ZX_INTERRUPT_MODE_EDGE_LOW, out_irq);
    if (status != ZX_OK) {
      return status;
    }
    return ZX_OK;
  } else if (address_ == 0x15) {
    // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
    zx_status_t status = zx::interrupt::create(zx::resource(get_root_resource()), 0x2b,
                                               ZX_INTERRUPT_MODE_EDGE_LOW, out_irq);
    if (status != ZX_OK) {
      return status;
    }
    return ZX_OK;
  }

  return ZX_ERR_NOT_FOUND;
}

void I2cChild::DdkUnbind(ddk::UnbindTxn txn) { txn.Reply(); }

void I2cChild::DdkRelease() { delete this; }

}  // namespace i2c
