Skip to content

Commit 8103e66

Browse files
committed
WIP: Support Pinephone Pro
Both cameras work now but the quality is very poor. Tested with Linux 6.1.12-1 from Arch Linux ARM (linux-megi).
1 parent af01107 commit 8103e66

File tree

8 files changed

+296
-70
lines changed

8 files changed

+296
-70
lines changed

config/motorola,osprey.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ preview-rate=30
1515
preview-fmt=RGGB10P
1616
rotate=270
1717
media-links=msm_csiphy0:1->msm_csid0:0,msm_csid0:1->msm_ispif0:0,msm_ispif0:1->msm_vfe0_rdi0:0
18+
media-formats=msm_csiphy0:1:RGGB10P:4096:2304,msm_csid0:0:RGGB10P:4096:2304,msm_csid0:1:RGGB10P:4096:2304,msm_ispif0:0:RGGB10P:4096:2304,msm_ispif0:1:RGGB10P:4096:2304,msm_vfe0_rdi0:0:RGGB10P:4096:2304

config/pine64,pinephone-pro.ini

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
[device]
2+
make=PINE64
3+
model=PinePhone
4+
5+
[rear]
6+
driver=imx258 1-001a
7+
media-driver=rkisp1
8+
capture-width=1048
9+
capture-height=780
10+
capture-rate=30
11+
capture-fmt=RGGB8
12+
preview-width=1048
13+
preview-height=780
14+
preview-rate=30
15+
preview-fmt=RGGB8
16+
rotate=270
17+
mirrored=false
18+
blacklevel=3
19+
whitelevel=255
20+
focallength=2.35
21+
cropfactor=10.81
22+
fnumber=2.2
23+
iso-min=100
24+
iso-max=64000
25+
flash-path=/sys/class/leds/white:flash
26+
media-links=imx258 1-001a:0->rkisp1_csi:0,rkisp1_csi:1->rkisp1_isp:0,rkisp1_isp:2->rkisp1_resizer_mainpath:0
27+
media-formats=imx258 1-001a:0:RGGB10P:1048:780,rkisp1_csi:0:RGGB10P:1048:780,rkisp1_isp:0:RGGB10P:1048:780,rkisp1_isp:2:RGGB8:1048:780,rkisp1_resizer_mainpath:0:RGGB8:1048:780,rkisp1_resizer_mainpath:1:RGGB8:1048:780
28+
media-crops=rkisp1_isp:0:0:0:1048:780,rkisp1_isp:2:0:0:1048:780,rkisp1_resizer_mainpath:0:0:0:1048:768
29+
30+
[front]
31+
driver=ov8858
32+
media-driver=rkisp1
33+
capture-width=3264
34+
capture-height=2448
35+
capture-rate=30
36+
capture-fmt=BGGR8
37+
preview-width=3264
38+
preview-height=2448
39+
preview-rate=30
40+
preview-fmt=BGGR8
41+
rotate=90
42+
mirrored=true
43+
focallength=2.94
44+
cropfactor=12.7
45+
fnumber=2.4
46+
flash-display=true
47+
media-links=ov8858:0->rkisp1_csi:0,rkisp1_csi:1->rkisp1_isp:0,rkisp1_isp:2->rkisp1_resizer_mainpath:0,rkisp1_resizer_mainpath:1->rkisp1_mainpath:0
48+
media-formats=ov8858:0:BGGR10P:3264:2448,rkisp1_csi:0:BGGR10P:3264:2448,rkisp1_isp:0:BGGR10P:3264:2448,rkisp1_isp:2:BGGR8:3264:2448,rkisp1_resizer_mainpath:0:BGGR8:3264:2448,rkisp1_resizer_mainpath:1:BGGR8:3264:2448
49+
media-crops=rkisp1_isp:0:0:0:3264:2448,rkisp1_isp:2:0:0:3264:2448,rkisp1_resizer_mainpath:0:0:0:3264:768

config/xiaomi,scorpio.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ preview-rate=30
1515
preview-fmt=RGGB10P
1616
rotate=90
1717
media-links=imx318 3-001a:0->msm_csiphy0:0,msm_csiphy0:1->msm_csid0:0,msm_csid0:1->msm_ispif0:0,msm_ispif0:1->msm_vfe0_rdi0:0
18+
media-formats=imx318 3-001a:0:RGGB10P:3840:2160,msm_csiphy0:0:RGGB10P:3840:2160,msm_csiphy0:1:RGGB10P:3840:2160,msm_csid0:0:RGGB10P:3840:2160,msm_csid0:1:RGGB10P:3840:2160,msm_ispif0:0:RGGB10P:3840:2160,msm_ispif0:1:RGGB10P:3840:2160,msm_vfe0_rdi0:0:RGGB10P:3840:2160

meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ install_data(
7272
'config/pine64,pinephone-1.0.ini',
7373
'config/pine64,pinephone-1.1.ini',
7474
'config/pine64,pinephone-1.2.ini',
75+
'config/pine64,pinephone-pro.ini',
7576
'config/pine64,pinetab.ini',
7677
'config/xiaomi,scorpio.ini',
7778
],

src/camera.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,12 @@ mp_camera_set_mode(MPCamera *camera, MPMode *mode)
327327
}
328328

329329
// Update the mode
330-
mode->pixel_format =
331-
mp_pixel_format_from_v4l_bus_code(fmt.format.code);
330+
331+
// TODO: Some how the format gets changed to YUYV if this isn't
332+
// commented out.
333+
//mode->pixel_format =
334+
// mp_pixel_format_from_v4l_bus_code(fmt.format.code);
335+
332336
mode->frame_interval = interval.interval;
333337
mode->width = fmt.format.width;
334338
mode->height = fmt.format.height;

src/device.c

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#include <string.h>
99
#include <sys/ioctl.h>
1010
#include <unistd.h>
11+
#include <linux/v4l2-subdev.h>
12+
#include <linux/media.h>
1113

1214
bool
1315
mp_find_device_path(struct media_v2_intf_devnode devnode, char *path, int length)
@@ -73,6 +75,46 @@ xioctl(int fd, int request, void *arg)
7375
return r;
7476
}
7577

78+
static int
79+
mp_device_get_fd_by_name(const MPDevice *device, const char *driver_name)
80+
{
81+
struct media_entity_desc desc = {};
82+
83+
desc.id |= MEDIA_ENT_ID_FLAG_NEXT;
84+
85+
while(true) {
86+
desc.id |= MEDIA_ENT_ID_FLAG_NEXT;
87+
if(xioctl(device->fd, MEDIA_IOC_ENUM_ENTITIES, &desc) == -1) {
88+
errno_printerr("MEDIA_IOC_ENUM_ENTITIES");
89+
return -1;
90+
}
91+
92+
if(strncmp(desc.name, driver_name, 32) == 0) {
93+
const uint32_t major = desc.dev.major;
94+
const uint32_t minor = desc.dev.minor;
95+
char path[256];
96+
int rc = snprintf(path, 256, "/dev/char/%u:%u", major, minor);
97+
98+
return rc > 0 ? open(path, O_RDWR) : -1;
99+
}
100+
}
101+
102+
return -1;
103+
}
104+
105+
static bool
106+
mp_xioctl(const MPDevice *device, const char *driver_name, unsigned long request, void *argp)
107+
{
108+
int fd = mp_device_get_fd_by_name(device, driver_name);
109+
110+
if(fd < 0)
111+
{
112+
printf("ERROR: device with driver name %s not found\n", driver_name);
113+
}
114+
115+
return fd >= 0 && xioctl(fd, request, argp) != -1;
116+
}
117+
76118
MPDevice *
77119
mp_device_find(const char *driver_name, const char *dev_name)
78120
{
@@ -183,6 +225,42 @@ mp_device_setup_entity_link(MPDevice *device,
183225
return true;
184226
}
185227

228+
void
229+
mp_device_setup_media_link(MPDevice *device,
230+
const struct mp_media_link_config *cfg,
231+
bool enable)
232+
{
233+
const struct media_v2_entity *source_entity =
234+
mp_device_find_entity(device, cfg->source_name);
235+
236+
const struct media_v2_entity *target_entity =
237+
mp_device_find_entity(device, cfg->target_name);
238+
239+
mp_device_setup_entity_link(device,
240+
source_entity->id,
241+
target_entity->id,
242+
cfg->source_port,
243+
cfg->target_port,
244+
enable);
245+
}
246+
247+
void
248+
mp_device_setup_media_link_pad_crop(MPDevice *device,
249+
const struct mp_media_crop_config *crop)
250+
{
251+
struct v4l2_subdev_crop v4l2_crop = {};
252+
v4l2_crop.pad = crop->pad;
253+
v4l2_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
254+
v4l2_crop.rect.top = crop->top;
255+
v4l2_crop.rect.left = crop->left;
256+
v4l2_crop.rect.width = crop->width;
257+
v4l2_crop.rect.height = crop->height;
258+
259+
if(!mp_xioctl(device, crop->name, VIDIOC_SUBDEV_S_CROP, &v4l2_crop)) {
260+
errno_printerr("VIDIOC_SUBDEV_S_CROP");
261+
}
262+
}
263+
186264
bool
187265
mp_device_setup_link(MPDevice *device,
188266
uint32_t source_pad_id,
@@ -237,6 +315,46 @@ mp_entity_pad_set_format(MPDevice *device,
237315
return true;
238316
}
239317

318+
const struct media_v2_pad *
319+
mp_device_get_pad_at_index_from_entity(const MPDevice *device, uint32_t entity_id, uint32_t index)
320+
{
321+
for (int i = 0; i < device->num_pads; ++i) {
322+
if (device->pads[i].entity_id == entity_id && index-- == 0) {
323+
return &device->pads[i];
324+
}
325+
}
326+
return NULL;
327+
}
328+
329+
bool
330+
mp_device_setup_link_by_name(MPDevice *device,
331+
const char *source_entity_name,
332+
uint32_t source_pad_index,
333+
const char *sink_entity_name,
334+
uint32_t sink_pad_index,
335+
bool enabled)
336+
{
337+
const struct media_v2_entity *source_entity =
338+
mp_device_find_entity
339+
(device, source_entity_name);
340+
const struct media_v2_entity *sink_entity =
341+
mp_device_find_entity
342+
(device, sink_entity_name);
343+
344+
struct media_link_desc link = {};
345+
link.flags = enabled ? MEDIA_LNK_FL_ENABLED : 0;
346+
link.source.entity = source_entity->id;
347+
link.source.index = source_pad_index;
348+
link.sink.entity = sink_entity->id;
349+
link.sink.index = sink_pad_index;
350+
if (xioctl(device->fd, MEDIA_IOC_SETUP_LINK, &link) == -1) {
351+
errno_printerr("MEDIA_IOC_SETUP_LINK");
352+
return false;
353+
}
354+
355+
return true;
356+
}
357+
240358
const struct media_v2_entity *
241359
mp_device_find_entity(const MPDevice *device, const char *driver_name)
242360
{

src/device.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include "mode.h"
4+
#include "camera_config.h"
45

56
#include <linux/media.h>
67
#include <stdbool.h>
@@ -26,6 +27,10 @@ bool mp_device_setup_entity_link(MPDevice *device,
2627
uint32_t sink_index,
2728
bool enabled);
2829

30+
void mp_device_setup_media_link(MPDevice *device,
31+
const struct mp_media_link_config *cfg,
32+
bool enable);
33+
2934
bool mp_device_setup_link(MPDevice *device,
3035
uint32_t source_pad_id,
3136
uint32_t sink_pad_id,
@@ -36,6 +41,13 @@ bool mp_entity_pad_set_format(MPDevice *device,
3641
uint32_t pad,
3742
MPMode *mode);
3843

44+
bool mp_device_setup_link_by_name(MPDevice *device,
45+
const char *source_entity_name,
46+
uint32_t source_pad_index,
47+
const char *sink_entity_name,
48+
uint32_t sink_pad_index,
49+
bool enabled);
50+
3951
const struct media_device_info *mp_device_get_info(const MPDevice *device);
4052
const struct media_v2_entity *mp_device_find_entity(const MPDevice *device,
4153
const char *driver_name);
@@ -81,3 +93,6 @@ MPDevice *mp_device_list_remove(MPDeviceList **device_list);
8193
MPDevice *mp_device_list_get(const MPDeviceList *device_list);
8294
const char *mp_device_list_get_path(const MPDeviceList *device_list);
8395
MPDeviceList *mp_device_list_next(const MPDeviceList *device_list);
96+
97+
void mp_device_setup_media_link_pad_crop(MPDevice *device,
98+
const struct mp_media_crop_config *crop);

0 commit comments

Comments
 (0)