Camera driver GPIO control

Hi,

I developed a custom camera driver for a dual camera setup and so far the kernel is compiling. The issue I have now is that I don’t know how to correctly control the camera.

To power on the camera, I use a I2C to GPIO expander where my power-on pin is (lets say, located at pin 8) and the pin to enable the oscillator (pin 9).
This will trigger the power sequencer chip on the PCB of the camera. Next I have to put the XCLR to high and start the INCK clock.

In the device tree I added the GPIO expander as defined in the e3333 driver example. In the I2C driver I have this as my power on function (mainly copied from the IMX274 or IMX185 driver):

static int imx392_power_on(struct camera_common_data *s_data) {
	int err = 0;
	struct camera_common_power_rail *pw = s_data->power;
	struct camera_common_pdata *pdata = s_data->pdata;
	struct device *dev = s_data->dev;

	dev_dbg(dev, "%s: power on\n", __func__);
	if (pdata && pdata->power_on) {
		err = pdata->power_on(pw);
		if (err)
			dev_err(dev, "%s failed.\n", __func__);
		else
			pw->state = SWITCH_ON;
		return err;
	};

	/*exit reset mode: XCLR */
	if (pw->reset_gpio) {
		gpio_set_value(pw->reset_gpio, 0);
		usleep_range(10, 50);
		gpio_set_value(pw->reset_gpio, 1);
		usleep_range(30, 50);
	};

	pw->state = SWITCH_ON;
	return 0;
};

My question here is, how do I know that it will turn on the power pin and how do I add the INCK pin?

hello FPSUsername,

you’ll also need gpio definition in device tree, please check reference drivers for GPIO implementation.
for example,
here’s how imx274 driver control reset-gpios.

<i>$l4t-r32.2/kerenl_src/kernel/nvidia/drivers/media/i2c/imx274.c</i>

        board_priv_pdata->reset_gpio = of_get_named_gpio(node,
                        "reset-gpios", 0);
        ...
        if (pw->reset_gpio)
                gpio_set_value(pw->reset_gpio, 0);

<i>$l4t-r32.2/kerenl_src/hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-quill-camera-imx274-a00.dtsi</i>

        reset-gpios = <&tegra_main_gpio CAM0_RST_L GPIO_ACTIVE_HIGH>;

Thank you!

I now understand where the GPIO names come from in the I2C driver.

I do have one other question regarding the GPIO pins. Each sensor can have a different address by simply switching a pin to high or low. This would mean that each sensor will have this one slight difference which could be solved as following:

<i>$l4t-r32.2/kerenl_src/hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-quill-camera-imx392-a00.dtsi</i>

    imx392_a@36 {
        address-gpios = <&tca9539_74 addr_0 GPIO_ACTIVE_LOW>;
    };
    imx392_b@37 {
       address-gpios = <&tca9539_74 addr_1 GPIO_ACTIVE_HIGH>;
    };

The problem with this is that it will interfere with the way the sensor will be powered on and off.

When the address gpio is set to 1, the output will be high for one of the sensors. When the sensor is about to turn off, all the GPIOs should be set to low or high impedance. This would mean that if the address gpio is set to 0, one of the sensors will get a high signal, which isn’t supposed to happen.

An other way is to just not define the address gpio in the specific sensor where it just has to be low.

What would be a proper way to approach this?

hello FPSUsername,

you should avoid using same gpio controls for different sensors.
there’re some general GPIO for your reference. such as CAM0_PWDN, CAM1_PWDN…etc.
$l4t-r32.2/kernel_src/hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-quill-camera-modules.dts

please also refer to your sensor specification, review the power-on sequence to check whether GPIO controls should used.
thanks