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.
This commit is contained in:
parent
a25ac08774
commit
b45489753a
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 (*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 (*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
|
||||
|
|
Loading…
Reference in New Issue