Skip to content

Commit d4d69f1

Browse files
6by9popcornmix
authored andcommitted
media: i2c: imx477: Add options for slightly modifying the link freq
The default link frequency of 450MHz has been noted to interfere with GPS if they are in close proximty. Add the option for 453 and 456MHz to move the signal slightly out of the band. (447MHz can not be offered as corruption is then observed on the 133x992 10bit mode). Signed-off-by: Dave Stevenson <[email protected]> fixup imx477 gps media: i2c: imx477: Fix link frequency menu "media: i2c: imx477: Add options for slightly modifying the link freq" created a link frequency menu with 2 items in instead of one. Correct this. Signed-off-by: Dave Stevenson <[email protected]> media: i2c: imx477: Add further link frequency options #6004 reports further issues with GPS interference. Untested, but adds further link frequency options. Signed-off-by: Dave Stevenson <[email protected]>
1 parent 5c58612 commit d4d69f1

File tree

1 file changed

+100
-19
lines changed

1 file changed

+100
-19
lines changed

drivers/media/i2c/imx477.c

Lines changed: 100 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,81 @@ struct imx477_mode {
164164
struct imx477_reg_list reg_list;
165165
};
166166

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+
},
169242
};
170243

171244
static const struct imx477_reg mode_common_regs[] = {
@@ -558,8 +631,6 @@ static const struct imx477_reg mode_4056x3040_regs[] = {
558631
{0x0309, 0x0c},
559632
{0x030b, 0x02},
560633
{0x030d, 0x02},
561-
{0x030e, 0x00},
562-
{0x030f, 0x96},
563634
{0x0310, 0x01},
564635
{0x0820, 0x07},
565636
{0x0821, 0x08},
@@ -659,8 +730,6 @@ static const struct imx477_reg mode_2028x1520_regs[] = {
659730
{0x0309, 0x0c},
660731
{0x030b, 0x02},
661732
{0x030d, 0x02},
662-
{0x030e, 0x00},
663-
{0x030f, 0x96},
664733
{0x0310, 0x01},
665734
{0x0820, 0x07},
666735
{0x0821, 0x08},
@@ -760,8 +829,6 @@ static const struct imx477_reg mode_2028x1080_regs[] = {
760829
{0x0309, 0x0c},
761830
{0x030b, 0x02},
762831
{0x030d, 0x02},
763-
{0x030e, 0x00},
764-
{0x030f, 0x96},
765832
{0x0310, 0x01},
766833
{0x0820, 0x07},
767834
{0x0821, 0x08},
@@ -890,8 +957,6 @@ static const struct imx477_reg mode_1332x990_regs[] = {
890957
{0x0309, 0x0a},
891958
{0x030b, 0x02},
892959
{0x030d, 0x02},
893-
{0x030e, 0x00},
894-
{0x030f, 0x96},
895960
{0x0310, 0x01},
896961
{0x0820, 0x07},
897962
{0x0821, 0x08},
@@ -1121,6 +1186,8 @@ struct imx477 {
11211186
struct v4l2_ctrl *vblank;
11221187
struct v4l2_ctrl *hblank;
11231188

1189+
unsigned int link_freq_idx;
1190+
11241191
/* Current mode */
11251192
const struct imx477_mode *mode;
11261193

@@ -1712,7 +1779,7 @@ static int imx477_get_selection(struct v4l2_subdev *sd,
17121779
static int imx477_start_streaming(struct imx477 *imx477)
17131780
{
17141781
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;
17161783
const struct imx477_reg_list *extra_regs;
17171784
int ret, tm;
17181785

@@ -1725,6 +1792,13 @@ static int imx477_start_streaming(struct imx477 *imx477)
17251792
extra_regs->num_of_regs);
17261793
}
17271794

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+
17281802
if (ret) {
17291803
dev_err(&client->dev, "%s failed to set common settings\n",
17301804
__func__);
@@ -2010,9 +2084,8 @@ static int imx477_init_controls(struct imx477 *imx477)
20102084
/* LINK_FREQ is also read only */
20112085
imx477->link_freq =
20122086
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]);
20162089
if (imx477->link_freq)
20172090
imx477->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
20182091

@@ -2110,13 +2183,14 @@ static void imx477_free_controls(struct imx477 *imx477)
21102183
mutex_destroy(&imx477->mutex);
21112184
}
21122185

2113-
static int imx477_check_hwcfg(struct device *dev)
2186+
static int imx477_check_hwcfg(struct device *dev, struct imx477 *imx477)
21142187
{
21152188
struct fwnode_handle *endpoint;
21162189
struct v4l2_fwnode_endpoint ep_cfg = {
21172190
.bus_type = V4L2_MBUS_CSI2_DPHY
21182191
};
21192192
int ret = -EINVAL;
2193+
int i;
21202194

21212195
endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
21222196
if (!endpoint) {
@@ -2141,11 +2215,18 @@ static int imx477_check_hwcfg(struct device *dev)
21412215
goto error_out;
21422216
}
21432217

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)) {
21462226
dev_err(dev, "Link frequency not supported: %lld\n",
21472227
ep_cfg.link_frequencies[0]);
2148-
goto error_out;
2228+
ret = -EINVAL;
2229+
goto error_out;
21492230
}
21502231

21512232
ret = 0;
@@ -2206,7 +2287,7 @@ static int imx477_probe(struct i2c_client *client)
22062287
(const struct imx477_compatible_data *)match->data;
22072288

22082289
/* Check the hardware configuration in device tree */
2209-
if (imx477_check_hwcfg(dev))
2290+
if (imx477_check_hwcfg(dev, imx477))
22102291
return -EINVAL;
22112292

22122293
/* Default the trigger mode from OF to -1, which means invalid */

0 commit comments

Comments
 (0)