[4/5] media: ov7670: add possibility to bypass pll for ov7675.
Commit Message
Signed-off-by: Javier Martin <javier.martin@vista-silicon.com>
---
drivers/media/i2c/ov7670.c | 24 ++++++++++++++++++++++--
include/media/ov7670.h | 1 +
2 files changed, 23 insertions(+), 2 deletions(-)
Comments
On Wed, 26 Sep 2012 11:47:56 +0200
Javier Martin <javier.martin@vista-silicon.com> wrote:
>
> Signed-off-by: Javier Martin <javier.martin@vista-silicon.com>
This one needs a changelog - what does bypassing the PLL do and why might
you want to do it? Otherwise:
Acked-by: Jonathan Corbet <corbet@lwn.net>
jon
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
On 26 September 2012 18:52, Jonathan Corbet <corbet@lwn.net> wrote:
> On Wed, 26 Sep 2012 11:47:56 +0200
> Javier Martin <javier.martin@vista-silicon.com> wrote:
>
>>
>> Signed-off-by: Javier Martin <javier.martin@vista-silicon.com>
>
> This one needs a changelog - what does bypassing the PLL do and why might
> you want to do it? Otherwise:
As I stated in a previous patch, frame rate depends on the pixclk. Moreover:
pixclk = xvclk / clkrc * PLLfactor
Bypassing the PLL means that the PLL gets out of the way so, in
practice, PLLfactor = 1
pixclk = xvclk / clkrc
For a frame rate of 30 fps a pixclk of 24MHz is needed. Since we have
a clean clock signal we want pixclk = xvclk.
If one applies the formula in ov7670_set_framerate() with PLLfactor =
1 and clock_speed = 24 MHz the resulting clkrc = 1 which means that:
pixclk = xvclk which is what we want
> Acked-by: Jonathan Corbet <corbet@lwn.net>
Thank you.
I will add a changelog when I send v2 of the series.
Regards.
@@ -210,6 +210,7 @@ struct ov7670_info {
int clock_speed; /* External clock speed (MHz) */
u8 clkrc; /* Clock divider value */
bool use_smbus; /* Use smbus I/O instead of I2C */
+ bool pll_bypass;
enum ov7670_model model;
};
@@ -778,7 +779,12 @@ static void ov7670_get_framerate(struct v4l2_subdev *sd,
{
struct ov7670_info *info = to_state(sd);
u32 clkrc = info->clkrc;
- u32 pll_factor = PLL_FACTOR;
+ int pll_factor;
+
+ if (info->pll_bypass)
+ pll_factor = 1;
+ else
+ pll_factor = PLL_FACTOR;
clkrc++;
if (info->fmt->mbus_code == V4L2_MBUS_FMT_SBGGR8_1X8)
@@ -794,7 +800,7 @@ static int ov7670_set_framerate(struct v4l2_subdev *sd,
{
struct ov7670_info *info = to_state(sd);
u32 clkrc;
- u32 pll_factor = PLL_FACTOR;
+ int pll_factor;
int ret;
/*
@@ -804,6 +810,16 @@ static int ov7670_set_framerate(struct v4l2_subdev *sd,
* pixclk = clock_speed / (clkrc + 1) * PLLfactor
*
*/
+ if (info->pll_bypass) {
+ pll_factor = 1;
+ ret = ov7670_write(sd, REG_DBLV, DBLV_BYPASS);
+ } else {
+ pll_factor = PLL_FACTOR;
+ ret = ov7670_write(sd, REG_DBLV, DBLV_X4);
+ }
+ if (ret < 0)
+ return ret;
+
if (tpf->numerator == 0 || tpf->denominator == 0) {
clkrc = 0;
} else {
@@ -831,6 +847,7 @@ static int ov7670_set_framerate(struct v4l2_subdev *sd,
ret = ov7670_write(sd, REG_CLKRC, info->clkrc);
if (ret < 0)
return ret;
+
return ov7670_write(sd, REG_DBLV, DBLV_X4);
}
@@ -1689,6 +1706,9 @@ static int ov7670_probe(struct i2c_client *client,
if (config->clock_speed)
info->clock_speed = config->clock_speed;
+
+ if (config->pll_bypass && id->driver_data != MODEL_OV7670)
+ info->pll_bypass = true;
}
/* Make sure it's an ov7670 */
@@ -15,6 +15,7 @@ struct ov7670_config {
int min_height; /* Filter out smaller sizes */
int clock_speed; /* External clock speed (MHz) */
bool use_smbus; /* Use smbus I/O instead of I2C */
+ bool pll_bypass; /* Choose whether to bypass the PLL */
};
#endif