根据霍尔开关状态,实现ov5695状态切换
功能描述:当检测到霍尔开关的中断时候,需要关断摄像头或者设置寄存器预览黑屏状态,不触发中断,摄像头恢复正常。
1.dts配置:
index 982c89462bfb..5b02c055d5aa 100755 --- a/arch/arm64/boot/dts/rockchip/rk3588s-t-ov5695-imx350.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588s-t-ov5695-imx350.dtsi @@ -103,6 +103,8 @@ ov5695: ov5695@10 { reset-gpios = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>; pwdn-gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_HIGH>; avdd-supply = <&vcc_frontcam>; + hall-ctl-gpio =<&gpio1 RK_PB1 GPIO_ACTIVE_HIGH>; + pinctrl-1 = <&hall_gpio>; rockchip,camera-module-index = <1>; rockchip,camera-module-facing = "front"; rockchip,camera-module-name = "default"; @@ -382,6 +384,10 @@ &rkisp_unite { &pinctrl { cam { + hall_gpio: hall-gpio { + rockchip,pins = <1 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + backcam_pwr: backcam-pwr { rockchip,pins =
默认内部上拉状态,当低电平时候触发中断。
2.TEST_PATTERN寄存器

测试模式控制寄存器,bit7设置为1可进入测试模式。

实现思想是触发中断,设置寄存器进入测试模式,反之则退出测试模式。
3.驱动实现:
3.1中断io初始化
--- a/drivers/media/i2c/ov5695.c +++ b/drivers/media/i2c/ov5695.c @@ -132,10 +132,14 @@ struct ov5695 { const char *module_facing; const char *module_name; const char *len_name; + struct gpio_desc *hall_ctl_gpio; + int hall_irq; + bool hall_opened; };
@@ -1390,7 +1434,7 @@ static int ov5695_probe(struct i2c_client *client, struct ov5695 *ov5695; struct v4l2_subdev *sd; char facing[2]; - int ret; + int ret,val; dev_info(dev, "driver version: %02x.%02x.%02x", DRIVER_VERSION >> 16, @@ -1432,6 +1476,29 @@ static int ov5695_probe(struct i2c_client *client, if (IS_ERR(ov5695->pwdn_gpio)) dev_warn(dev, "Failed to get pwdn-gpios\n"); + // 获取hall-ctl-gpio + ov5695->hall_ctl_gpio = devm_gpiod_get(dev, "hall-ctl", GPIOD_IN); + if (IS_ERR(ov5695->hall_ctl_gpio)) { + dev_warn(dev, "Failed to get hall-ctl-gpios (%ld)\n", + PTR_ERR(ov5695->hall_ctl_gpio)); + ov5695->hall_ctl_gpio = NULL; + } else { + // 获取中断号 + ov5695->hall_irq = gpiod_to_irq(ov5695->hall_ctl_gpio); + if (ov5695->hall_irq < 0) { + dev_err(dev, "Failed to get hall interrupt: %d\n", ov5695->hall_irq); + } else { + ret = ov5695_setup_hall_interrupt(ov5695); + if (ret) + dev_err(dev, "Failed to request hall interrupt: %d\n", ret); + else + dev_info(dev, "Registered hall interrupt (IRQ: %d)\n", ov5695->hall_irq); + } + } + //记录开机霍尔开关状态 + val = gpiod_get_value(ov5695->hall_ctl_gpio); + ov5695->hall_opened = (val == 0); + ret = ov5695_configure_regulators(ov5695);
3.2.中断实现:
@@ -1103,6 +1107,41 @@ static void __ov5695_power_off(struct ov5695 *ov5695) regulator_bulk_disable(OV5695_NUM_SUPPLIES, ov5695->supplies); } +// 中断处理函数 +static irqreturn_t ov5695_hall_irq_handler(int irq, void *dev_id) +{ + struct ov5695 *ov5695 = dev_id; + int val = gpiod_get_value(ov5695->hall_ctl_gpio); + + dev_info(&ov5695->client->dev, "Hall interrupt triggered! State: %d\n", val); + ov5695->hall_opened = (val == 0); + + if (ov5695->streaming) { + if(ov5695->hall_opened){ + ov5695_write_reg(ov5695->client, OV5695_REG_TEST_PATTERN, + OV5695_REG_VALUE_08BIT, OV5695_TEST_PATTERN_ENABLE); + + }else{ + ov5695_write_reg(ov5695->client, OV5695_REG_TEST_PATTERN, + OV5695_REG_VALUE_08BIT, OV5695_TEST_PATTERN_DISABLE); + } + } + return IRQ_HANDLED; +} + +// 设置中断 +static int ov5695_setup_hall_interrupt(struct ov5695 *ov5695) +{ + int ret; + + ret = devm_request_threaded_irq(&ov5695->client->dev, ov5695->hall_irq, + NULL, ov5695_hall_irq_handler, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "ov5695_hall", ov5695); + return ret; +} + +
3.3.霍尔开关触发状态,camera重新从后台打开,会对底层驱动做io_ctrl操作,也需要设置寄存器
@@ -1220,6 +1259,11 @@ static int ov5695_set_ctrl(struct v4l2_ctrl *ctrl) s64 max; int ret = 0; + if (ov5695->hall_opened) { + ov5695_write_reg(ov5695->client, OV5695_REG_TEST_PATTERN, + OV5695_REG_VALUE_08BIT, OV5695_TEST_PATTERN_ENABLE); + } + /* Propagate change of current control to all related controls */ switch (ctrl->id) { case V4L2_CID_VBLANK:

浙公网安备 33010602011771号