/*
/*
/*Copyright (C) 2015 The Android Open Source Project
/*
/*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
/*
/*     http://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.
 */
 *
 * 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;
}
