// 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;
 }
