Re: [PATCH v3] media: i2c: imx335: Support multiple link frequency

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

 



Hi Umang,

Thanks for the patch.

Note that Daniele and Paul are no longer maintaining the driver.

On Wed, Dec 13, 2023 at 02:47:12PM +0530, Umang Jain wrote:
> Support link frequency of 445MHz in addition to 594MHz.
> Break out the register set specific to each data lane rate and also add
> the general timing register set corresponding to the each data
> lane rate.
> 
> Signed-off-by: Umang Jain <umang.jain@xxxxxxxxxxxxxxxx>
> ---
> Changes in v3:
> - Use tabspace for indent as denoted by checkpatch.
> 
> Changes in v2:
> - Split out from [PATCH v3 0/8] media: Sony IMX335 improvements
>   where original patch was introduced.
> - Add general timing registers to each data lane rate configuration
> - Reword commit message. 
> ---
>  drivers/media/i2c/imx335.c | 108 +++++++++++++++++++++++++++++--------
>  1 file changed, 87 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c
> index 7a37eb327ff4..ffceeb8a15c7 100644
> --- a/drivers/media/i2c/imx335.c
> +++ b/drivers/media/i2c/imx335.c
> @@ -49,7 +49,8 @@
>  #define IMX335_INCLK_RATE	24000000
>  
>  /* CSI2 HW configuration */
> -#define IMX335_LINK_FREQ	594000000
> +#define IMX335_LINK_FREQ_594MHz	594000000
> +#define IMX335_LINK_FREQ_445MHz	445500000
>  #define IMX335_NUM_DATA_LANES	4
>  
>  #define IMX335_REG_MIN		0x00
> @@ -99,7 +100,6 @@ static const char * const imx335_supply_name[] = {
>   * @vblank_min: Minimum vertical blanking in lines
>   * @vblank_max: Maximum vertical blanking in lines
>   * @pclk: Sensor pixel clock
> - * @link_freq_idx: Link frequency index
>   * @reg_list: Register list for sensor mode
>   */
>  struct imx335_mode {
> @@ -111,7 +111,6 @@ struct imx335_mode {
>  	u32 vblank_min;
>  	u32 vblank_max;
>  	u64 pclk;
> -	u32 link_freq_idx;
>  	struct imx335_reg_list reg_list;
>  };
>  
> @@ -133,6 +132,7 @@ struct imx335_mode {
>   * @again_ctrl: Pointer to analog gain control
>   * @vblank: Vertical blanking in lines
>   * @cur_mode: Pointer to current selected sensor mode
> + * @link_freq_idx: Selected link frequency index
>   * @mutex: Mutex for serializing sensor controls
>   * @cur_mbus_code: Currently selected media bus format code
>   */
> @@ -156,20 +156,16 @@ struct imx335 {
>  	};
>  	u32 vblank;
>  	const struct imx335_mode *cur_mode;
> +	u32 link_freq_idx;
>  	struct mutex mutex;
>  	u32 cur_mbus_code;
>  };
>  
> -static const s64 link_freq[] = {
> -	IMX335_LINK_FREQ,
> -};
>  
>  /* Sensor mode registers */
>  static const struct imx335_reg mode_2592x1940_regs[] = {
>  	{0x3000, 0x01},
>  	{0x3002, 0x00},
> -	{0x300c, 0x3b},
> -	{0x300d, 0x2a},
>  	{0x3018, 0x04},
>  	{0x302c, 0x3c},
>  	{0x302e, 0x20},
> @@ -177,10 +173,6 @@ static const struct imx335_reg mode_2592x1940_regs[] = {
>  	{0x3074, 0xc8},
>  	{0x3076, 0x28},
>  	{0x304c, 0x00},
> -	{0x314c, 0xc6},
> -	{0x315a, 0x02},
> -	{0x3168, 0xa0},
> -	{0x316a, 0x7e},
>  	{0x31a1, 0x00},
>  	{0x3288, 0x21},
>  	{0x328a, 0x02},
> @@ -266,6 +258,65 @@ static const struct imx335_reg raw12_framefmt_regs[] = {
>  	{0x341d, 0x00},
>  };
>  
> +static const struct imx335_reg mipi_data_rate_1188Mbps[] = {
> +	{0x300c, 0x3b},
> +	{0x300d, 0x2a},
> +	{0x314c, 0xc6},
> +	{0x314d, 0x00},
> +	{0x315a, 0x02},
> +	{0x3168, 0xa0},
> +	{0x316a, 0x7e},
> +	{0x319e, 0x01},
> +	{0x3a18, 0x8f},
> +	{0x3a1a, 0x4f},
> +	{0x3a1c, 0x47},
> +	{0x3a1e, 0x37},
> +	{0x3a1f, 0x01},
> +	{0x3a20, 0x4f},
> +	{0x3a22, 0x87},
> +	{0x3a24, 0x4f},
> +	{0x3a26, 0x7f},
> +	{0x3a28, 0x3f},
> +};
> +
> +static const struct imx335_reg mipi_data_rate_891Mbps[] = {
> +	{0x300c, 0x3b},
> +	{0x300d, 0x2a},
> +	{0x314c, 0x29},
> +	{0x314d, 0x01},
> +	{0x315a, 0x06},
> +	{0x3168, 0xa0},
> +	{0x316a, 0x7e},
> +	{0x319e, 0x02},
> +	{0x3a18, 0x7f},
> +	{0x3a1a, 0x37},
> +	{0x3a1c, 0x37},
> +	{0x3a1e, 0xf7},
> +	{0x3a20, 0x3f},
> +	{0x3a22, 0x6f},
> +	{0x3a24, 0x3f},
> +	{0x3a26, 0x5f},
> +	{0x3a28, 0x2f},
> +};
> +
> +static const s64 link_freq[] = {
> +	/* Corresponds to 1188Mbps data lane rate */
> +	IMX335_LINK_FREQ_594MHz,
> +	/* Corresponds to 891Mbps data lane rate */
> +	IMX335_LINK_FREQ_445MHz,
> +};
> +
> +static const struct imx335_reg_list link_freq_reglist[] = {
> +	{
> +		.num_of_regs = ARRAY_SIZE(mipi_data_rate_1188Mbps),
> +		.regs = mipi_data_rate_1188Mbps,
> +	},
> +	{
> +		.num_of_regs = ARRAY_SIZE(mipi_data_rate_891Mbps),
> +		.regs = mipi_data_rate_891Mbps,
> +	},
> +};
> +
>  static const u32 imx335_mbus_codes[] = {
>  	MEDIA_BUS_FMT_SRGGB12_1X12,
>  	MEDIA_BUS_FMT_SRGGB10_1X10,
> @@ -280,7 +331,6 @@ static const struct imx335_mode supported_mode = {
>  	.vblank_min = 2560,
>  	.vblank_max = 133060,
>  	.pclk = 396000000,
> -	.link_freq_idx = 0,
>  	.reg_list = {
>  		.num_of_regs = ARRAY_SIZE(mode_2592x1940_regs),
>  		.regs = mode_2592x1940_regs,
> @@ -405,7 +455,7 @@ static int imx335_update_controls(struct imx335 *imx335,
>  {
>  	int ret;
>  
> -	ret = __v4l2_ctrl_s_ctrl(imx335->link_freq_ctrl, mode->link_freq_idx);
> +	ret = __v4l2_ctrl_s_ctrl(imx335->link_freq_ctrl, imx335->link_freq_idx);
>  	if (ret)
>  		return ret;
>  
> @@ -755,6 +805,14 @@ static int imx335_start_streaming(struct imx335 *imx335)
>  	const struct imx335_reg_list *reg_list;
>  	int ret;
>  
> +	/* Setup PLL */
> +	reg_list = &link_freq_reglist[imx335->link_freq_idx];
> +	ret = imx335_write_regs(imx335, reg_list->regs, reg_list->num_of_regs);
> +	if (ret) {
> +		dev_err(imx335->dev, "%s failed to set plls\n", __func__);
> +		return ret;
> +	}
> +
>  	/* Write sensor mode registers */
>  	reg_list = &imx335->cur_mode->reg_list;
>  	ret = imx335_write_regs(imx335, reg_list->regs,
> @@ -881,7 +939,7 @@ static int imx335_parse_hw_config(struct imx335 *imx335)
>  	};
>  	struct fwnode_handle *ep;
>  	unsigned long rate;
> -	unsigned int i;
> +	unsigned int i, j;
>  	int ret;
>  
>  	if (!fwnode)
> @@ -945,13 +1003,21 @@ static int imx335_parse_hw_config(struct imx335 *imx335)
>  		goto done_endpoint_free;
>  	}
>  
> -	for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++)
> -		if (bus_cfg.link_frequencies[i] == IMX335_LINK_FREQ)
> -			goto done_endpoint_free;
>  
> -	dev_err(imx335->dev, "no compatible link frequencies found\n");
> +	for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
> +		for (j = 0; j < ARRAY_SIZE(link_freq); j++) {
> +			if (bus_cfg.link_frequencies[i] == link_freq[j]) {
> +				imx335->link_freq_idx = j;
> +				break;

Instead of stabbing the old implementation, could you instead use
v4l2_link_freq_to_bitmap()
<URL:https://patchwork.linuxtv.org/project/linux-media/patch/20240108075221.15757-2-sakari.ailus@xxxxxxxxxxxxxxx/>?

> +			}
> +		}
>  
> -	ret = -EINVAL;
> +		if (j == ARRAY_SIZE(link_freq)) {
> +			ret = dev_err_probe(imx335->dev, -EINVAL,
> +					    "no supported link freq found\n");
> +			goto done_endpoint_free;
> +		}
> +	}
>  
>  done_endpoint_free:
>  	v4l2_fwnode_endpoint_free(&bus_cfg);
> @@ -1101,7 +1167,7 @@ static int imx335_init_controls(struct imx335 *imx335)
>  							V4L2_CID_LINK_FREQ,
>  							ARRAY_SIZE(link_freq) -
>  							1,
> -							mode->link_freq_idx,
> +							imx335->link_freq_idx,
>  							link_freq);
>  	if (imx335->link_freq_ctrl)
>  		imx335->link_freq_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;

-- 
Regards,

Sakari Ailus




[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