@@ -104,6 +104,11 @@ struct imx258_reg_list {
104104 const struct imx258_reg * regs ;
105105};
106106
107+ struct imx258_link_cfg {
108+ unsigned int lf_to_pix_rate_factor ;
109+ struct imx258_reg_list reg_list ;
110+ };
111+
107112#define IMX258_LANE_CONFIGS 2
108113#define IMX258_2_LANE_MODE 0
109114#define IMX258_4_LANE_MODE 1
@@ -113,8 +118,8 @@ struct imx258_link_freq_config {
113118 u64 link_frequency ;
114119 u32 pixels_per_line ;
115120
116- /* PLL registers for this link frequency */
117- struct imx258_reg_list reg_list [IMX258_LANE_CONFIGS ];
121+ /* Configuration for this link frequency / num lanes selection */
122+ struct imx258_link_cfg link_cfg [IMX258_LANE_CONFIGS ];
118123};
119124
120125/* Mode : resolution and related config&values */
@@ -273,7 +278,7 @@ static const struct imx258_reg mipi_640mbps_19_2mhz_4l[] = {
273278static const struct imx258_reg mipi_642mbps_24mhz_2l [] = {
274279 { 0x0136 , 0x18 },
275280 { 0x0137 , 0x00 },
276- { 0x0301 , 0x0A },
281+ { 0x0301 , 0x05 },
277282 { 0x0303 , 0x02 },
278283 { 0x0305 , 0x04 },
279284 { 0x0306 , 0x00 },
@@ -690,14 +695,22 @@ enum {
690695};
691696
692697/*
693- * pixel_rate = link_freq * data-rate * nr_of_lanes / bits_per_sample
694- * data rate => double data rate;
695- * number of lanes => (configurable 2 or 4);
696- * bits per pixel => 10
698+ * Pixel rate does not necessarily relate to link frequency on this sensor as
699+ * there is a FIFO between the pixel array pipeline and the MIPI serializer.
700+ * The recommendation from Sony is that the pixel array is always run with a
701+ * line length of 5352 pixels, which means that there is a large amount of
702+ * blanking time for the 1048x780 mode. There is no need to replicate this
703+ * blanking on the CSI2 bus, and the configuration of register 0x0301 allows the
704+ * divider to be altered.
705+ *
706+ * The actual factor between link frequency and pixel rate is in the
707+ * imx258_link_cfg, so use this to convert between the two.
708+ * bits per pixel being 10, and D-PHY being DDR is assumed by this function, so
709+ * the value is only the combination of number of lanes and pixel clock divider.
697710 */
698- static u64 link_freq_to_pixel_rate (u64 f , unsigned int nlanes )
711+ static u64 link_freq_to_pixel_rate (u64 f , const struct imx258_link_cfg * link_cfg )
699712{
700- f *= 2 * nlanes ;
713+ f *= 2 * link_cfg -> lf_to_pix_rate_factor ;
701714 do_div (f , 10 );
702715
703716 return f ;
@@ -722,31 +735,33 @@ static const s64 link_freq_menu_items_24[] = {
722735 IMX258_LINK_FREQ_321MHZ ,
723736};
724737
738+ #define REGS (_list ) { .num_of_regs = ARRAY_SIZE(_list), .regs = _list, }
739+
725740/* Link frequency configs */
726741static const struct imx258_link_freq_config link_freq_configs_19_2 [] = {
727742 [IMX258_LINK_FREQ_1267MBPS ] = {
728743 .pixels_per_line = IMX258_PPL_DEFAULT ,
729- .reg_list = {
744+ .link_cfg = {
730745 [IMX258_2_LANE_MODE ] = {
731- .num_of_regs = ARRAY_SIZE ( mipi_1267mbps_19_2mhz_2l ) ,
732- .regs = mipi_1267mbps_19_2mhz_2l ,
746+ .lf_to_pix_rate_factor = 2 * 2 ,
747+ .reg_list = REGS ( mipi_1267mbps_19_2mhz_2l ) ,
733748 },
734749 [IMX258_4_LANE_MODE ] = {
735- .num_of_regs = ARRAY_SIZE ( mipi_1267mbps_19_2mhz_4l ) ,
736- .regs = mipi_1267mbps_19_2mhz_4l ,
750+ .lf_to_pix_rate_factor = 4 ,
751+ .reg_list = REGS ( mipi_1267mbps_19_2mhz_4l ) ,
737752 },
738753 }
739754 },
740755 [IMX258_LINK_FREQ_640MBPS ] = {
741756 .pixels_per_line = IMX258_PPL_DEFAULT ,
742- .reg_list = {
757+ .link_cfg = {
743758 [IMX258_2_LANE_MODE ] = {
744- .num_of_regs = ARRAY_SIZE ( mipi_640mbps_19_2mhz_2l ) ,
745- .regs = mipi_640mbps_19_2mhz_2l ,
759+ .lf_to_pix_rate_factor = 2 ,
760+ .reg_list = REGS ( mipi_640mbps_19_2mhz_2l ) ,
746761 },
747762 [IMX258_4_LANE_MODE ] = {
748- .num_of_regs = ARRAY_SIZE ( mipi_640mbps_19_2mhz_4l ) ,
749- .regs = mipi_640mbps_19_2mhz_4l ,
763+ .lf_to_pix_rate_factor = 4 ,
764+ .reg_list = REGS ( mipi_640mbps_19_2mhz_4l ) ,
750765 },
751766 }
752767 },
@@ -755,27 +770,27 @@ static const struct imx258_link_freq_config link_freq_configs_19_2[] = {
755770static const struct imx258_link_freq_config link_freq_configs_24 [] = {
756771 [IMX258_LINK_FREQ_1267MBPS ] = {
757772 .pixels_per_line = IMX258_PPL_DEFAULT ,
758- .reg_list = {
773+ .link_cfg = {
759774 [IMX258_2_LANE_MODE ] = {
760- .num_of_regs = ARRAY_SIZE ( mipi_1272mbps_24mhz_2l ) ,
761- .regs = mipi_1272mbps_24mhz_2l ,
775+ .lf_to_pix_rate_factor = 2 ,
776+ .reg_list = REGS ( mipi_1272mbps_24mhz_2l ) ,
762777 },
763778 [IMX258_4_LANE_MODE ] = {
764- .num_of_regs = ARRAY_SIZE ( mipi_1272mbps_24mhz_4l ) ,
765- .regs = mipi_1272mbps_24mhz_4l ,
779+ .lf_to_pix_rate_factor = 4 ,
780+ .reg_list = REGS ( mipi_1272mbps_24mhz_4l ) ,
766781 },
767782 }
768783 },
769784 [IMX258_LINK_FREQ_640MBPS ] = {
770785 .pixels_per_line = IMX258_PPL_DEFAULT ,
771- .reg_list = {
786+ .link_cfg = {
772787 [IMX258_2_LANE_MODE ] = {
773- .num_of_regs = ARRAY_SIZE ( mipi_642mbps_24mhz_2l ) ,
774- .regs = mipi_642mbps_24mhz_2l ,
788+ .lf_to_pix_rate_factor = 2 * 2 ,
789+ .reg_list = REGS ( mipi_642mbps_24mhz_2l ) ,
775790 },
776791 [IMX258_4_LANE_MODE ] = {
777- .num_of_regs = ARRAY_SIZE ( mipi_642mbps_24mhz_4l ) ,
778- .regs = mipi_642mbps_24mhz_4l ,
792+ .lf_to_pix_rate_factor = 4 ,
793+ .reg_list = REGS ( mipi_642mbps_24mhz_4l ) ,
779794 },
780795 }
781796 },
@@ -857,7 +872,7 @@ struct imx258 {
857872
858873 const struct imx258_link_freq_config * link_freq_configs ;
859874 const s64 * link_freq_menu_items ;
860- unsigned int nlanes ;
875+ unsigned int lane_mode_idx ;
861876 unsigned int csi2_flags ;
862877
863878 /*
@@ -1212,8 +1227,10 @@ static int imx258_set_pad_format(struct v4l2_subdev *sd,
12121227 struct v4l2_subdev_format * fmt )
12131228{
12141229 struct imx258 * imx258 = to_imx258 (sd );
1215- const struct imx258_mode * mode ;
1230+ const struct imx258_link_freq_config * link_freq_cfgs ;
1231+ const struct imx258_link_cfg * link_cfg ;
12161232 struct v4l2_mbus_framefmt * framefmt ;
1233+ const struct imx258_mode * mode ;
12171234 s32 vblank_def ;
12181235 s32 vblank_min ;
12191236 s64 h_blank ;
@@ -1236,7 +1253,11 @@ static int imx258_set_pad_format(struct v4l2_subdev *sd,
12361253 __v4l2_ctrl_s_ctrl (imx258 -> link_freq , mode -> link_freq_index );
12371254
12381255 link_freq = imx258 -> link_freq_menu_items [mode -> link_freq_index ];
1239- pixel_rate = link_freq_to_pixel_rate (link_freq , imx258 -> nlanes );
1256+ link_freq_cfgs =
1257+ & imx258 -> link_freq_configs [mode -> link_freq_index ];
1258+
1259+ link_cfg = & link_freq_cfgs -> link_cfg [imx258 -> lane_mode_idx ];
1260+ pixel_rate = link_freq_to_pixel_rate (link_freq , link_cfg );
12401261 __v4l2_ctrl_modify_range (imx258 -> pixel_rate , pixel_rate ,
12411262 pixel_rate , 1 , pixel_rate );
12421263 /* Update limits and set FPS to default */
@@ -1333,7 +1354,8 @@ static int imx258_start_streaming(struct imx258 *imx258)
13331354 /* Setup PLL */
13341355 link_freq_index = imx258 -> cur_mode -> link_freq_index ;
13351356 link_freq_cfg = & imx258 -> link_freq_configs [link_freq_index ];
1336- reg_list = & link_freq_cfg -> reg_list [imx258 -> nlanes == 2 ? 0 : 1 ];
1357+
1358+ reg_list = & link_freq_cfg -> link_cfg [imx258 -> lane_mode_idx ].reg_list ;
13371359 ret = imx258_write_regs (imx258 , reg_list -> regs , reg_list -> num_of_regs );
13381360 if (ret ) {
13391361 dev_err (& client -> dev , "%s failed to set plls\n" , __func__ );
@@ -1543,8 +1565,10 @@ static const struct v4l2_subdev_internal_ops imx258_internal_ops = {
15431565static int imx258_init_controls (struct imx258 * imx258 )
15441566{
15451567 struct i2c_client * client = v4l2_get_subdevdata (& imx258 -> sd );
1568+ const struct imx258_link_freq_config * link_freq_cfgs ;
15461569 struct v4l2_fwnode_device_properties props ;
15471570 struct v4l2_ctrl_handler * ctrl_hdlr ;
1571+ const struct imx258_link_cfg * link_cfg ;
15481572 s64 vblank_def ;
15491573 s64 vblank_min ;
15501574 s64 pixel_rate ;
@@ -1567,8 +1591,11 @@ static int imx258_init_controls(struct imx258 *imx258)
15671591 if (imx258 -> link_freq )
15681592 imx258 -> link_freq -> flags |= V4L2_CTRL_FLAG_READ_ONLY ;
15691593
1594+ link_freq_cfgs = & imx258 -> link_freq_configs [0 ];
1595+ link_cfg = link_freq_cfgs [imx258 -> lane_mode_idx ].link_cfg ;
15701596 pixel_rate = link_freq_to_pixel_rate (imx258 -> link_freq_menu_items [0 ],
1571- imx258 -> nlanes );
1597+ link_cfg );
1598+
15721599 /* By default, PIXEL_RATE is read only */
15731600 imx258 -> pixel_rate = v4l2_ctrl_new_std (ctrl_hdlr , & imx258_ctrl_ops ,
15741601 V4L2_CID_PIXEL_RATE ,
@@ -1739,10 +1766,16 @@ static int imx258_probe(struct i2c_client *client)
17391766 }
17401767
17411768 /* Get number of data lanes */
1742- imx258 -> nlanes = ep .bus .mipi_csi2 .num_data_lanes ;
1743- if (imx258 -> nlanes != 2 && imx258 -> nlanes != 4 ) {
1769+ switch (ep .bus .mipi_csi2 .num_data_lanes ) {
1770+ case 2 :
1771+ imx258 -> lane_mode_idx = IMX258_2_LANE_MODE ;
1772+ break ;
1773+ case 4 :
1774+ imx258 -> lane_mode_idx = IMX258_4_LANE_MODE ;
1775+ break ;
1776+ default :
17441777 dev_err (& client -> dev , "Invalid data lanes: %u\n" ,
1745- imx258 -> nlanes );
1778+ ep . bus . mipi_csi2 . num_data_lanes );
17461779 ret = - EINVAL ;
17471780 goto error_endpoint_poweron ;
17481781 }
0 commit comments