Re: [PATCH v9 1/1] media: i2c: Add Omnivision OV02C10 sensor driver

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

 



Hi Sakari,

On 19-Mar-25 4:16 PM, Sakari Ailus wrote:
> Hi Hans,
> 
> On Wed, Mar 19, 2025 at 03:59:31PM +0100, Hans de Goede wrote:
>> Hi Sakari,
>>
>> On 14-Mar-25 1:46 PM, Sakari Ailus wrote:
>>> Hi Hans,
>>>
>>> Thanks for the update.
>>>
>>> On Fri, Mar 14, 2025 at 11:11:25AM +0100, Hans de Goede wrote:
>>>> From: Heimir Thor Sverrisson <heimir.sverrisson@xxxxxxxxx>
>>>>
>>>> Add a new driver for the Omnivision OV02C10 camera sensor. This is based
>>>> on the out of tree driver by Hao Yao <hao.yao@xxxxxxxxx> from:
>>>> https://github.com/intel/ipu6-drivers/blob/master/drivers/media/i2c/ov02c10.c
>>>>
>>>> This has been tested on a Dell XPS 9440 together with the IPU6 isys CSI
>>>> driver and the libcamera software ISP code.
>>>>
>>>> Tested-by: Ingvar Hagelund <ingvar@xxxxxxxxxxxxxxxxxx>
>>>> Signed-off-by: Heimir Thor Sverrisson <heimir.sverrisson@xxxxxxxxx>
>>>> Co-developed-by: Hans de Goede <hdegoede@xxxxxxxxxx>
>>>> Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx>
>>
>> <snip>
>>
>>>> diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c
>>>> new file mode 100644
>>>> index 000000000000..5626aa2fe62c
>>>> --- /dev/null
>>>> +++ b/drivers/media/i2c/ov02c10.c
>>>> @@ -0,0 +1,1012 @@
>>
>> <snip>
>>
>>>> +static const struct reg_sequence sensor_1928x1092_30fps_setting[] = {
>>>
>>> Could you use struct cci_reg_sequence for this?
>>>
>>>> +	{0x0301, 0x08},
>>>
>>> { CCI_REG8(0x0301), 0x08 },
>>>
>>> etc.
>>>
>>> That would also enable using human-readable names in this list.
>>
>> TBH I would rather not, adding the CCI_REGx everywhere will make
>> it harder to keep the out of tree code in sync with this, using
>> raw struct reg_sequence combined with regmap_multi_reg_write()
>> is sort of the norm for drivers converted to the CCI helpers.
>>
>> Also while using symbolic register names (defines) greatly
>> improves the readability of other code accessing the registers,
>> I find it unhelpful for these large just send a bunch of
>> register values to the sensor cases, especially since for many
>> of the addresses we've no clue what we're sending / what 
>> the register does.
> 
> That's true for the undocumented ones (and this being an OV sensor, there
> are many) but for the rest it's helpful.
> 
> I presume there's no need for updating downstream drivers after we have one
> in upstream?

Well Intel's camera team has a habit of adding downstream changes
to drivers after they have been mainlined to e.g. support a different
CSI lane count.

Or even just downstream patches to driver which they never had in their
downstream repo, see e.g. the patches for ov13b10 and ov08x40 here:

https://github.com/intel/ipu6-drivers/tree/master/patch/v6.12

>>>> +	{0x0303, 0x06},
>>>> +	{0x0304, 0x01},
>>>> +	{0x0305, 0xe0},
>>
>> <snip>
>>
>>>> +};
>>>> +
>>>> +static const struct reg_sequence sensor_1928x1092_30fps_1lane_setting[] = {
>>>> +	{0x301b, 0xd2},
>>>> +	{0x3027, 0xe1},
>>>> +	{0x380c, 0x08},
>>>> +	{0x380d, 0xe8},
>>>> +	{0x380e, 0x04},
>>>> +	{0x380f, 0x8c},
>>>> +	{0x394e, 0x0b},
>>>> +	{0x4800, 0x24},
>>>> +	{0x5000, 0xf5},
>>>> +	/* plls */
>>>> +	{0x0303, 0x05},
>>>> +	{0x0305, 0x90},
>>>> +	{0x0316, 0x90},
>>>> +	{0x3016, 0x12},
>>>> +};
>>>> +
>>>> +static const struct reg_sequence sensor_1928x1092_30fps_2lane_setting[] = {
>>>> +	{0x301b, 0xf0},
>>>> +	{0x3027, 0xf1},
>>>> +	{0x380c, 0x04},
>>>> +	{0x380d, 0x74},
>>>> +	{0x380e, 0x09},
>>>> +	{0x380f, 0x18},
>>>> +	{0x394e, 0x0a},
>>>> +	{0x4041, 0x20},
>>>> +	{0x4884, 0x04},
>>>> +	{0x4800, 0x64},
>>>> +	{0x4d00, 0x03},
>>>> +	{0x4d01, 0xd8},
>>>> +	{0x4d02, 0xba},
>>>> +	{0x4d03, 0xa0},
>>>> +	{0x4d04, 0xb7},
>>>> +	{0x4d05, 0x34},
>>>> +	{0x4d0d, 0x00},
>>>> +	{0x5000, 0xfd},
>>>> +	{0x481f, 0x30},
>>>
>>> It's surprising to have more registers when the number of lanes is 2. I
>>> guess for 1 lane case it's using defaults?
>>
>> I guess so. At your request I split the registers which were
>> different for the 1 / 2 lane cases into 2 separate register lists
>> and some register writes where only in the long 2 lane register list
>> of the previous version.
> 
> Ok. Adding further modes later on will require addressing this.
> 
>>
>>>> +static int ov02c10_test_pattern(struct ov02c10 *ov02c10, int pattern)
>>>> +{
>>>> +	int ret = 0;
>>>> +
>>>> +	if (!pattern)
>>>> +		return cci_update_bits(ov02c10->regmap, OV02C10_REG_TEST_PATTERN,
>>>> +				       BIT(7), 0, NULL);
>>>> +
>>>> +	cci_update_bits(ov02c10->regmap, OV02C10_REG_TEST_PATTERN,
>>>> +			0x03, pattern - 1, &ret);
>>>> +	cci_update_bits(ov02c10->regmap, OV02C10_REG_TEST_PATTERN,
>>>> +			BIT(7), OV02C10_TEST_PATTERN_ENABLE, &ret);
>>>
>>> I'd do here:
>>>
>>> 	return cci_update_bits(...);
>>
>> Since we are relying on the error preserving / propagating
>> behavior of the CCI helpers here that feels weird / inconsistent,
>> I would expect either:
>>
>> 	ret = cci_update_bits(ov02c10->regmap, OV02C10_REG_TEST_PATTERN,
>> 			      0x03, pattern - 1, NULL);
>> 	if (ret)
>> 		return ret;
>>
>> 	return cci_update_bits(ov02c10->regmap, OV02C10_REG_TEST_PATTERN,
>> 			       BIT(7), OV02C10_TEST_PATTERN_ENABLE, NULL);
>> }
>>
>> or:
>>
>> 	cci_update_bits(ov02c10->regmap, OV02C10_REG_TEST_PATTERN,
>> 			0x03, pattern - 1, &ret);
>> 	cci_update_bits(ov02c10->regmap, OV02C10_REG_TEST_PATTERN,
>> 			BIT(7), OV02C10_TEST_PATTERN_ENABLE, &ret);
>> 	return ret;
>> }
>>
>> not a mix of the 2, with my preference going to the latter.
> 
> Works for me, too, although I expect someone, will come some day and submit
> a cleanup patch for this. :-)
> 
> I'm ok with v10, I guess further cleanup can be done if / when more
> functionality is added.

That is good to hear, thank you.

Regards,

Hans






[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