2121#include <media/v4l2-fwnode.h>
2222#include <media/v4l2-image-sizes.h>
2323#include <media/v4l2-mediabus.h>
24- #include <media/v4l2-of.h>
2524
2625/* IMX219 supported geometry */
27- #define IMX219_WIDTH 3280 //3280
26+ #define IMX219_WIDTH 3280
2827#define IMX219_HEIGHT 2464
28+ #define IMX219_HTS 3448
29+ #define IMX219_VTS 2500
30+
2931#define IMX219_TABLE_END 0xffff
3032#define IMX219_ANALOGUE_GAIN_MULTIPLIER 256
3133#define IMX219_ANALOGUE_GAIN_MIN (1 * IMX219_ANALOGUE_GAIN_MULTIPLIER)
3234#define IMX219_ANALOGUE_GAIN_MAX (8 * IMX219_ANALOGUE_GAIN_MULTIPLIER)
35+
3336/* In dB*256 */
3437#define IMX219_DIGITAL_GAIN_MIN 256
3538#define IMX219_DIGITAL_GAIN_MAX 4095
3639
40+ #define IMX219_DIGITAL_EXPOSURE_MIN 0
41+ #define IMX219_DIGITAL_EXPOSURE_MAX 4095
42+
43+ #define IMX219_LANES 2
44+ #define IMX219_BITS_PER_SAMPLE 10
45+
46+ static const s64 link_freq_menu_items [] = {
47+ 456000000 ,
48+ };
49+
3750struct imx219_reg {
3851 u16 addr ;
3952 u8 val ;
@@ -143,6 +156,7 @@ struct imx219 {
143156 int vflip ;
144157 u8 analogue_gain ;
145158 u16 digital_gain ; /* bits 11:0 */
159+ u16 exposure_time ;
146160 u16 test_pattern ;
147161 u16 test_pattern_solid_color_r ;
148162 u16 test_pattern_solid_color_gr ;
@@ -287,6 +301,12 @@ static int imx219_s_stream(struct v4l2_subdev *sd, int enable)
287301 if (ret )
288302 return ret ;
289303
304+ /* Handle exposure time */
305+ ret = reg_write (client , 0x015a , priv -> exposure_time >> 8 );
306+ ret |= reg_write (client , 0x015b , priv -> exposure_time & 0xff );
307+ if (ret )
308+ return ret ;
309+
290310 /* Handle test pattern */
291311 if (priv -> test_pattern ) {
292312 ret = reg_write (client , 0x0600 , priv -> test_pattern >> 8 );
@@ -326,54 +346,6 @@ static int imx219_s_stream(struct v4l2_subdev *sd, int enable)
326346 return reg_write_table (client , start );
327347}
328348
329- static int imx219_cropcap (struct v4l2_subdev * sd , struct v4l2_cropcap * crop )
330- {
331- if (crop -> type != V4L2_BUF_TYPE_VIDEO_CAPTURE )
332- return - EINVAL ;
333-
334- crop -> bounds .left = 0 ;
335- crop -> bounds .top = 0 ;
336- crop -> bounds .width = IMX219_WIDTH ;
337- crop -> bounds .height = IMX219_HEIGHT ;
338- crop -> defrect = crop -> bounds ;
339- crop -> pixelaspect .numerator = 1 ;
340- crop -> pixelaspect .denominator = 1 ;
341-
342- return 0 ;
343- }
344-
345- static int imx219_g_crop (struct v4l2_subdev * sd , struct v4l2_crop * crop )
346- {
347- struct i2c_client * client = v4l2_get_subdevdata (sd );
348- struct imx219 * priv = to_imx219 (client );
349-
350- crop -> type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
351- crop -> c = priv -> crop_rect ;
352-
353- return 0 ;
354- }
355-
356- static int imx219_s_crop (struct v4l2_subdev * sd , const struct v4l2_crop * crop )
357- {
358- struct i2c_client * client = v4l2_get_subdevdata (sd );
359- struct imx219 * priv = to_imx219 (client );
360- struct v4l2_rect rect = crop -> c ;
361- u8 reg ;
362-
363- rect .left = ALIGN (rect .left , 2 );
364- rect .width = ALIGN (rect .width , 2 );
365- rect .top = ALIGN (rect .top , 2 );
366- rect .height = ALIGN (rect .height , 2 );
367- priv -> crop_rect = rect ;
368-
369- /* If enabled, apply settings immediately */
370- reg = reg_read (client , 0x0100 );
371- if ((reg & 0x1f ) == 0x01 )
372- imx219_s_stream (sd , 1 );
373-
374- return 0 ;
375- }
376-
377349static int imx219_enum_mbus_fmt (struct v4l2_subdev * sd , unsigned int index ,
378350 u32 * code )
379351{
@@ -558,6 +530,9 @@ static int imx219_s_ctrl(struct v4l2_ctrl *ctrl)
558530 */
559531 priv -> digital_gain = ctrl -> val ;
560532 break ;
533+ case V4L2_CID_EXPOSURE :
534+ priv -> exposure_time = ctrl -> val ;
535+ break ;
561536 case V4L2_CID_TEST_PATTERN :
562537 return imx219_s_ctrl_test_pattern (ctrl );
563538 default :
@@ -598,9 +573,6 @@ static int imx219_get_fmt(struct v4l2_subdev *sd,
598573/* Various V4L2 operations tables */
599574static struct v4l2_subdev_video_ops imx219_subdev_video_ops = {
600575 .s_stream = imx219_s_stream ,
601- .cropcap = imx219_cropcap ,
602- .g_crop = imx219_g_crop ,
603- .s_crop = imx219_s_crop ,
604576};
605577
606578static struct v4l2_subdev_core_ops imx219_subdev_core_ops = {
@@ -703,13 +675,16 @@ static int imx219_ctrls_init(struct v4l2_subdev *sd)
703675{
704676 struct i2c_client * client = v4l2_get_subdevdata (sd );
705677 struct imx219 * priv = to_imx219 (client );
678+ u32 pixel_rate , h_blank , v_blank ;
706679 int ret ;
707680
708681 v4l2_ctrl_handler_init (& priv -> ctrl_handler , 10 );
709682 v4l2_ctrl_new_std (& priv -> ctrl_handler , & imx219_ctrl_ops ,
710683 V4L2_CID_HFLIP , 0 , 1 , 1 , 0 );
711684 v4l2_ctrl_new_std (& priv -> ctrl_handler , & imx219_ctrl_ops ,
712685 V4L2_CID_VFLIP , 0 , 1 , 1 , 0 );
686+
687+ /* exposure */
713688 v4l2_ctrl_new_std (& priv -> ctrl_handler , & imx219_ctrl_ops ,
714689 V4L2_CID_ANALOGUE_GAIN ,
715690 IMX219_ANALOGUE_GAIN_MIN ,
@@ -718,7 +693,30 @@ static int imx219_ctrls_init(struct v4l2_subdev *sd)
718693 v4l2_ctrl_new_std (& priv -> ctrl_handler , & imx219_ctrl_ops ,
719694 V4L2_CID_GAIN ,
720695 IMX219_DIGITAL_GAIN_MIN ,
721- IMX219_DIGITAL_GAIN_MAX , 1 , IMX219_DIGITAL_GAIN_MIN );
696+ IMX219_DIGITAL_GAIN_MAX , 1 ,
697+ IMX219_DIGITAL_GAIN_MIN );
698+ v4l2_ctrl_new_std (& priv -> ctrl_handler , & imx219_ctrl_ops ,
699+ V4L2_CID_EXPOSURE ,
700+ IMX219_DIGITAL_EXPOSURE_MIN ,
701+ IMX219_DIGITAL_EXPOSURE_MAX , 1 ,
702+ IMX219_DIGITAL_EXPOSURE_MIN );
703+
704+ /* blank */
705+ h_blank = IMX219_HTS - IMX219_WIDTH ;
706+ v4l2_ctrl_new_std (& priv -> ctrl_handler , NULL , V4L2_CID_HBLANK ,
707+ h_blank , h_blank , 1 , h_blank );
708+ v_blank = IMX219_VTS - IMX219_HEIGHT ;
709+ v4l2_ctrl_new_std (& priv -> ctrl_handler , NULL , V4L2_CID_VBLANK ,
710+ v_blank , v_blank , 1 , v_blank );
711+
712+ /* freq */
713+ v4l2_ctrl_new_int_menu (& priv -> ctrl_handler , NULL , V4L2_CID_LINK_FREQ ,
714+ 0 , 0 , link_freq_menu_items );
715+ pixel_rate = (link_freq_menu_items [0 ] * 2 * IMX219_LANES ) /
716+ IMX219_BITS_PER_SAMPLE ;
717+ v4l2_ctrl_new_std (& priv -> ctrl_handler , NULL , V4L2_CID_PIXEL_RATE ,
718+ 0 , pixel_rate , 1 , pixel_rate );
719+
722720 v4l2_ctrl_new_std_menu_items (& priv -> ctrl_handler , & imx219_ctrl_ops ,
723721 V4L2_CID_TEST_PATTERN ,
724722 ARRAY_SIZE (tp_qmenu ) - 1 , 0 , 0 , tp_qmenu );
0 commit comments