Thread (15 messages) 15 messages, 4 authors, 2024-02-27

Re: [PATCH v4 2/2] media: i2c: Add GC08A3 image sensor driver

From: Zhi Mao (毛智) <zhi.mao@mediatek.com>
Date: 2024-02-27 01:36:29
Also in: linux-devicetree, linux-media, linux-mediatek, lkml

Hi Sakari,

Thanks for your feedback.

On Wed, 2024-02-21 at 07:43 +0000, sakari.ailus@linux.intel.com wrote:
 	 
External email : Please do not click links or open attachments until
you have verified the sender or the content.
 Hi Zhi,

On Wed, Feb 21, 2024 at 02:37:27AM +0000, Zhi Mao (毛智) wrote:
quoted
Hi Laurent & sakari,

Thanks for your feedback.

On Tue, 2024-02-20 at 07:25 +0000, sakari.ailus@linux.intel.com
wrote:
quoted
quoted
  
External email : Please do not click links or open attachments
until
quoted
quoted
you have verified the sender or the content.
 Hi Zhi,

On Tue, Feb 20, 2024 at 05:45:54AM +0000, Zhi Mao (毛智) wrote:
quoted
Hi Laurent,

Thanks for you reply.
I'd like to ask for advice about how to contrl "reset-pin",
please
quoted
quoted
quoted
check the below comments.

On Tue, 2024-02-20 at 05:01 +0200, Laurent Pinchart wrote:
quoted
  
External email : Please do not click links or open
attachments
quoted
quoted
until
quoted
quoted
you have verified the sender or the content.
 Hi Zhi,

On Tue, Feb 20, 2024 at 02:12:26AM +0000, Zhi Mao (毛智) wrote:
quoted
On Tue, 2024-02-06 at 20:45 +0200, Laurent Pinchart wrote:
quoted
On Sun, Feb 04, 2024 at 02:15:38PM +0800, Zhi Mao wrote:
quoted
Add a V4L2 sub-device driver for Galaxycore GC08A3
image
quoted
quoted
quoted
quoted
sensor.
quoted
quoted
quoted
Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
---
 drivers/media/i2c/Kconfig  |   10 +
 drivers/media/i2c/Makefile |    1 +
 drivers/media/i2c/gc08a3.c | 1448
++++++++++++++++++++++++++++++++++++
quoted
quoted
quoted
 3 files changed, 1459 insertions(+)
 create mode 100644 drivers/media/i2c/gc08a3.c
[snip]
quoted
quoted
quoted
diff --git a/drivers/media/i2c/gc08a3.c
b/drivers/media/i2c/gc08a3.c
quoted
quoted
quoted
new file mode 100644
index 000000000000..3fc7fffb815c
--- /dev/null
+++ b/drivers/media/i2c/gc08a3.c
@@ -0,0 +1,1448 @@
[snip]
quoted
quoted
quoted
+static int gc08a3_power_on(struct device *dev)
+{
+struct i2c_client *client = to_i2c_client(dev);
+struct v4l2_subdev *sd = i2c_get_clientdata(client);
+struct gc08a3 *gc08a3 = to_gc08a3(sd);
+int ret;
+
+ret =
regulator_bulk_enable(ARRAY_SIZE(gc08a3_supply_name),
quoted
quoted
quoted
quoted
quoted
+    gc08a3->supplies);
+if (ret < 0) {
+dev_err(gc08a3->dev, "failed to enable regulators:
%d\n",
quoted
quoted
quoted
quoted
ret);
quoted
quoted
quoted
+return ret;
+}
+
+ret = clk_prepare_enable(gc08a3->xclk);
+if (ret < 0) {
+regulator_bulk_disable(ARRAY_SIZE(gc08a3_supply_name),
+       gc08a3->supplies);
+dev_err(gc08a3->dev, "clk prepare enable failed\n");
+return ret;
+}
+
+usleep_range(GC08A3_MIN_SLEEP_US,
GC08A3_MAX_SLEEP_US);
quoted
quoted
quoted
quoted
quoted
quoted
quoted
+
+gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);
Are you asserting reset when powering on ? That sounds
wrong,
quoted
quoted
you
quoted
quoted
should
quoted
quoted
de-assert reset here (and acquire the reset gpio in
probe()
quoted
quoted
with
quoted
quoted
quoted
quoted
GPIOD_OUT_HIGH). Drivers should use logical levels for
GPIOs,
quoted
quoted
quoted
quoted
setting a
quoted
quoted
GPIO named "reset" to 1 should assert the reset signal,
even
quoted
quoted
if
quoted
quoted
the
quoted
quoted
physical signal is active low. You may have the wrong
polarity in
quoted
quoted
the
quoted
quoted
device tree.
According to the sensor power sequence sepc, "reset" pin
should
quoted
quoted
be
quoted
quoted
pull
quoted
from low to high after "dovdd/dvdd/avdd" power on, so I
follow
quoted
quoted
this
quoted
quoted
quoted
power sequece to pull "reset" pin high in software flow.
From a hardware point of view that's right, but the Linux
kernel
quoted
quoted
quoted
quoted
handles
logical level of GPIOs. If a GPIO is named "reset", it is
expected
quoted
quoted
that
calling

gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);

will "assert" the reset signal, setting it to a logical
"reset =
quoted
quoted
quoted
quoted
true"
level. This maps to the hardware 0V output level, as the
signal
quoted
quoted
is
quoted
quoted
active-low. To achieve this, define the reset GPIO as active
low
quoted
quoted
in
quoted
quoted
DT,
and the GPIO framework will invert the signal for you. You
should
quoted
quoted
quoted
quoted
then
call

gpiod_set_value_cansleep(gc08a3->reset_gpio, 1);

in the driver when you want to assert reset (set it to 0V),
and
quoted
quoted
quoted
quoted
gpiod_set_value_cansleep(gc08a3->reset_gpio, 0);

when you want to deassert it (set it to 3.3V, or whatever the
I/O
quoted
quoted
quoted
quoted
voltage for the signal is).

This way all driver use logical states, and the inversion is
handled
quoted
quoted
in
DT.
Sensor power sequence as below:
                      ------------------
                     | | |
                     | | | 
dvdd/avdd/dovdd  --------
                               ---------
                              |
                              |
reset-pin        -------------

In order to match this power sequece, "reset-pin" contrl flow
is
quoted
quoted
below:
quoted
1. config the "reset-pin" is "active-high" in DTS:
    reset-gpios = <&pio 19 GPIO_ACTIVE_HIGH>;

2. image sensor driver probe function:
gc08a3->reset_gpio = devm_gpiod_get(dev, "reset",
GPIOD_OUT_LOW);  //init "reset-pin" is low

3. image sensor driver power_on function:
gpiod_set_value_cansleep(gc08a3->reset_gpio, 1); //pull "reset-
pin"
quoted
quoted
quoted
high 

so, the expect state of "reset-pin" is from low to high.
If I am wrong, please correct me.

From Documentation/driver-api/gpio/consumer.rst:

As a consumer should not have to care about the physical line
level, all of the gpiod_set_value_xxx() or
gpiod_set_array_value_xxx() functions operate with the *logical*
value. With this they take the active low property into account.
This means that they check whether the GPIO is configured to be
active low, and if so, they manipulate the passed value before
the
quoted
quoted
physical line level is driven.

I.e. when you want to enable reset, you set the value to 1 in the
driver. I
think you're now setting the value to 0 in that case. The
opposite
quoted
quoted
for
disabling it of course.
After checking "Documentation/driver-api/gpio/consumer.rst":
To summarize::
  Function (example)                 line
property          physical
quoted
line
...
  gpiod_set_value(desc, 1);          default (active high)  high
  gpiod_set_value(desc, 0);          active low             high
...


From my understanding, it seems that "reset-pin" is using the
following(active_high) case in current code: 
"gpiod_set_value(desc, 1);          default (active high)  high" 

Do you mean, we should use the "active_low" case:
"gpiod_set_value(desc, 0);          active low             high"
Code should be changed as below:
1. config the "reset-pin" is "active-low" in DTS:
   - reset-gpios = <&pio 19 GPIO_ACTIVE_LOW>
2. image sensor driver power_on function:
   - gpiod_set_value_cansleep(gc08a3->reset_gpio, 0); //pull high 
Is that so?
Correct.
fixed in patch:v6
-- 
Regards,

Sakari Ailus
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help