/*
 * Copyright 2015 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * This file was copied from https://github.com/devttys0/libmpsse.git (sha1
 * f1a6744b), and modified to suite the Chromium OS project.
 *
 * Internal functions used by libmpsse.
 *
 * Craig Heffner
 * 27 December 2011
 */

#include <string.h>

#include "trunks/ftdi/support.h"

/* Write data to the FTDI chip */
int raw_write(struct mpsse_context* mpsse, uint8_t* buf, int size) {
  int retval = MPSSE_FAIL;

  if (mpsse->mode) {
    if (ftdi_write_data(&mpsse->ftdi, buf, size) == size) {
      retval = MPSSE_OK;
    }
  }

  return retval;
}

/* Read data from the FTDI chip */
int raw_read(struct mpsse_context* mpsse, uint8_t* buf, int size) {
  int n = 0, r = 0;

  if (mpsse->mode) {
    while (n < size) {
      r = ftdi_read_data(&mpsse->ftdi, buf, size);
      if (r < 0)
        break;
      n += r;
    }

    if (mpsse->flush_after_read) {
      /*
       * Make sure the buffers are cleared after a read or subsequent reads may
       *fail.
       *
       * Is this needed anymore? It slows down repetitive read operations by
       *~8%.
       */
      ftdi_usb_purge_rx_buffer(&mpsse->ftdi);
    }
  }

  return n;
}

/* Sets the read and write timeout periods for bulk usb data transfers. */
void set_timeouts(struct mpsse_context* mpsse, int timeout) {
  if (mpsse->mode) {
    mpsse->ftdi.usb_read_timeout = timeout;
    mpsse->ftdi.usb_write_timeout = timeout;
  }

  return;
}

/* Convert a frequency to a clock divisor */
uint16_t freq2div(uint32_t system_clock, uint32_t freq) {
  return (((system_clock / freq) / 2) - 1);
}

/* Convert a clock divisor to a frequency */
uint32_t div2freq(uint32_t system_clock, uint16_t div) {
  return (system_clock / ((1 + div) * 2));
}

/* Builds a buffer of commands + data blocks */
uint8_t* build_block_buffer(struct mpsse_context* mpsse,
                                  uint8_t cmd,
                                  const uint8_t* data,
                                  int size,
                                  int* buf_size) {
  uint8_t* buf = NULL;
  int i = 0, j = 0, k = 0, dsize = 0, num_blocks = 0, total_size = 0,
      xfer_size = 0;
  uint16_t rsize = 0;

  *buf_size = 0;

  /* Data block size is 1 in I2C, or when in bitmode */
  if (mpsse->mode == I2C || (cmd & MPSSE_BITMODE)) {
    xfer_size = 1;
  } else {
    xfer_size = mpsse->xsize;
  }

  num_blocks = (size / xfer_size);
  if (size % xfer_size) {
    num_blocks++;
  }

  /* The total size of the data will be the data size + the write command */
  total_size = size + (CMD_SIZE * num_blocks);

  /* In I2C we have to add 3 additional commands per data block */
  if (mpsse->mode == I2C) {
    total_size += (CMD_SIZE * 3 * num_blocks);
  }

  buf = malloc(total_size);
  if (buf) {
    memset(buf, 0, total_size);

    for (j = 0; j < num_blocks; j++) {
      dsize = size - k;
      if (dsize > xfer_size) {
        dsize = xfer_size;
      }

      /* The reported size of this block is block size - 1 */
      rsize = dsize - 1;

      /* For I2C we need to ensure that the clock pin is set low prior to
       * clocking out data */
      if (mpsse->mode == I2C) {
        buf[i++] = SET_BITS_LOW;
        buf[i++] = mpsse->pstart & ~SK;

        /* On receive, we need to ensure that the data out line is set as an
         * input to avoid contention on the bus */
        if (cmd == mpsse->rx) {
          buf[i++] = mpsse->tris & ~DO;
        } else {
          buf[i++] = mpsse->tris;
        }
      }

      /* Copy in the command for this block */
      buf[i++] = cmd;
      buf[i++] = (rsize & 0xFF);
      if (!(cmd & MPSSE_BITMODE)) {
        buf[i++] = ((rsize >> 8) & 0xFF);
      }

      /* On a write, copy the data to transmit after the command */
      if (cmd == mpsse->tx || cmd == mpsse->txrx) {
        memcpy(buf + i, data + k, dsize);

        /* i == offset into buf */
        i += dsize;
        /* k == offset into data */
        k += dsize;
      }

      /* In I2C mode we need to clock one ACK bit after each byte */
      if (mpsse->mode == I2C) {
        /* If we are receiving data, then we need to clock out an ACK for each
         * byte */
        if (cmd == mpsse->rx) {
          buf[i++] = SET_BITS_LOW;
          buf[i++] = mpsse->pstart & ~SK;
          buf[i++] = mpsse->tris;

          buf[i++] = mpsse->tx | MPSSE_BITMODE;
          buf[i++] = 0;
          buf[i++] = mpsse->tack;
        }
        /* If we are sending data, then we need to clock in an ACK for each byte
           */
        else if (cmd == mpsse->tx) {
          /* Need to make data out an input to avoid contention on the bus when
           * the slave sends an ACK */
          buf[i++] = SET_BITS_LOW;
          buf[i++] = mpsse->pstart & ~SK;
          buf[i++] = mpsse->tris & ~DO;

          buf[i++] = mpsse->rx | MPSSE_BITMODE;
          buf[i++] = 0;
          buf[i++] = SEND_IMMEDIATE;
        }
      }
    }

    *buf_size = i;
  }

  return buf;
}

/* Set the low bit pins high/low */
int set_bits_low(struct mpsse_context* mpsse, int port) {
  char buf[CMD_SIZE] = {0};

  buf[0] = SET_BITS_LOW;
  buf[1] = port;
  buf[2] = mpsse->tris;

  return raw_write(mpsse, (uint8_t*)&buf, sizeof(buf));
}

/* Set the high bit pins high/low */
int set_bits_high(struct mpsse_context* mpsse, int port) {
  char buf[CMD_SIZE] = {0};

  buf[0] = SET_BITS_HIGH;
  buf[1] = port;
  buf[2] = mpsse->trish;

  return raw_write(mpsse, (uint8_t*)&buf, sizeof(buf));
}

/* Set the GPIO pins high/low */
int gpio_write(struct mpsse_context* mpsse, int pin, int direction) {
  int retval = MPSSE_FAIL;

  if (mpsse->mode == BITBANG) {
    if (direction == HIGH) {
      mpsse->bitbang |= (1 << pin);
    } else {
      mpsse->bitbang &= ~(1 << pin);
    }

    if (set_bits_high(mpsse, mpsse->bitbang) == MPSSE_OK) {
      retval = raw_write(mpsse, (uint8_t*)&mpsse->bitbang, 1);
    }
  } else {
    /* The first four pins can't be changed unless we are in a stopped status */
    if (pin < NUM_GPIOL_PINS && mpsse->status == STOPPED) {
      /* Convert pin number (0-3) to the corresponding pin bit */
      pin = (GPIO0 << pin);

      if (direction == HIGH) {
        mpsse->pstart |= pin;
        mpsse->pidle |= pin;
        mpsse->pstop |= pin;
      } else {
        mpsse->pstart &= ~pin;
        mpsse->pidle &= ~pin;
        mpsse->pstop &= ~pin;
      }

      retval = set_bits_low(mpsse, mpsse->pstop);
    } else if (pin >= NUM_GPIOL_PINS && pin < NUM_GPIO_PINS) {
      /* Convert pin number (4 - 11) to the corresponding pin bit */
      pin -= NUM_GPIOL_PINS;

      if (direction == HIGH) {
        mpsse->gpioh |= (1 << pin);
      } else {
        mpsse->gpioh &= ~(1 << pin);
      }

      retval = set_bits_high(mpsse, mpsse->gpioh);
    }
  }

  return retval;
}

/* Checks if a given MPSSE context is valid. */
int is_valid_context(struct mpsse_context* mpsse) {
  return mpsse != NULL;
}
