@@ -239,6 +239,7 @@ enum pad_types { IMAGE_PAD, METADATA_PAD, NUM_PADS };
239
239
240
240
#define V4L2_CID_USER_IMX500_INFERENCE_WINDOW (V4L2_CID_USER_IMX500_BASE + 0)
241
241
#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)
242
243
243
244
#define ONE_MIB (1024 * 1024)
244
245
@@ -1365,6 +1366,7 @@ struct imx500 {
1365
1366
struct v4l2_ctrl * vblank ;
1366
1367
struct v4l2_ctrl * hblank ;
1367
1368
struct v4l2_ctrl * network_fw_ctrl ;
1369
+ struct v4l2_ctrl * device_id ;
1368
1370
1369
1371
struct v4l2_rect inference_window ;
1370
1372
@@ -1579,6 +1581,25 @@ static int imx500_set_inference_window(struct imx500 *imx500)
1579
1581
ARRAY_SIZE (window_regs ), NULL );
1580
1582
}
1581
1583
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
+
1582
1603
static int imx500_reg_val_write_cbk (void * arg ,
1583
1604
const struct cci_reg_sequence * reg )
1584
1605
{
@@ -1619,6 +1640,7 @@ static int imx500_validate_fw_block(const char *data, size_t maxlen)
1619
1640
static const char footer_id [] = { '3' , '6' , '9' , '5' };
1620
1641
1621
1642
u32 data_size ;
1643
+ u32 extra_bytes_size = 0 ;
1622
1644
1623
1645
const char * end = data + maxlen ;
1624
1646
@@ -1635,13 +1657,16 @@ static int imx500_validate_fw_block(const char *data, size_t maxlen)
1635
1657
memcpy (& data_size , data + sizeof (header_id ), sizeof (data_size ));
1636
1658
data_size = ___constant_swab32 (data_size );
1637
1659
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 )
1639
1664
return -1 ;
1640
1665
if (memcmp (data + data_size + footer_size - sizeof (footer_id ),
1641
1666
& footer_id , sizeof (footer_id )))
1642
1667
return -1 ;
1643
1668
1644
- return data_size + footer_size ;
1669
+ return data_size + footer_size + extra_bytes_size ;
1645
1670
}
1646
1671
1647
1672
/* Parse fw block by block, returning total valid fw size */
@@ -1875,6 +1900,7 @@ static void imx500_clear_fw_network(struct imx500 *imx500)
1875
1900
imx500 -> fw_network = NULL ;
1876
1901
imx500 -> network_written = false;
1877
1902
imx500 -> fw_progress = 0 ;
1903
+ v4l2_ctrl_activate (imx500 -> device_id , false);
1878
1904
}
1879
1905
1880
1906
static int imx500_set_ctrl (struct v4l2_ctrl * ctrl )
@@ -1997,7 +2023,31 @@ static int imx500_set_ctrl(struct v4l2_ctrl *ctrl)
1997
2023
return ret ;
1998
2024
}
1999
2025
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
+
2000
2049
static const struct v4l2_ctrl_ops imx500_ctrl_ops = {
2050
+ .g_volatile_ctrl = imx500_get_ctrl ,
2001
2051
.s_ctrl = imx500_set_ctrl ,
2002
2052
};
2003
2053
@@ -2592,6 +2642,8 @@ static int imx500_start_streaming(struct imx500 *imx500)
2592
2642
__func__ );
2593
2643
return ret ;
2594
2644
}
2645
+
2646
+ v4l2_ctrl_activate (imx500 -> device_id , true);
2595
2647
}
2596
2648
2597
2649
/* Apply default values of current mode */
@@ -2846,6 +2898,22 @@ static const struct v4l2_ctrl_config network_fw_fd = {
2846
2898
.def = -1 ,
2847
2899
};
2848
2900
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
+
2849
2917
/* Initialize control handlers */
2850
2918
static int imx500_init_controls (struct imx500 * imx500 )
2851
2919
{
@@ -2909,6 +2977,8 @@ static int imx500_init_controls(struct imx500 *imx500)
2909
2977
v4l2_ctrl_new_custom (ctrl_hdlr , & inf_window_ctrl , NULL );
2910
2978
imx500 -> network_fw_ctrl =
2911
2979
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 );
2912
2982
2913
2983
if (ctrl_hdlr -> error ) {
2914
2984
ret = ctrl_hdlr -> error ;
0 commit comments