rt_err_t _control(rt_device_t dev, rt_uint8_t cmd, void *args) { RT_ASSERT(dev); switch (cmd) { case VBUS_IOC_LISCFG: { struct rt_vbus_dev *vdev = dev->user_data; struct rt_vbus_dev_liscfg *liscfg = args; RT_ASSERT(vdev->chnr != 0); if (!liscfg) return -RT_ERROR; rt_vbus_register_listener(vdev->chnr, liscfg->event, liscfg->listener, liscfg->ctx); return RT_EOK; } break; #ifdef RT_VBUS_USING_FLOW_CONTROL case VBUS_IOCRECV_WM: { struct rt_vbus_dev *vdev = dev->user_data; struct rt_vbus_wm_cfg *cfg; RT_ASSERT(vdev->chnr != 0); if (!args) return -RT_ERROR; cfg = (struct rt_vbus_wm_cfg*)args; if (cfg->low > cfg->high) return -RT_ERROR; rt_vbus_set_recv_wm(vdev->chnr, cfg->low, cfg->high); return RT_EOK; } break; case VBUS_IOCPOST_WM: { struct rt_vbus_dev *vdev = dev->user_data; struct rt_vbus_wm_cfg *cfg; RT_ASSERT(vdev->chnr != 0); if (!args) return -RT_ERROR; cfg = (struct rt_vbus_wm_cfg*)args; if (cfg->low > cfg->high) return -RT_ERROR; rt_vbus_set_post_wm(vdev->chnr, cfg->low, cfg->high); return RT_EOK; } break; #endif default: break; }; return -RT_ENOSYS; }
static long vbus_chnx_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { int res = -ENOTTY; switch (cmd) { #ifdef RT_VBUS_USING_FLOW_CONTROL case VBUS_IOCRECV_WM: { struct rt_vbus_wm_cfg cfg; unsigned long chnr = (unsigned long)filp->private_data; if (copy_from_user(&cfg, (struct rt_vbus_wm_cfg*)arg, sizeof(cfg))) return -EFAULT; rt_vbus_set_recv_wm(chnr, cfg.low, cfg.high); return 0; } break; case VBUS_IOCPOST_WM: { struct rt_vbus_wm_cfg cfg; unsigned long chnr = (unsigned long)filp->private_data; if (copy_from_user(&cfg, (struct rt_vbus_wm_cfg*)arg, sizeof(cfg))) return -EFAULT; rt_vbus_set_post_wm(chnr, cfg.low, cfg.high); return 0; } break; #endif default: break; }; return res; }