@@ -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
@@ -1579,6 +1580,25 @@ static int imx500_set_inference_window(struct imx500 *imx500)
15791580 ARRAY_SIZE (window_regs ), NULL );
15801581}
15811582
1583+ static int imx500_get_device_id (struct imx500 * imx500 , u32 * device_id )
1584+ {
1585+ const u32 addr = 0xd040 ;
1586+ unsigned int i ;
1587+ int ret = 0 ;
1588+ u64 tmp , data ;
1589+
1590+ for (i = 0 ; i < 4 ; i ++ ) {
1591+ ret = cci_read (imx500 -> regmap , CCI_REG32 (addr + i * 4 ), & tmp ,
1592+ NULL );
1593+ if (ret )
1594+ return - EREMOTEIO ;
1595+ data = tmp & 0xffffffff ;
1596+ device_id [i ] = data ;
1597+ }
1598+
1599+ return ret ;
1600+ }
1601+
15821602static int imx500_reg_val_write_cbk (void * arg ,
15831603 const struct cci_reg_sequence * reg )
15841604{
@@ -1619,6 +1639,7 @@ static int imx500_validate_fw_block(const char *data, size_t maxlen)
16191639 static const char footer_id [] = { '3' , '6' , '9' , '5' };
16201640
16211641 u32 data_size ;
1642+ u32 extra_bytes_size = 0 ;
16221643
16231644 const char * end = data + maxlen ;
16241645
@@ -1635,13 +1656,16 @@ static int imx500_validate_fw_block(const char *data, size_t maxlen)
16351656 memcpy (& data_size , data + sizeof (header_id ), sizeof (data_size ));
16361657 data_size = ___constant_swab32 (data_size );
16371658
1638- if (end - data_size - footer_size < data )
1659+ /* check the device_lock flag */
1660+ extra_bytes_size = * ((u8 * )(data + 0x0e )) & 0x01 ? 32 : 0 ;
1661+
1662+ if (end - data_size - footer_size - extra_bytes_size < data )
16391663 return -1 ;
16401664 if (memcmp (data + data_size + footer_size - sizeof (footer_id ),
16411665 & footer_id , sizeof (footer_id )))
16421666 return -1 ;
16431667
1644- return data_size + footer_size ;
1668+ return data_size + footer_size + extra_bytes_size ;
16451669}
16461670
16471671/* Parse fw block by block, returning total valid fw size */
@@ -1997,7 +2021,35 @@ static int imx500_set_ctrl(struct v4l2_ctrl *ctrl)
19972021 return ret ;
19982022}
19992023
2024+ static int imx500_get_ctrl (struct v4l2_ctrl * ctrl )
2025+ {
2026+ struct imx500 * imx500 = container_of (ctrl -> handler , struct imx500 ,
2027+ ctrl_handler );
2028+ struct i2c_client * client = v4l2_get_subdevdata (& imx500 -> sd );
2029+ u32 device_id [4 ] = {0 };
2030+ int ret ;
2031+
2032+ switch (ctrl -> id ) {
2033+ case V4L2_CID_USER_GET_IMX500_DEVICE_ID :
2034+ if (!imx500 -> network_written ) {
2035+ dev_err (& client -> dev , "Unable to get device id without network fw loaded\n" );
2036+ return - EINVAL ;
2037+ }
2038+ ret = imx500_get_device_id (imx500 , device_id );
2039+ memcpy (ctrl -> p_new .p_u32 , device_id , sizeof (device_id ));
2040+ break ;
2041+ default :
2042+ dev_info (& client -> dev , "ctrl(id:0x%x,val:0x%x) is not handled\n" ,
2043+ ctrl -> id , ctrl -> val );
2044+ ret = - EINVAL ;
2045+ break ;
2046+ }
2047+
2048+ return ret ;
2049+ }
2050+
20002051static const struct v4l2_ctrl_ops imx500_ctrl_ops = {
2052+ .g_volatile_ctrl = imx500_get_ctrl ,
20012053 .s_ctrl = imx500_set_ctrl ,
20022054};
20032055
@@ -2846,6 +2898,21 @@ 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+ .elem_size = sizeof (u32 ),
2910+ .min = 0x00 ,
2911+ .max = U32_MAX ,
2912+ .step = 1 ,
2913+ .def = 0 ,
2914+ };
2915+
28492916/* Initialize control handlers */
28502917static int imx500_init_controls (struct imx500 * imx500 )
28512918{
@@ -2909,6 +2976,7 @@ static int imx500_init_controls(struct imx500 *imx500)
29092976 v4l2_ctrl_new_custom (ctrl_hdlr , & inf_window_ctrl , NULL );
29102977 imx500 -> network_fw_ctrl =
29112978 v4l2_ctrl_new_custom (ctrl_hdlr , & network_fw_fd , NULL );
2979+ v4l2_ctrl_new_custom (ctrl_hdlr , & cam_get_device_id , NULL );
29122980
29132981 if (ctrl_hdlr -> error ) {
29142982 ret = ctrl_hdlr -> error ;
0 commit comments