[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID:
 <PN3P287MB18291DD344424C8F45790FC18BFBA@PN3P287MB1829.INDP287.PROD.OUTLOOK.COM>
Date: Thu, 30 Oct 2025 06:52:42 +0000
From: Tarang Raval <tarang.raval@...iconsignals.io>
To: Svyatoslav Ryhel <clamor95@...il.com>
CC: Sakari Ailus <sakari.ailus@...ux.intel.com>, Mauro Carvalho Chehab
	<mchehab@...nel.org>, Rob Herring <robh@...nel.org>, Krzysztof Kozlowski
	<krzk+dt@...nel.org>, Conor Dooley <conor+dt@...nel.org>, Hans Verkuil
	<hverkuil@...all.nl>, Hans de Goede <hansg@...nel.org>, Arnd Bergmann
	<arnd@...db.de>, Dongcheng Yan <dongcheng.yan@...el.com>,
	André Apitzsch <git@...tzsch.eu>, Sylvain Petinot
	<sylvain.petinot@...s.st.com>, Benjamin Mugnier
	<benjamin.mugnier@...s.st.com>, Heimir Thor Sverrisson
	<heimir.sverrisson@...il.com>, "linux-media@...r.kernel.org"
	<linux-media@...r.kernel.org>, "devicetree@...r.kernel.org"
	<devicetree@...r.kernel.org>, "linux-kernel@...r.kernel.org"
	<linux-kernel@...r.kernel.org>
Subject: Re: [PATCH v2 2/2 RESEND] media: i2c: add Sony IMX111 CMOS camera
 sensor driver
Hi Svyatoslav,
> > > > On Tue, Oct 28, 2025 at 11:22:00AM +0200, Svyatoslav Ryhel wrote:
> > > > > Add a v4l2 sub-device driver for the Sony IMX111 image sensor. This is a
> > > > > camera sensor using the i2c bus for control and the csi-2 bus for data.
> > > > >
> > > > > The following features are supported:
> > > > > - manual exposure, digital and analog gain control support
> > > > > - pixel rate/link freq control support
> > > > > - supported resolution up to 3280x2464 for single shot capture
> > > > > - supported resolution up to 1920x1080 @ 30fps for video
> > > > > - supported bayer order output SGBRG10 and SGBRG8
> > > > >
> > > > > Camera module seems to be partially compatible with Nokia SMIA but it
> > > > > lacks a few registers required for clock calculations and has different
> > > > > vendor-specific per-mode configurations which makes it incompatible with
> > > > > existing CCS driver.
> > > > >
> > > > > Signed-off-by: Svyatoslav Ryhel <clamor95@...il.com>
> >
> > ...
> >
> > > > > +#include <linux/clk.h>
> > > > > +#include <linux/delay.h>
> > > > > +#include <linux/gpio/consumer.h>
> > > > > +#include <linux/i2c.h>
> > > > > +#include <linux/kernel.h>
> > > > > +#include <linux/media.h>
> > > > > +#include <linux/module.h>
> > > > > +#include <linux/pm_runtime.h>
> > > > > +#include <linux/ratelimit.h>
> > > > > +#include <linux/regmap.h>
> > > > > +#include <linux/regulator/consumer.h>
> > > > > +#include <linux/slab.h>
> > > > > +#include <linux/string.h>
> > > > > +#include <linux/types.h>
> > > > > +#include <linux/videodev2.h>
> > > > > +#include <linux/units.h>
> > > > > +
> > > > > +#include <media/media-entity.h>
> > > > > +#include <media/v4l2-async.h>
> > > > > +#include <media/v4l2-cci.h>
> > > > > +#include <media/v4l2-ctrls.h>
> > > > > +#include <media/v4l2-device.h>
> > > > > +#include <media/v4l2-fwnode.h>
> > > > > +#include <media/v4l2-event.h>
> > > > > +#include <media/v4l2-image-sizes.h>
> > > > > +#include <media/v4l2-subdev.h>
> > > > > +#include <media/v4l2-mediabus.h>
> >
> > A few of those headers seem to be unused and can be removed
> >
> > Like:
> >
> > #include <linux/ratelimit.h>
> > #include <linux/slab.h>
> > #include <linux/string.h>
> > #include <media/v4l2-event.h>
> > #include <media/v4l2-image-sizes.h>
> >
> > ...
> >
> > > > > +/* product information registers */
> > > > > +#define IMX111_PRODUCT_ID                    CCI_REG16(0x0000)
> > > > > +#define   IMX111_CHIP_ID                     0x111
> > > > > +#define IMX111_REVISION                              CCI_REG8(0x0002)
> > > > > +#define IMX111_MANUFACTURER_ID                       CCI_REG8(0x0003)
> > > > > +#define IMX111_SMIA_VER                              CCI_REG8(0x0004)
> > > > > +#define IMX111_FRAME_COUNTER                 CCI_REG8(0x0005)
> > > > > +#define IMX111_PIXEL_ORDER                   CCI_REG8(0x0006)
> > > > > +
> > > > > +/* general configuration registers */
> > > > > +#define IMX111_STREAMING_MODE                        CCI_REG8(0x0100)
> > > > > +#define   IMX111_MODE_STANDBY                        0
> > > > > +#define   IMX111_MODE_STREAMING                      1
> > > > > +#define IMX111_IMAGE_ORIENTATION             CCI_REG8(0x0101)
> > > > > +#define   IMX111_IMAGE_HFLIP                 BIT(0)
> > > > > +#define   IMX111_IMAGE_VFLIP                 BIT(1)
> > > > > +#define IMX111_SOFTWARE_RESET                        CCI_REG8(0x0103)
> > > > > +#define   IMX111_RESET_ON                    1
> > > > > +#define IMX111_GROUP_WRITE                   CCI_REG8(0x0104)
> > > > > +#define   IMX111_GROUP_WRITE_ON                      1
> > > > > +#define IMX111_FRAME_DROP                    CCI_REG8(0x0105)
> > > > > +#define   IMX111_FRAME_DROP_ON                       1
> > > > > +#define IMX111_CHANNEL_ID                    CCI_REG8(0x0110)
> > > > > +#define IMX111_SIGNALLING_MODE                       CCI_REG8(0x0111)
> > > > > +#define IMX111_DATA_DEPTH                    CCI_REG16(0x0112)
> > > > > +#define   IMX111_DATA_DEPTH_RAW8             0x08
> > > > > +#define   IMX111_DATA_DEPTH_RAW10            0x0a
> > > > > +
> > > > > +/* integration time registers */
> > > > > +#define IMX111_INTEGRATION_TIME                      CCI_REG16(0x0202)
> > > > > +#define IMX111_INTEGRATION_TIME_MIN          0x1
> > > > > +#define IMX111_INTEGRATION_TIME_MAX          0xffff
> > > > > +#define IMX111_INTEGRATION_TIME_STEP         1
> > > > > +
> > > > > +/* analog gain control */
> > > > > +#define IMX111_REG_ANALOG_GAIN                       CCI_REG8(0x0205)
> > > > > +#define IMX111_ANA_GAIN_MIN                  0
> > > > > +#define IMX111_ANA_GAIN_MAX                  240
> > > > > +#define IMX111_ANA_GAIN_STEP                 1
> > > > > +#define IMX111_ANA_GAIN_DEFAULT                      0
> > > > > +
> > > > > +/* digital gain control */
> > > > > +#define IMX111_REG_DIG_GAIN_GREENR           CCI_REG16(0x020e)
> > > > > +#define IMX111_REG_DIG_GAIN_RED                      CCI_REG16(0x0210)
> > > > > +#define IMX111_REG_DIG_GAIN_BLUE             CCI_REG16(0x0212)
> > > > > +#define IMX111_REG_DIG_GAIN_GREENB           CCI_REG16(0x0214)
> > > > > +#define IMX111_DGTL_GAIN_MIN                 0x0100
> > > > > +#define IMX111_DGTL_GAIN_MAX                 0x0fff
> > > > > +#define IMX111_DGTL_GAIN_DEFAULT             0x0100
> > > > > +#define IMX111_DGTL_GAIN_STEP                        1
> > > > > +
> > > > > +/* clock configuration registers */
> > > > > +#define IMX111_PIXEL_CLK_DIVIDER_PLL1                CCI_REG8(0x0301) /* fixed to 10 */
> > > > > +#define IMX111_SYSTEM_CLK_DIVIDER_PLL1               CCI_REG8(0x0303) /* fixed to 1 */
> > > > > +#define IMX111_PRE_PLL_CLK_DIVIDER_PLL1              CCI_REG8(0x0305)
> > > > > +#define IMX111_PLL_MULTIPLIER_PLL1           CCI_REG8(0x0307)
> > > > > +#define IMX111_PLL_SETTLING_TIME             CCI_REG8(0x303c)
> > > > > +#define   IMX111_PLL_SETTLING_TIME_DEFAULT   200
> > > > > +#define IMX111_POST_DIVIDER                  CCI_REG8(0x30a4)
> > > > > +#define   IMX111_POST_DIVIDER_DIV1           2
> > > > > +#define   IMX111_POST_DIVIDER_DIV2           0
> > > > > +#define   IMX111_POST_DIVIDER_DIV4           1
> > > > > +
> > > > > +/* frame timing registers */
> > > > > +#define IMX111_VERTICAL_TOTAL_LENGTH         CCI_REG16(0x0340)
> > > > > +#define IMX111_HORIZONTAL_TOTAL_LENGTH               CCI_REG16(0x0342)
> > > > > +
> > > > > +/* image size registers */
> > > > > +#define IMX111_HORIZONTAL_START                      CCI_REG16(0x0344)
> > > > > +#define IMX111_VERTICAL_START                        CCI_REG16(0x0346)
> > > > > +#define IMX111_HORIZONTAL_END                        CCI_REG16(0x0348)
> > > > > +#define IMX111_VERTICAL_END                  CCI_REG16(0x034a)
> > > > > +#define IMX111_IMAGE_WIDTH                   CCI_REG16(0x034c)
> > > > > +#define IMX111_IMAGE_HEIGHT                  CCI_REG16(0x034e)
> >
> > In the mode register settings, you can use the above macros.
> >
> > > > > +static const struct cci_reg_sequence mode_820x614[] = {
> > > > > +     { CCI_REG8(0x0340), 0x04 },     { CCI_REG8(0x0341), 0xec },
> > > > > +     { CCI_REG8(0x0342), 0x0d },     { CCI_REG8(0x0343), 0xd0 },
> > > > > +     { CCI_REG8(0x0344), 0x00 },     { CCI_REG8(0x0345), 0x08 },
> > > > > +     { CCI_REG8(0x0346), 0x00 },     { CCI_REG8(0x0347), 0x34 },
> > > > > +     { CCI_REG8(0x0348), 0x0c },     { CCI_REG8(0x0349), 0xd7 },
> > > > > +     { CCI_REG8(0x034a), 0x09 },     { CCI_REG8(0x034b), 0xcb },
> > > > > +     { CCI_REG8(0x034c), 0x03 },     { CCI_REG8(0x034d), 0x34 },
> > > > > +     { CCI_REG8(0x034e), 0x02 },     { CCI_REG8(0x034f), 0x66 },
> >
> > Here, you can use those macros.
> >
> > Likewise, in every mode.
> >
> 
> This is not as simple as a substitution, imx111 requires group write
> in order to write 16bit values to registers. I will see what I can do
> about this.
It is straightforward, even if group writes are present. 
static const struct cci_reg_sequence mode_820x614[] = {
	// group hold ON Register Write  
	{ IMX111_VERTICAL_TOTAL_LENGTH, 0x04ec },
	.
 	.
	.
	{ IMX111_IMAGE_HEIGHT,		0x0266 },
	// group hold OFF  Register write
};
However, in your register settings, I do not find any group hold ON or OFF
register before or after these image size–related registers. This appears 
to be a simple substitution.
If I have misunderstood something, please let me know.
One more suggestion: you can create a helper function for group writes
It is up to you, if you want, you can make this change.
static int imx111_group_write(struct imx111 *sensor, bool enable)
{
	int ret;
	
	if (enable)
		cci_update_bits(sensor->regmap, IMX111_GROUP_WRITE, 
				IMX111_GROUP_WRITE_ON, IMX111_GROUP_WRITE_ON, 
				&ret); 
	else
		cci_update_bits(sensor->regmap, IMX111_GROUP_WRITE, 
				IMX111_GROUP_WRITE_ON, 0, &ret);
	 
	return ret;
}
It removes the repeated cci_update_bits(... GROUP_WRITE ...) boilerplate.
	
Best Regards,
Tarang
Powered by blists - more mailing lists
 
