static int lirc_ioctl()

in drivers/rc/lirc_dev.c [257:582]


static int lirc_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{
  FAR struct lirc_fh_s *fh = filep->f_priv;
  FAR struct lirc_lowerhalf_s *lower = fh->lower;
  FAR struct lirc_upperhalf_s *upper = lower->priv;
  FAR unsigned int *val = (FAR unsigned int *)(uintptr_t)arg;
  int ret;

  ret = nxmutex_lock(&upper->lock);
  if (ret < 0)
    {
      return ret;
    }

  switch (cmd)
    {
      case LIRC_GET_FEATURES:
        switch (lower->ops->driver_type)
          {
            case LIRC_DRIVER_SCANCODE:
              *val = LIRC_CAN_REC_SCANCODE;
              break;
            case LIRC_DRIVER_IR_RAW:
              *val = LIRC_CAN_REC_MODE2;
              break;
            default:
              *val = 0;
              break;
          }

        if (lower->rx_resolution)
          {
            *val |= LIRC_CAN_GET_REC_RESOLUTION;
          }

        if (lower->ops->tx_ir)
          {
            *val |= LIRC_CAN_SEND_PULSE;
          }

        if (lower->ops->tx_scancode)
          {
            *val |= LIRC_CAN_SEND_SCANCODE;
          }

        if (lower->ops->s_tx_mask)
          {
            *val |= LIRC_CAN_SET_TRANSMITTER_MASK;
          }

        if (lower->ops->s_tx_carrier)
          {
            *val |= LIRC_CAN_SET_SEND_CARRIER;
          }

        if (lower->ops->s_tx_duty_cycle)
          {
            *val |= LIRC_CAN_SET_SEND_DUTY_CYCLE;
          }

        if (lower->ops->s_rx_carrier_range)
          {
            *val |= LIRC_CAN_SET_REC_CARRIER |
                    LIRC_CAN_SET_REC_CARRIER_RANGE;
          }

        if (lower->ops->s_learning_mode)
          {
            *val |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
          }

        if (lower->ops->s_carrier_report)
          {
            *val |= LIRC_CAN_MEASURE_CARRIER;
          }

        if (lower->max_timeout)
          {
            *val |= LIRC_CAN_SET_REC_TIMEOUT;
          }
        break;

      /* mode support */

      case LIRC_GET_REC_MODE:
        if (lower->ops->driver_type == LIRC_DRIVER_IR_RAW_TX)
          {
            ret = -ENOTTY;
          }
        else
          {
            *val = fh->rec_mode;
          }
        break;

      case LIRC_SET_REC_MODE:
        switch (lower->ops->driver_type)
          {
            case LIRC_DRIVER_IR_RAW_TX:
              ret = -ENOTTY;
              break;

            case LIRC_DRIVER_SCANCODE:
              if (arg != LIRC_MODE_SCANCODE)
                {
                  ret = -EINVAL;
                }
              break;

            case LIRC_DRIVER_IR_RAW:
              if (arg != LIRC_MODE_MODE2)
                {
                  ret = -EINVAL;
                }
              break;
          }

        if (ret >= 0)
          {
            fh->rec_mode = arg;
          }
        break;

      case LIRC_GET_SEND_MODE:
        if (!lower->ops->tx_ir && !lower->ops->tx_scancode)
          {
            ret = -ENOTTY;
          }
        else
          {
            *val = fh->send_mode;
          }
        break;

      case LIRC_SET_SEND_MODE:
        if ((arg == LIRC_MODE_PULSE && lower->ops->tx_ir) ||
            (arg == LIRC_MODE_SCANCODE && lower->ops->tx_scancode))
          {
            fh->send_mode = arg;
          }
        else
          {
            ret = -EINVAL;
          }
        break;

      /* TX settings */

      case LIRC_SET_TRANSMITTER_MASK:
        if (!lower->ops->s_tx_mask)
          {
            ret = -ENOTTY;
          }
        else
          {
            ret = lower->ops->s_tx_mask(lower, arg);
          }
        break;

      case LIRC_SET_SEND_CARRIER:
        if (!lower->ops->s_tx_carrier)
          {
            ret = -ENOTTY;
          }
        else
          {
            ret = lower->ops->s_tx_carrier(lower, arg);
          }
        break;

      case LIRC_SET_SEND_DUTY_CYCLE:
        if (!lower->ops->s_tx_duty_cycle)
          {
            ret = -ENOTTY;
          }
        else if (arg <= 0 || arg >= 100)
          {
            ret = -EINVAL;
          }
        else
          {
            ret = lower->ops->s_tx_duty_cycle(lower, arg);
          }
        break;

      /* RX settings */

      case LIRC_SET_REC_CARRIER:
        if (!lower->ops->s_rx_carrier_range)
          {
            ret = -ENOTTY;
          }
        else if (arg <= 0)
          {
            ret = -EINVAL;
          }
        else
          {
            ret = lower->ops->s_rx_carrier_range(lower,
                                                 fh->carrier_low, arg);
          }
        break;

      case LIRC_SET_REC_CARRIER_RANGE:
        if (!lower->ops->s_rx_carrier_range)
          {
            ret = -ENOTTY;
          }
        else if (arg <= 0)
          {
            ret = -EINVAL;
          }
        else
          {
            fh->carrier_low = arg;
          }
        break;

      case LIRC_GET_REC_RESOLUTION:
        if (!lower->rx_resolution)
          {
            ret = -ENOTTY;
          }
        else
          {
            *val = lower->rx_resolution;
          }
        break;

      case LIRC_SET_WIDEBAND_RECEIVER:
        if (!lower->ops->s_learning_mode)
          {
            ret = -ENOTTY;
          }
        else
          {
            ret = lower->ops->s_learning_mode(lower, !!arg);
          }
        break;

      case LIRC_SET_MEASURE_CARRIER_MODE:
        if (!lower->ops->s_carrier_report)
          {
            ret = -ENOTTY;
          }
        else
          {
            ret = lower->ops->s_carrier_report(lower, !!arg);
          }
        break;

      /* Generic timeout support */

      case LIRC_GET_MIN_TIMEOUT:
        if (!lower->min_timeout)
          {
            ret = -ENOTTY;
          }
        else
          {
            *val = lower->min_timeout;
          }
        break;

      case LIRC_GET_MAX_TIMEOUT:
        if (!lower->max_timeout)
          {
            ret = -ENOTTY;
          }
        else
          {
            *val = lower->max_timeout;
          }
        break;

      case LIRC_SET_REC_TIMEOUT:
        if (!lower->max_timeout)
          {
            ret = -ENOTTY;
          }
        else
          {
            if (arg < lower->min_timeout || arg > lower->max_timeout)
              {
                ret = -EINVAL;
              }
            else if (lower->ops->s_timeout)
              {
                ret = lower->ops->s_timeout(lower, arg);
              }
            else
              {
                lower->timeout = arg;
              }
          }
        break;

      case LIRC_GET_REC_TIMEOUT:
        if (!lower->timeout)
          {
            ret = -ENOTTY;
          }
        else
          {
            *val = lower->timeout;
          }
        break;

      case LIRC_SET_REC_TIMEOUT_REPORTS:
        if (lower->ops->driver_type != LIRC_DRIVER_IR_RAW)
          {
            ret = -ENOTTY;
          }
        else
          {
            fh->send_timeout_reports = !!arg;
          }
        break;

      default:
        ret = -ENOTTY;
    }

  nxmutex_unlock(&upper->lock);
  return ret;
}