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