Merge commit '3d712791cdfaf3011a49ac70dca4fd25febec256'

* commit '3d712791cdfaf3011a49ac70dca4fd25febec256': (28 commits)
  media: rockchip: isp: add iommu fault handler
  drm/rockchip: vop2: Fix error handling for get dclk_src
  arm64: dts: rockchip: rk3576-rk806: Changing the implementation of pin functions
  arm64: dts: rockchip: rk3588-rk806: Changing the implementation of pin functions
  regulator: rk806: Modify the implementation of RK806 shutdown
  ARM: configs: rv1126b-aoa.config: Add config and enable ROCKCHIP_AOA_MIDDLEWARE with module
  arm64: dts: rockchip: rv1126b-evb: enable AOA features
  arm64: dts: rockchip: rv1126b-aoa: Add aoa_middleware node and enable related modules for AOA feature
  arm64: dts: rockchip: rv1126b: Add aoa/dma-lp/aoa_mmap/aoa_sram for AOA feature
  soc: rockchip: aoa_middleware: Add support AOA middleware modules
  media: rockchip: isp: fix unite div calculation
  media: spi: add ms41908 and ms41968
  include: rk_vcm_head: add zoom1 field
  include: uapi: rk-camera-module.h add more exp_mode of lofic
  media: i2c: ox03c10 support get single frame info of hdr_compr
  include: uapi: rk-camera-module.h add cmd RKMODULE_GET_HDR_COMPR_SINGLE_FRAME_INFO
  include: uapi: rk-camera-module.h add cmd RKMODULE_SET_BAYER_MODE
  media: i2c: ox03c10 add more control of blc
  include: uapi: rk-camera-module.h: RKMODULE_SET_BLC add more param
  media: i2c: ox03c10 support set reg_setting config
  ...

Change-Id: Iff99fdadff16fe12a21a46dae18465c851911160
This commit is contained in:
Tao Huang
2025-07-31 19:20:11 +08:00
31 changed files with 8198 additions and 1140 deletions

View File

@@ -0,0 +1 @@
CONFIG_ROCKCHIP_AOA_MIDDLEWARE=m

View File

@@ -17,9 +17,8 @@
interrupt-parent = <&gpio0>;
interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default", "pmic-power-off";
pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, <&rk806_dvs2_null>, <&rk806_dvs3_null>;
pinctrl-1 = <&rk806_dvs1_pwrdn>;
pinctrl-names = "default";
pinctrl-0 = <&pmic_pins>;
/* 2800mv-3500mv */
low_voltage_threshold = <3000>;

View File

@@ -21,9 +21,8 @@
interrupt-parent = <&gpio0>;
interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default", "pmic-power-off";
pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, <&rk806_dvs2_null>, <&rk806_dvs3_null>;
pinctrl-1 = <&rk806_dvs1_pwrdn>;
pinctrl-names = "default";
pinctrl-0 = <&pmic_pins>;
/* 2800mv-3500mv */
low_voltage_threshold = <3000>;
@@ -411,9 +410,6 @@
interrupt-parent = <&gpio0>;
interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&rk806_slave_dvs1_null>, <&rk806_slave_dvs2_null>, <&rk806_slave_dvs3_null>;
/* 0: restart PMU;
* 1: reset all the power off reset registers,
* forcing the state to switch to ACTIVE mode;

View File

@@ -23,9 +23,8 @@
interrupt-parent = <&gpio0>;
interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default", "pmic-power-off";
pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, <&rk806_dvs2_null>, <&rk806_dvs3_null>;
pinctrl-1 = <&rk806_dvs1_pwrdn>;
pinctrl-names = "default";
pinctrl-0 = <&pmic_pins>;
/* 2800mv-3500mv */
low_voltage_threshold = <3000>;

View File

@@ -21,9 +21,8 @@
interrupt-parent = <&gpio0>;
interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default", "pmic-power-off";
pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, <&rk806_dvs2_null>, <&rk806_dvs3_null>;
pinctrl-1 = <&rk806_dvs1_pwrdn>;
pinctrl-names = "default";
pinctrl-0 = <&pmic_pins>;
/* 2800mv-3500mv */
low_voltage_threshold = <3000>;
@@ -409,10 +408,6 @@
interrupt-parent = <&gpio0>;
interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default", "pmic-sleep";
pinctrl-0 = <&rk806_slave_dvs1_null>, <&rk806_slave_dvs2_null>, <&rk806_slave_dvs3_null>;
pinctrl-1 = <&rk806_slave_dvs1_slp>, <&rk806_slave_dvs2_null>, <&rk806_slave_dvs3_null>;
/* 0: restart PMU;
* 1: reset all the power off reset registers,
* forcing the state to switch to ACTIVE mode;

View File

@@ -0,0 +1,27 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
/ {
aoa_middleware {
compatible = "rockchip,aoa-middleware";
memory-region = <&aoa_sram>;
rockchip,aoa = <&aoa>;
rockchip,dma = <&dmac_lp>;
};
};
&dmac_lp {
/* Avoid being mapped by standard DMA drivers */
compatible = "rockchip,rv1126b-dma-lp";
status = "okay";
};
&aoa {
status = "okay";
};
&aoa_sram {
status = "okay";
};

View File

@@ -6,6 +6,8 @@
#include <dt-bindings/display/drm_mipi_dsi.h>
#include <dt-bindings/input/input.h>
#include "rv1126b-aoa.dtsi"
/ {
chosen {
bootargs = "earlycon=uart8250,mmio32,0x20810000 console=ttyFIQ0 rw root=PARTUUID=614e0000-0000 rootfstype=ext4 rootwait snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=32K";

View File

@@ -1629,6 +1629,16 @@
};
};
dmac_lp: dma-controller@20880000 {
compatible = "rockchip,rv1126b-dma", "rockchip,dma";
reg = <0x20880000 0x2000>;
interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&xin24m>;
clock-names = "aclk";
#dma-cells = <1>;
status = "disabled";
};
audio_codec_pmu: audio-codec@20898000 {
compatible = "rockchip,rv1126b-codec", "rockchip,rk3506-codec";
reg = <0x20898000 0x1000>;
@@ -1642,6 +1652,16 @@
status = "disabled";
};
aoa: aoa@208b0000 {
compatible = "rockchip,rv1126b-aoa", "rockchip,aoa";
reg = <0x208b0000 0x1000>;
interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>;
resets = <&cru SRST_PRESETN_AOA_TDD>, <&cru SRST_PRESETN_AOA_FE>,
<&cru SRST_PRESETN_AOA_AAD>, <&cru SRST_PRESETN_AOA_APB>;
reset-names = "atd", "afe", "aad", "apb";
status = "disabled";
};
fspi1: spi@208c0000 {
compatible = "rockchip,rv1126b-fspi", "rockchip,fspi";
reg = <0x208c0000 0x4000>;
@@ -3556,6 +3576,15 @@
<0x22710000 0x1000>;
};
aoa_sram: sram@3ff20000 {
compatible = "mmio-sram";
reg = <0x3ff20000 0x10000>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x3ff20000 0x10000>;
status = "disabled";
};
system_sram: sram@3ffb0000 {
compatible = "mmio-sram";
reg = <0x3ffb0000 0x10000>;

View File

@@ -15202,9 +15202,9 @@ static int vop2_create_crtc(struct vop2 *vop2, uint8_t enabled_vp_mask)
snprintf(clk_name, sizeof(clk_name), "dclk_src_vp%d", vp->id);
vp->dclk_parent = devm_clk_get_optional(vop2->dev, clk_name);
if (IS_ERR(vp->dclk)) {
if (IS_ERR(vp->dclk_parent)) {
DRM_DEV_ERROR(vop2->dev, "failed to get %s\n", clk_name);
return PTR_ERR(vp->dclk);
return PTR_ERR(vp->dclk_parent);
}
crtc = &vp->rockchip_crtc.crtc;

File diff suppressed because it is too large Load Diff

View File

@@ -1014,9 +1014,25 @@ static const struct of_device_id rkisp_hw_of_match[] = {
{},
};
static inline bool is_iommu_enable(struct device *dev)
static int rkisp_iommu_fault_handle(struct iommu_domain *iommu, struct device *iommu_dev,
unsigned long iova, int status, void *arg)
{
struct rkisp_hw_dev *hw_dev = arg;
dev_err(iommu_dev, "fault addr:0x%08lx status:%x arg:%p\n", iova, status, arg);
if (!hw_dev) {
dev_err(iommu_dev, "pagefault without device to handle\n");
return 0;
}
rockchip_iommu_mask_irq(hw_dev->dev);
return 0;
}
static inline bool is_iommu_enable(struct rkisp_hw_dev *hw_dev)
{
struct device *dev = hw_dev->dev;
struct device_node *iommu;
struct iommu_domain *domain;
iommu = of_parse_phandle(dev->of_node, "iommus", 0);
if (!iommu) {
@@ -1029,6 +1045,9 @@ static inline bool is_iommu_enable(struct device *dev)
}
of_node_put(iommu);
domain = iommu_get_domain_for_dev(dev);
if (domain)
iommu_set_fault_handler(domain, rkisp_iommu_fault_handle, hw_dev);
return true;
}
@@ -1469,7 +1488,7 @@ static int rkisp_hw_probe(struct platform_device *pdev)
hw_dev->is_dma_sg_ops = true;
hw_dev->is_buf_init = false;
hw_dev->is_shutdown = false;
hw_dev->is_mmu = is_iommu_enable(dev);
hw_dev->is_mmu = is_iommu_enable(hw_dev);
ret = of_reserved_mem_device_init(dev);
if (ret) {
is_mem_reserved = false;

View File

@@ -3003,22 +3003,34 @@ static int rkisp_unite_div(struct rkisp_device *dev, u32 w, u32 h)
case ISP_V30:
max_size = CIF_ISP_INPUT_W_MAX_V30 * CIF_ISP_INPUT_H_MAX_V30;
max_w = CIF_ISP_INPUT_W_MAX_V30;
max_h = max_size / w;
if (w > max_w)
max_h = max_size * 2 / w;
else
max_h = max_size / w;
break;
case ISP_V32:
max_size = CIF_ISP_INPUT_W_MAX_V32 * CIF_ISP_INPUT_H_MAX_V32;
max_w = CIF_ISP_INPUT_W_MAX_V32;
max_h = max_size / w;
if (w > max_w)
max_h = max_size * 2 / w;
else
max_h = max_size / w;
break;
case ISP_V32_L:
max_size = CIF_ISP_INPUT_W_MAX_V32_L * CIF_ISP_INPUT_H_MAX_V32_L;
max_w = CIF_ISP_INPUT_W_MAX_V32_L;
max_h = max_size / w;
if (w > max_w)
max_h = max_size * 2 / w;
else
max_h = max_size / w;
break;
case ISP_V33:
max_size = CIF_ISP_INPUT_W_MAX_V33 * CIF_ISP_INPUT_H_MAX_V33;
max_w = CIF_ISP_INPUT_W_MAX_V33;
max_h = max_size / w;
if (w > max_w)
max_h = max_size * 2 / w;
else
max_h = max_size / w;
break;
case ISP_V35:
max_size = CIF_ISP_INPUT_W_MAX_V35 * CIF_ISP_INPUT_H_MAX_V35;
@@ -3028,7 +3040,10 @@ static int rkisp_unite_div(struct rkisp_device *dev, u32 w, u32 h)
case ISP_V39:
max_size = CIF_ISP_INPUT_W_MAX_V39_UNITE / 2 * CIF_ISP_INPUT_H_MAX_V39_UNITE;
max_w = CIF_ISP_INPUT_W_MAX_V39;
max_h = max_size / w;
if (w > max_w)
max_h = max_size * 2 / w;
else
max_h = max_size / w;
break;
default:
return -EINVAL;

View File

@@ -31,6 +31,20 @@ config VIDEO_ROCKCHIP_PREISP
help
Support for Pre-isp on the rockchip SoC.
config VIDEO_MS41908
tristate "Relmon MS41908 motor driver"
depends on SPI && VIDEO_DEV
select VIDEO_V4L2_SUBDEV_API
help
Support motor driver By MS41908 for camera Lens.
config VIDEO_MS41968
tristate "Relmon MS41968 motor driver"
depends on SPI && VIDEO_DEV
select VIDEO_V4L2_SUBDEV_API
help
Support motor driver By MS41968 for camera Lens.
endmenu
endif

View File

@@ -8,3 +8,5 @@ obj-$(CONFIG_CXD2880_SPI_DRV) += cxd2880-spi.o
obj-$(CONFIG_VIDEO_GS1662) += gs1662.o
obj-$(CONFIG_VIDEO_ROCKCHIP_PREISP) += rk1608.o rk1608_dphy.o
rk1608-objs += rk1608_dev.o rk1608_core.o
obj-$(CONFIG_VIDEO_MS41908) += ms41908.o
obj-$(CONFIG_VIDEO_MS41968) += ms41968.o

3103
drivers/media/spi/ms41908.c Normal file

File diff suppressed because it is too large Load Diff

3503
drivers/media/spi/ms41968.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1250,12 +1250,10 @@ static void rk806_regulator_shutdown(struct platform_device *pdev)
if (system_state == SYSTEM_POWER_OFF) {
rk806_shutdown_requence_config(rk806);
if ((rk806->pins->p) && (rk806->pins->power_off))
pinctrl_select_state(rk806->pins->p, rk806->pins->power_off);
rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_NULL_FUN);
rk806_field_write(rk806, PWRCTRL1_POL, POL_HIGH);
rk806_field_write(rk806, PWRCTRL1_FUN, PWRCTRL_POWOFF_FUN);
}
if (system_state == SYSTEM_RESTART)
if ((rk806->pins->p) && (rk806->pins->reset))
pinctrl_select_state(rk806->pins->p, rk806->pins->reset);
}
static const struct platform_device_id rk806_regulator_id_table[] = {

View File

@@ -372,6 +372,7 @@ config RK_ZONEINFO_PROCFS
help
Dump all zone information.
source "drivers/soc/rockchip/aoa_middleware/Kconfig"
source "drivers/soc/rockchip/minidump/Kconfig"
endmenu

View File

@@ -2,6 +2,7 @@
#
# Rockchip Soc drivers
#
obj-$(CONFIG_ROCKCHIP_AOA_MIDDLEWARE) += aoa_middleware/
obj-$(CONFIG_ROCKCHIP_AMP) += rockchip_amp.o
obj-$(CONFIG_ROCKCHIP_CPUINFO) += rockchip-cpuinfo.o
obj-$(CONFIG_ROCKCHIP_CSU) += rockchip_csu.o

View File

@@ -0,0 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
config ROCKCHIP_AOA_MIDDLEWARE
tristate "Rockchip AOA Middleware Driver"
help
Enable this configuration option to enable notify (AOA/DMA) events
on driver for user applications.

View File

@@ -0,0 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Rockchip AOA Middleware Modules
#
obj-$(CONFIG_ROCKCHIP_AOA_MIDDLEWARE) += rk_aoa.o
rk_aoa-objs := aoa_drv.o aoa_mmap.o aoa_middleware.o lp_rkdma.o

View File

@@ -0,0 +1,81 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Rockchip AOA Controller Driver
*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
* Author: Xing Zheng <zhengxing@rock-chips.com>
*/
#include <linux/reset.h>
#include <sound/dmaengine_pcm.h>
#include "aoa_drv.h"
#include "aoa_middleware.h"
#define DRV_NAME "rockchip-aoa"
#define AOA_AAD_IRQ_ST 0x01a8
struct rk_aoa_dev {
struct device *dev;
struct reset_control *rst;
void __iomem *base;
};
static const struct of_device_id rockchip_aoa_match[] __maybe_unused = {
{ .compatible = "rockchip,aoa", },
{},
};
static irqreturn_t rockchip_aoa_isr(int irq, void *devid)
{
struct rk_aoa_dev *aoa = (struct rk_aoa_dev *)devid;
u32 st, s;
st = readl(aoa->base + AOA_AAD_IRQ_ST);
writel(st, aoa->base + AOA_AAD_IRQ_ST);
for (s = 1; s < 8; s++) {
if (st & (1 << s))
aoa_middleware_aoa_notifier(s);
}
return IRQ_HANDLED;
}
int rockchip_aoa_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
struct rk_aoa_dev *aoa;
int ret, irq;
aoa = devm_kzalloc(&pdev->dev, sizeof(*aoa), GFP_KERNEL);
if (!aoa)
return -ENOMEM;
aoa->dev = &pdev->dev;
dev_set_drvdata(&pdev->dev, aoa);
aoa->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(aoa->base))
return PTR_ERR(aoa->base);
aoa->rst = devm_reset_control_array_get_optional_exclusive(aoa->dev);
if (IS_ERR(aoa->rst))
return PTR_ERR(aoa->rst);
irq = platform_get_irq_optional(pdev, 0);
if (irq > 0) {
ret = devm_request_irq(&pdev->dev, irq, rockchip_aoa_isr,
IRQF_SHARED, node->name, aoa);
if (ret) {
dev_err(&pdev->dev, "Failed to request irq %d\n", irq);
return ret;
}
}
return 0;
}
int rockchip_aoa_remove(struct platform_device *pdev)
{
return 0;
}

View File

@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Rockchip AOA Controller Driver
*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
* Author: Xing Zheng <zhengxing@rock-chips.com>
*/
#ifndef __AOA_DRV_H__
#define __AOA_DRV_H__
int rockchip_aoa_probe(struct platform_device *pdev);
int rockchip_aoa_remove(struct platform_device *pdev);
#endif /* __AOA_DRV_H__ */

View File

@@ -0,0 +1,279 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Rockchip AOA Middleware Driver
*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
* Author: Xing Zheng <zhengxing@rock-chips.com>
*/
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/nospec.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include "aoa_middleware.h"
#include "aoa_mmap.h"
#include "aoa_drv.h"
#include "lp_rkdma.h"
#define NOTIFY_RKDMA_SET_PERIODS _IOR('N', 1, u32)
#define NOTIFY_RKDMA_GET_TIMESTAMP_NS _IOR('N', 2, s64)
struct notify_ns {
s32 ns_id;
s64 ns;
};
struct notify_rkdma {
s64 *ns_tbl;
s32 last_ns_id;
u32 periods;
};
struct aoa_middleware_devs {
struct device *dev;
struct platform_device *pdev_aoa;
struct platform_device *pdev_dma;
};
static struct fasync_struct *rk_aoa_fasync_queue;
static struct fasync_struct *rk_dma_fasync_queue;
static struct notify_rkdma g_notify;
static struct notify_ns g_dma_ns;
int aoa_middleware_aoa_notifier(s32 status)
{
/* AOA Notify starting from SIGRTMIN + 1 */
kill_fasync(&rk_aoa_fasync_queue, SIGRTMIN + status, POLL_IN);
return 0;
}
EXPORT_SYMBOL(aoa_middleware_aoa_notifier);
int aoa_middleware_dma_notifier(s32 dma_count)
{
struct notify_rkdma *n_rkdma = &g_notify;
struct notify_ns *n_ns = &g_dma_ns;
struct timespec64 ts;
s32 delta_id;
ktime_get_boottime_ts64(&ts);
n_ns->ns = timespec64_to_ns(&ts);
kill_fasync(&rk_dma_fasync_queue, SIGRTMIN + 0, POLL_IN);
/* ns_id: start from 1, range: 0 ~ (periods-1) */
if (dma_count < 0 || dma_count >= n_rkdma->periods) {
pr_err("Invalid dma_count: %d\n", dma_count);
return -EINVAL;
}
dma_count = array_index_nospec(dma_count, n_rkdma->periods);
n_ns->ns_id = dma_count;
n_rkdma->ns_tbl[n_ns->ns_id] = n_ns->ns;
if (n_ns->ns_id < n_rkdma->last_ns_id)
delta_id = n_ns->ns_id + n_rkdma->periods - n_rkdma->last_ns_id;
else
delta_id = n_ns->ns_id - n_rkdma->last_ns_id;
if (delta_id > 1) {
s32 missed_id = 0;
while (missed_id <= delta_id) {
/**
* During sleep, the CPU does not respond to DMA interruptsand
* requires manual calibration of PTS.
*/
s32 id = (n_ns->ns_id - missed_id);
if (id < 0)
id += n_rkdma->periods;
n_rkdma->ns_tbl[id] = n_ns->ns - missed_id * 16000000;
missed_id++;
}
}
n_rkdma->last_ns_id = n_ns->ns_id;
return 0;
}
EXPORT_SYMBOL(aoa_middleware_dma_notifier);
static int rk_aoa_notifier_fasync(int fd, struct file *file, int mode)
{
return fasync_helper(fd, file, mode, &rk_aoa_fasync_queue);
}
static const struct file_operations rk_aoa_notifier_fops = {
.owner = THIS_MODULE,
.fasync = rk_aoa_notifier_fasync,
};
static struct miscdevice rk_aoa_notifier_misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = "rk-aoa-notifier",
.fops = &rk_aoa_notifier_fops,
};
static int rk_dma_notifier_fasync(int fd, struct file *file, int mode)
{
return fasync_helper(fd, file, mode, &rk_dma_fasync_queue);
}
static long rk_dma_notifier_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct notify_rkdma *n_rkdma = &g_notify;
struct notify_ns n_ns_user;
switch (cmd) {
case NOTIFY_RKDMA_SET_PERIODS:
n_rkdma->periods = arg;
kfree(n_rkdma->ns_tbl);
n_rkdma->last_ns_id = 0; /* last_ns_id start from 0, current ns_id start from 1 */
n_rkdma->ns_tbl = kcalloc(n_rkdma->periods, sizeof(s64), GFP_KERNEL);
pr_debug("rk_dma_notifier: set and alloc ns table periods: %d\n", n_rkdma->periods);
break;
case NOTIFY_RKDMA_GET_TIMESTAMP_NS:
/* return last timestamp from ns */
if (copy_from_user(&n_ns_user, (struct notify_ns __user *)arg, sizeof(n_ns_user)))
return -EFAULT;
if (n_ns_user.ns_id < 0 || n_ns_user.ns_id >= n_rkdma->periods) {
pr_err("Invalid ns_id: %d\n", n_ns_user.ns_id);
return -EINVAL;
}
n_ns_user.ns_id = array_index_nospec(n_ns_user.ns_id, n_rkdma->periods);
n_ns_user.ns = n_rkdma->ns_tbl[n_ns_user.ns_id];
if (copy_to_user((struct notify_ns __user *)arg, &n_ns_user, sizeof(n_ns_user)))
return -EFAULT;
break;
default:
return -ENOTTY;
}
return 0;
}
static const struct file_operations rk_dma_notifier_fops = {
.owner = THIS_MODULE,
.fasync = rk_dma_notifier_fasync,
.compat_ioctl = rk_dma_notifier_ioctl,
.unlocked_ioctl = rk_dma_notifier_ioctl,
};
static struct miscdevice rk_dma_notifier_misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = "rk-dma-notifier",
.fops = &rk_dma_notifier_fops,
};
static int aoa_middleware_probe(struct platform_device *pdev)
{
struct aoa_middleware_devs *amw_d;
struct platform_device *pdev_slave;
struct device_node *np;
int ret;
amw_d = devm_kzalloc(&pdev->dev, sizeof(*amw_d), GFP_KERNEL);
if (!amw_d)
return -ENOMEM;
amw_d->dev = &pdev->dev;
/* prepare rockchip aoa control driver */
np = of_parse_phandle(pdev->dev.of_node, "rockchip,aoa", 0);
if (!np || !of_device_is_available(np)) {
dev_err(&pdev->dev, "can't find 'rockchip,aoa' node\n");
return -ENODEV;
}
pdev_slave = of_find_device_by_node(np);
of_node_put(np);
if (!pdev_slave) {
dev_err(&pdev->dev, "get aoa node failed\n");
return -ENODEV;
}
ret = rockchip_aoa_probe(pdev_slave);
if (ret) {
dev_err(&pdev->dev, "probe rockchip aoa failed: %d\n", ret);
return ret;
}
amw_d->pdev_aoa = pdev_slave;
/* prepare rockchip low-power dma driver */
np = of_parse_phandle(pdev->dev.of_node, "rockchip,dma", 0);
if (!np || !of_device_is_available(np)) {
dev_err(&pdev->dev, "can't find 'rockchip,dma' node\n");
return -ENODEV;
}
pdev_slave = of_find_device_by_node(np);
of_node_put(np);
if (!pdev_slave) {
dev_err(&pdev->dev, "get dma node failed\n");
return -ENODEV;
}
ret = lp_rkdma_probe(pdev_slave);
if (ret) {
dev_err(&pdev->dev, "probe rockchip dma failed: %d\n", ret);
return ret;
}
amw_d->pdev_dma = pdev_slave;
/* prepare aoa memory mapping */
ret = aoa_mmap_probe(pdev);
if (ret) {
dev_err(&pdev->dev, "%s: aoa mmap probe failed (%d)\n", __func__, ret);
return ret;
}
/* prepare aoa/dma notifiers */
ret = misc_register(&rk_aoa_notifier_misc);
if (ret) {
dev_err(&pdev->dev, "%s: aoa notifier misc register failed (%d)\n", __func__, ret);
return ret;
}
ret = misc_register(&rk_dma_notifier_misc);
if (ret) {
dev_err(&pdev->dev, "%s: dma notifier misc register failed (%d)\n", __func__, ret);
return ret;
}
platform_set_drvdata(pdev, amw_d);
dev_info(&pdev->dev, "%s: all aoa middlewares are registered\n", __func__);
return 0;
}
static int aoa_middleware_remove(struct platform_device *pdev)
{
struct aoa_middleware_devs *amw_d = platform_get_drvdata(pdev);
if (IS_ERR(amw_d))
return -EINVAL;
rockchip_aoa_remove(amw_d->pdev_aoa);
lp_rkdma_remove(amw_d->pdev_dma);
aoa_mmap_remove(pdev);
misc_deregister(&rk_dma_notifier_misc);
misc_deregister(&rk_aoa_notifier_misc);
dev_info(&pdev->dev, "%s: all aoa middlewares are unregistered\n", __func__);
return 0;
}
static const struct of_device_id aoa_middleware_of_match[] = {
{ .compatible = "rockchip,aoa-middleware", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, aoa_middleware_of_match);
static struct platform_driver aoa_middleware_driver = {
.probe = aoa_middleware_probe,
.remove = aoa_middleware_remove,
.driver = {
.name = "aoa-middleware",
.of_match_table = aoa_middleware_of_match,
},
};
module_platform_driver(aoa_middleware_driver);
MODULE_DESCRIPTION("Rockchip AOA Middleware Driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("xing.zheng@rock-chips.com");

View File

@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Rockchip AOA Middleware Driver
*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
* Author: Xing Zheng <zhengxing@rock-chips.com>
*/
#ifndef __AOA_MIDDLEWARE_H__
#define __AOA_MIDDLEWARE_H__
int aoa_middleware_aoa_notifier(s32 status);
int aoa_middleware_dma_notifier(s32 dma_count);
#endif /* __AOA_MIDDLEWARE_H__ */

View File

@@ -0,0 +1,155 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Rockchip AOA Memory Mapping Driver
*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
* Author: Xing Zheng <zhengxing@rock-chips.com>
*/
#include <linux/device.h>
#include <linux/ioctl.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/of_address.h>
#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>
#include "aoa_mmap.h"
#define DEVICE_NAME "aoa-mmap"
#define AOA_MMAP_IOC_MAGIC 'a'
#define AOA_MMAP_IOC_GET_INFO _IOR(AOA_MMAP_IOC_MAGIC, 1, struct aoa_mmap_info)
struct aoa_mmap_info {
__u32 phys_addr;
__u32 size;
};
struct aoa_mmap_dev {
struct device *dev; /* dev structure of platform device */
void __iomem *kvirt; /* kernel virtual address, obtained by memremap */
phys_addr_t phys; /* fixed physical start (0x3ff20000) */
u32 size; /* size 64KB */
struct miscdevice misc;
};
static int aoa_mmap_open(struct inode *inode, struct file *file)
{
struct miscdevice *misc = file->private_data;
struct aoa_mmap_dev *am_d = container_of(misc, struct aoa_mmap_dev, misc);
file->private_data = am_d;
return 0;
}
static int aoa_mmap_release(struct inode *inode, struct file *file)
{
return 0;
}
static int aoa_mmap_mmap(struct file *file, struct vm_area_struct *vma)
{
struct aoa_mmap_dev *am_d = file->private_data;
unsigned long length = vma->vm_end - vma->vm_start;
/* The length cannot exceed the reserved size */
if (length > am_d->size)
return -EINVAL;
/* Force Non-Cacheable */
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
/* Mapping to user space by physical address */
return remap_pfn_range(vma, vma->vm_start, am_d->phys >> PAGE_SHIFT,
length, vma->vm_page_prot);
}
static long aoa_mmap_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct aoa_mmap_dev *am_d = file->private_data;
struct aoa_mmap_info info;
if (unlikely(!am_d))
return -ENODEV;
if (IS_ERR(am_d))
return PTR_ERR(am_d);
switch (cmd) {
case AOA_MMAP_IOC_GET_INFO:
info.phys_addr = am_d->phys;
info.size = am_d->size;
if (copy_to_user((struct aoa_mmap_info __user *)arg, &info, sizeof(info)))
return -EFAULT;
return 0;
default:
return -EINVAL;
}
}
static const struct file_operations aoa_mmap_fops = {
.owner = THIS_MODULE,
.open = aoa_mmap_open,
.release = aoa_mmap_release,
.mmap = aoa_mmap_mmap,
.unlocked_ioctl = aoa_mmap_ioctl,
};
int aoa_mmap_probe(struct platform_device *pdev)
{
struct aoa_mmap_dev *am_d;
struct resource res;
struct device_node *res_node;
int ret;
am_d = devm_kzalloc(&pdev->dev, sizeof(*am_d), GFP_KERNEL);
if (!am_d)
return -ENOMEM;
am_d->dev = &pdev->dev;
res_node = of_parse_phandle(pdev->dev.of_node, "memory-region", 0);
if (!res_node) {
dev_err(&pdev->dev, "failed to get memory region node\n");
return -ENODEV;
}
ret = of_address_to_resource(res_node, 0, &res);
of_node_put(res_node);
if (ret) {
dev_err(&pdev->dev, "failed to get reserved region address\n");
return -ENODEV;
}
am_d->phys = res.start;
am_d->size = resource_size(&res);
/* ioremap the SRAM area (Non-Cacheable Device memory) */
am_d->kvirt = devm_ioremap(am_d->dev, am_d->phys, am_d->size);
if (!am_d->kvirt) {
dev_err(am_d->dev, "ioremap failed\n");
return -ENOMEM;
}
am_d->misc.minor = MISC_DYNAMIC_MINOR;
am_d->misc.name = DEVICE_NAME;
am_d->misc.fops = &aoa_mmap_fops;
ret = misc_register(&am_d->misc);
if (ret) {
dev_err(am_d->dev, "misc_register failed: %d\n", ret);
return ret;
}
platform_set_drvdata(pdev, am_d);
dev_info(am_d->dev, "aoa_mmap_mem: mapped phys=%pa size=%u\n",
&am_d->phys, am_d->size);
return 0;
}
int aoa_mmap_remove(struct platform_device *pdev)
{
struct aoa_mmap_dev *am_d = platform_get_drvdata(pdev);
misc_deregister(&am_d->misc);
return 0;
}

View File

@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Rockchip AOA Memory Mapping Driver
*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
* Author: Xing Zheng <zhengxing@rock-chips.com>
*/
#ifndef __AOA_MMAP_H__
#define __AOA_MMAP_H__
int aoa_mmap_probe(struct platform_device *pdev);
int aoa_mmap_remove(struct platform_device *pdev);
#endif /* __AOA_MMAP_H__ */

View File

@@ -0,0 +1,228 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Rockchip Low Power DMA Driver
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
* Author: Xing Zheng <zhengxing@rock-chips.com>
*/
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/io-64-nonatomic-hi-lo.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include "lp_rkdma.h"
#include "aoa_middleware.h"
#define DRIVER_NAME "lp-rkdma"
#define DMA_MAX_SIZE (0x1000000)
#define LLI_BLOCK_SIZE (SZ_4K)
#define RK_DMA_VER(major, minor) (((major) << 16) | ((minor) << 0))
#define HIWORD_UPDATE(v, h, l) (((v) << (l)) | (GENMASK((h), (l)) << 16))
#define GENMASK_VAL(v, h, l) (((v) & GENMASK(h, l)) >> l)
#define RK_DMA_CMN_GROUP_SIZE 0x100
#define RK_DMA_LCH_GROUP_SIZE 0x40
#define RK_DMA_CMN_REG(x) (d->base + (x))
#define RK_DMA_LCH_REG(x) (l->base + (x))
#define RK_DMA_LCHn_REG(n, x) (d->base + RK_DMA_CMN_GROUP_SIZE + \
(RK_DMA_LCH_GROUP_SIZE * (n)) + (x))
/* RK_DMA Common Register Define */
#define RK_DMA_CMN_VER RK_DMA_CMN_REG(0x0000) /* Address Offset: 0x0000 */
#define RK_DMA_CMN_CFG RK_DMA_CMN_REG(0x0004) /* Address Offset: 0x0004 */
#define RK_DMA_CMN_CTL0 RK_DMA_CMN_REG(0x0008) /* Address Offset: 0x0008 */
#define RK_DMA_CMN_CTL1 RK_DMA_CMN_REG(0x000c) /* Address Offset: 0x000C */
#define RK_DMA_CMN_AXICTL RK_DMA_CMN_REG(0x0010) /* Address Offset: 0x0010 */
#define RK_DMA_CMN_DYNCTL RK_DMA_CMN_REG(0x0014) /* Address Offset: 0x0014 */
#define RK_DMA_CMN_IS0 RK_DMA_CMN_REG(0x0018) /* Address Offset: 0x0018 */
#define RK_DMA_CMN_IS1 RK_DMA_CMN_REG(0x001c) /* Address Offset: 0x001C */
#define RK_DMA_CMN_CAP0 RK_DMA_CMN_REG(0x0030) /* Address Offset: 0x0030 */
#define RK_DMA_CMN_CAP1 RK_DMA_CMN_REG(0x0034) /* Address Offset: 0x0034 */
#define RK_DMA_CMN_PCH_EN RK_DMA_CMN_REG(0x0040) /* Address Offset: 0x0040 */
#define RK_DMA_CMN_PCH_SEN RK_DMA_CMN_REG(0x0044) /* Address Offset: 0x0044 */
/* RK_DMA_Logic Channel Register Define */
#define RK_DMA_LCH_CTL0 RK_DMA_LCH_REG(0x0000) /* Address Offset: 0x0000 */
#define RK_DMA_LCH_CTL1 RK_DMA_LCH_REG(0x0004) /* Address Offset: 0x0004 */
#define RK_DMA_LCH_CMDBA RK_DMA_LCH_REG(0x0008) /* Address Offset: 0x0008 */
#define RK_DMA_LCH_TRF_CMD RK_DMA_LCH_REG(0x000c) /* Address Offset: 0x000C */
#define RK_DMA_LCH_CMDBA_HIGH RK_DMA_LCH_REG(0x0010) /* Address Offset: 0x0010 */
#define RK_DMA_LCH_IS RK_DMA_LCH_REG(0x0014) /* Address Offset: 0x0014 */
#define RK_DMA_LCH_IE RK_DMA_LCH_REG(0x0018) /* Address Offset: 0x0018 */
#define RK_DMA_LCH_DBGS0 RK_DMA_LCH_REG(0x001c) /* Address Offset: 0x001C */
#define RK_DMA_LCH_DBGC0 RK_DMA_LCH_REG(0x0020) /* Address Offset: 0x0020 */
#define RK_DMA_LCH_LLI_CNT RK_DMA_LCH_REG(0x0030) /* Address Offset: 0x0030 */
/* CMN_VER */
#define CMN_VER_MAJOR(v) GENMASK_VAL(v, 31, 16)
#define CMN_VER_MINOR(v) GENMASK_VAL(v, 15, 0)
/* CMN_CFG */
#define CMN_CFG_EN HIWORD_UPDATE(1, 0, 0)
#define CMN_CFG_DIS HIWORD_UPDATE(0, 0, 0)
#define CMN_CFG_SRST HIWORD_UPDATE(1, 1, 1)
#define CMN_CFG_IE_EN HIWORD_UPDATE(1, 2, 2)
#define CMN_CFG_IE_DIS HIWORD_UPDATE(0, 2, 2)
/* CMN_CAP0 */
#define CMN_LCH_NUM(v) (GENMASK_VAL(v, 5, 0) + 1)
#define CMN_PCH_NUM(v) (GENMASK_VAL(v, 11, 6) + 1)
#define CMN_BUF_DEPTH(v) (GENMASK_VAL(v, 31, 21) + 1)
/* CMN_CAP1 */
#define CMN_AXI_SIZE(v) (1 << GENMASK_VAL(v, 2, 0))
#define CMN_AXI_LEN(v) (GENMASK_VAL(v, 10, 3) + 1)
#define CMN_AXADDR_WIDTH(v) (32 + GENMASK_VAL(v, 18, 14) - 3)
#define CMN_AXOSR_SUP(v) (GENMASK_VAL(v, 23, 19) + 1)
/* CMN_PCH_EN */
#define CMN_PCH_EN(n) HIWORD_UPDATE(1, (n), (n))
#define CMN_PCH_DIS(n) HIWORD_UPDATE(0, (n), (n))
struct lp_rkdma_lch {
void __iomem *base;
u32 id;
};
struct lp_rkdma_dev {
struct device *dev;
struct lp_rkdma_lch *lch;
struct clk_bulk_data *clks;
void __iomem *base;
int irq;
int num_clks;
u32 bus_width;
u32 buf_dep;
u32 dma_channels;
u32 dma_requests;
u32 version;
};
static int lp_rkdma_init(struct lp_rkdma_dev *d)
{
int i, lch, pch, buswidth, maxburst, dep, addrwidth;
u32 cap0, cap1, ver;
writel(CMN_CFG_EN | CMN_CFG_IE_EN, RK_DMA_CMN_CFG);
ver = readl(RK_DMA_CMN_VER);
cap0 = readl(RK_DMA_CMN_CAP0);
cap1 = readl(RK_DMA_CMN_CAP1);
lch = CMN_LCH_NUM(cap0);
pch = CMN_PCH_NUM(cap0);
dep = CMN_BUF_DEPTH(cap0);
addrwidth = CMN_AXADDR_WIDTH(cap1);
buswidth = CMN_AXI_SIZE(cap1);
maxburst = CMN_AXI_LEN(cap1);
d->version = ver;
d->bus_width = buswidth;
d->buf_dep = dep;
d->dma_channels = CMN_LCH_NUM(cap0);
d->dma_requests = CMN_LCH_NUM(cap0);
writel(0xffffffff, RK_DMA_CMN_DYNCTL);
writel(0xffffffff, RK_DMA_CMN_IS0);
writel(0xffffffff, RK_DMA_CMN_IS1);
for (i = 0; i < pch; i++)
writel(CMN_PCH_EN(i), RK_DMA_CMN_PCH_EN);
dev_info(d->dev, "Lowpower RKDMA: NR_LCH-%d NR_PCH-%d PCH_BUF-%dx%dBytes AXI_LEN-%d ADDR-%dBits V%lu.%lu\n",
lch, pch, dep, buswidth, maxburst, addrwidth,
CMN_VER_MAJOR(ver), CMN_VER_MINOR(ver));
return 0;
}
static irqreturn_t lp_rkdma_irq_handler(int irq, void *dev_id)
{
struct lp_rkdma_dev *d = (struct lp_rkdma_dev *)dev_id;
struct lp_rkdma_lch *l = &d->lch[0];
u64 is = 0, is_raw = 0;
u32 i = 0;
aoa_middleware_dma_notifier(readl(RK_DMA_LCH_LLI_CNT));
is = readq(RK_DMA_CMN_IS0);
is_raw = is;
while (is) {
i = __ffs64(is);
is &= ~BIT_ULL(i);
l = &d->lch[i];
writel(readl(RK_DMA_LCH_IS), RK_DMA_LCH_IS);
}
writeq(is_raw, RK_DMA_CMN_IS0);
return IRQ_HANDLED;
}
int lp_rkdma_probe(struct platform_device *pdev)
{
struct lp_rkdma_dev *d;
int i, ret;
d = devm_kzalloc(&pdev->dev, sizeof(*d), GFP_KERNEL);
if (!d)
return -ENOMEM;
d->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(d->base))
return PTR_ERR(d->base);
d->num_clks = devm_clk_bulk_get_all(&pdev->dev, &d->clks);
if (d->num_clks < 1) {
dev_err(&pdev->dev, "Failed to get clk\n");
return -ENODEV;
}
d->irq = platform_get_irq(pdev, 0);
platform_set_drvdata(pdev, d);
/* Enable clock before access registers */
ret = clk_bulk_prepare_enable(d->num_clks, d->clks);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to enable clk: %d\n", ret);
return ret;
}
lp_rkdma_init(d);
/* init lch channel */
d->lch = devm_kcalloc(&pdev->dev, d->dma_channels, sizeof(struct lp_rkdma_lch), GFP_KERNEL);
if (!d->lch) {
ret = -ENOMEM;
goto err_disable_clk;
}
for (i = 0; i < d->dma_channels; i++) {
struct lp_rkdma_lch *l = &d->lch[i];
l->id = i;
l->base = RK_DMA_LCHn_REG(i, 0);
}
return devm_request_irq(&pdev->dev, d->irq, lp_rkdma_irq_handler, 0, dev_name(&pdev->dev), d);
err_disable_clk:
clk_bulk_disable_unprepare(d->num_clks, d->clks);
return ret;
}
int lp_rkdma_remove(struct platform_device *pdev)
{
struct lp_rkdma_dev *d = platform_get_drvdata(pdev);
clk_bulk_disable_unprepare(d->num_clks, d->clks);
return 0;
}

View File

@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Rockchip Low Power DMA Driver
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
* Author: Xing Zheng <zhengxing@rock-chips.com>
*/
#ifndef __LP_RKDMA_H__
#define __LP_RKDMA_H__
int lp_rkdma_probe(struct platform_device *pdev);
int lp_rkdma_remove(struct platform_device *pdev);
#endif /* __LP_RKDMA_H__ */

View File

@@ -232,6 +232,30 @@
#define RKMODULE_GET_ERROR_INFO \
_IOR('V', BASE_VIDIOC_PRIVATE + 56, struct rkmodule_error_info)
#define RKMODULE_SET_EXPAND_SINGLE_MODE \
_IOW('V', BASE_VIDIOC_PRIVATE + 57, __u32)
#define RKMODULE_SET_LENC \
_IOW('V', BASE_VIDIOC_PRIVATE + 58, struct rkmodule_lenc_gain)
#define RKMODULE_GET_LENC_INFO \
_IOR('V', BASE_VIDIOC_PRIVATE + 59, struct rkmodule_lenc_info)
#define RKMODULE_SET_REG_SETTING \
_IOW('V', BASE_VIDIOC_PRIVATE + 60, struct rkmodule_reg_setting)
#define RKMODULE_SET_BAYER_MODE \
_IOW('V', BASE_VIDIOC_PRIVATE + 61, struct rkmodule_bayer_param)
#define RKMODULE_GET_HDR_COMPR_SINGLE_FRAME_INFO \
_IOR('V', BASE_VIDIOC_PRIVATE + 62, struct rkmodule_hdr_compr_single_frame_info)
#define RKMODULE_REG_LIST_MAX (16)
struct rkmodule_reg_struct {
__u32 reg_addr;
__u32 reg_val;
};
struct rkmodule_i2cdev_info {
__u8 slave_addr;
} __attribute__ ((packed));
@@ -537,6 +561,8 @@ enum exp_mode_e {
EXP_HDR3_DCG_VS,
EXP_HDR3_DCG_SPD,
EXP_HDR3_STA,
EXP_HDR3_DCG_LOFIC,
EXP_HDR3_LCG_LOFIC_VS,
};
struct rkmodule_hdr_cfg {
@@ -964,9 +990,15 @@ enum rkmodule_blc_type {
};
struct rkmodule_blc_group {
__u32 enable;
__u32 group_num;
enum rkmodule_blc_type blc_type[RKMODULE_MAX_BLC_GROUP];
__u32 blc[RKMODULE_MAX_BLC_GROUP];
__u32 bkdg_sw_en;
__u32 dgbk2bkdg_thred;
__u32 bkdg2dgbk_thred;
__u32 reg_num;
struct rkmodule_reg_struct reg_list[RKMODULE_REG_LIST_MAX];
};
enum rkmodule_bayer_mode {
@@ -995,4 +1027,63 @@ struct rkmodule_error_info {
__u8 detail[256];
};
enum rkmodule_expand_single_mode {
EXPAND_SINGLE_LCG,
EXPAND_SINGLE_HCG,
EXPAND_SINGLE_VS,
EXPAND_SINGLE_SPD,
EXPAND_SINGLE_LOFIC,
};
#define RKMODULE_MAX_LENC_GROUP (4)
struct rkmodule_lenc_gain {
__u32 g[RKMODULE_LSCDATA_LEN];
__u32 b[RKMODULE_LSCDATA_LEN];
__u32 r[RKMODULE_LSCDATA_LEN];
};
struct rkmodule_lenc_data {
__u16 rgain;
__u16 bgain;
struct rkmodule_lenc_gain lenc_gain;
};
struct rkmodule_lenc_inf {
__u32 flag;
__u32 group_num;
__u32 lenc_gain_len;
struct rkmodule_lenc_data lenc_data[RKMODULE_MAX_LENC_GROUP];
};
struct rkmodule_lenc_info {
__u32 bit_width;
__u32 grid_num;
__u32 reserved[8];
};
enum rkmodule_binning_mode {
BAYER_BINNING_2X2,
BAYER_SKIP_2X2,
QBC_BINNING_2X2,
};
struct rkmodule_reg_setting {
__u32 setting_id;
__u32 binning_mode;
__u32 reg_num;
struct rkmodule_reg_struct reg_list[RKMODULE_REG_LIST_MAX];
};
struct rkmodule_bayer_param {
__u32 bayer_mode;
__u32 reg_num;
struct rkmodule_reg_struct reg_list[RKMODULE_REG_LIST_MAX];
};
struct rkmodule_hdr_compr_single_frame_info {
__u32 single_bitwidth;
__u32 reserved[8];
};
#endif /* _UAPI_RKMODULE_CAMERA_H */

View File

@@ -100,11 +100,13 @@ struct rk_cam_set_focus {
struct rk_cam_zoom_pos {
__s32 zoom_pos;
__s32 zoom1_pos;
__s32 focus_pos;
};
struct rk_cam_set_zoom {
_Bool is_need_zoom_reback;
_Bool is_need_zoom1_reback;
_Bool is_need_focus_reback;
__u32 setzoom_cnt;
struct rk_cam_zoom_pos zoom_pos[VCMDRV_SETZOOM_MAXCNT];