| Message ID | 20261018102700.32980-1-tobias.predel@gmail.com |
|---|---|
| State | New |
| Headers | show |
| Series |
|
| Related | show |
On Sun, Oct 18, 2026 at 12:27:00PM +0200, Tobias Predel wrote: > Add camera sensor properties and a camera sensor helper for the Hynix > Hi556, a 5MP sensor used as the user-facing camera on IPU6 laptops such > as the HP Dragonfly 13.5 inch G4. > > The unit cell size is 1.12um. The test pattern modes follow the order of > the menu exposed by the kernel driver, the same as for the Hi846. > > The black level was measured on raw 10-bit frames as the intercept of a > linear fit of the mean pixel value against exposure time, at analogue > gain codes 0 and 64 (63.95 and 64.20 respectively), giving 64 at 10 > bits. I would be interested in knowing how you have performed measures, especially why you seems to suggest you have varied both the exposure time and the analogue gain (if I understand it right). > > The kernel driver exposes analogue gain codes 0 to 240 in steps of 1. > The gain is 1 + code / 16, giving 1x to 16x. This was verified on raw > frames of a static scene, with a gain code 0 reference frame captured > before and after each step to cancel out light changes: the measured Was that done with continuous capture ? Or are you changing the gain and taking 1 picture ? What does it mean capturing a reference frame with 0 gain before a single capture ? > gain is within 1% of the model for codes 0 to 224, and 1.5% below it at > code 240. > > Without the helper, the soft ISP falls back to the uncalibrated defaults > and cannot convert between gain codes and gain values. > > Signed-off-by: Tobias Predel <tobias.predel@gmail.com> > Assisted-by: Claude:claude-opus-5-5 libcamera doesn't accept LLM generated patches. I should have read the before reviewing, maybe. In this case the code change is minimal and you seem to have done most the work doing the measurement etc, so I'm not sure if this patch has to be considered or not. > --- > > Notes: > Tested on an HP Dragonfly 13.5 inch G4 (Hi556 on IPU6 ISYS, simple pipeline > handler with the soft ISP); the runtime log confirms that the helper and the > sensor properties are picked up. > > This patch was written with the help of an AI coding assistant (hence the > Assisted-by trailer, following the Linux kernel's coding-assistants > guidelines; checkstyle doesn't know that trailer key yet). I reviewed the > code and ran the measurements on the hardware myself. > > src/ipa/libipa/camera_sensor_helper.cpp | 13 +++++++++++++ > .../sensor/camera_sensor_properties.cpp | 18 ++++++++++++++++++ > 2 files changed, 31 insertions(+) > > diff --git a/src/ipa/libipa/camera_sensor_helper.cpp b/src/ipa/libipa/camera_sensor_helper.cpp > index 359040ec7..87d72afa0 100644 > --- a/src/ipa/libipa/camera_sensor_helper.cpp > +++ b/src/ipa/libipa/camera_sensor_helper.cpp > @@ -519,6 +519,19 @@ public: > }; > REGISTER_CAMERA_SENSOR_HELPER("gc08a3", CameraSensorHelperGc08a3) > > +class CameraSensorHelperHi556 : public CameraSensorHelper > +{ > +public: > + CameraSensorHelperHi556() > + { > + /* Measured: 64 at 10bits. */ > + blackLevel_ = 4096; > + /* Analogue gain is 1 + code / 16, codes 0 to 240 (1x to 16x). */ > + gain_ = AnalogueGainLinear{ 1, 16, 0, 16 }; > + } > +}; > +REGISTER_CAMERA_SENSOR_HELPER("hi556", CameraSensorHelperHi556) > + > class CameraSensorHelperHm1246 : public CameraSensorHelper > { > public: > diff --git a/src/libcamera/sensor/camera_sensor_properties.cpp b/src/libcamera/sensor/camera_sensor_properties.cpp > index 20cfd0bc1..203ffb382 100644 > --- a/src/libcamera/sensor/camera_sensor_properties.cpp > +++ b/src/libcamera/sensor/camera_sensor_properties.cpp > @@ -132,6 +132,24 @@ const CameraSensorProperties *CameraSensorProperties::get(const std::string &sen > .hblankDelay = 2 > }, > } }, > + { "hi556", { > + .unitCellSize = { 1120, 1120 }, > + .testPatternModes = { > + { controls::draft::TestPatternModeOff, 0 }, > + { controls::draft::TestPatternModeSolidColor, 1 }, > + { controls::draft::TestPatternModeColorBars, 2 }, > + { controls::draft::TestPatternModeColorBarsFadeToGray, 3 }, > + { controls::draft::TestPatternModePn9, 4 }, > + /* > + * No corresponding test pattern mode for: > + * 5: "Gradient Horizontal" > + * 6: "Gradient Vertical" > + * 7: "Check Board" > + * 8: "Slant Pattern" > + */ > + }, > + .sensorDelays = { }, > + } }, > { "hi846", { > .unitCellSize = { 1120, 1120 }, > .testPatternModes = { > -- > 2.56.0 >
Hi Jacopo, Thanks for the review. On Mon, Oct 19, 2026 at 05:20:14PM +0200, Jacopo Mondi wrote: > On Sun, Oct 18, 2026 at 12:27:00PM +0200, Tobias Predel wrote: > > The black level was measured on raw 10-bit frames as the intercept of a > > linear fit of the mean pixel value against exposure time, at analogue > > gain codes 0 and 64 (63.95 and 64.20 respectively), giving 64 at 10 > > bits. > > I would be interested in knowing how you have performed measures, > especially why you seems to suggest you have varied both the exposure > time and the analogue gain (if I understand it right). Yes, both were varied, but for different purposes. For each of the two gain codes I captured raw BA10 frames at several exposure times and fitted the mean pixel value against the exposure time. The intercept at zero exposure is the black level. The second gain code was only a check of where the pedestal sits. If the offset were added before the analogue gain, the intercept at code 64 (5x) would be about 5 * 64 = 320; it stays at 64 (63.95 at 1x, 64.20 at 5x), so the pedestal is added after the gain and a single black level is correct for all gains. > > The kernel driver exposes analogue gain codes 0 to 240 in steps of 1. > > The gain is 1 + code / 16, giving 1x to 16x. This was verified on raw > > frames of a static scene, with a gain code 0 reference frame captured > > before and after each step to cancel out light changes: the measured > > Was that done with continuous capture ? Or are you changing the gain and > taking 1 picture ? What does it mean capturing a reference frame with > 0 gain before a single capture ? Not continuous. The script sets the controls on the sensor subdev with v4l2-ctl and then starts a separate short stream for each capture, skipping the first 4 frames and averaging the next 3, at 2592x1944 BA10. Exposure (2000 lines), vertical blanking (30000) and digital gain (1x) are fixed for the whole run; only the analogue gain changes. The scene was a wall in daylight, and daylight drifts by a few percent over the minute the sweep takes. So the sequence is code 0, code 16, code 0, code 32, code 0, ..., code 240, code 0 and the gain at each step is (mean(code N) - 64) / ((mean(code 0 before) + mean(code 0 after)) / 2 - 64) i.e. each gain capture is compared to the average of the 1x captures taken just before and after it, which cancels a slow, roughly linear change in light. The means only use pixels that are below 900 in the code 240 capture, so clipped pixels don't bias the higher gains. > > Signed-off-by: Tobias Predel <tobias.predel@gmail.com> > > Assisted-by: Claude:claude-opus-5-5 > > libcamera doesn't accept LLM generated patches. > > I should have read the before reviewing, maybe. > > In this case the code change is minimal and you seem to have done most > the work doing the measurement etc, so I'm not sure if this patch has > to be considered or not. Sorry, I wasn't aware of this policy; I looked in Documentation/contributing.rst and didn't find it there, so I added the trailer to be transparent about it. Claude Code was driving the whole testing as described above to get the correct values, meaning it drafted and ran the scripts by itself and applied/tested the patches. If it helps, I can rewrite the commit message myself and resend a v2 without the trailer, or drop the patch if the policy rules it out. I'll go with whatever you and the other maintainers prefer. Regards, Tobias
Hi 2026. 10. 18. 12:27 keltezéssel, Tobias Predel írta: > Add camera sensor properties and a camera sensor helper for the Hynix > Hi556, a 5MP sensor used as the user-facing camera on IPU6 laptops such > as the HP Dragonfly 13.5 inch G4. > > The unit cell size is 1.12um. The test pattern modes follow the order of > the menu exposed by the kernel driver, the same as for the Hi846. > > The black level was measured on raw 10-bit frames as the intercept of a > linear fit of the mean pixel value against exposure time, at analogue > gain codes 0 and 64 (63.95 and 64.20 respectively), giving 64 at 10 > bits. > > The kernel driver exposes analogue gain codes 0 to 240 in steps of 1. > The gain is 1 + code / 16, giving 1x to 16x. This was verified on raw > frames of a static scene, with a gain code 0 reference frame captured > before and after each step to cancel out light changes: the measured > gain is within 1% of the model for codes 0 to 224, and 1.5% below it at > code 240. > > Without the helper, the soft ISP falls back to the uncalibrated defaults > and cannot convert between gain codes and gain values. > > Signed-off-by: Tobias Predel <tobias.predel@gmail.com> > Assisted-by: Claude:claude-opus-5-5 > --- > > Notes: > Tested on an HP Dragonfly 13.5 inch G4 (Hi556 on IPU6 ISYS, simple pipeline > handler with the soft ISP); the runtime log confirms that the helper and the > sensor properties are picked up. > > This patch was written with the help of an AI coding assistant (hence the > Assisted-by trailer, following the Linux kernel's coding-assistants > guidelines; checkstyle doesn't know that trailer key yet). I reviewed the > code and ran the measurements on the hardware myself. > > src/ipa/libipa/camera_sensor_helper.cpp | 13 +++++++++++++ > .../sensor/camera_sensor_properties.cpp | 18 ++++++++++++++++++ > 2 files changed, 31 insertions(+) > > diff --git a/src/ipa/libipa/camera_sensor_helper.cpp b/src/ipa/libipa/camera_sensor_helper.cpp > index 359040ec7..87d72afa0 100644 > --- a/src/ipa/libipa/camera_sensor_helper.cpp > +++ b/src/ipa/libipa/camera_sensor_helper.cpp > @@ -519,6 +519,19 @@ public: > }; > REGISTER_CAMERA_SENSOR_HELPER("gc08a3", CameraSensorHelperGc08a3) > > +class CameraSensorHelperHi556 : public CameraSensorHelper > +{ > +public: > + CameraSensorHelperHi556() > + { > + /* Measured: 64 at 10bits. */ > + blackLevel_ = 4096; > + /* Analogue gain is 1 + code / 16, codes 0 to 240 (1x to 16x). */ > + gain_ = AnalogueGainLinear{ 1, 16, 0, 16 }; The unit cell size and analogue gain are both confirmed by data sheets: * https://www.scribd.com/document/658971145/Hi-556W * https://cdn.specpick.com/images/photonics/products/AAA0556NXX_YACF5D0C9SHC__637812903077918008.pdf It also mentions "black level calibration": Black level is caused from pixel characteristics and analog channel offset. It makes poor image quality in dark condition and misleads color balance. To reduce these phenomenon, sensor automatically calibrates the black level every frame. The masked pixels in pixel array are used to calculate the black level. but I couldn't find any indication that some kind of target could be set / retrieved. > + } > +}; > +REGISTER_CAMERA_SENSOR_HELPER("hi556", CameraSensorHelperHi556) > + > class CameraSensorHelperHm1246 : public CameraSensorHelper > { > public: > diff --git a/src/libcamera/sensor/camera_sensor_properties.cpp b/src/libcamera/sensor/camera_sensor_properties.cpp > index 20cfd0bc1..203ffb382 100644 > --- a/src/libcamera/sensor/camera_sensor_properties.cpp > +++ b/src/libcamera/sensor/camera_sensor_properties.cpp > @@ -132,6 +132,24 @@ const CameraSensorProperties *CameraSensorProperties::get(const std::string &sen > .hblankDelay = 2 > }, > } }, > + { "hi556", { > + .unitCellSize = { 1120, 1120 }, > + .testPatternModes = { > + { controls::draft::TestPatternModeOff, 0 }, > + { controls::draft::TestPatternModeSolidColor, 1 }, > + { controls::draft::TestPatternModeColorBars, 2 }, > + { controls::draft::TestPatternModeColorBarsFadeToGray, 3 }, > + { controls::draft::TestPatternModePn9, 4 }, Did you verify these? > + /* > + * No corresponding test pattern mode for: > + * 5: "Gradient Horizontal" > + * 6: "Gradient Vertical" > + * 7: "Check Board" > + * 8: "Slant Pattern" > + */ > + }, > + .sensorDelays = { }, > + } }, > { "hi846", { > .unitCellSize = { 1120, 1120 }, > .testPatternModes = {
diff --git a/src/ipa/libipa/camera_sensor_helper.cpp b/src/ipa/libipa/camera_sensor_helper.cpp index 359040ec7..87d72afa0 100644 --- a/src/ipa/libipa/camera_sensor_helper.cpp +++ b/src/ipa/libipa/camera_sensor_helper.cpp @@ -519,6 +519,19 @@ public: }; REGISTER_CAMERA_SENSOR_HELPER("gc08a3", CameraSensorHelperGc08a3) +class CameraSensorHelperHi556 : public CameraSensorHelper +{ +public: + CameraSensorHelperHi556() + { + /* Measured: 64 at 10bits. */ + blackLevel_ = 4096; + /* Analogue gain is 1 + code / 16, codes 0 to 240 (1x to 16x). */ + gain_ = AnalogueGainLinear{ 1, 16, 0, 16 }; + } +}; +REGISTER_CAMERA_SENSOR_HELPER("hi556", CameraSensorHelperHi556) + class CameraSensorHelperHm1246 : public CameraSensorHelper { public: diff --git a/src/libcamera/sensor/camera_sensor_properties.cpp b/src/libcamera/sensor/camera_sensor_properties.cpp index 20cfd0bc1..203ffb382 100644 --- a/src/libcamera/sensor/camera_sensor_properties.cpp +++ b/src/libcamera/sensor/camera_sensor_properties.cpp @@ -132,6 +132,24 @@ const CameraSensorProperties *CameraSensorProperties::get(const std::string &sen .hblankDelay = 2 }, } }, + { "hi556", { + .unitCellSize = { 1120, 1120 }, + .testPatternModes = { + { controls::draft::TestPatternModeOff, 0 }, + { controls::draft::TestPatternModeSolidColor, 1 }, + { controls::draft::TestPatternModeColorBars, 2 }, + { controls::draft::TestPatternModeColorBarsFadeToGray, 3 }, + { controls::draft::TestPatternModePn9, 4 }, + /* + * No corresponding test pattern mode for: + * 5: "Gradient Horizontal" + * 6: "Gradient Vertical" + * 7: "Check Board" + * 8: "Slant Pattern" + */ + }, + .sensorDelays = { }, + } }, { "hi846", { .unitCellSize = { 1120, 1120 }, .testPatternModes = {
Add camera sensor properties and a camera sensor helper for the Hynix Hi556, a 5MP sensor used as the user-facing camera on IPU6 laptops such as the HP Dragonfly 13.5 inch G4. The unit cell size is 1.12um. The test pattern modes follow the order of the menu exposed by the kernel driver, the same as for the Hi846. The black level was measured on raw 10-bit frames as the intercept of a linear fit of the mean pixel value against exposure time, at analogue gain codes 0 and 64 (63.95 and 64.20 respectively), giving 64 at 10 bits. The kernel driver exposes analogue gain codes 0 to 240 in steps of 1. The gain is 1 + code / 16, giving 1x to 16x. This was verified on raw frames of a static scene, with a gain code 0 reference frame captured before and after each step to cancel out light changes: the measured gain is within 1% of the model for codes 0 to 224, and 1.5% below it at code 240. Without the helper, the soft ISP falls back to the uncalibrated defaults and cannot convert between gain codes and gain values. Signed-off-by: Tobias Predel <tobias.predel@gmail.com> Assisted-by: Claude:claude-opus-5-5 --- Notes: Tested on an HP Dragonfly 13.5 inch G4 (Hi556 on IPU6 ISYS, simple pipeline handler with the soft ISP); the runtime log confirms that the helper and the sensor properties are picked up. This patch was written with the help of an AI coding assistant (hence the Assisted-by trailer, following the Linux kernel's coding-assistants guidelines; checkstyle doesn't know that trailer key yet). I reviewed the code and ran the measurements on the hardware myself. src/ipa/libipa/camera_sensor_helper.cpp | 13 +++++++++++++ .../sensor/camera_sensor_properties.cpp | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+)