Skip to content

add mira220 image sensor #6717

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: rpi-6.12.y
Choose a base branch
from

Conversation

fiepfiep
Copy link

@fiepfiep fiepfiep commented Mar 12, 2025

add driver / device tree support for ams mira220

needed changes also done for libcamera.

Copy link
Contributor

@6by9 6by9 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've started to review this, but I'm noticing a lot of my comments from #6552 haven't been addressed.

If embedded data isn't required, then do not include it.

data-lanes = <1 2>;
// clock-noncontinuous;
link-frequencies =
/bits/ 64 <456000000>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the correct link frequency for this sensor?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

currently operating at 1.5 Gbit/s per lane

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

solved, set to 750, as datarate is 1500Mbit/s


/* Embedded metadata stream structure */
#define MIRA220_EMBEDDED_LINE_WIDTH 16384
#define MIRA220_NUM_EMBEDDED_LINES 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this sensor actually have useful embedded metadata? It's disabled in libcamera.

I'd made the same comment in #6552 (comment) that this isn't how mainline are implementing metadata, so it's simpler to not implement it in the driver if not needed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed the embedded data

// 1600_1400_30fps_12b_2lanes

static const struct mira220_reg full_1600_1400_1500_12b_2lanes_reg[] = {
{0x1003,0x2}, //,Initial Upload
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment isn't useful.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

solved


// 1600_1400_30fps_12b_2lanes

static const struct mira220_reg full_1600_1400_1500_12b_2lanes_reg[] = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have about 18 registers that differ between these 3 huge tables. Break out all the common stuff into a common table, and only send the bits that change per mode

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, will do.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

simplified, reduced driver to 1 mode only.

#define MIRA220_PIXEL_ARRAY_WIDTH 1600U
#define MIRA220_PIXEL_ARRAY_HEIGHT 1400U

#define MIRA220_ANALOG_GAIN_REG 0x400A
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment made at #6552 (comment) that the V4L2_CCI is preferred rather than bare register defines as it encodes the size of each register.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I converted everything to the new style cci writes

static const char * const mira220_supply_name[] = {
// TODO(jalv): Check supply names
/* Supplies can be enabled in any order */
"VANA", /* Analog (2.8V) supply */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regulators should be named in lower case.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

@pelwell
Copy link
Contributor

pelwell commented Apr 2, 2025

I'll warn you now that, once the content of these commits has been approved, the end result should ideally be 3 commits - driver changes, config changes, and overlay/README changes.

@@ -58,28 +58,6 @@
};
};

fragment@102 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you delete this fragment by mistake? The media-controller parameter refers to it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that is a mistake.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put it back. thanks for finding out.

@fiepfiep fiepfiep marked this pull request as draft April 2, 2025 19:57
@fiepfiep
Copy link
Author

fiepfiep commented Apr 2, 2025

I'll warn you now that, once the content of these commits has been approved, the end result should ideally be 3 commits - driver changes, config changes, and overlay/README changes.

I will keep it in mind. Once all is approved by you I will refactor it to 3 commits.

@fiepfiep fiepfiep requested a review from 6by9 April 2, 2025 21:43
@fiepfiep fiepfiep marked this pull request as ready for review April 2, 2025 21:43
@fiepfiep fiepfiep marked this pull request as draft April 2, 2025 21:44
@fiepfiep
Copy link
Author

fiepfiep commented Apr 2, 2025

I cleaned up the driver a bit, implemented the new CCI_REG style writes, and took care of 6by9's comments.
Please let me know if you find other issues before we can do the merge.

Copy link
Contributor

@pelwell pelwell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from the extra blank lines in the README, the overlay looks good.

Checkpatch has lots of complaints about the driver which you should really fix. Nobody using printk directly anymore, for example.

The only additional change I would like (apart from refactoring down to 3 commits as discussed) is the addition of CONFIG_VIDEO_MIRA220 to the new PREEMPT_RT config file arm64/bcm2711_rt_defconfig.

@@ -3632,6 +3649,7 @@ Params: rotation Mounting rotation of the camera sensor (0 or
Appears not to work on Pi3.



Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like an unnecessary change.

@@ -3511,6 +3511,23 @@ Params:
(default 16).



Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 blank lines is enough.

Copy link
Contributor

@6by9 6by9 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still a number of my previous review comments haven't been addressed.

  • Please remove the references to the embedded data pad.
  • Please remove all commented out code.
  • Please remove all redundant comments.
  • Please rationalise the logging messages. Very few should be needed at all.
  • Regulator names should be consistently in lower case.

<&csi_frag>, "target:0=",<&csi0>,
<&clk_frag>, "target:0=",<&cam0_clk>,
<&cam_node>, "clocks:0=",<&cam0_clk>,
<&cam_node>, "VANA-supply:0=",<&cam0_reg>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your supply is now vana-supply, so this won't match.

@@ -149,6 +149,20 @@ config VIDEO_HI847
To compile this driver as a module, choose M here: the
module will be called hi847.

config VIDEO_MIRA220
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are normally in alphabetical order. (I see the Arducam drivers have got out of position during forward porting).

Annoyingly this will also move the position in the defconfigs, so perhaps I don't care enough.

@@ -49,6 +49,7 @@ obj-$(CONFIG_VIDEO_HI556) += hi556.o
obj-$(CONFIG_VIDEO_HI846) += hi846.o
obj-$(CONFIG_VIDEO_HI847) += hi847.o
obj-$(CONFIG_VIDEO_I2C) += video-i2c.o
obj-$(CONFIG_VIDEO_MIRA220) += mira220.o
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto - alphabetical order please.


#define MIRA220_ANALOG_GAIN_MIN 1
#define MIRA220_ANALOG_GAIN_MAX \
1 /* Fixed analog gain to 1, to avoid unexpected behavior. */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weird line breaking. That does seem quite a limitation though if you have no analogue gain.

// Outdated. See below.
// pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample
// 1.0Gb/s * 2 * 2 / 12 = 357913941
// #define MIRA220_PIXEL_RATE (357913941)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's outdated, then please remove it.


/*test cci write*/
ret = cci_read(mira220->regmap, MIRA220_EXP_TIME_REG, &readval, &ret);
otherval = readval & 0xFFFF;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why read the value before writing it? You do nothing with the result.

if (mira220_check_hwcfg(dev))
return -EINVAL;

/* Parse device tree to check if dtoverlay has param skip-reg-upload=1 */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh?

}

static const struct dev_pm_ops mira220_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(mira220_suspend, mira220_resume)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't be implementing SLEEP_OPS.

SET_RUNTIME_PM_OPS(mira220_power_off, mira220_power_on, NULL)
};

static const struct of_device_id mira220_dt_ids[] = { { .compatible =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the normal formatting for dt_ids.

static const struct of_device_id mira220_dt_ids[] = {
	{ .compatible = "ams,mira220" },
	{ /* sentinel */ }
};

MODULE_DEVICE_TABLE(of, mira220_dt_ids);

static const struct i2c_device_id mira220_ids[] = { { "mira220", 0 }, {} };
MODULE_DEVICE_TABLE(i2c, mira220_ids);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't need I2C ids. This driver needs config data, so you can't load via sysfs.

@pelwell
Copy link
Contributor

pelwell commented Apr 6, 2025

FYI the build checks explicitly set CONFIG_WERROR=y, overriding the defconfigs:

scripts/config --file ${{github.workspace}}/build/.config --set-val CONFIG_WERROR y

@fiepfiep fiepfiep force-pushed the rpi-6.12.y branch 2 times, most recently from 6c62034 to a0c3d9c Compare April 15, 2025 13:23
@fiepfiep fiepfiep requested a review from 6by9 April 15, 2025 13:25
@fiepfiep
Copy link
Author

@pelwell could you run your checks again? I split my changes into 3 commits as requested.

@pelwell
Copy link
Contributor

pelwell commented Apr 15, 2025

It looks like somebody has started them. Please mark the PR as "Ready for review" when you think it is. However, there is no excuse for some of these (https://github.com/raspberrypi/linux/actions/runs/14470568709/job/40583365956?pr=6717#step:6:80) checkpatch errors such as trailing whitespace.

@fiepfiep fiepfiep marked this pull request as ready for review April 15, 2025 15:41
@fiepfiep
Copy link
Author

fiepfiep commented Apr 16, 2025

I still get this error in checkpatch, what does it mean?
@pelwell

 WARNING: From:/Signed-off-by: email name mismatch: 'From: philippe baetens <[email protected]>' != 'Signed-off-by: Philippe Baetens <[email protected]>'
Error: WARNING: From:/Signed-off-by: email name mismatch: 'From: philippe baetens <[email protected]>' != 'Signed-off-by: Philippe Baetens <[email protected]>'

@pelwell
Copy link
Contributor

pelwell commented Apr 16, 2025

Is it possibly just that your name appears with and without uppercase letters? I'm not bothered about that, but it makes sense to fix it to avoid such errors in the future.

@fiepfiep
Copy link
Author

Is it possibly just that your name appears with and without uppercase letters? I'm not bothered about that, but it makes sense to fix it to avoid such errors in the future.

that seems to be the case indeed. i modified the commit signoff message + some of the checkpatch remarks. Hope it is ok now.

@pelwell
Copy link
Contributor

pelwell commented Apr 16, 2025

That's fixed it. I'll give these builds time to complete, in which time 6by9 may want to chip in, but I've been taking his silence for consent.

@6by9
Copy link
Contributor

6by9 commented Apr 16, 2025

That's fixed it. I'll give these builds time to complete, in which time 6by9 may want to chip in, but I've been taking his silence for consent.

No, just hadn't had a chance to look through.
It looks like several of my previous comments haven't been addressed, eg the overlay override cam0 still setting VANA-supply and changing vana-supply.

@fiepfiep
Copy link
Author

So - what are the next steps to get this driver into the raspberry linux kernel?
At the moment I'm only merging into the 6.12 kernel. What about older or newer kernel versions?
How does this driver propagate to official bookworm builds?

thanks.

Copy link
Contributor

@6by9 6by9 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In reading through to see if my previous comments had been addressed, add a number more.

There are a fair number of commented out blocks of code. They should be reviewed and removed where redundant.

@@ -934,6 +934,7 @@ CONFIG_VIDEO_BCM2835_UNICAM_LEGACY=m
CONFIG_VIDEO_BCM2835_UNICAM=m
CONFIG_VIDEO_ARDUCAM_64MP=m
CONFIG_VIDEO_ARDUCAM_PIVARIETY=m
CONFIG_VIDEO_MIRA220=m
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the move within Kconfig to keep everything in alphabetical order, I'm expecting this to be the wrong location in the defconfig.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right. will move to the line below the IMX sensors.

//MEDIA_BUS_FMT_Y8_1X8,
//MEDIA_BUS_FMT_Y10_1X10,
//MEDIA_BUS_FMT_Y12_1X12,
MEDIA_BUS_FMT_SGRBG8_1X8,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment just before this says that the sensor is monochrome, and yet you've used the GRBG Bayer pattern code. So which is it?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sensor comes both as RGB and mono. For now, I'm only doing the RGB.

reg_list = &mira220->mode->reg_list;
ret = cci_multi_reg_write(mira220->regmap, reg_list->regs,
reg_list->num_of_regs, NULL);
// ret = mira220_write_regs(mira220, reg_list->regs, reg_list->num_of_regs);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the now redundant line.

int ret = 0;

mutex_lock(&mira220->mutex);
if (mira220->streaming == enable) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should never be possible as the framework blocks it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you mean all mutex statements are not needed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mira220->streaming is not required. The framework should never call set_stream(..., 1) if the stream is already enabled, or set_stream(... , 0) if there wasn't also a previous call to set_stream(..., 1) that returned 0.

If that means you don't need the mutex, then that's a bonus.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, clear. Will fix that too.

struct mira220 *mira220 = to_mira220(sd);
int ret;

if (mira220->streaming) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resume shouldn't start streaming directly as the whole pipeline needs to be started correctly.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resume got deleted (unused)


// Make the vblank control read only. This could be changed to allow changing framerate in
// runtime, but would require adapting other settings
// mira220->vblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has changed in that you have VBLANK control, so remove the comment and the commented out code.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure.

(void)mira220;

regulator_bulk_disable(MIRA220_NUM_SUPPLIES, mira220->supplies);
clk_disable_unprepare(mira220->xclk);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clock and regulators are disabled in the opposite order to being prepared.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, will swap order.

return ret;
}

static int __maybe_unused mira220_suspend(struct device *dev)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both mira220_suspend and mira220_resume are totally unused. Remove them.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will remove them.

@6by9
Copy link
Contributor

6by9 commented Apr 16, 2025

So - what are the next steps to get this driver into the raspberry linux kernel? At the moment I'm only merging into the 6.12 kernel. What about older or newer kernel versions? How does this driver propagate to official bookworm builds?

Older kernels won't get updated.

Later kernels will get a forward port, as long as there aren't any significant build changes required by the every-changing kernel APIs. Simple changes are likely to get fixed up. Significant changes without obvious fixups will be reported back to you to fix - we don't undertake the full support burden of 3rd party drivers, and they may get dropped from the defconfigs if not fixed and/or get the BROKEN tag added to the Kconfig entry if the situation persists for a significant period.

rpi-update gets kernel updates normally several time a week.
Raspberry Pi OS gets updates every few months based on when significant things occur, providing no significant issues are known about at that point.

philippe baetens added 3 commits April 16, 2025 18:18
Adds defconfig for the Mira220 1600x1400 global
shutter image sensor

Signed-off-by: philippe baetens <[email protected]>
Adds an overlay for the Mira220 1600x1400 global
shutter image sensor

Signed-off-by: philippe baetens <[email protected]>
Adds a driver for the NIR-enhanced Mira220 1600x1400 global
shutter image sensor.

Signed-off-by: philippe baetens <[email protected]>
@pelwell
Copy link
Contributor

pelwell commented Apr 22, 2025

Some of @6by9's comments have yet to be addressed, but the overlay and general structure look okay to me.

@fiepfiep
Copy link
Author

fiepfiep commented Apr 22, 2025

Some of @6by9's comments have yet to be addressed, but the overlay and general structure look okay to me.

Thanks for reviewing. I believe I addressed all of @6by9's comments, but I might have missed something.. Can you be a bit more specific? thanks!

Also: each time I just 'force push' 3 new commits (overlay, conf, i2c driver) - not sure if this is your preferred way, or if you like to see my full commit history?

// Definitions for MIRA220 camera module on VC I2C bus


//#include <dt-bindings/gpio/gpio.h>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this commented out section left here for a reason? If so, explain why in a comment, otherwise delete.

@pelwell
Copy link
Contributor

pelwell commented Apr 22, 2025

philippe baetens added 2 commits April 23, 2025 23:58
Small fixes, mostly cosmetic.
Removed unneeded code.
Differentiate between physical array and active array.

Signed-off-by: philippe baetens <[email protected]>
Remove commented out code.

Signed-off-by: philippe baetens <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants