@@ -37,12 +37,22 @@ MODULE_PARM_DESC(qbc_adjust, "Quad Bayer broken line correction strength [0,2-5]
3737#define IMX708_MODE_STANDBY 0x00
3838#define IMX708_MODE_STREAMING 0x01
3939
40- #define IMX708_EXCLK_FREQ 0x18
41-
4240#define IMX708_REG_ORIENTATION CCI_REG8(0x101)
4341
42+ #define IMX708_REG_EXCK_FREQ CCI_REG16(0x0136)
43+ #define IMX708_EXCLK_FREQ 0x1800
4444#define IMX708_INCLK_FREQ 24000000
4545
46+ #define IMX708_REG_IVT_PREDIV CCI_REG8(0x0305)
47+ #define IMX708_IVT_PREDIV 0x02
48+ #define IMX708_REG_IVT_MPY CCI_REG16(0x0306)
49+
50+ #define IMX708_REG_IOP_SYSCK_DIV CCI_REG8(0x030b)
51+ #define IMX708_IOP_SYSCK_DIV 0x02
52+ #define IMX708_REG_IOP_PREDIV CCI_REG8(0x030d)
53+ #define IMX708_IOP_PREDIV 0x04
54+ #define IMX708_REG_IOP_MPY CCI_REG16(0x030e)
55+
4656/* Default initial pixel rate, will get updated for each mode. */
4757#define IMX708_INITIAL_PIXEL_RATE 590000000
4858
@@ -194,56 +204,14 @@ static const u8 pdaf_gains[2][9] = {
194204 { 0x36 , 0x36 , 0x36 , 0x39 , 0x3e , 0x46 , 0x4c , 0x4c , 0x4c }
195205};
196206
197- /* Link frequency setup */
198- enum {
199- IMX708_LINK_FREQ_450MHZ ,
200- IMX708_LINK_FREQ_447MHZ ,
201- IMX708_LINK_FREQ_453MHZ ,
202- };
203-
204- static const s64 link_freqs [] = {
205- [IMX708_LINK_FREQ_450MHZ ] = 450000000 ,
206- [IMX708_LINK_FREQ_447MHZ ] = 447000000 ,
207- [IMX708_LINK_FREQ_453MHZ ] = 453000000 ,
208- };
209-
210- /* 450MHz is the nominal "default" link frequency */
211- static const struct cci_reg_sequence link_450Mhz_regs [] = {
212- {CCI_REG8 (0x030E ), 0x01 },
213- {CCI_REG8 (0x030F ), 0x2c },
214- };
215-
216- static const struct cci_reg_sequence link_447Mhz_regs [] = {
217- {CCI_REG8 (0x030E ), 0x01 },
218- {CCI_REG8 (0x030F ), 0x2a },
219- };
220-
221- static const struct cci_reg_sequence link_453Mhz_regs [] = {
222- {CCI_REG8 (0x030E ), 0x01 },
223- {CCI_REG8 (0x030F ), 0x2e },
224- };
225-
226- static const struct imx708_reg_list link_freq_regs [] = {
227- [IMX708_LINK_FREQ_450MHZ ] = {
228- .regs = link_450Mhz_regs ,
229- .num_of_regs = ARRAY_SIZE (link_450Mhz_regs )
230- },
231- [IMX708_LINK_FREQ_447MHZ ] = {
232- .regs = link_447Mhz_regs ,
233- .num_of_regs = ARRAY_SIZE (link_447Mhz_regs )
234- },
235- [IMX708_LINK_FREQ_453MHZ ] = {
236- .regs = link_453Mhz_regs ,
237- .num_of_regs = ARRAY_SIZE (link_453Mhz_regs )
238- },
239- };
240-
241207static const struct cci_reg_sequence mode_common_regs [] = {
242208 {CCI_REG8 (0x0100 ), 0x00 },
243- {CCI_REG8 (0x0136 ), IMX708_EXCLK_FREQ }, //REG_EXCK_FREQ_MSB
244- {CCI_REG8 (0x0137 ), 0x00 }, //REG_EXCK_FREQ_LSB
245- {CCI_REG8 (0x33F0 ), 0x02 }, //REG_IOPSYCK_DIV
246- {CCI_REG8 (0x33F1 ), 0x05 }, //REG_IOPPXCK_DIV
209+ {IMX708_REG_EXCK_FREQ , IMX708_EXCLK_FREQ },
210+ {CCI_REG8 (0x33F0 ), 0x02 },
211+ {CCI_REG8 (0x33F1 ), 0x05 },
212+ {IMX708_REG_IVT_PREDIV , IMX708_IVT_PREDIV },
213+ {IMX708_REG_IOP_SYSCK_DIV , IMX708_IOP_SYSCK_DIV },
214+ {IMX708_REG_IOP_PREDIV , IMX708_IOP_PREDIV },
247215 {CCI_REG8 (0x3062 ), 0x00 },
248216 {CCI_REG8 (0x3063 ), 0x12 },
249217 {CCI_REG8 (0x3068 ), 0x00 },
@@ -328,11 +296,8 @@ static const struct cci_reg_sequence mode_4608x2592_regs[] = {
328296 {CCI_REG8 (0x034F ), 0x20 },
329297 {CCI_REG8 (0x0301 ), 0x05 },
330298 {CCI_REG8 (0x0303 ), 0x02 },
331- {CCI_REG8 (0x0305 ), 0x02 },
332299 {CCI_REG8 (0x0306 ), 0x00 },
333300 {CCI_REG8 (0x0307 ), 0x7C },
334- {CCI_REG8 (0x030B ), 0x02 },
335- {CCI_REG8 (0x030D ), 0x04 },
336301 {CCI_REG8 (0x0310 ), 0x01 },
337302 {CCI_REG8 (0x3CA0 ), 0x00 },
338303 {CCI_REG8 (0x3CA1 ), 0x64 },
@@ -414,11 +379,8 @@ static const struct cci_reg_sequence mode_2x2binned_regs[] = {
414379 {CCI_REG8 (0x034F ), 0x10 },
415380 {CCI_REG8 (0x0301 ), 0x05 },
416381 {CCI_REG8 (0x0303 ), 0x02 },
417- {CCI_REG8 (0x0305 ), 0x02 },
418382 {CCI_REG8 (0x0306 ), 0x00 },
419383 {CCI_REG8 (0x0307 ), 0x7A },
420- {CCI_REG8 (0x030B ), 0x02 },
421- {CCI_REG8 (0x030D ), 0x04 },
422384 {CCI_REG8 (0x0310 ), 0x01 },
423385 {CCI_REG8 (0x3CA0 ), 0x00 },
424386 {CCI_REG8 (0x3CA1 ), 0x3C },
@@ -500,11 +462,8 @@ static const struct cci_reg_sequence mode_2x2binned_720p_regs[] = {
500462 {CCI_REG8 (0x034F ), 0x60 },
501463 {CCI_REG8 (0x0301 ), 0x05 },
502464 {CCI_REG8 (0x0303 ), 0x02 },
503- {CCI_REG8 (0x0305 ), 0x02 },
504465 {CCI_REG8 (0x0306 ), 0x00 },
505466 {CCI_REG8 (0x0307 ), 0x76 },
506- {CCI_REG8 (0x030B ), 0x02 },
507- {CCI_REG8 (0x030D ), 0x04 },
508467 {CCI_REG8 (0x0310 ), 0x01 },
509468 {CCI_REG8 (0x3CA0 ), 0x00 },
510469 {CCI_REG8 (0x3CA1 ), 0x3C },
@@ -586,11 +545,8 @@ static const struct cci_reg_sequence mode_hdr_regs[] = {
586545 {CCI_REG8 (0x034F ), 0x10 },
587546 {CCI_REG8 (0x0301 ), 0x05 },
588547 {CCI_REG8 (0x0303 ), 0x02 },
589- {CCI_REG8 (0x0305 ), 0x02 },
590548 {CCI_REG8 (0x0306 ), 0x00 },
591549 {CCI_REG8 (0x0307 ), 0xA2 },
592- {CCI_REG8 (0x030B ), 0x02 },
593- {CCI_REG8 (0x030D ), 0x04 },
594550 {CCI_REG8 (0x0310 ), 0x01 },
595551 {CCI_REG8 (0x3CA0 ), 0x00 },
596552 {CCI_REG8 (0x3CA1 ), 0x00 },
@@ -832,7 +788,8 @@ struct imx708 {
832788 /* Current long exposure factor in use. Set through V4L2_CID_VBLANK */
833789 unsigned int long_exp_shift ;
834790
835- unsigned int link_freq_idx ;
791+ s64 link_freq_value ;
792+ u16 iop_pll_mpy ;
836793};
837794
838795static inline struct imx708 * to_imx708 (struct v4l2_subdev * _sd )
@@ -1367,7 +1324,7 @@ static int imx708_get_selection(struct v4l2_subdev *sd,
13671324static int imx708_start_streaming (struct imx708 * imx708 )
13681325{
13691326 struct i2c_client * client = v4l2_get_subdevdata (& imx708 -> sd );
1370- const struct imx708_reg_list * reg_list , * freq_regs ;
1327+ const struct imx708_reg_list * reg_list ;
13711328 int i , ret ;
13721329 u64 val ;
13731330
@@ -1413,11 +1370,10 @@ static int imx708_start_streaming(struct imx708 *imx708)
14131370 }
14141371
14151372 /* Update the link frequency registers */
1416- freq_regs = & link_freq_regs [imx708 -> link_freq_idx ];
1417- ret = cci_multi_reg_write (imx708 -> regmap , freq_regs -> regs ,
1418- freq_regs -> num_of_regs , NULL );
1373+ ret = cci_write (imx708 -> regmap , IMX708_REG_IOP_MPY , imx708 -> iop_pll_mpy ,
1374+ NULL );
14191375 if (ret ) {
1420- dev_err (& client -> dev , "%s failed to set link frequency registers \n" ,
1376+ dev_err (& client -> dev , "%s failed to set link frequency register \n" ,
14211377 __func__ );
14221378 return ret ;
14231379 }
@@ -1706,7 +1662,7 @@ static int imx708_init_controls(struct imx708 *imx708)
17061662
17071663 ctrl = v4l2_ctrl_new_int_menu (ctrl_hdlr , & imx708_ctrl_ops ,
17081664 V4L2_CID_LINK_FREQ , 0 , 0 ,
1709- & link_freqs [ imx708 -> link_freq_idx ] );
1665+ & imx708 -> link_freq_value );
17101666 if (ctrl )
17111667 ctrl -> flags |= V4L2_CTRL_FLAG_READ_ONLY ;
17121668
@@ -1807,6 +1763,25 @@ static void imx708_free_controls(struct imx708 *imx708)
18071763 mutex_destroy (& imx708 -> mutex );
18081764}
18091765
1766+ static int imx708_check_link_freq (s64 link_frequency , u16 * mpy_out )
1767+ {
1768+ s64 mpy = link_frequency * 2 * IMX708_IOP_SYSCK_DIV * IMX708_IOP_PREDIV ;
1769+ s64 tmp ;
1770+
1771+ mpy = do_div (mpy , IMX708_INCLK_FREQ );
1772+
1773+ tmp = mpy * (IMX708_INCLK_FREQ / IMX708_IOP_PREDIV );
1774+ do_div (tmp , IMX708_IOP_SYSCK_DIV / 2 );
1775+
1776+ if (tmp != link_frequency )
1777+ return - EINVAL ;
1778+
1779+ if (mpy_out )
1780+ * mpy_out = mpy ;
1781+
1782+ return 0 ;
1783+ }
1784+
18101785static int imx708_check_hwcfg (struct device * dev , struct imx708 * imx708 )
18111786{
18121787 struct fwnode_handle * endpoint ;
@@ -1839,16 +1814,16 @@ static int imx708_check_hwcfg(struct device *dev, struct imx708 *imx708)
18391814 goto error_out ;
18401815 }
18411816
1842- for (i = 0 ; i < ARRAY_SIZE (link_freqs ); i ++ ) {
1843- if (link_freqs [i ] == ep_cfg .link_frequencies [0 ]) {
1844- imx708 -> link_freq_idx = i ;
1817+ for (i = 0 ; i < ep_cfg .nr_of_link_frequencies ; i ++ ) {
1818+ if (!imx708_check_link_freq (ep_cfg .link_frequencies [i ],
1819+ & imx708 -> iop_pll_mpy )) {
1820+ imx708 -> link_freq_value = ep_cfg .link_frequencies [i ];
18451821 break ;
18461822 }
18471823 }
18481824
1849- if (i == ARRAY_SIZE (link_freqs )) {
1850- dev_err (dev , "Link frequency not supported: %lld\n" ,
1851- ep_cfg .link_frequencies [0 ]);
1825+ if (i == ep_cfg .nr_of_link_frequencies ) {
1826+ dev_err (dev , "No link frequencies supported\n" );
18521827 ret = - EINVAL ;
18531828 goto error_out ;
18541829 }
0 commit comments