// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

// Get NULL from here
#include "usb_controlep.h"

#include <stddef.h>

#include "sw/device/lib/common.h"
#include "usb_consts.h"
#include "usbdev.h"

// Device descriptor
static uint8_t dev_dscr[] = {
    18,    // bLength
    1,     // bDescriptorType
    0x00,  // bcdUSB[0]
    0x02,  // bcdUSB[1]
    0x00,  // bDeviceClass (defined at interface level)
    0x00,  // bDeviceSubClass
    0x00,  // bDeviceProtocol
    64,    // bMaxPacketSize0

    0xd1,  // idVendor[0] 0x18d1 Google Inc.
    0x18,  // idVendor[1]
    0x3a,  // idProduct[0] lowRISC generic FS USB
    0x50,  // idProduct[1] (allocated by Google)

    0,    // bcdDevice[0]
    0x1,  // bcdDevice[1]
    0,    // iManufacturer
    0,    // iProduct
    0,    // iSerialNumber
    1     // bNumConfigurations
};

static ctstate_t setup_req(usb_controlep_ctx_t *ctctx, void *ctx,
                           usbbufid_t buf, int bmRequestType, int bRequest,
                           int wValue, int wIndex, int wLength) {
  size_t len;
  uint32_t stat;
  int zero, type;
  switch (bRequest) {
    case kUsbSetupReqGetDescriptor:
      if ((wValue & 0xff00) == 0x100) {
        // Device descriptor
        len = sizeof(dev_dscr);
        if (wLength < len) {
          len = wLength;
        }
        usbdev_buf_copyto_byid(ctx, buf, dev_dscr, len);
        usbdev_sendbuf_byid(ctx, buf, len, ctctx->ep);
        return kCtWaitIn;
      } else if ((wValue & 0xff00) == 0x200) {
        // Configuration descriptor
        len = ctctx->cfg_dscr_len;
        if (wLength < len) {
          len = wLength;
        }
        usbdev_buf_copyto_byid(ctx, buf, ctctx->cfg_dscr, len);
        usbdev_sendbuf_byid(ctx, buf, len, ctctx->ep);
        return kCtWaitIn;
      }
      return kCtIdle;  // unknown

    case kUsbSetupReqSetAddress:
      ctctx->new_dev = wValue & 0x7f;
      // send zero length packet for status phase
      usbdev_sendbuf_byid(ctx, buf, 0, ctctx->ep);
      return kCtAddrStatIn;

    case kUsbSetupReqSetConfiguration:
      // only ever expect this to be 1 since there is one config descriptor
      ctctx->usb_config = wValue;
      // send zero length packet for status phase
      usbdev_sendbuf_byid(ctx, buf, 0, ctctx->ep);
      return kCtStatIn;

    case kUsbSetupReqGetConfiguration:
      len = sizeof(ctctx->usb_config);
      if (wLength < len) {
        len = wLength;
      }
      // return the value that was set
      usbdev_buf_copyto_byid(ctx, buf, &ctctx->usb_config, len);
      usbdev_sendbuf_byid(ctx, buf, len, ctctx->ep);
      return kCtWaitIn;

    case kUsbSetupReqSetFeature:
      if (wValue == kUsbFeatureEndpointHalt) {
        usbdev_halt(ctx, wIndex, 1);
      } else if (wValue == kUsbFeatureDeviceRemoteWakeup) {
        usbdev_rem_wake_en(ctx, 1);
      }
      // send zero length packet for status phase
      usbdev_sendbuf_byid(ctx, buf, 0, ctctx->ep);
      return kCtStatIn;

    case kUsbSetupReqClearFeature:
      if (wValue == kUsbFeatureEndpointHalt) {
        usbdev_halt(ctx, wIndex, 0);
      } else if (wValue == kUsbFeatureDeviceRemoteWakeup) {
        usbdev_rem_wake_en(ctx, 0);
      }
      // send zero length packet for status phase
      usbdev_sendbuf_byid(ctx, buf, 0, ctctx->ep);
      return kCtStatIn;

    case kUsbSetupReqGetStatus:
      len = 2;
      type = bmRequestType & kUsbReqTypeRecipientMask;
      if (type == kUsbReqTypeDevice) {
        stat = (usbdev_can_rem_wake(ctx) ? kUsbStatusRemWake : 0) |
               kUsbStatusSelfPowered;
      } else if (type == kUsbReqTypeEndpoint) {
        stat = usbdev_halted(ctx, wIndex) ? kUsbStatusHalted : 0;
      } else {
        stat = 0;
      }
      if (wLength < len) {
        len = wLength;
      }
      // return the value that was set
      usbdev_buf_copyto_byid(ctx, buf, &stat, len);
      usbdev_sendbuf_byid(ctx, buf, len, ctctx->ep);
      return kCtWaitIn;

    case kUsbSetupReqSetInterface:
      // Don't support alternate interfaces, so just ignore
      // send zero length packet for status phase
      usbdev_sendbuf_byid(ctx, buf, 0, ctctx->ep);
      return kCtStatIn;

    case kUsbSetupReqGetInterface:
      zero = 0;
      len = 1;
      if (wLength < len) {
        len = wLength;
      }
      // Don't support interface, so return zero
      usbdev_buf_copyto_byid(ctx, buf, &zero, len);
      usbdev_sendbuf_byid(ctx, buf, len, ctctx->ep);
      return kCtWaitIn;

    case kUsbSetupReqSynchFrame:
      zero = 0;
      len = 2;
      if (wLength < len) {
        len = wLength;
      }
      // Don't support synch_frame so return zero
      usbdev_buf_copyto_byid(ctx, buf, &zero, len);
      usbdev_sendbuf_byid(ctx, buf, len, ctctx->ep);
      return kCtWaitIn;
  }
  return kCtError;
}

static void ctrl_tx_done(void *ctctx_v) {
  usb_controlep_ctx_t *ctctx = (usb_controlep_ctx_t *)ctctx_v;
  void *ctx = ctctx->ctx;
  TRC_C('A' + ctctx->ctrlstate);
  switch (ctctx->ctrlstate) {
    case kCtAddrStatIn:
      // Now the status was sent on device 0 can switch to new device ID
      usbdev_set_deviceid(ctx, ctctx->new_dev);
      TRC_I(ctctx->new_dev, 8);
      ctctx->ctrlstate = kCtIdle;
      return;
    case kCtStatIn:
      ctctx->ctrlstate = kCtIdle;
      return;
    case kCtWaitIn:
      ctctx->ctrlstate = kCtStatOut;
      return;
    default:
      break;
  }
  TRC_S("USB: unexpected IN ");
  TRC_I((ctctx->ctrlstate << 24), 32);
}

static void ctrl_rx(void *ctctx_v, usbbufid_t buf, int size, int setup) {
  usb_controlep_ctx_t *ctctx = (usb_controlep_ctx_t *)ctctx_v;
  void *ctx = ctctx->ctx;
  volatile uint8_t *bp = (volatile uint8_t *)usbdev_buf_idtoaddr(ctx, buf);
  if (size > BUF_LENGTH) {
    size = BUF_LENGTH;
  }

  TRC_C('0' + ctctx->ctrlstate);
  switch (ctctx->ctrlstate) {
    case kCtIdle:
      // Waiting to be set up
      if (setup && (size == 8)) {
        int bmRequestType = bp[0];
        int bRequest = bp[1];
        int wValue = (bp[3] << 8) | bp[2];
        int wIndex = (bp[5] << 8) | bp[4];
        int wLength = (bp[7] << 8) | bp[6];
        TRC_C('0' + bRequest);

        ctctx->ctrlstate = setup_req(ctctx, ctx, buf, bmRequestType, bRequest,
                                     wValue, wIndex, wLength);
        if (ctctx->ctrlstate != kCtError) {
          return;
        }
      }
      break;

    case kCtStatOut:
      // Have sent some data, waiting STATUS stage
      if (!setup && (size == 0)) {
        ctctx->ctrlstate = kCtIdle;
        return;
      }
      // anything else is unexpected
      break;

    default:
      // Error
      break;
  }
  TRC_S("USB: unCT ");
  TRC_I((ctctx->ctrlstate << 24) | setup << 16 | size, 32);
  TRC_C(':');
  for (int i = 0; i < size; i++) {
    TRC_I(bp[i], 8);
    TRC_C(' ');
  }
  usbdev_buf_free_byid(ctx, buf);
  ctctx->ctrlstate = kCtIdle;
}

void usb_controlep_init(usb_controlep_ctx_t *ctctx, usbdev_ctx_t *ctx, int ep,
                        const uint8_t *cfg_dscr, size_t cfg_dscr_len) {
  ctctx->ctx = ctx;
  usbdev_endpoint_setup(ctx, ep, 1, ctctx, ctrl_tx_done, ctrl_rx, NULL);
  ctctx->ctrlstate = kCtIdle;
  ctctx->cfg_dscr = cfg_dscr;
  ctctx->cfg_dscr_len = cfg_dscr_len;
}
