@@ -164,8 +164,48 @@ struct imx477_mode {
164
164
struct imx477_reg_list reg_list ;
165
165
};
166
166
167
- static const s64 imx477_link_freq_menu [] = {
168
- IMX477_DEFAULT_LINK_FREQ ,
167
+ /* Link frequency setup */
168
+ enum {
169
+ IMX477_LINK_FREQ_450MHZ ,
170
+ IMX477_LINK_FREQ_447MHZ ,
171
+ IMX477_LINK_FREQ_453MHZ ,
172
+ };
173
+
174
+ static const s64 link_freqs [] = {
175
+ [IMX477_LINK_FREQ_450MHZ ] = 450000000 ,
176
+ [IMX477_LINK_FREQ_447MHZ ] = 447000000 ,
177
+ [IMX477_LINK_FREQ_453MHZ ] = 453000000 ,
178
+ };
179
+
180
+ /* 450MHz is the nominal "default" link frequency */
181
+ static const struct imx477_reg link_450Mhz_regs [] = {
182
+ {0x030E , 0x00 },
183
+ {0x030F , 0x96 },
184
+ };
185
+
186
+ static const struct imx477_reg link_447Mhz_regs [] = {
187
+ {0x030E , 0x00 },
188
+ {0x030F , 0x95 },
189
+ };
190
+
191
+ static const struct imx477_reg link_453Mhz_regs [] = {
192
+ {0x030E , 0x00 },
193
+ {0x030F , 0x97 },
194
+ };
195
+
196
+ static const struct imx477_reg_list link_freq_regs [] = {
197
+ [IMX477_LINK_FREQ_450MHZ ] = {
198
+ .regs = link_450Mhz_regs ,
199
+ .num_of_regs = ARRAY_SIZE (link_450Mhz_regs )
200
+ },
201
+ [IMX477_LINK_FREQ_447MHZ ] = {
202
+ .regs = link_447Mhz_regs ,
203
+ .num_of_regs = ARRAY_SIZE (link_447Mhz_regs )
204
+ },
205
+ [IMX477_LINK_FREQ_453MHZ ] = {
206
+ .regs = link_453Mhz_regs ,
207
+ .num_of_regs = ARRAY_SIZE (link_453Mhz_regs )
208
+ },
169
209
};
170
210
171
211
static const struct imx477_reg mode_common_regs [] = {
@@ -558,8 +598,6 @@ static const struct imx477_reg mode_4056x3040_regs[] = {
558
598
{0x0309 , 0x0c },
559
599
{0x030b , 0x02 },
560
600
{0x030d , 0x02 },
561
- {0x030e , 0x00 },
562
- {0x030f , 0x96 },
563
601
{0x0310 , 0x01 },
564
602
{0x0820 , 0x07 },
565
603
{0x0821 , 0x08 },
@@ -659,8 +697,6 @@ static const struct imx477_reg mode_2028x1520_regs[] = {
659
697
{0x0309 , 0x0c },
660
698
{0x030b , 0x02 },
661
699
{0x030d , 0x02 },
662
- {0x030e , 0x00 },
663
- {0x030f , 0x96 },
664
700
{0x0310 , 0x01 },
665
701
{0x0820 , 0x07 },
666
702
{0x0821 , 0x08 },
@@ -760,8 +796,6 @@ static const struct imx477_reg mode_2028x1080_regs[] = {
760
796
{0x0309 , 0x0c },
761
797
{0x030b , 0x02 },
762
798
{0x030d , 0x02 },
763
- {0x030e , 0x00 },
764
- {0x030f , 0x96 },
765
799
{0x0310 , 0x01 },
766
800
{0x0820 , 0x07 },
767
801
{0x0821 , 0x08 },
@@ -890,8 +924,6 @@ static const struct imx477_reg mode_1332x990_regs[] = {
890
924
{0x0309 , 0x0a },
891
925
{0x030b , 0x02 },
892
926
{0x030d , 0x02 },
893
- {0x030e , 0x00 },
894
- {0x030f , 0x96 },
895
927
{0x0310 , 0x01 },
896
928
{0x0820 , 0x07 },
897
929
{0x0821 , 0x08 },
@@ -1121,6 +1153,8 @@ struct imx477 {
1121
1153
struct v4l2_ctrl * vblank ;
1122
1154
struct v4l2_ctrl * hblank ;
1123
1155
1156
+ unsigned int link_freq_idx ;
1157
+
1124
1158
/* Current mode */
1125
1159
const struct imx477_mode * mode ;
1126
1160
@@ -1712,7 +1746,7 @@ static int imx477_get_selection(struct v4l2_subdev *sd,
1712
1746
static int imx477_start_streaming (struct imx477 * imx477 )
1713
1747
{
1714
1748
struct i2c_client * client = v4l2_get_subdevdata (& imx477 -> sd );
1715
- const struct imx477_reg_list * reg_list ;
1749
+ const struct imx477_reg_list * reg_list , * freq_regs ;
1716
1750
const struct imx477_reg_list * extra_regs ;
1717
1751
int ret , tm ;
1718
1752
@@ -1725,6 +1759,13 @@ static int imx477_start_streaming(struct imx477 *imx477)
1725
1759
extra_regs -> num_of_regs );
1726
1760
}
1727
1761
1762
+ if (!ret ) {
1763
+ /* Update the link frequency registers */
1764
+ freq_regs = & link_freq_regs [imx477 -> link_freq_idx ];
1765
+ ret = imx477_write_regs (imx477 , freq_regs -> regs ,
1766
+ freq_regs -> num_of_regs );
1767
+ }
1768
+
1728
1769
if (ret ) {
1729
1770
dev_err (& client -> dev , "%s failed to set common settings\n" ,
1730
1771
__func__ );
@@ -2010,9 +2051,8 @@ static int imx477_init_controls(struct imx477 *imx477)
2010
2051
/* LINK_FREQ is also read only */
2011
2052
imx477 -> link_freq =
2012
2053
v4l2_ctrl_new_int_menu (ctrl_hdlr , & imx477_ctrl_ops ,
2013
- V4L2_CID_LINK_FREQ ,
2014
- ARRAY_SIZE (imx477_link_freq_menu ) - 1 , 0 ,
2015
- imx477_link_freq_menu );
2054
+ V4L2_CID_LINK_FREQ , 1 , 0 ,
2055
+ & link_freqs [imx477 -> link_freq_idx ]);
2016
2056
if (imx477 -> link_freq )
2017
2057
imx477 -> link_freq -> flags |= V4L2_CTRL_FLAG_READ_ONLY ;
2018
2058
@@ -2110,13 +2150,14 @@ static void imx477_free_controls(struct imx477 *imx477)
2110
2150
mutex_destroy (& imx477 -> mutex );
2111
2151
}
2112
2152
2113
- static int imx477_check_hwcfg (struct device * dev )
2153
+ static int imx477_check_hwcfg (struct device * dev , struct imx477 * imx477 )
2114
2154
{
2115
2155
struct fwnode_handle * endpoint ;
2116
2156
struct v4l2_fwnode_endpoint ep_cfg = {
2117
2157
.bus_type = V4L2_MBUS_CSI2_DPHY
2118
2158
};
2119
2159
int ret = - EINVAL ;
2160
+ int i ;
2120
2161
2121
2162
endpoint = fwnode_graph_get_next_endpoint (dev_fwnode (dev ), NULL );
2122
2163
if (!endpoint ) {
@@ -2141,11 +2182,18 @@ static int imx477_check_hwcfg(struct device *dev)
2141
2182
goto error_out ;
2142
2183
}
2143
2184
2144
- if (ep_cfg .nr_of_link_frequencies != 1 ||
2145
- ep_cfg .link_frequencies [0 ] != IMX477_DEFAULT_LINK_FREQ ) {
2185
+ for (i = 0 ; i < ARRAY_SIZE (link_freqs ); i ++ ) {
2186
+ if (link_freqs [i ] == ep_cfg .link_frequencies [0 ]) {
2187
+ imx477 -> link_freq_idx = i ;
2188
+ break ;
2189
+ }
2190
+ }
2191
+
2192
+ if (i == ARRAY_SIZE (link_freqs )) {
2146
2193
dev_err (dev , "Link frequency not supported: %lld\n" ,
2147
2194
ep_cfg .link_frequencies [0 ]);
2148
- goto error_out ;
2195
+ ret = - EINVAL ;
2196
+ goto error_out ;
2149
2197
}
2150
2198
2151
2199
ret = 0 ;
@@ -2206,7 +2254,7 @@ static int imx477_probe(struct i2c_client *client)
2206
2254
(const struct imx477_compatible_data * )match -> data ;
2207
2255
2208
2256
/* Check the hardware configuration in device tree */
2209
- if (imx477_check_hwcfg (dev ))
2257
+ if (imx477_check_hwcfg (dev , imx477 ))
2210
2258
return - EINVAL ;
2211
2259
2212
2260
/* Default the trigger mode from OF to -1, which means invalid */
0 commit comments