@@ -239,6 +239,7 @@ enum pad_types { IMAGE_PAD, METADATA_PAD, NUM_PADS };
239239
240240#define V4L2_CID_USER_IMX500_INFERENCE_WINDOW (V4L2_CID_USER_IMX500_BASE + 0)
241241#define V4L2_CID_USER_IMX500_NETWORK_FW_FD (V4L2_CID_USER_IMX500_BASE + 1)
242+ #define V4L2_CID_USER_GET_IMX500_DEVICE_ID (V4L2_CID_USER_IMX500_BASE + 2)
242243
243244#define ONE_MIB (1024 * 1024)
244245
@@ -1365,6 +1366,7 @@ struct imx500 {
13651366 struct v4l2_ctrl * vblank ;
13661367 struct v4l2_ctrl * hblank ;
13671368 struct v4l2_ctrl * network_fw_ctrl ;
1369+ struct v4l2_ctrl * device_id ;
13681370
13691371 struct v4l2_rect inference_window ;
13701372
@@ -1579,6 +1581,25 @@ static int imx500_set_inference_window(struct imx500 *imx500)
15791581 ARRAY_SIZE (window_regs ), NULL );
15801582}
15811583
1584+ static int imx500_get_device_id (struct imx500 * imx500 , u32 * device_id )
1585+ {
1586+ const u32 addr = 0xd040 ;
1587+ unsigned int i ;
1588+ int ret = 0 ;
1589+ u64 tmp , data ;
1590+
1591+ for (i = 0 ; i < 4 ; i ++ ) {
1592+ ret = cci_read (imx500 -> regmap , CCI_REG32 (addr + i * 4 ), & tmp ,
1593+ NULL );
1594+ if (ret )
1595+ return - EREMOTEIO ;
1596+ data = tmp & 0xffffffff ;
1597+ device_id [i ] = data ;
1598+ }
1599+
1600+ return ret ;
1601+ }
1602+
15821603static int imx500_reg_val_write_cbk (void * arg ,
15831604 const struct cci_reg_sequence * reg )
15841605{
@@ -1619,6 +1640,7 @@ static int imx500_validate_fw_block(const char *data, size_t maxlen)
16191640 static const char footer_id [] = { '3' , '6' , '9' , '5' };
16201641
16211642 u32 data_size ;
1643+ u32 extra_bytes_size = 0 ;
16221644
16231645 const char * end = data + maxlen ;
16241646
@@ -1635,13 +1657,16 @@ static int imx500_validate_fw_block(const char *data, size_t maxlen)
16351657 memcpy (& data_size , data + sizeof (header_id ), sizeof (data_size ));
16361658 data_size = ___constant_swab32 (data_size );
16371659
1638- if (end - data_size - footer_size < data )
1660+ /* check the device_lock flag */
1661+ extra_bytes_size = * ((u8 * )(data + 0x0e )) & 0x01 ? 32 : 0 ;
1662+
1663+ if (end - data_size - footer_size - extra_bytes_size < data )
16391664 return -1 ;
16401665 if (memcmp (data + data_size + footer_size - sizeof (footer_id ),
16411666 & footer_id , sizeof (footer_id )))
16421667 return -1 ;
16431668
1644- return data_size + footer_size ;
1669+ return data_size + footer_size + extra_bytes_size ;
16451670}
16461671
16471672/* Parse fw block by block, returning total valid fw size */
@@ -1875,6 +1900,7 @@ static void imx500_clear_fw_network(struct imx500 *imx500)
18751900 imx500 -> fw_network = NULL ;
18761901 imx500 -> network_written = false;
18771902 imx500 -> fw_progress = 0 ;
1903+ v4l2_ctrl_activate (imx500 -> device_id , false);
18781904}
18791905
18801906static int imx500_set_ctrl (struct v4l2_ctrl * ctrl )
@@ -1997,7 +2023,31 @@ static int imx500_set_ctrl(struct v4l2_ctrl *ctrl)
19972023 return ret ;
19982024}
19992025
2026+ static int imx500_get_ctrl (struct v4l2_ctrl * ctrl )
2027+ {
2028+ struct imx500 * imx500 = container_of (ctrl -> handler , struct imx500 ,
2029+ ctrl_handler );
2030+ struct i2c_client * client = v4l2_get_subdevdata (& imx500 -> sd );
2031+ u32 device_id [4 ] = {0 };
2032+ int ret ;
2033+
2034+ switch (ctrl -> id ) {
2035+ case V4L2_CID_USER_GET_IMX500_DEVICE_ID :
2036+ ret = imx500_get_device_id (imx500 , device_id );
2037+ memcpy (ctrl -> p_new .p_u32 , device_id , sizeof (device_id ));
2038+ break ;
2039+ default :
2040+ dev_info (& client -> dev , "ctrl(id:0x%x,val:0x%x) is not handled\n" ,
2041+ ctrl -> id , ctrl -> val );
2042+ ret = - EINVAL ;
2043+ break ;
2044+ }
2045+
2046+ return ret ;
2047+ }
2048+
20002049static const struct v4l2_ctrl_ops imx500_ctrl_ops = {
2050+ .g_volatile_ctrl = imx500_get_ctrl ,
20012051 .s_ctrl = imx500_set_ctrl ,
20022052};
20032053
@@ -2592,6 +2642,8 @@ static int imx500_start_streaming(struct imx500 *imx500)
25922642 __func__ );
25932643 return ret ;
25942644 }
2645+
2646+ v4l2_ctrl_activate (imx500 -> device_id , true);
25952647 }
25962648
25972649 /* Apply default values of current mode */
@@ -2846,6 +2898,22 @@ static const struct v4l2_ctrl_config network_fw_fd = {
28462898 .def = -1 ,
28472899};
28482900
2901+ /* Custom control to get camera device id */
2902+ static const struct v4l2_ctrl_config cam_get_device_id = {
2903+ .name = "Get IMX500 Device ID" ,
2904+ .id = V4L2_CID_USER_GET_IMX500_DEVICE_ID ,
2905+ .dims [0 ] = 4 ,
2906+ .ops = & imx500_ctrl_ops ,
2907+ .type = V4L2_CTRL_TYPE_U32 ,
2908+ .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_VOLATILE |
2909+ V4L2_CTRL_FLAG_INACTIVE ,
2910+ .elem_size = sizeof (u32 ),
2911+ .min = 0x00 ,
2912+ .max = U32_MAX ,
2913+ .step = 1 ,
2914+ .def = 0 ,
2915+ };
2916+
28492917/* Initialize control handlers */
28502918static int imx500_init_controls (struct imx500 * imx500 )
28512919{
@@ -2909,6 +2977,8 @@ static int imx500_init_controls(struct imx500 *imx500)
29092977 v4l2_ctrl_new_custom (ctrl_hdlr , & inf_window_ctrl , NULL );
29102978 imx500 -> network_fw_ctrl =
29112979 v4l2_ctrl_new_custom (ctrl_hdlr , & network_fw_fd , NULL );
2980+ imx500 -> device_id =
2981+ v4l2_ctrl_new_custom (ctrl_hdlr , & cam_get_device_id , NULL );
29122982
29132983 if (ctrl_hdlr -> error ) {
29142984 ret = ctrl_hdlr -> error ;
0 commit comments