Re: [PATCH/RFC v1 2/9] media: i2c: Add a driver for the onsemi AR0144 camera sensor

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Laurent,

On 6/30/24 10:17 PM, Laurent Pinchart wrote:
> The AR0144 is a 1/4" 1MP CMOS camera sensor from onsemi. The driver
> supports both the monochrome and color versions, and both the parallel
> and MIPI CSI-2 interfaces. Due to limitations of the test platform, only
> the CSI-2 output has been tested.
> 
> The driver supports 8-, 10- and 12-bit output formats, analog crop and
> binning/skipping. It exposes controls that cover the usual use cases for
> camera sensors.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx>
> ---
>  MAINTAINERS                |    1 +
>  drivers/media/i2c/Kconfig  |   11 +
>  drivers/media/i2c/Makefile |    1 +
>  drivers/media/i2c/ar0144.c | 1826 ++++++++++++++++++++++++++++++++++++
>  4 files changed, 1839 insertions(+)
>  create mode 100644 drivers/media/i2c/ar0144.c
> 
...
> +
> +/* -----------------------------------------------------------------------------
> + * PLL
> + */
> +
> +static int ar0144_pll_calculate(struct ar0144 *sensor, struct ccs_pll *pll,
> +				unsigned int link_freq, unsigned int bpp)
> +{
> +	struct ccs_pll_limits limits = {
> +		.min_ext_clk_freq_hz = 6000000,
> +		.max_ext_clk_freq_hz = 48000000,
> +
> +		.vt_fr = {
> +			.min_pre_pll_clk_div = 1,
> +			.max_pre_pll_clk_div = 63,
> +			.min_pll_ip_clk_freq_hz = 1000000,	/* min_pll_op_clk_freq_hz / max_pll_multiplier */
> +			.max_pll_ip_clk_freq_hz = 24000000,	/* max_pll_op_clk_freq_hz / min_pll_multiplier */
> +			.min_pll_multiplier = 32,
> +			.max_pll_multiplier = 384,
> +			.min_pll_op_clk_freq_hz = 384000000,
> +			.max_pll_op_clk_freq_hz = 768000000,
> +		},
> +		.vt_bk = {
> +			.min_sys_clk_div = 1,
> +			.max_sys_clk_div = 16,
> +			.min_pix_clk_div = 4,
> +			.max_pix_clk_div = 16,
> +			.min_pix_clk_freq_hz = 6000000,		/* No documented limit */
> +			.max_pix_clk_freq_hz = 74250000,
> +		},
> +		.op_bk = {
> +			.min_sys_clk_div = 1,
> +			.max_sys_clk_div = 16,
> +			.min_pix_clk_div = 8,
> +			.max_pix_clk_div = 12,
> +			.min_pix_clk_freq_hz = 6000000,		/* No documented limit */
> +			.max_pix_clk_freq_hz = 74250000,
> +		},
> +
> +		.min_line_length_pck_bin = 1200 + AR0144_MIN_HBLANK,	/* To be checked */
> +		.min_line_length_pck = 1200 + AR0144_MIN_HBLANK,
> +	};
> +	unsigned int num_lanes = sensor->bus_cfg.bus.mipi_csi2.num_data_lanes;
> +	int ret;
> +
> +	/*
> +	 * The OP pixel clock limits depends on the number of lanes, which the
> +	 * PLL calculator doesn't take into account despite specifying the
> +	 * CCS_PLL_FLAG_LANE_SPEED_MODEL flag. Adjust them manually.
> +	 */
> +	limits.op_bk.min_pix_clk_freq_hz /= num_lanes;
> +	limits.op_bk.max_pix_clk_freq_hz /= num_lanes;
> +
> +	/*
> +	 * There are no documented constraints on the sys clock frequency, for
> +	 * either branch. Recover them based on the PLL output clock frequency
> +	 * and sys_clk_div limits on one hand, and the pix clock frequency and
> +	 * the pix_clk_div limits on the other hand.
> +	 */
> +	limits.vt_bk.min_sys_clk_freq_hz =
> +		max(limits.vt_fr.min_pll_op_clk_freq_hz / limits.vt_bk.max_sys_clk_div,
> +		    limits.vt_bk.min_pix_clk_freq_hz * limits.vt_bk.min_pix_clk_div);
> +	limits.vt_bk.max_sys_clk_freq_hz =
> +		min(limits.vt_fr.max_pll_op_clk_freq_hz / limits.vt_bk.min_sys_clk_div,
> +		    limits.vt_bk.max_pix_clk_freq_hz * limits.vt_bk.max_pix_clk_div);
> +
> +	limits.op_bk.min_sys_clk_freq_hz =
> +		max(limits.vt_fr.min_pll_op_clk_freq_hz / limits.op_bk.max_sys_clk_div,
> +		    limits.op_bk.min_pix_clk_freq_hz * limits.op_bk.min_pix_clk_div);
> +	limits.op_bk.max_sys_clk_freq_hz =
> +		min(limits.vt_fr.max_pll_op_clk_freq_hz / limits.op_bk.min_sys_clk_div,
> +		    limits.op_bk.max_pix_clk_freq_hz * limits.op_bk.max_pix_clk_div);
> +
> +	memset(pll, 0, sizeof(*pll));
> +
> +	pll->bus_type = CCS_PLL_BUS_TYPE_CSI2_DPHY;
> +	pll->op_lanes = num_lanes;
> +	pll->vt_lanes = 1;
> +	pll->csi2.lanes = num_lanes;
> +	/*
> +	 * As the sensor doesn't support FIFO derating, binning doesn't
> +	 * influence the PLL configuration. Hardcode the binning factors.
> +	 */
> +	pll->binning_horizontal = 1;
> +	pll->binning_vertical = 1;
> +	pll->scale_m = 1;
> +	pll->scale_n = 1;
> +	pll->bits_per_pixel = bpp;
> +	pll->flags = CCS_PLL_FLAG_LANE_SPEED_MODEL;
> +	pll->link_freq = link_freq;
> +	pll->ext_clk_freq_hz = clk_get_rate(sensor->clk);
> +
> +	ret = ccs_pll_calculate(sensor->dev, &limits, pll);
> +	if (ret)
> +		return ret;
> +
> +	/*
> +	 * The sensor ignores the LSB of the PLL multiplier. If the multiplier
> +	 * is an odd value, as a workaround to avoid precision loss, multiply
> +	 * both the pre-divider and the multiplier by 2 if this doesn't bring
> +	 * them beyond their maximum values. This doesn't necessarily guarantee
> +	 * optimum PLL parameters. Ideally the PLL calculator should handle
> +	 * this constraint.
> +	 */
> +	if ((pll->vt_fr.pll_multiplier & 1) &&
> +	    pll->vt_fr.pll_multiplier * 2 <= limits.vt_fr.max_pll_multiplier &&
> +	    pll->vt_fr.pre_pll_clk_div * 2 <= limits.vt_fr.max_pre_pll_clk_div) {
> +		pll->vt_fr.pll_multiplier *= 2;
> +		pll->vt_fr.pre_pll_clk_div *= 2;
> +	}
> +
> +	if (pll->vt_fr.pll_multiplier & 1)
> +		dev_warn(sensor->dev,
> +			 "Odd PLL multiplier, link frequency %u will not be exact\n",
> +			 pll->link_freq);
> +
> +	return 0;
> +}

Dongcheng and I are trying to calculate the AR pll like code here. But
we did not find any datasheet or manual to refer to. Even vendor has no
idea. Could you share which doc can help us to do that?

> +
> +static int ar0144_pll_update(struct ar0144 *sensor,
> +			     const struct ar0144_format_info *info)
> +{
> +	u64 link_freq;
> +	int ret;
> +
> +	link_freq = sensor->bus_cfg.link_frequencies[sensor->link_freq->val];
> +	ret = ar0144_pll_calculate(sensor, &sensor->pll, link_freq, info->bpp);
> +	if (ret) {
> +		dev_err(sensor->dev, "PLL calculations failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	__v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate,
> +				 sensor->pll.pixel_rate_pixel_array);
> +
> +	return 0;
> +}
> +
...
> 

-- 
Best regards,
Bingbu Cao




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux