diff --git a/drivers/sensors/sensor.c b/drivers/sensors/sensor.c index c6001dbf9c..25431ae489 100644 --- a/drivers/sensors/sensor.c +++ b/drivers/sensors/sensor.c @@ -196,7 +196,8 @@ static bool sensor_is_updated(unsigned long generation, return generation > ugeneration; } -static int sensor_update_interval(FAR struct sensor_upperhalf_s *upper, +static int sensor_update_interval(FAR struct file *filep, + FAR struct sensor_upperhalf_s *upper, FAR struct sensor_user_s *user, unsigned long interval) { @@ -237,7 +238,7 @@ update: if (min_interval != ULONG_MAX && lower->ops->set_interval) { - ret = lower->ops->set_interval(lower, &min_interval); + ret = lower->ops->set_interval(lower, filep, &min_interval); if (ret < 0) { return ret; @@ -250,7 +251,8 @@ update: return ret; } -static int sensor_update_latency(FAR struct sensor_upperhalf_s *upper, +static int sensor_update_latency(FAR struct file *filep, + FAR struct sensor_upperhalf_s *upper, FAR struct sensor_user_s *user, unsigned long latency) { @@ -296,7 +298,7 @@ update: if (min_latency != ULONG_MAX && lower->ops->batch) { - ret = lower->ops->batch(lower, &min_latency); + ret = lower->ops->batch(lower, filep, &min_latency); if (ret < 0) { return ret; @@ -368,14 +370,23 @@ static int sensor_open(FAR struct file *filep) goto errout_with_sem; } + if (lower->ops->open) + { + ret = lower->ops->open(lower, filep); + if (ret < 0) + { + goto errout_with_user; + } + } + if (filep->f_oflags & O_RDOK) { if (upper->state.nsubscribers == 0 && lower->ops->activate) { - ret = lower->ops->activate(lower, true); + ret = lower->ops->activate(lower, filep, true); if (ret < 0) { - goto errout_with_user; + goto errout_with_open; } } @@ -401,6 +412,12 @@ static int sensor_open(FAR struct file *filep) filep->f_priv = user; goto errout_with_sem; +errout_with_open: + if (lower->ops->close) + { + lower->ops->close(lower, filep); + } + errout_with_user: kmm_free(user); errout_with_sem: @@ -422,12 +439,22 @@ static int sensor_close(FAR struct file *filep) return ret; } + if (lower->ops->close) + { + ret = lower->ops->close(lower, filep); + if (ret < 0) + { + nxsem_post(&upper->exclsem); + return ret; + } + } + if (filep->f_oflags & O_RDOK) { upper->state.nsubscribers--; if (upper->state.nsubscribers == 0 && lower->ops->activate) { - lower->ops->activate(lower, false); + lower->ops->activate(lower, filep, false); } } @@ -437,8 +464,8 @@ static int sensor_close(FAR struct file *filep) } list_delete(&user->node); - sensor_update_latency(upper, user, ULONG_MAX); - sensor_update_interval(upper, user, ULONG_MAX); + sensor_update_latency(filep, upper, user, ULONG_MAX); + sensor_update_interval(filep, upper, user, ULONG_MAX); nxsem_destroy(&user->buffersem); /* The user is closed, notify to other users */ @@ -494,7 +521,7 @@ static ssize_t sensor_read(FAR struct file *filep, FAR char *buffer, goto out; } - ret = lower->ops->fetch(lower, buffer, len); + ret = lower->ops->fetch(lower, filep, buffer, len); } else { @@ -604,13 +631,13 @@ static int sensor_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case SNIOC_SET_INTERVAL: { - ret = sensor_update_interval(upper, user, arg); + ret = sensor_update_interval(filep, upper, user, arg); } break; case SNIOC_BATCH: { - ret = sensor_update_latency(upper, user, arg); + ret = sensor_update_latency(filep, upper, user, arg); } break; @@ -622,7 +649,7 @@ static int sensor_ioctl(FAR struct file *filep, int cmd, unsigned long arg) break; } - ret = lower->ops->selftest(lower, arg); + ret = lower->ops->selftest(lower, filep, arg); } break; @@ -634,7 +661,7 @@ static int sensor_ioctl(FAR struct file *filep, int cmd, unsigned long arg) break; } - ret = lower->ops->set_calibvalue(lower, arg); + ret = lower->ops->set_calibvalue(lower, filep, arg); } break; @@ -646,7 +673,7 @@ static int sensor_ioctl(FAR struct file *filep, int cmd, unsigned long arg) break; } - ret = lower->ops->calibrate(lower, arg); + ret = lower->ops->calibrate(lower, filep, arg); } break; @@ -682,7 +709,7 @@ static int sensor_ioctl(FAR struct file *filep, int cmd, unsigned long arg) if (lower->ops->control) { - ret = lower->ops->control(lower, cmd, arg); + ret = lower->ops->control(lower, filep, cmd, arg); } else { diff --git a/include/nuttx/sensors/sensor.h b/include/nuttx/sensors/sensor.h index 9be32a3268..a9ef796eb7 100644 --- a/include/nuttx/sensors/sensor.h +++ b/include/nuttx/sensors/sensor.h @@ -32,6 +32,7 @@ #include #include +#include #include /**************************************************************************** @@ -584,6 +585,48 @@ struct sensor_cap /* Type: Capacitance */ struct sensor_lowerhalf_s; struct sensor_ops_s { + /************************************************************************** + * Name: open + * + * Description: + * The open method differs from the activate method with true because + * it's called and turned off every times, and it receives the pointer + * of file and the instance of lowerhalf sensor driver. It uses to do + * something about initialize for every user. + * + * Input Parameters: + * lower - The instance of lower half sensor driver + * filep - The pointer of file, represents each user using the sensor + * + * Returned Value: + * Zero (OK) or positive on success; a negated errno value on failure. + * + **************************************************************************/ + + CODE int (*open)(FAR struct sensor_lowerhalf_s *lower, + FAR struct file *filep); + + /************************************************************************** + * Name: close + * + * Description: + * The close method differs from the activate method with false because + * it's called and turned off every times, and it receives the pointer + * of file and the instance of lowerhalf sensor driver. It uses to do + * something about uninitialize for every user. + * + * Input Parameters: + * lower - The instance of lower half sensor driver. + * filep - The pointer of file, represents each user using the sensor. + * + * Returned Value: + * Zero (OK) or positive on success; a negated errno value on failure. + * + **************************************************************************/ + + CODE int (*close)(FAR struct sensor_lowerhalf_s *lower, + FAR struct file *filep); + /************************************************************************** * Name: activate * @@ -594,6 +637,7 @@ struct sensor_ops_s * * Input Parameters: * lower - The instance of lower half sensor driver + * filep - The pointer of file, represents each user using the sensor. * enable - true(enable) and false(disable) * * Returned Value: @@ -601,7 +645,8 @@ struct sensor_ops_s * **************************************************************************/ - CODE int (*activate)(FAR struct sensor_lowerhalf_s *lower, bool enable); + CODE int (*activate)(FAR struct sensor_lowerhalf_s *lower, + FAR struct file *filep, bool enable); /************************************************************************** * Name: set_interval @@ -619,6 +664,7 @@ struct sensor_ops_s * * Input Parameters: * lower - The instance of lower half sensor driver. + * filep - The pointer of file, represents each user using sensor. * period_us - the time between samples, in us, it may be overwrite by * lower half driver. * @@ -628,6 +674,7 @@ struct sensor_ops_s **************************************************************************/ CODE int (*set_interval)(FAR struct sensor_lowerhalf_s *lower, + FAR struct file *filep, FAR unsigned long *period_us); /************************************************************************** @@ -663,6 +710,7 @@ struct sensor_ops_s * * Input Parameters: * lower - The instance of lower half sensor driver. + * filep - The pointer of file, represents each user using sensor. * latency_us - the time between batch data, in us. It may by overwrite * by lower half driver. * @@ -672,6 +720,7 @@ struct sensor_ops_s **************************************************************************/ CODE int (*batch)(FAR struct sensor_lowerhalf_s *lower, + FAR struct file *filep, FAR unsigned long *latency_us); /************************************************************************** @@ -693,6 +742,7 @@ struct sensor_ops_s * * Input Parameters: * lower - The instance of lower half sensor driver. + * filep - The pointer of file, represents each user using sensor. * buffer - The buffer of receive sensor event, it's provided by * file_operation::sensor_read. * buflen - The size of buffer. @@ -704,6 +754,7 @@ struct sensor_ops_s **************************************************************************/ CODE int (*fetch)(FAR struct sensor_lowerhalf_s *lower, + FAR struct file *filep, FAR char *buffer, size_t buflen); /************************************************************************** @@ -718,6 +769,7 @@ struct sensor_ops_s * * Input Parameters: * lower - The instance of lower half sensor driver. + * filep - The pointer of file, represents each user using sensor. * arg - The parameters associated with selftest. * * Returned Value: @@ -726,6 +778,7 @@ struct sensor_ops_s **************************************************************************/ CODE int (*selftest)(FAR struct sensor_lowerhalf_s *lower, + FAR struct file *filep, unsigned long arg); /************************************************************************** @@ -738,6 +791,7 @@ struct sensor_ops_s * * Input Parameters: * lower - The instance of lower half sensor driver. + * filep - The pointer of file, represents each user using sensor. * arg - The parameters associated with calibration value. * * Returned Value: @@ -746,6 +800,7 @@ struct sensor_ops_s **************************************************************************/ CODE int (*set_calibvalue)(FAR struct sensor_lowerhalf_s *lower, + FAR struct file *filep, unsigned long arg); /**************************************************************************** @@ -762,6 +817,7 @@ struct sensor_ops_s * * Input Parameters: * lower - The instance of lower half sensor driver. + * filep - The pointer of file, represents each user using sensor. * arg - The parameters associated with calibration value. * * Returned Value: @@ -770,6 +826,7 @@ struct sensor_ops_s **************************************************************************/ CODE int (*calibrate)(FAR struct sensor_lowerhalf_s *lower, + FAR struct file *filep, unsigned long arg); /************************************************************************** @@ -781,6 +838,7 @@ struct sensor_ops_s * * Input Parameters: * lower - The instance of lower half sensor driver. + * filep - The pointer of file, represents each user using sensor. * cmd - The special cmd for sensor. * arg - The parameters associated with cmd. * @@ -791,6 +849,7 @@ struct sensor_ops_s **************************************************************************/ CODE int (*control)(FAR struct sensor_lowerhalf_s *lower, + FAR struct file *filep, int cmd, unsigned long arg); };