-
Notifications
You must be signed in to change notification settings - Fork 5k
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
Add support for Arducam OV64A40 64Mpx camera module #5708
Add support for Arducam OV64A40 64Mpx camera module #5708
Conversation
From a very quick review:
|
Hi Dave,
Ah! didn't know! I'll add it
deferring to @kbingham
Several changes compared to v1 sent to the ML. More or less from memory:
I plan to send a v2 of the driver to linux-media
user configurable link frequencies (I presume you mean through the associated control) allows to increase the frame rate, but for compatibility reasons with arducam produced accessories (I presume the csi-2 serializers) the lower frequency is selected by default.
Yeah, I should take care of that, before sending it to the ml probably
no, not intentional. What other defconfigs should I take care of ?
I should really add myself there Thanks for the feedback! |
Naush mentioned that you'd previously discussed something funny giving green images. I guess we ought to investigate.
If you send that, I'll do a review on it there. The ideal is for us to apply the accepted patch for this driver, but I appreciate that can take some time.
You don't hotplug serialisers, so isn't this better done in DT? Overlays support overrides, so you drop the link frequency if other factors require it. We've done something similar on imx708 as it was too close to GPS frequencies. (I've never understood why the choice of link frequency should ever be left to userspace). Normally I'd expect the serialisers and deserialisers to require DT entries of their own, but I can foresee how these have been implemented.
arm/configs/bcmrpi_defconfig is Pi 0&1 - probably skip that one as 512MB is too little RAM for these huge images. arm/configs/bcm2835_defconfig is the upstream defconfig, so please do NOT change that one. |
Are you suggesting then to use 456MHz as default and reduce the link frequency by using the |
Yes. Now I can predict the reality of how Arducam's serializer/deserializer has been implemented with some MCU configuring it all rather then letting Linux do it, but at least loading via I understand the choice of link frequency to be a system level decision, (eg the imx708 tweak to avoid interference with GPS signals) so why involve userspace? Unrelated, but just looking at the driver again, that I also noticed in passing that register 0x3f00 is set to the same value 3 times. |
That's true, I concur that selecting the link_frequency could easily be done with a dt param or in the overlay if needed. Let me check with arducam and try to use the highest link_freq by default
The chip supports address auto-increment, so for consecutive addresses it could be possible indeed to use REG32 or even REG64 to avoid repeating the "slave_address[7:0]" + "register[15:8] register[7:0]" bytes at the beginning of each transaction. Of course this will make it much harder to later untangle registers and move them away from register tables. Also, I suspect most of those registers are set to the POR default, but of course comparing each of them with the datasheet default values is a quite tedious and error-prone job. I see what I can do.
and 0x350b as well, and there might be others indeed |
Yes, absolutely - haven't got round to a next revision yet - but it's on my plate to look at this. Hopefully soon after I finish working on the IMX283. And I still envisage a set of VCM helpers to abstract all the vcm drivers out from all the parts that are common. There's very little module specific handling in vcm drivers as far as I can see so far. |
A quick update as I've had a more detailed look to that huge table.. Most registers there reported are undocumented in the datasheet version I have. There are very long sequences of undocumented registers initialized to the same identical values. I suspect those registers could probably be removed completely, but who knows... Back to the topic of re-assembling RGB8 into REG32 writes, being most registers undocumented, I cannot tell if registers are 8 bits or longer, even if all the documented ones I have are 8 bits. To be honest I'm not sure how to better move forward with that table, I understand that it's a very long startup delay, even more so because the suggested delay before streaming is started is a full frame exposure time, which at max resolution could go up to 500 milliseconds... |
I'd missed the delay added after sending You've had similar comments from Sakari on linux-media
If each of the modes includes the same set of registers rather than relying on defaults or the common list, then you can send the common list once in CCI is largely just specifying that the register address auto-increments on each byte written, therefore you can write a 32bit value via There's nothing stopping you extending that further to write as many consecutive bytes as happen to occur.
could become
Write that on the bus and 16 * 4 = 48 bytes transferred becomes 19 bytes for a 60% reduction in time. 32 consecutive registers would give a 64% saving (35 bytes instead of 96). CCI may be the current darling, but it doesn't solve all problems in the most efficient way. |
I can certainly do this to pay the long write price once only
It doesn't mention CCI, no suprises, but it reports a 'sequential write from random location" mode which is compatible
I got that part
It's not about CCI being pretty or not, it's about reworking a table of 4k entries most of them undocumented. As I presume those settings have been received from the manufacturer, I would be tempted to say that if the manufacturer is not happy with the startup performances of their sensor, they're very welcome to contribute to the driver and make it more performant. |
Knowing Omnivision and Sony, they'll have sent through a spreadsheet with settings. I'll leave it to you as you're going to be the listed maintainer. At least doing it only once removes most of the pain. See what further comments Sakari makes. |
I can only capture RAW on the pi5 due to the size of the images. In which format would you prefer to receive the images ? |
Ideally just the raw image data, but I can cope with a DNG or similar. If necessary I could probably generate an image of the relevant size, but having a genuine image removes one variable. |
yeah but you know on the pi5 I can either get 9152x6944-RG16 or 9152x6944-PC1R. Any preference ?
|
9152x6944-RG16 |
and to make it actually useful I should probably send you the full res (9248x6944) one that generates green images in some output resolutions And for your reference this a table of the results we had
|
e1a8e35
to
2529395
Compare
Changelog for this new version
|
2529395
to
b084d2c
Compare
I copied the overlay integration from fa45fc7 but dtoverlaycheck still fails. What am I missing ? |
arch/arm/boot/dts/overlays/README
Outdated
@@ -807,6 +807,7 @@ Params: cam0-arducam-64mp Select Arducam64MP for camera on port 0 | |||
cam0-imx708 Select IMX708 for camera on port 0 | |||
cam0-ov2311 Select OV2311 for camera on port 0 | |||
cam0-ov5647 Select OV5647 for camera on port 0 | |||
cam0-ov6a40 Select OV64A40 for camera on port 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These added parameters are all misnamed, but the overlay looks good once they've been renamed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh that was really stupid, sorry, I didn't notice. Fixed a re-pushed
b084d2c
to
c8d1e2c
Compare
Are you happy with this, @6by9? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The media subsystem requires checkpatch.pl --strict (https://elixir.free-electrons.com/linux/latest/source/Documentation/driver-api/media/maintainer-entry-profile.rst#L153), which flags up a couple of extra CHECKs
CHECK: multiple assignments should be avoided
#3111: FILE: drivers/media/i2c/ov64a40.c:3040:
+ fse->min_width = fse->max_width = mode->width;
CHECK: multiple assignments should be avoided
#3112: FILE: drivers/media/i2c/ov64a40.c:3041:
+ fse->min_height = fse->max_height = mode->height;
CHECK: Alignment should match open parenthesis
#3402: FILE: drivers/media/i2c/ov64a40.c:3331:
+ ov64a40->link_freq = v4l2_ctrl_new_int_menu(hdlr, &ov64a40_ctrl_ops,
+ V4L2_CID_LINK_FREQ,
CHECK: Alignment should match open parenthesis
#3414: FILE: drivers/media/i2c/ov64a40.c:3343:
+ ov64a40->hblank = v4l2_ctrl_new_std(hdlr, &ov64a40_ctrl_ops,
+ V4L2_CID_HBLANK, hblank_val, hblank_val, 1,
CHECK: Blank lines aren't necessary before a close brace '}'
#3505: FILE: drivers/media/i2c/ov64a40.c:3434:
+
+ }
CHECK: Alignment should match open parenthesis
#3525: FILE: drivers/media/i2c/ov64a40.c:3454:
+ ov64a40->link_frequencies = devm_kcalloc(ov64a40->dev,
+ v4l2_fwnode.nr_of_link_frequencies,
Other comments inline.
drivers/media/i2c/ov64a40.c
Outdated
OV64A40_EXPOSURE_MIN, exp_max, | ||
1, OV64A40_EXPOSURE_MIN); | ||
|
||
/* FIXME: see comment in init_ctrl about ppl multiplier. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume you mean ov64a40_init_controls
, but I'm not sure what there is to fix here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe not a FIXME but rather a note to explain why there's a ppl * 4 below
drivers/media/i2c/ov64a40.c
Outdated
/* | ||
* FIXME: When reporting HBLANK, we need to multiply PPL by 4 as the | ||
* sensor has an internal multiplier. Multiply PIXEL_RATE by 4 to | ||
* maintain a correct frame duration calculation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, what is there to fix? This appears to be a statement of how the sensor works internally rather than something that needs fixing.
Potentially more obvious is to define OV64A40_PIXEL_RATE to be the genuine pixel rate, and compensate when computing you delay in start_streaming.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, these might not be FIXME items.
It's not about the delay in start_streaming, it's about userspace compute a correct frame duration
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only other place OV64A40_PIXEL_RATE is used is in the delay at start streaming.
#define OV64A40_PIXEL_RATE 300000000
as that is the actual pixel rate, but your calc in start_streaming becomes
delay += DIV_ROUND_UP(timings->ppl * 4 * ov64a40->exposure->cur.val,
OV64A40_PIXEL_RATE / 1000 / 1000);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I'm anyway registering PIXEL_RATE * 4
as the control value, I can indeed do that
drivers/media/i2c/ov64a40.c
Outdated
#define OV64A40_PLL2_DIVSP CCI_REG8(0x032d) | ||
#define OV64A40_PLL2_DACPREDIV CCI_REG8(0x032e) | ||
|
||
/* FIXME: validate vblank_min! */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When is that being validated and by whom?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
again this was a note to record the min vblank is not characterized in the datasheet
drivers/media/i2c/ov64a40.c
Outdated
ctrl->val >> 7, &ret); | ||
cci_write(ov64a40->cci, OV64A40_REG_MEC_LONG_GAIN_FINE, | ||
(ctrl->val & 0x7f) << 1, &ret); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't that just a CCI16 write of ctrl->val << 1
, or are the two registers the wrong way round?
Nit pick: comment says xxx_GAIN, whilst the register is GAIN_xxx.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The coarse gain is 7 bits long. We should be safe as we define a max value for the control and could probably write this in one go, but if you don't particularly mind, I would keep it this way to be explicit on how the registers are assembled
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ctrl_handler does guarantee that the value will remain in range.
Swapping to
#define OV64A40_REG_MEC_LONG_GAIN CCI_REG16(0x3508)
...
cci_write(ov64a40->cci, OV64A40_REG_MEC_LONG_GAIN, ctrl->val << 1, &ret);
gets rid of ov64a40_set_anagain
totally.
It felt fairly arbitrary that V4L2_CID_VBLANK was written out in full in ov64a40_set_ctrl
, but V4L2_CID_ANALOGUE_GAIN was split out as a separate function.
{ CCI_REG8(0x4888), 0x10 }, { CCI_REG8(0x4860), 0x00 }, | ||
{ CCI_REG8(0x4850), 0x43 }, { CCI_REG8(0x480C), 0x92 }, | ||
{ CCI_REG8(0x5001), 0x21 } | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This table is far shorter than the other mode reg_lists. Now that you're not sending ov64a40_init with the CCI_REG8(0x0103), 0x01
reset every time you start_streaming, do none of the extra settings matter in this mode such that a mode switch from another mode to it still works correctly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can only rely on the registers list received from the vendor so I trust they are correct but I can try to start two streaming sessions one after the other with different settings
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do.
Currently if you set mode 4624x3472, start_streaming, stop_streaming, set mode 9248x6944, start_streaming, then the first mode set will have written registers 0x034b, 0x3504, 0x360d, 0x368a, etc to a value that may or may not be the default, but are then not reset to the default on starting the second mode.
With no datasheet and no sensor I can't say if they're the defaults or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right and mixing modes doesn't work as expected.
I tried expanding the 9248x6944 by resetting registers to the values specified in the init table, but that's not enough as I get sub-optimal results (all white frames, or hangs) depending on how I alternate modes.
Again, most registers are not documented and I just a confirmation from Arducam that there are no plans to reduce the register table sizes compared to what OV provided and which gives the best results.
All in all, I'm going to re-write the full init table at start_stream time, as I cannot possibly test all the combinations of modes and check which undocumented register has been overwritten or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Up to you.
Personally I would have dumped the default values of all the registers written by any of these mode specific tables, and then added the default values to the tables wherever the register is missing.
drivers/media/i2c/ov64a40.c
Outdated
#define OV64A40_PLL1_PRE_DIV0 CCI_REG8(0x0301) | ||
#define OV64A40_PLL1_PRE_DIV CCI_REG8(0x0303) | ||
#define OV64A40_PLL1_MULTIPLIER_H CCI_REG8(0x0304) | ||
#define OV64A40_PLL1_MULTIPLIER_L CCI_REG8(0x0305) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this not a CCI_REG16 for PLL1_MULTIPLIER? Ditto PLL2_MULTIPLIER below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, but since these are written once only per streaming session I don't think it makes a difference ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could say that about any register though, so why bother with CCI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does CCI have to do with this ? It's the second salty comment about CCI, what's wrong with it ? it saves every driver from re-implementing the same write/read routines, I guess that's a win. Anywa if these two registers bother you particularly, I can change them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
combining split high/low registers to a single value makes things clearer and easier to comprehend IMO. That's what I particularly like about CCI_REG16() at least.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does CCI have to do with this ? It's the second salty comment about CCI, what's wrong with it ? it saves every driver from re-implementing the same write/read routines, I guess that's a win. Anywa if these two registers bother you particularly, I can change them.
I'm making comments on the patch as I'm reading through. You're using the CCI framework, but there appears to be interpretations of the register map that have been missed.
I'd make exactly the same comment if I was reading and reviewing it on linux-media (I'm happy to review the patches sent there if you'd prefer).
The other issue over the length of the init table is that I'd like to see efficient system performance, and over sending I2C commands is quite a long way from that. It's nothing against CCI per se, just that it's not a great fit there.
drivers/media/i2c/ov64a40.c
Outdated
|
||
#define OV64A40_REG_MEC_LONG_GAIN_COARSE CCI_REG8(0x3508) | ||
#define OV64A40_REG_MEC_LONG_GAIN_FINE CCI_REG8(0x3509) | ||
#define OV64A40_ANA_GAIN_MIN 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your cam_helper says the gain code is gain * 128
, so do values below 128 (ie below unity gain) actually work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might have missed why they shouldn't..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@davidplowman will correct me I'm sure, but aiui what would the point be of capturing the photons, potentially saturating the well and blowing out the image, and then reducing the amplitude of that image. If you really want that, apply a <x1.0 digital gain later.
A value of 0 for x0.0 would give a totally black image.
Very few sensors actually do sensible things with analogue gain <x1.0, hence my question of whether it works or not. Sony and OnSemi tend to use the weird gain formulae as then a register value of 0 falls out as x1.0.
#define OV64A40_REG_MEC_LONG_GAIN_COARSE CCI_REG8(0x3508) | ||
#define OV64A40_REG_MEC_LONG_GAIN_FINE CCI_REG8(0x3509) | ||
#define OV64A40_ANA_GAIN_MIN 0 | ||
#define OV64A40_ANA_GAIN_MAX 0x7ff |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Observation: Max here is 0x7ff, or x15.99. set_anagain
says that COARSE_GAIN (ie the integer bit) is 7 bits wide, which would allow x127.99.
Is this just sloppiness in the datasheet, and the top 3 bits of COARSE_GAIN are required to be 0 then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably it's a datasheet issue. Arducam has tested all the supported gain values and found that values larger than 0x7ff corrupts the image and required to reduce max gain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
x15.99 sounds a fairly typical max analogue gain.
Potentially a cleanup of the comment below over how many bits are available for COARSE_GAIN.
drivers/media/i2c/ov64a40.c
Outdated
OV64A40_EXPOSURE_MIN, exp_max, 1, | ||
OV64A40_EXPOSURE_MIN); | ||
|
||
hblank_val = OV64A40_PLL_DEFAULT * 4 - ov64a40->mode->width; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OV64A40_PLL_DEFAULT as 0x1480 is only valid on a 360MHz link frequency in full res mode.
Use ov64a40_get_timings
to get the actual ppl of the mode, otherwise the initial mode is going to have the wrong HBLANK if on a 456MHz link freq. (It also means that OV64A40_PLL_DEFAULT is redundant).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah right, thanks
I had to chose between going > 80 cols or non aligning to the open parenthesis. Knowing Sakari cares a lot about 80 cols, I went for the second option |
They are only CHECKs, but I expect you'd get the same query in a review on linux-media. You're permitted to split the line after the
complies with both requirements. hblank is just splitting the lists of parameters in different places
likewise is permitted. As for multiple assignments, it's only 2 extra lines of code. I give up arguing at that point.
|
drivers/media/i2c/ov64a40.c
Outdated
.timings_default = { | ||
/* 2.6 FPS */ | ||
[OV64A40_LINK_FREQ_456M_ID] = { | ||
.vts = 0x1ba0, /* 7072 */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant to ask this before. But why do you use hex values here and then a /* comment */ to state the value in decimal? Why not just use the decimal value? To me that's more readable - and doesn't need a comment to state the hex value - so the two wouldn't ever get out of sync.
The units on these vts/ppl/top/left entries make far more sense in decimal...
drivers/media/i2c/ov64a40.c
Outdated
}, | ||
.digital_crop = { | ||
.left = 0x11, | ||
.top = 0x10, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Particularly here - I don't think we should mix and match hex and decimal ... decimal values make more sense all through.
I'd linked to test firmware back in #5708 (comment) I've just kicked the firmware builds again, and it's been merged. We release firmware and prebuilt kernels together through https://github.com/raspberrypi/rpi-firmware, so as long the firmware change is merged before this PR (which it has been), then you'll get both together. Up to you when you test the firmware change. |
<&csi_frag>, "target:0=",<&csi0>, | ||
<&clk_frag>, "target:0=",<&cam0_clk>, | ||
<&cam_node>, "clocks:0=",<&cam0_clk>, | ||
<&cam_node>, "VANA-supply:0=",<&cam0_reg>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the name is spelled wrong here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does look like it should be avdd-supply
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, thanks for spotting. Fixed in next version.
Executing
but downloaded and decompressed it and updated it to the expected version,
and the 64mp capture was normal, and the all-green picture no longer appeared: |
f6077e9
to
fef62d7
Compare
OK to merge, @6by9? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Passing comment on the new mode looking odd. If you say that is the mode you want, then fine by me.
Everything else looks fine.
drivers/media/i2c/ov64a40.c
Outdated
.analogue_crop = { | ||
.left = 624, | ||
.top = 472, | ||
.width = 8671, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
left + width = 624 + 8671 = 9295. Isn't the sensor only 9286 wide?
top + height = 472 + 6503 = 6975. The sensor is 6976 pixels high.
So this isn't a centre crop as would normally be expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
left + width = 624 + 8671 = 9295. Isn't the sensor only 9286 wide? top + height = 472 + 6503 = 6975. The sensor is 6976 pixels high.
So this isn't a centre crop as would normally be expected.
After reading the code, width is actually horizontal_end, and it does not add left.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ArduCAM who has provided me the mode info
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I'll leave it to the end of the day for a response, but otherwise I'm happy to merge.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's really horizontal_end as Arducam say, then the variables should be named appropriately. width
and height
have fairly obvious meanings which don't match the use here. Doubly confusing as width
and height
in digital_crop do appear to be the width and height of the region.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ooook
I'll rename
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah wait, it's a struct v4l2_rect
I can't pick arbitrary name and I don't think it's worth defining a dedicated type just for this (I'm sure someone would ask during review why a custom type is needed)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In which case make it actually represent width and height, and do the maths to compute OV64A40_REG_TIMING_CTRL4 and OV64A40_REG_TIMING_CTRL6 in ov64a40_program_geometry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
width is actually horizontal_end, and it does not add left. |
rotation = <&cam_node>,"rotation:0"; | ||
orientation = <&cam_node>,"orientation:0"; | ||
media-controller = <&csi>,"brcm,media-controller?"; | ||
cam0 = <&i2c_frag>, "target:0=",<&i2c_vc>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cam0 = <&i2c_frag>, "target:0=",<&i2c_vc>,
The i2c_vc
here should be replaced by i2c_csi_dsi0
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ups. I wonder where this comes from as no other overlay uses i2c_vc
.
I'll fix, sorry for the hiccup
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated for Pi5.
i2c_vc is GPIOs 0&1, and on Pi0-4 will also be aliased to i2c_csi_dsi0.
On Pi5 both i2c_csi_dsi and i2c_csi_dsi0 are dedicated I2C buses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does it mean it is correct to use i2c_csi_dsi0
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does it mean it is correct to use
i2c_csi_dsi0
?
@6by9 can you confirm this so I can send a new version and possibly send the same driver version to mainline this morning ?
drivers/media/i2c/ov64a40.c
Outdated
.analogue_crop = { | ||
.left = 624, | ||
.top = 472, | ||
.width = 8671, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
left + width = 624 + 8671 = 9295. Isn't the sensor only 9286 wide? top + height = 472 + 6503 = 6975. The sensor is 6976 pixels high.
So this isn't a centre crop as would normally be expected.
After reading the code, width is actually horizontal_end, and it does not add left.
Okay, it looks like I forgot to submit a review. . (not very familiar with GitHub’s review process...) |
In addition, can we enable pi zero compilation by default? Although large resolution cannot be used, small resolution can be used normally (to avoid receiving complaints from users that the camera cannot be detected) |
According to https://www.raspberrypi.com/documentation/computers/linux_kernel.html#default_configuration I should enable the sensor and the lens compilation for |
Without suitable warnings I think you're going to get just as many complaints that the default behaviour of rpicam-still in selecting the highest resolution mode for the still capture fails as for not being detected.
I haven't checked the module sizes, but it's not going to make a huge difference if enabled on Pi0&1. Largely it comes down to Arducam documenting what can and can't work. As it's a third party sensor it won't be in our docs. |
The CSI2 specification specifies a standard method to access camera sensor registers called "Camera Control Interface (CCI)". This uses either 8 or 16 bit (big-endian wire order) register addresses and supports 8, 16, 24 or 32 bit (big-endian wire order) register widths. Currently a lot of Linux camera sensor drivers all have their own custom helpers for this, often copy and pasted from other drivers. Add a set of generic helpers for this so that all sensor drivers can switch to a single common implementation. These helpers take an extra optional "int *err" function parameter, this can be used to chain a bunch of register accesses together with only a single error check at the end, rather than needing to error check each individual register access. The first failing call will set the contents of err to a non 0 value and all other calls will then become no-ops. Link: https://lore.kernel.org/linux-media/[email protected]/ Reviewed-by: Andy Shevchenko <[email protected]> Tested-by: Tommaso Merciai <[email protected]> Reviewed-by: Tommaso Merciai <[email protected]> Signed-off-by: Hans de Goede <[email protected]> Signed-off-by: Sakari Ailus <[email protected]> Signed-off-by: Mauro Carvalho Chehab <[email protected]> (cherry picked from commit 613cbb9)
Add bindings for OmniVision OV64A40. Signed-off-by: Jacopo Mondi <[email protected]>
Add YAML device tree bindings for the ROHM BU64754 VCM Motor Driver for Camera Autofocus. Signed-off-by: Kieran Bingham <[email protected]> Signed-off-by: Jacopo Mondi <[email protected]>
Add a driver for the OmniVision OV64A40 image sensor. Signed-off-by: Jacopo Mondi <[email protected]>
Add support for the ROHM BU64754 Motor Driver for Camera Autofocus. A V4L2 Subdevice is registered and provides a single V4L2_CID_FOCUS_ABSOLUTE control. Signed-off-by: Kieran Bingham <[email protected]> Signed-off-by: Jacopo Mondi <[email protected]>
Arducam have integrated an Omnivision OV64A40 with a ROHM BU64754 VCM with a Raspberry Pi compatible cable pinout. Provide an overlay to support the module. Also add support to the camera mux overlays. Signed-off-by: Jacopo Mondi <[email protected]> Signed-off-by: Kieran Bingham <[email protected]>
Compile both the OV64A40 and the BU64754 drivers used by the Arducam 64MP camera module based as modules in the defconfig files for - rpi5 - rpi4 - rpi2/3 - rpi1/0 Signed-off-by: Jacopo Mondi <[email protected]>
fef62d7
to
0f7705a
Compare
Hopefully this should be the last version ? I'll send the same version of the sensor driver to mainline. Any requested change that doesn't dramatically impact the driver can be later backported on the version merged here ? |
Looks good - thanks. @pelwell anything else you want to raise? Otherwise hit the merge button. |
No - I think we've been round the loop often enough. Merging. |
Just a thought over the analogue crops before you send your patch set to the mailing list. You've defined the widths and heights as odd numbers. That is almost certainly incorrect as it messes up Bayer orders with flips. The conversion from left and width to end pixel is normally |
Too late :)
Correct. You can comment there and I can fix it, then send a patch on top for your bsp ? (I already have one smatch warning fixed in the mainline version and not here. Sorry, but keeping the two in sync is rather painful) |
You hadn't sent the patch when I started the comment, so had nowhere else to post it. Happy to shift to mailing list review comments now, and we can fix up this tree once it gets merged. |
kernel: configs: rpi: Compile TSC2007 as module See: raspberrypi/linux#5776 kernel: Cfe improvements See: raspberrypi/linux#5632 kernel: Add support for Arducam OV64A40 64Mpx camera module See: raspberrypi/linux#5708 kernel: 2712 MOP/MOPlet fixes See: raspberrypi/linux#5773 kernel: dts: bcm2712: put usb under /axi not /soc See: raspberrypi/linux#5772
kernel: configs: rpi: Compile TSC2007 as module See: raspberrypi/linux#5776 kernel: Cfe improvements See: raspberrypi/linux#5632 kernel: Add support for Arducam OV64A40 64Mpx camera module See: raspberrypi/linux#5708 kernel: 2712 MOP/MOPlet fixes See: raspberrypi/linux#5773 kernel: dts: bcm2712: put usb under /axi not /soc See: raspberrypi/linux#5772
Hello,
this pull request adds support for the Arducam OV64A40 camera module by providing a driver for the sensor and the lens driver.
The driver uses the CCI helpers which are included in the pull request.
Support for the driver has been sent upstream but not yet included in linux-media.