@@ -164,8 +164,81 @@ 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_453MHZ ,
171
+ IMX477_LINK_FREQ_456MHZ ,
172
+ IMX477_LINK_FREQ_459MHZ ,
173
+ IMX477_LINK_FREQ_462MHZ ,
174
+ IMX477_LINK_FREQ_498MHZ ,
175
+ };
176
+
177
+ static const s64 link_freqs [] = {
178
+ [IMX477_LINK_FREQ_450MHZ ] = 450000000 ,
179
+ [IMX477_LINK_FREQ_453MHZ ] = 453000000 ,
180
+ [IMX477_LINK_FREQ_456MHZ ] = 456000000 ,
181
+ [IMX477_LINK_FREQ_459MHZ ] = 459000000 ,
182
+ [IMX477_LINK_FREQ_462MHZ ] = 462000000 ,
183
+ [IMX477_LINK_FREQ_498MHZ ] = 498000000 ,
184
+ };
185
+
186
+ /* 450MHz is the nominal "default" link frequency */
187
+ static const struct imx477_reg link_450Mhz_regs [] = {
188
+ {0x030E , 0x00 },
189
+ {0x030F , 0x96 },
190
+ };
191
+
192
+ static const struct imx477_reg link_453Mhz_regs [] = {
193
+ {0x030E , 0x00 },
194
+ {0x030F , 0x97 },
195
+ };
196
+
197
+ static const struct imx477_reg link_456Mhz_regs [] = {
198
+ {0x030E , 0x00 },
199
+ {0x030F , 0x98 },
200
+ };
201
+
202
+ static const struct imx477_reg link_459Mhz_regs [] = {
203
+ {0x030E , 0x00 },
204
+ {0x030F , 0x99 },
205
+ };
206
+
207
+ static const struct imx477_reg link_462Mhz_regs [] = {
208
+ {0x030E , 0x00 },
209
+ {0x030F , 0x9a },
210
+ };
211
+
212
+ static const struct imx477_reg link_498Mhz_regs [] = {
213
+ {0x030E , 0x00 },
214
+ {0x030F , 0xa6 },
215
+ };
216
+
217
+ static const struct imx477_reg_list link_freq_regs [] = {
218
+ [IMX477_LINK_FREQ_450MHZ ] = {
219
+ .regs = link_450Mhz_regs ,
220
+ .num_of_regs = ARRAY_SIZE (link_450Mhz_regs )
221
+ },
222
+ [IMX477_LINK_FREQ_453MHZ ] = {
223
+ .regs = link_453Mhz_regs ,
224
+ .num_of_regs = ARRAY_SIZE (link_453Mhz_regs )
225
+ },
226
+ [IMX477_LINK_FREQ_456MHZ ] = {
227
+ .regs = link_456Mhz_regs ,
228
+ .num_of_regs = ARRAY_SIZE (link_456Mhz_regs )
229
+ },
230
+ [IMX477_LINK_FREQ_459MHZ ] = {
231
+ .regs = link_459Mhz_regs ,
232
+ .num_of_regs = ARRAY_SIZE (link_459Mhz_regs )
233
+ },
234
+ [IMX477_LINK_FREQ_462MHZ ] = {
235
+ .regs = link_462Mhz_regs ,
236
+ .num_of_regs = ARRAY_SIZE (link_462Mhz_regs )
237
+ },
238
+ [IMX477_LINK_FREQ_498MHZ ] = {
239
+ .regs = link_498Mhz_regs ,
240
+ .num_of_regs = ARRAY_SIZE (link_498Mhz_regs )
241
+ },
169
242
};
170
243
171
244
static const struct imx477_reg mode_common_regs [] = {
@@ -558,8 +631,6 @@ static const struct imx477_reg mode_4056x3040_regs[] = {
558
631
{0x0309 , 0x0c },
559
632
{0x030b , 0x02 },
560
633
{0x030d , 0x02 },
561
- {0x030e , 0x00 },
562
- {0x030f , 0x96 },
563
634
{0x0310 , 0x01 },
564
635
{0x0820 , 0x07 },
565
636
{0x0821 , 0x08 },
@@ -659,8 +730,6 @@ static const struct imx477_reg mode_2028x1520_regs[] = {
659
730
{0x0309 , 0x0c },
660
731
{0x030b , 0x02 },
661
732
{0x030d , 0x02 },
662
- {0x030e , 0x00 },
663
- {0x030f , 0x96 },
664
733
{0x0310 , 0x01 },
665
734
{0x0820 , 0x07 },
666
735
{0x0821 , 0x08 },
@@ -760,8 +829,6 @@ static const struct imx477_reg mode_2028x1080_regs[] = {
760
829
{0x0309 , 0x0c },
761
830
{0x030b , 0x02 },
762
831
{0x030d , 0x02 },
763
- {0x030e , 0x00 },
764
- {0x030f , 0x96 },
765
832
{0x0310 , 0x01 },
766
833
{0x0820 , 0x07 },
767
834
{0x0821 , 0x08 },
@@ -890,8 +957,6 @@ static const struct imx477_reg mode_1332x990_regs[] = {
890
957
{0x0309 , 0x0a },
891
958
{0x030b , 0x02 },
892
959
{0x030d , 0x02 },
893
- {0x030e , 0x00 },
894
- {0x030f , 0x96 },
895
960
{0x0310 , 0x01 },
896
961
{0x0820 , 0x07 },
897
962
{0x0821 , 0x08 },
@@ -1121,6 +1186,8 @@ struct imx477 {
1121
1186
struct v4l2_ctrl * vblank ;
1122
1187
struct v4l2_ctrl * hblank ;
1123
1188
1189
+ unsigned int link_freq_idx ;
1190
+
1124
1191
/* Current mode */
1125
1192
const struct imx477_mode * mode ;
1126
1193
@@ -1712,7 +1779,7 @@ static int imx477_get_selection(struct v4l2_subdev *sd,
1712
1779
static int imx477_start_streaming (struct imx477 * imx477 )
1713
1780
{
1714
1781
struct i2c_client * client = v4l2_get_subdevdata (& imx477 -> sd );
1715
- const struct imx477_reg_list * reg_list ;
1782
+ const struct imx477_reg_list * reg_list , * freq_regs ;
1716
1783
const struct imx477_reg_list * extra_regs ;
1717
1784
int ret , tm ;
1718
1785
@@ -1725,6 +1792,13 @@ static int imx477_start_streaming(struct imx477 *imx477)
1725
1792
extra_regs -> num_of_regs );
1726
1793
}
1727
1794
1795
+ if (!ret ) {
1796
+ /* Update the link frequency registers */
1797
+ freq_regs = & link_freq_regs [imx477 -> link_freq_idx ];
1798
+ ret = imx477_write_regs (imx477 , freq_regs -> regs ,
1799
+ freq_regs -> num_of_regs );
1800
+ }
1801
+
1728
1802
if (ret ) {
1729
1803
dev_err (& client -> dev , "%s failed to set common settings\n" ,
1730
1804
__func__ );
@@ -2010,9 +2084,8 @@ static int imx477_init_controls(struct imx477 *imx477)
2010
2084
/* LINK_FREQ is also read only */
2011
2085
imx477 -> link_freq =
2012
2086
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 );
2087
+ V4L2_CID_LINK_FREQ , 0 , 0 ,
2088
+ & link_freqs [imx477 -> link_freq_idx ]);
2016
2089
if (imx477 -> link_freq )
2017
2090
imx477 -> link_freq -> flags |= V4L2_CTRL_FLAG_READ_ONLY ;
2018
2091
@@ -2110,13 +2183,14 @@ static void imx477_free_controls(struct imx477 *imx477)
2110
2183
mutex_destroy (& imx477 -> mutex );
2111
2184
}
2112
2185
2113
- static int imx477_check_hwcfg (struct device * dev )
2186
+ static int imx477_check_hwcfg (struct device * dev , struct imx477 * imx477 )
2114
2187
{
2115
2188
struct fwnode_handle * endpoint ;
2116
2189
struct v4l2_fwnode_endpoint ep_cfg = {
2117
2190
.bus_type = V4L2_MBUS_CSI2_DPHY
2118
2191
};
2119
2192
int ret = - EINVAL ;
2193
+ int i ;
2120
2194
2121
2195
endpoint = fwnode_graph_get_next_endpoint (dev_fwnode (dev ), NULL );
2122
2196
if (!endpoint ) {
@@ -2141,11 +2215,18 @@ static int imx477_check_hwcfg(struct device *dev)
2141
2215
goto error_out ;
2142
2216
}
2143
2217
2144
- if (ep_cfg .nr_of_link_frequencies != 1 ||
2145
- ep_cfg .link_frequencies [0 ] != IMX477_DEFAULT_LINK_FREQ ) {
2218
+ for (i = 0 ; i < ARRAY_SIZE (link_freqs ); i ++ ) {
2219
+ if (link_freqs [i ] == ep_cfg .link_frequencies [0 ]) {
2220
+ imx477 -> link_freq_idx = i ;
2221
+ break ;
2222
+ }
2223
+ }
2224
+
2225
+ if (i == ARRAY_SIZE (link_freqs )) {
2146
2226
dev_err (dev , "Link frequency not supported: %lld\n" ,
2147
2227
ep_cfg .link_frequencies [0 ]);
2148
- goto error_out ;
2228
+ ret = - EINVAL ;
2229
+ goto error_out ;
2149
2230
}
2150
2231
2151
2232
ret = 0 ;
@@ -2206,7 +2287,7 @@ static int imx477_probe(struct i2c_client *client)
2206
2287
(const struct imx477_compatible_data * )match -> data ;
2207
2288
2208
2289
/* Check the hardware configuration in device tree */
2209
- if (imx477_check_hwcfg (dev ))
2290
+ if (imx477_check_hwcfg (dev , imx477 ))
2210
2291
return - EINVAL ;
2211
2292
2212
2293
/* Default the trigger mode from OF to -1, which means invalid */
0 commit comments