You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by pk...@apache.org on 2022/05/30 17:38:56 UTC
[incubator-nuttx] 03/11: drivers/video: Enable to select connected image sensor driver at runtime
This is an automated email from the ASF dual-hosted git repository.
pkarashchenko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit b45489753aaf914669b5f130915ee9d739e82e7f
Author: SPRESENSE <41...@users.noreply.github.com>
AuthorDate: Mon Nov 29 09:31:43 2021 +0900
drivers/video: Enable to select connected image sensor driver at runtime
Enable to select connected image sensor driver at runtime by adding is_available()
to image sensor I/F.
---
drivers/video/isx012.c | 52 ++++++++++++++++++++++++++++++++++++++++-
drivers/video/video.c | 52 ++++++++++++++++++++++++++++++++++++-----
include/nuttx/video/imgsensor.h | 43 +++++++++++++++++-----------------
3 files changed, 119 insertions(+), 28 deletions(-)
diff --git a/drivers/video/isx012.c b/drivers/video/isx012.c
index ea4658e8f1..83f06d77e5 100644
--- a/drivers/video/isx012.c
+++ b/drivers/video/isx012.c
@@ -140,6 +140,9 @@
(((val - min) % step) == 0) ? \
OK : -EINVAL))
+#define ISX012_CHIPID_L (0x0000c460)
+#define ISX012_CHIPID_H (0x00005516)
+
/****************************************************************************
* Private Types
****************************************************************************/
@@ -215,6 +218,7 @@ static bool is_movie_needed(uint8_t fmt, uint8_t fps);
/* image sensor device operations interface */
+static bool isx012_is_available(void);
static int isx012_init(void);
static int isx012_uninit(void);
static const char *isx012_get_driver_name(void);
@@ -615,6 +619,7 @@ static uint8_t g_isx012_iso_regval[] =
static struct imgsensor_ops_s g_isx012_ops =
{
+ isx012_is_available, /* is HW available */
isx012_init, /* init */
isx012_uninit, /* uninit */
isx012_get_driver_name, /* get driver name */
@@ -1236,6 +1241,45 @@ int init_isx012(FAR struct isx012_dev_s *priv)
return ret;
}
+static void get_chipid(uint32_t *l, uint32_t *h)
+{
+ uint16_t l1;
+ uint16_t l2;
+ uint16_t h1;
+ uint16_t h2;
+
+ ASSERT(l && h);
+
+ l1 = isx012_getreg(&g_isx012_private, OTP_CHIPID_L, 2);
+ l2 = isx012_getreg(&g_isx012_private, OTP_CHIPID_L + 2, 2);
+
+ h1 = isx012_getreg(&g_isx012_private, OTP_CHIPID_H, 2);
+ h2 = isx012_getreg(&g_isx012_private, OTP_CHIPID_H + 2, 2);
+
+ *l = (l2 << 16) | l1;
+ *h = (h2 << 16) | h1;
+}
+
+static bool isx012_is_available(void)
+{
+ bool ret = false;
+ uint32_t l;
+ uint32_t h;
+
+ isx012_init();
+
+ get_chipid(&l, &h);
+
+ if ((l == ISX012_CHIPID_L) && (h == ISX012_CHIPID_H))
+ {
+ ret = true;
+ }
+
+ isx012_uninit();
+
+ return ret;
+}
+
static int isx012_init(void)
{
FAR struct isx012_dev_s *priv = &g_isx012_private;
@@ -2885,11 +2929,17 @@ static int isx012_set_shd(FAR isx012_dev_t *priv)
int isx012_initialize(void)
{
+ int ret;
FAR struct isx012_dev_s *priv = &g_isx012_private;
/* Regiser image sensor operations variable */
- imgsensor_register(&g_isx012_ops);
+ ret = imgsensor_register(&g_isx012_ops);
+ if (ret != OK)
+ {
+ verr("Failed to register ops to video driver.\n");
+ return ret;
+ }
/* Initialize other information */
diff --git a/drivers/video/video.c b/drivers/video/video.c
index 79b4c6f3ba..c8e4980cd1 100644
--- a/drivers/video/video.c
+++ b/drivers/video/video.c
@@ -398,6 +398,8 @@ static video_parameter_name_t g_video_parameter_name[] =
};
static FAR void *video_handler;
+static FAR const struct imgsensor_ops_s **g_video_registered_sensor;
+static int g_video_registered_sensor_num;
static FAR const struct imgsensor_ops_s *g_video_sensor_ops;
static FAR const struct imgdata_ops_s *g_video_data_ops;
@@ -930,6 +932,24 @@ static bool is_sem_waited(FAR sem_t *sem)
}
}
+static FAR const struct imgsensor_ops_s *get_connected_imgsensor(void)
+{
+ int i;
+ FAR const struct imgsensor_ops_s *ops = NULL;
+
+ for (i = 0; i < g_video_registered_sensor_num; i++)
+ {
+ if (g_video_registered_sensor[i] &&
+ g_video_registered_sensor[i]->is_available())
+ {
+ ops = g_video_registered_sensor[i];
+ break;
+ }
+ }
+
+ return ops;
+}
+
static int video_open(FAR struct file *filep)
{
FAR struct inode *inode = filep->f_inode;
@@ -941,15 +961,23 @@ static int video_open(FAR struct file *filep)
{
/* Only in first execution, open device */
- ret = g_video_sensor_ops->init();
- if (ret == OK)
+ g_video_sensor_ops = get_connected_imgsensor();
+ if (g_video_sensor_ops)
{
- ret = g_video_data_ops->init();
+ ret = g_video_sensor_ops->init();
if (ret == OK)
{
- initialize_resources(priv);
+ ret = g_video_data_ops->init();
+ if (ret == OK)
+ {
+ initialize_resources(priv);
+ }
}
}
+ else
+ {
+ ret = -ENODEV;
+ }
}
/* In second or later execution, ret is initial value(=OK) */
@@ -3018,9 +3046,21 @@ int video_uninitialize(void)
return OK;
}
-void imgsensor_register(FAR const struct imgsensor_ops_s *ops)
+int imgsensor_register(FAR const struct imgsensor_ops_s *ops)
{
- g_video_sensor_ops = ops;
+ int ret = -ENOMEM;
+ FAR const struct imgsensor_ops_s **new_addr;
+
+ new_addr = realloc(g_video_registered_sensor,
+ sizeof(ops) * (g_video_registered_sensor_num + 1));
+ if (new_addr)
+ {
+ new_addr[g_video_registered_sensor_num++] = ops;
+ g_video_registered_sensor = new_addr;
+ ret = OK;
+ }
+
+ return ret;
}
void imgdata_register(FAR const struct imgdata_ops_s *ops)
diff --git a/include/nuttx/video/imgsensor.h b/include/nuttx/video/imgsensor.h
index 0254250cf7..8d1f60109b 100644
--- a/include/nuttx/video/imgsensor.h
+++ b/include/nuttx/video/imgsensor.h
@@ -303,27 +303,28 @@ typedef union imgsensor_value_u
struct imgsensor_ops_s
{
- CODE int (*init)(void);
- CODE int (*uninit)(void);
+ CODE bool (*is_available)(void);
+ CODE int (*init)(void);
+ CODE int (*uninit)(void);
CODE const char * (*get_driver_name)(void);
- CODE int (*validate_frame_setting)(imgsensor_stream_type_t type,
- uint8_t nr_datafmts,
- FAR imgsensor_format_t *datafmts,
- FAR imgsensor_interval_t *interval);
- CODE int (*start_capture)(imgsensor_stream_type_t type,
- uint8_t nr_datafmts,
- FAR imgsensor_format_t *datafmts,
- FAR imgsensor_interval_t *interval);
- CODE int (*stop_capture)(imgsensor_stream_type_t type);
-
- CODE int (*get_supported_value)(uint32_t id,
- FAR imgsensor_supported_value_t *value);
- CODE int (*get_value)(uint32_t id,
- uint32_t size,
- FAR imgsensor_value_t *value);
- CODE int (*set_value)(uint32_t id,
- uint32_t size,
- imgsensor_value_t value);
+ CODE int (*validate_frame_setting)(imgsensor_stream_type_t type,
+ uint8_t nr_datafmts,
+ FAR imgsensor_format_t *datafmts,
+ FAR imgsensor_interval_t *interval);
+ CODE int (*start_capture)(imgsensor_stream_type_t type,
+ uint8_t nr_datafmts,
+ FAR imgsensor_format_t *datafmts,
+ FAR imgsensor_interval_t *interval);
+ CODE int (*stop_capture)(imgsensor_stream_type_t type);
+
+ CODE int (*get_supported_value)(uint32_t id,
+ FAR imgsensor_supported_value_t *value);
+ CODE int (*get_value)(uint32_t id,
+ uint32_t size,
+ FAR imgsensor_value_t *value);
+ CODE int (*set_value)(uint32_t id,
+ uint32_t size,
+ imgsensor_value_t value);
};
#ifdef __cplusplus
@@ -340,7 +341,7 @@ extern "C"
/* Register image sensor operations. */
-void imgsensor_register(FAR const struct imgsensor_ops_s *ops);
+int imgsensor_register(FAR const struct imgsensor_ops_s *ops);
#undef EXTERN
#ifdef __cplusplus