В этой статье в качестве примера используется внешнее подключение RK3568 к GC8034. Сначала описывается метод адаптации камеры MIPI CSI, а затем приводятся некоторые подробности о драйвере датчика cmos и рабочем процессе драйвера датчика cmos.
Он поддерживает интерфейс MIPI CSI. Этот интерфейс является 4LANE и может быть разделен на два интерфейса 2LANE. Модуль камеры — TSC8034-HYX5, производитель неизвестен, основное управление этим модулем — GC8034. Кроме того, в модуле имеется DW9714, который представляет собой VCM, используемый для управления расширением и сжатием линзы. Модуль подключается к плате адаптера, а затем плата адаптера подключается к интерфейсу MIPI CSI платы разработки YY3568 через кабель. Аппаратные соединения следующие.
Большинство датчиков изображения cmos, представленных в настоящее время на рынке, обычно включают в себя интерфейсы управления (i2c\spi и т. д.) для чтения и записи регистров, а также интерфейсы данных (csi/bt656 и т. д.) для передачи необработанных данных изображения.
Весь анализ исходного кода в этой статье основан на версии ядра rk 4.19. Соответствующий исходный код можно получить на сайте Hot Wheels Technology по адресу загрузки.
Ссылка на исходный код Android: https://pan.baidu.com/s/1rK-3hwkVd0FYBdSrQrbyVA?pwd=n8io.
Ссылка на исходный код Debian: https://pan.baidu.com/s/1NynxVL6VnqPBSOVkRu8J7Q?pwd=t6cg
Исходный код ядра, используемый Android и Debian, один и тот же.
V4L2 (Видео для linux2) — это драйвер ядра для видеоустройств в Linux. В настоящее время все платформы RK используют платформу V4L2 для работы с камерой. Состав платформы V4L2 примерно такой, как показано на рисунке ниже.
В V4L2 есть три типа устройств: v4l2-subdev, v4l2_device и videobuf2-core.
v4l2-subdev относится к аппаратному интерфейсу, включая датчик, а также к интерфейсам датчиков, таким как mipicsi или bt656 и т. д. Для пользовательского уровня управляющим узлом является /dev/v4l-subdevX.
v4l2_device относится к устройству, которое может передавать данные на пользовательский уровень. На платформе rk этим устройством может быть ISP (блок обработки сигналов изображения) или CIF (интерфейс камеры). ISP имеет функции обработки изображений, функции масштабирования и сжатия. Если вам нужно предварительно обработать изображение, вам нужно использовать ISP. Его управляющий узел — /dev/videoX.
videobuf2-core используется для выделения и обработки буферов видеокадров, например, для обеспечения поддержки mmap и других операций.
Сначала настройте ссылку。из-заGC8034получатьиз Изображения должны быть предварительно обработаны, прежде чем они смогут быть использованы пользовательским слоем.,Поэтому вам нужно использовать интернет-провайдера,Установите ссылку наGC8034-> MIPI интерфейс->ISP。
Сначала настройте GC8034. Определение интерфейса встроенной камеры следующее:
Здесь видно, что вывод сброса использует GPIO3_B5, вывод включения питания использует GPIO4_B5, а затем использует I2C4 для связи с GC8034 и DW9714. Кроме того, часы камеры должны обеспечиваться основным элементом управления. заключается в следующем.
&i2c4 {
status = "okay";
dw9714: dw9714@c {
compatible = "dongwoon,dw9714";
status = "okay";
reg = <0x0c>;
rockchip,camera-module-index = <0>;
rockchip,vcm-start-current = <10>;
rockchip,vcm-rated-current = <85>;
rockchip,vcm-step-mode = <5>;
rockchip,camera-module-facing = "back";
};
gc8034: gc8034@37 {
compatible = "galaxycore,gc8034";
reg = <0x37>;
clocks = <&cru CLK_CIF_OUT>;
clock-names = "xvclk";
power-domains = <&power RK3568_PD_VI>;
//sensor mclk настройки pinctl. Если рабочие часы датчика предоставляются мастером, их необходимо настроить здесь.
pinctrl-names = "default";
pinctrl-0 = <&cif_clk>;
// сброс назначения контактов и эффективный уровень
reset-gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>;
// Назначение контактов отключения питания и эффективный уровень
pwdn-gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_LOW>;
rockchip,grf = <&grf>;
// Номер модуля, не повторяйте этот номер
rockchip,camera-module-index = <0>;
// Ориентация модуля, в том числе «сзади» и «спереди»
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "RK-CMK-8M-2-v1";
rockchip,camera-module-lens-name = "CK8401";
lens-focus = <&dw9714>;
port {
gc8034_out: endpoint {
// csi2 Имя порта на стороне dphy
remote-endpoint = <&mipi_in_ucam0>;
// csi2 dphy Количество полос движения, 1 полоса <1>, 4-полосная это <1 2 3 4>
// rk3568 поддерживает два режима: 1*4 полосы и 2*2 линии.
data-lanes = <1 2 3 4>;
};
};
};
};
Затем вам необходимо настроить ссылку CSI. CSI RK3568 имеет два режима работы: 1*4LANE и 2*2LANE. В первом случае вам необходимо включить csi2_dphy0 и отключить csi2_dphy1/csi2_dphy2. Последнее является противоположностью. Входной конец CSI — это GC8034, соединение 4LANE, а выходной конец — ISP, поэтому конфигурация следующая.
&csi2_dphy0 {
//csi2_dphy0 не используется одновременно с csi2_dphy1/csi2_dphy2, это взаимоисключающее
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipi_in_ucam0: endpoint@2 {
reg = <2>;
remote-endpoint = <&gc8034_out>;
data-lanes = <1 2 3 4>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
csidphy_out: endpoint@0 {
reg = <0>;
remote-endpoint = <&isp0_in>;
};
};
};
};
Тогда интернет-провайдеру нужно только настроить входную сторону для CSI.
&rkisp_vir0 {
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
isp0_in: endpoint@0 {
reg = <0>;
remote-endpoint = <&csidphy_out>;
};
};
};
После настройки этой ссылки скомпилируйте ядро, а затем запишите ядро на плату, чтобы использовать камеру.
Журнал ядра выглядит следующим образом
Если вы видите этот журнал, это означает, что связь между gc8034 и csi2-dphy подключена.
Ниже представлен драйвер GC8034. В ядре, благодаря существованию платформы V4L2, процессы платформы большинства драйверов датчика изображения cmos аналогичны, за исключением различий в операциях с регистрами.
Первый — регистрация драйвера. GC8034 поддерживает настройку регистров через I2C, но его интерфейс CSI можно использовать только для отправки необработанных данных изображения и им нельзя управлять. Следовательно, это устройство I2C. Начало работы драйвера — регистрация устройства I2C. следующее
Когда описание устройства в дереве устройств соответствует драйверу, будет выполнена функция проверки. Давайте посмотрим на функцию зонда.
static int gc8034_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
struct device_node *node = dev->of_node;
struct gc8034 *gc8034;
struct v4l2_subdev *sd;
char facing[2];
int ret;
...
gc8034 = devm_kzalloc(dev, sizeof(*gc8034), GFP_KERNEL);
if (!gc8034)
return -ENOMEM;
// Эти данные предназначены для sensor из ioctl Получить статус модуля
// Платформа RK Некоторые приложения верхнего уровня (например, приложение Android для камеры) Эту информацию необходимо получить для переключения передней и задней камеры, согласования параметров 3А и т. д.
ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
&gc8034->module_index);
ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
&gc8034->module_facing);
ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
&gc8034->module_name);
ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
&gc8034->len_name);
...
gc8034->client = client;
gc8034->xvclk = devm_clk_get(dev, "xvclk");
...
// источник питания Сброс и т. д. gpio получать
...
ret = gc8034_configure_regulators(gc8034);
...
// Эта функцияполучатьсоответствоватьизинтерфейс,То есть конфигурация дерева устройств CSIиз,В основном количество полос
ret = gc8034_parse_of(gc8034);
...
// pinctrlресурсполучать
...
mutex_init(&gc8034->mutex);
// самое важноеизписьмочисло v4l2_i2c_subdev_init Эта функция регистрирует v4l2 subdev, то есть регистрация этой камеры в фреймворке v4l2
// в gc8034_subdev_ops визто естьgc8034Реагировать на контроль верхнего уровняиз回调письмочисло
sd = &gc8034->subdev;
v4l2_i2c_subdev_init(sd, client, &gc8034_subdev_ops);
ret = gc8034_initialize_controls(gc8034);
...
// Включение питания
ret = __gc8034_power_on(gc8034);
...
// Определите этоi2cОно там?gc8034существовать,Если из не существует, все вышеперечисленные операции будут завершены.
ret = gc8034_check_sensor_id(gc8034, client);
...
// Читать gc8034 отп регистрация
gc8034_otp_enable(gc8034);
gc8034_otp_read(gc8034);
gc8034_otp_disable(gc8034);
#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
sd->internal_ops = &gc8034_internal_ops;
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
V4L2_SUBDEV_FL_HAS_EVENTS;
#endif
#if defined(CONFIG_MEDIA_CONTROLLER)
gc8034->pad.flags = MEDIA_PAD_FL_SOURCE;
sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
ret = media_entity_pads_init(&sd->entity, 1, &gc8034->pad);
if (ret < 0)
goto err_power_off;
#endif
...
// Это устройство v4l2 использует асинхронную регистрацию.
ret = v4l2_async_register_subdev_sensor_common(sd);
...
return 0;
...
}
Вся функция зонда очень длинная. Здесь удалены части обработки ошибок и печати, а для остальных операций предусмотрены комментарии. Процесс его работы заключается в том, чтобы сначала получить информацию из дерева устройств, затем подать заявку на такие ресурсы, как gpio, зарегистрировать устройство v4l2, а затем попытаться прочитать идентификатор gc8034. Если gc8034 существует, прочитать его регистр otp. Во время процесса запуска ядра эта информация распечатывается с помощью регистра otp.
Вообще говоря, модуль необходимо откалибровать при выходе с завода, поскольку существуют аппаратные различия в модулях, разработанных разными производителями на основе одного и того же сенсорного чипа. Калибровка включает в себя AF (калибровку автоматической фокусировки), AWB (калибровку баланса белого). , LSC (калибровка затенения объектива), а также дата, месяц и год изготовления модуля, название производителя и т. д. Первое обычно должно быть получено верхним уровнем, чтобы верхний уровень мог настроить параметры калибровки.
Кроме того, в структуре v4l2 есть несколько важных структур. следующее
static const struct v4l2_subdev_core_ops gc8034_core_ops = {
.s_power = gc8034_s_power,
.ioctl = gc8034_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl32 = gc8034_compat_ioctl32,
#endif
};
static const struct v4l2_subdev_video_ops gc8034_video_ops = {
.s_stream = gc8034_s_stream,
.g_frame_interval = gc8034_g_frame_interval,
.g_mbus_config = gc8034_g_mbus_config,
};
static const struct v4l2_subdev_pad_ops gc8034_pad_ops = {
.enum_mbus_code = gc8034_enum_mbus_code,
.enum_frame_size = gc8034_enum_frame_sizes,
.enum_frame_interval = gc8034_enum_frame_interval,
.get_fmt = gc8034_get_fmt,
.set_fmt = gc8034_set_fmt,
};
static const struct v4l2_subdev_ops gc8034_subdev_ops = {
.core = &gc8034_core_ops,
.video = &gc8034_video_ops,
.pad = &gc8034_pad_ops,
};
в,
v4l2_subdev_core_ops — это в основном реализация общей инициализации. Операция включения и выключения реализована в gc8034, которая представляет собой функцию gc8034_s_power, а также есть операция ioctl — gc8034_ioctl и gc8034_compat_ioctl32.
Эта функция s_power в основном использует структуру управления питанием Linux (pm) для реализации высокого и низкого уровня напряжения на выводе включения питания gc8034. Этот драйвер реализует функции приостановки и возобновления в dev_pm_ops.
Существует также функция write_array, которая в основном используется для инициализации большинства регистров. Оригинальные производители большинства датчиков предоставляют таблицы конфигурации регистров для нескольких разрешений. Размещение этой функции здесь означает, что все регистры повторно инициализируются каждый раз, когда включается питание gc8034.
Функция ioctl обычно реализует некоторые частные команды ioctl платформы (общие команды ioctl v4l2 реализуются через другие операции). Например, RKMODULE_GET_MODULE_INFO здесь предназначен для получения ориентации и имени конфигурации дерева устройств, а RKMODULE_AWB_CFG — для получения значения в регистре otp, упомянутом выше.
v4l2_subdev_video_ops в основном управляет видеопотоком, из которых необходимо реализовать s_stream для управления открытием и закрытием видеопотока. g_frame_interval используется для получения текущей частоты кадров, g_mbus_config используется для получения номера полосы, который может быть только 2-полосным и 4-полосным для gc8034.
v4l2_subdev_pad_ops в основном управляет форматом видео. enum_mbus_code enum_frame_size
Три члена enum_frame_interval предназначены для получения формата, разрешения и частоты кадров, поддерживаемых текущим датчиком. Два члена get_fmt и set_fmt используются для получения и установки разрешения формата и частоты кадров текущего датчика.
Для платформы rk для реализации драйвера датчика достаточно реализовать вышеуказанный API. Если это другие платформы, это зависит от того, требуется ли приватный ioctl. Универсальный драйвер v4l2 не требует частного ioctl.
Подвести итог
В этой статье в качестве примера используется внешнее подключение RK3568 к GC8034. Сначала описывается метод адаптации камеры MIPI CSI, а затем приводятся некоторые подробности о драйвере датчика cmos и рабочем процессе драйвера датчика cmos. Обратитесь к драйверу GC8034iz.,Может быть реализован на общей платформеsensorизприспособление。