RK3568 Sensor驱动开发移植
说明
RK3568 Sensor 驱动位于 drivers/media/i2c 目录下。
可以把Sensor 驱动的开发移植概括为以下 5 个部分:
- 按照Sensor的datasheet 编写上下电时序,主要包括 vdd、reset、powerdown、clk 等
- 配置Sensor 的寄存器以输出所需的分辨率、格式
- 编写 struct v4l2_subdev_ops 所需要的回调函数,一般包括 set_fmt、get_fmt、s_stream、s_power
- 增加 v4l2 controller 用来设置如fps、exposure、gain、test pattern
- 编写 probe()函数,并添加 Media Control 及 Sub Device 初始化代码
dts
根据硬件的设计,主要是正确配置clk及 pinctl(iomux)、根据原理图设置上电时序所需要的 regulator 及 gpio、增加 port 子节点,与 cif 或者 isp 建立连接:
- pinctrl,初始化必要的pin iomux,包括了 reset pin 、pwdn pin、power pin初始化和 clk iomux
- clock,指定名称为xvclk(驱动会讯取名为 xvclk 的 clock),即 24M 时钟
- vdd supply,Sensor 需要的三路供电 avdd、dovdd、dvdd
- port 子节点,定义了一个 endpoint,声明需要与 mipi_in_wcam 建立连接。同样地 mipi dphy 会引用wcam_out
- data-lanes 指定了 Sensor使用几个 lane。wcam_out节点中,data-lanes需要与之相匹配
以gc8034为例:
&i2c4 {
status = "okay";
gc8034: gc8034@37 {
compatible = "galaxycore,gc8034";// 需要与驱动中的匹配字符串一致
status = "okay";
reg = <0x37>;// sensor I2C 设备地址
clocks = <&cru CLK_CIF_OUT>;// sensor clickin 配置
clock-names = "xvclk";
pinctrl-names = "default";// pinctl 设置
pinctrl-0 = <&cif_clk>;
reset-gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>;// reset 管脚分配及有效电平
pwdn-gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_LOW>;// power 管脚分配及有效电平
rockchip,grf = <&grf>;
rockchip,camera-module-index = <0>;// 模组编号,该编号不要重复
rockchip,camera-module-facing = "back";// 模组朝向,有"back"和"front"
// 模组名和 lens 名被用来和 IQ xml 文件做匹配
rockchip,camera-module-name = "RK-CMK-8M-2-v1";// 模组名
rockchip,camera-module-lens-name = "CK8401";// lens 名
/*lens-focus = <&vm149c>; // vcm 驱动设置,支持 AF 时需要有这个设置*/
avdd-supply = <&vcc2v8_dvp>; // sensor 电源配置
dovdd-supply = <&vcc1v8_dvp>;
dvdd-supply = <&vcc1v8_dvp>;
port {
gc8034_out: endpoint {
remote-endpoint = <&mipi_in_ucam1>;// mipi dphy 端的 port 名
data-lanes = <1 2 3 4>;// mipi lane 数, 1lane 为 <1>, 4lane 为 <1 2 3 4>
};
};
};
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
驱动
上下电时序
不同 Sensor 对上下电时序要求不同,在 Sensor 厂家提供的 DataSheet 中,一般会有上电时序图,只需要按顺序配置即可。其中_power_on() 即是用来给 Sensor 上电。
上电时序简要说明如下:
- 首先提供 xvclk(即 mclk)
- 紧接着 reset pin 、pwdn pin使能
- 各路的 vdd 上电。这里使用了 regulator_bulk ,因为 vdd,vodd,avdd 三者无严格顺序。如果vdd 之间有严格的要求,需要分开处理
- 设置Sensor Reset,powerdown pin 为工作状态。Reset,powerdown 、、Power可能只需要一个。根据Sensor 封装及硬件原理图的实际需要配置
- 最后按Sensor的时序要求,是否需要delay 诺干个 clk cycle 之后,上电才算完成
代码如下:
static int __gc8034_power_on(struct gc8034 *gc8034)
{
int ret;
u32 delay_us;
struct device *dev = &gc8034->client->dev;
if (!IS_ERR(gc8034->power_gpio))
gpiod_set_value_cansleep(gc8034->power_gpio, 1);
usleep_range(1000, 2000);
if (!IS_ERR_OR_NULL(gc8034->pins_default)) {
ret = pinctrl_select_state(gc8034->pinctrl,
gc8034->pins_default);
if (ret < 0)
dev_err(dev, "could not set pins\n");
}
ret = clk_set_rate(gc8034->xvclk, GC8034_XVCLK_FREQ);
if (ret < 0)
dev_warn(dev, "Failed to set xvclk rate (24MHz)\n");
if (clk_get_rate(gc8034->xvclk) != GC8034_XVCLK_FREQ)
dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
ret = clk_prepare_enable(gc8034->xvclk);
if (ret < 0) {
dev_err(dev, "Failed to enable xvclk\n");
return ret;
}
if (!IS_ERR(gc8034->reset_gpio))
gpiod_set_value_cansleep(gc8034->reset_gpio, 1);
ret = regulator_bulk_enable(GC8034_NUM_SUPPLIES, gc8034->supplies);
if (ret < 0) {
dev_err(dev, "Failed to enable regulators\n");
goto disable_clk;
}
usleep_range(1000, 1100);
if (!IS_ERR(gc8034->reset_gpio))
gpiod_set_value_cansleep(gc8034->reset_gpio, 0);
usleep_range(500, 1000);
if (!IS_ERR(gc8034->pwdn_gpio))
gpiod_set_value_cansleep(gc8034->pwdn_gpio, 0);
/* 8192 cycles prior to first SCCB transaction */
delay_us = gc8034_cal_delay(8192);
usleep_range(delay_us, delay_us * 2);
return 0;
disable_clk:
clk_disable_unprepare(gc8034->xvclk);
return ret;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
同样,datasheet 中还会有下电时序(Power Down Sequence),也需要按要求实现,代码如下:
static void __gc8034_power_off(struct gc8034 *gc8034)
{
int ret;
if (!IS_ERR(gc8034->pwdn_gpio))
gpiod_set_value_cansleep(gc8034->pwdn_gpio, 1);
clk_disable_unprepare(gc8034->xvclk);
if (!IS_ERR(gc8034->reset_gpio))
gpiod_set_value_cansleep(gc8034->reset_gpio, 1);
if (!IS_ERR_OR_NULL(gc8034->pins_sleep)) {
ret = pinctrl_select_state(gc8034->pinctrl,
gc8034->pins_sleep);
if (ret < 0)
dev_dbg(&gc8034->client->dev, "could not set pins\n");
}
if (!IS_ERR(gc8034->power_gpio))
gpiod_set_value_cansleep(gc8034->power_gpio, 0);
regulator_bulk_disable(GC8034_NUM_SUPPLIES, gc8034->supplies);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
Sensor Regs Init
在 Sensor驱动中,需要定义了 struct sensor_mode ,用来初始化不同的 Sensor mode,即Sensor可以输出不同分辨率的图像、不同的fps等。Mode 包括分辨率(width、height),Mbus Code,max_fps,寄存器初始化列表等。
struct sensor_mode
struct gc8034_mode {
u32 width;//有效图像宽度
u32 height;//有效图像高度
struct v4l2_fract max_fps;//图像 FPS, denominator/numerator 为 fps
u32 hts_def;//默认 HTS,为有效图像宽度 + HBLANK
u32 vts_def;//默认 VTS,为有效图像高度 + VBLANK
u32 exp_def;//默认曝光时间
const struct regval *reg_list;//寄存器列表
};
static const struct gc8034_mode supported_modes_2lane[] = {
{
.width = 1632,
.height = 1224,
.max_fps = {
.numerator = 10000,
.denominator = 300000,
},
.exp_def = 0x09a0,
.hts_def = 0x0858 * 2,
.vts_def = 0x09c4,
.reg_list = gc8034_1632x1224_regs_2lane,
},
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
ensor驱动中的 exp_def 、 hts_def 、 vts_def ,从datasheet中查找到对应的寄存器,并从寄存器列表中找到初始化时配置的值即可。
初始化寄存器
/*
* Xclk 24Mhz
* max_framerate 30fps
* mipi_datarate per lane 672Mbps
*/
static const struct regval gc8034_1632x1224_regs_2lane[] = {
/*SYS*/
{0xf2, 0x00},
{0xf4, 0x80},
{0xf5, 0x19},
{0xf6, 0x44},
{0xf8, 0x63},
{0xfa, 0x45},
{0xf9, 0x00},
{0xf7, 0x95},
{0xfc, 0x00},
{0xfc, 0x00},
{0xfc, 0xea},
{0xfe, 0x03},
{0x03, 0x9a},
{0xfc, 0xee},
{0xfe, 0x10},
{0xfe, 0x00},
{0xfe, 0x10},
{0xfe, 0x00},
/*ISP*/
{0xfe, 0x00},
{0x80, 0x10},
{0xad, 0x30},
{0x66, 0x2c},
{0xbc, 0x49},
/*Crop window*/
{0x90, 0x01},
{0x92, BINNING_STARTY}, //crop y
{0x94, BINNING_STARTX}, //crop x
{0x95, 0x04},
{0x96, 0xc8},
{0x97, 0x06},
{0x98, 0x60},
/*MIPI*/
{0xfe, 0x03},
{0x01, 0x07},
{0x02, 0x03},
{0x04, 0x80},
{0x11, 0x2b},
{0x12, 0xf8},
{0x13, 0x07},
{0x15, 0x10}, //LP mode
{0x16, 0x29},
{0x17, 0xff},
{0x18, 0x01},
{0x19, 0xaa},
{0x1a, 0x02},
{0x21, 0x05},
{0x22, 0x06},
{0x23, 0x16},
{0x24, 0x00},
{0x25, 0x12},
{0x26, 0x07},
{0x29, 0x07},
{0x2a, 0x08},
{0x2b, 0x07},
{0xfe, 0x00},
{0x3f, 0x00},
{REG_NULL, 0x00},
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
寄存器初始化列表,请按厂家提供的直接填入即可。需要注意的是,列表最后用了 REG_NULL 表示结束。注意REG_NULL不要和寄存器地址冲突。
版权声明:本文为CSDN博主「悲伤的小强」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_29890089/article/details/121282260
- 分享
- 举报

-
浏览量:1333次2023-12-08 16:48:29
-
浏览量:1517次2024-02-18 17:07:58
-
浏览量:2083次2024-01-10 10:01:45
-
浏览量:18735次2022-09-30 16:51:48
-
浏览量:4266次2022-10-11 10:48:08
-
浏览量:2807次2022-09-30 16:48:25
-
浏览量:6947次2022-10-08 14:00:42
-
浏览量:10446次2022-10-10 11:27:15
-
浏览量:8316次2022-10-13 19:26:04
-
浏览量:5296次2022-09-26 11:51:17
-
浏览量:11065次2022-10-09 15:56:41
-
浏览量:3863次2024-03-18 14:27:20
-
浏览量:5274次2022-10-14 08:34:42
-
浏览量:11959次2022-10-18 09:33:58
-
浏览量:10167次2022-09-27 10:22:54
-
浏览量:1171次2024-03-12 16:42:47
-
浏览量:13612次2022-09-28 13:51:28
-
浏览量:8879次2022-10-17 11:49:55
-
浏览量:1879次2024-01-12 17:56:48
- 第二波任性大奖名单公布!看看有木有你?
- 独家采访:结盟Intel,瑞芯微首款WCDMA芯片即将问世
- RV1126运行rknn_yolov5_demo案例失败解决方法
- camera闪光灯驱动移植笔记-基于rk3568
- 安装rk1109/rk1126环境
- RK3399Pro及RK3399通过 Arm SystemReady 认证
- 【RK3288游戏王兼容能力PK评测】ps:这绝对绝对不是一次叫板
- 这也许是当前最适合“游戏微主机”的芯片了!看亚太OTT峰会上如何剖析RK3288
- imx327 处理 sensor 预览画面整体均匀偏红问题
- rv1126_rv1109移植opencv with ffmpeg for rtsp
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖

tomato






举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明