Skip to content

Xiaomi MI A1 S5K5E8YX front camera support - #257

Open
obolon-svitle wants to merge 4 commits into
msm8953-mainline:7.0.9/mainfrom
obolon-svitle:mia1-frontcam
Open

Xiaomi MI A1 S5K5E8YX front camera support#257
obolon-svitle wants to merge 4 commits into
msm8953-mainline:7.0.9/mainfrom
obolon-svitle:mia1-frontcam

Conversation

@obolon-svitle

@obolon-svitle obolon-svitle commented Jul 12, 2026

Copy link
Copy Markdown

The stuff was tested on my Xiaomi MI A1 with a fresh edge postmarketos. The picture quality seems to be alrightish as for a not tuned sensor.

With LIBCAMERA_SOFTISP_MODE=cpu, FPS with libcamera is far more stable (though not perfect) than with egl debayer. I'd blame freedreno but can't say for sure due to the lack of experience with it.

Below is the output of some typical camera tooling apps used to test the module and dts:

qcom-msm8953:~$ v4l2-ctl -d /dev/v4l-subdev16  --all
Driver Info:
        Driver version   : 7.0.9
        Capabilities     : 0x00000000
        Client Capabilities: 0x0000000000000002
interval-uses-which 
User Controls

                       exposure 0x00980911 (int)    : min=8 max=1964 step=1 default=990 value=990 flags=has-min-max
                horizontal_flip 0x00980914 (bool)   : default=0 value=0 flags=modify-layout, has-min-max
                  vertical_flip 0x00980915 (bool)   : default=0 value=0 flags=modify-layout, has-min-max

Camera Controls

             camera_orientation 0x009a0922 (menu)   : min=0 max=2 default=0 value=0 (Front) flags=read-only, has-min-max
                                0: Front
                                1: Back
                                2: External
         camera_sensor_rotation 0x009a0923 (int)    : min=90 max=90 step=1 default=90 value=90 flags=read-only, has-min-max

Image Source Controls

              vertical_blanking 0x009e0901 (int)    : min=24 max=63591 step=1 default=24 value=24 flags=has-min-max
            horizontal_blanking 0x009e0902 (int)    : min=264 max=264 step=1 default=264 value=264 flags=read-only, has-min-max
                  analogue_gain 0x009e0903 (int)    : min=32 max=512 step=1 default=32 value=32 flags=has-min-max

Image Processing Controls

                 link_frequency 0x009f0901 (intmenu): min=0 max=0 default=0 value=0 (420000000 0x1908b100) flags=read-only, has-min-max
                                0: 420000000 (0x1908b100)
                     pixel_rate 0x009f0902 (int64)  : min=0 max=168000000 step=1 default=168000000 value=168000000 flags=read-only, has-min-max
                   test_pattern 0x009f0903 (menu)   : min=0 max=3 default=0 value=0 (Disabled) flags=has-min-max
                                0: Disabled
                                1: Solid colour
                                2: Colour bars
                                3: Fade to grey colour bars

qcom-msm8953:~$ cam -c /base/soc@0/cci@1b0c000/i2c-bus@1/camera-sensor@2d --capture=64
[0:03:49.399801986] [3469]  INFO Camera camera_manager.cpp:340 libcamera v0.7.1
[0:03:49.457128568] [3470]  WARN CameraSensorProperties camera_sensor_properties.cpp:538 No static properties available for 's5k5e8yx'
[0:03:49.457194711] [3470]  WARN CameraSensorProperties camera_sensor_properties.cpp:540 Please consider updating the camera sensor properties database
[0:03:49.457225126] [3470]  WARN CameraSensor camera_sensor_legacy.cpp:502 's5k5e8yx 4-002d': No sensor delays found in static properties. Assuming unverified defaults.
[0:03:49.461099364] [3470]  WARN IPAProxy ipa_proxy.cpp:196 Configuration file 's5k5e8yx.yaml' not found for IPA module 'simple', falling back to '/usr/share/libcamera/ipa/simple/uncalibrated.yaml'
[0:03:49.461216129] [3470]  WARN IPASoft soft_simple.cpp:104 IPASoft: Failed to create camera sensor helper for s5k5e8yx
[0:03:49.462013278] [3470]  INFO Camera camera_manager.cpp:223 Adding camera '/base/soc@0/cci@1b0c000/i2c-bus@1/camera-sensor@2d' for pipeline handler simple
Using camera /base/soc@0/cci@1b0c000/i2c-bus@1/camera-sensor@2d as cam0
[0:03:49.462927400] [3469]  INFO Camera camera.cpp:1216 configuring streams: (0) 2584x1944-ABGR8888/sRGB
[0:03:49.463295768] [3470]  INFO SimplePipeline simple.cpp:1568 Input buffer stride ignored by the driver. Requested 3328, got 3240
[0:03:49.463376753] [3470]  INFO IPASoft soft_simple.cpp:258 IPASoft: Exposure 8-1964, gain 32-512 (1)
[0:03:49.463449875] [3470]  INFO SoftwareIsp software_isp.cpp:291 Input 2592x1944-GRBG-10-CSI2P stride 3240
[0:03:49.652551548] [3472]  INFO eGL egl.cpp:319 EGL: EGL_VERSION: 1.5
[0:03:49.652640241] [3472]  INFO eGL egl.cpp:320 EGL: EGL_VENDOR: Mesa Project
[0:03:49.652659772] [3472]  INFO eGL egl.cpp:321 EGL: EGL_CLIENT_APIS: OpenGL OpenGL_ES 
[0:03:49.652677063] [3472]  INFO eGL egl.cpp:322 EGL: EGL_EXTENSIONS: EGL_ANDROID_blob_cache EGL_ANDROID_native_fence_sync EGL_EXT_config_select_group EGL_EXT_create_context_robustness EGL_EXT_image_dma_buf_import EGL_EXT_image_dma_buf_import_modifiers EGL_EXT_query_reset_notification_strategy EGL_EXT_surface_compression EGL_IMG_context_priority EGL_KHR_cl_event2 EGL_KHR_config_attribs EGL_KHR_context_flush_control EGL_KHR_create_context EGL_KHR_create_context_no_error EGL_KHR_fence_sync EGL_KHR_get_all_proc_addresses EGL_KHR_gl_colorspace EGL_KHR_gl_renderbuffer_image EGL_KHR_gl_texture_2D_image EGL_KHR_gl_texture_3D_image EGL_KHR_gl_texture_cubemap_image EGL_KHR_image_base EGL_KHR_no_config_context EGL_KHR_reusable_sync EGL_KHR_surfaceless_context EGL_EXT_pixel_format_float EGL_KHR_wait_sync EGL_MESA_configless_context EGL_MESA_gl_interop EGL_MESA_image_dma_buf_export EGL_MESA_query_driver EGL_MESA_x11_native_visual_id EGL_NV_context_priority_realtime 
[0:03:49.660507671] [3472]  INFO eGL egl.cpp:363 EGL: GL_RENDERER: FD506
[0:03:49.660646414] [3472]  INFO eGL egl.cpp:364 EGL: GL_VERSION: OpenGL ES 3.1 Mesa 26.1.1
cam0: Capture 64 frames
[0:03:49.733434274] [3472]  INFO Debayer debayer_egl.cpp:520 Importing input buffer with DMABuf import failed, falling back to upload
229.728480 (0.00 fps) cam0-stream0 seq: 000000 bytesused: 20404224
229.761896 (29.93 fps) cam0-stream0 seq: 000001 bytesused: 20404224
229.795299 (29.94 fps) cam0-stream0 seq: 000002 bytesused: 20404224
229.828852 (29.80 fps) cam0-stream0 seq: 000003 bytesused: 20404224
229.929232 (9.96 fps) cam0-stream0 seq: 000004 bytesused: 20404224
229.996101 (14.95 fps) cam0-stream0 seq: 000005 bytesused: 20404224
230.063090 (14.93 fps) cam0-stream0 seq: 000006 bytesused: 20404224
230.129933 (14.96 fps) cam0-stream0 seq: 000007 bytesused: 2040422
^C

qcom-msm8953:~$ plasma-camera
[0:05:08.134112539] [3621]  INFO Camera camera_manager.cpp:340 libcamera v0.7.1
[0:05:08.192983383] [3631]  WARN CameraSensorProperties camera_sensor_properties.cpp:538 No static properties available for 's5k5e8yx'
[0:05:08.193050676] [3631]  WARN CameraSensorProperties camera_sensor_properties.cpp:540 Please consider updating the camera sensor properties database
[0:05:08.193081718] [3631]  WARN CameraSensor camera_sensor_legacy.cpp:502 's5k5e8yx 4-002d': No sensor delays found in static properties. Assuming unverified defaults.
[0:05:08.199061355] [3631]  WARN IPAProxy ipa_proxy.cpp:196 Configuration file 's5k5e8yx.yaml' not found for IPA module 'simple', falling back to '/usr/share/libcamera/ipa/simple/uncalibrated.yaml'
[0:05:08.199205106] [3631]  WARN IPASoft soft_simple.cpp:104 IPASoft: Failed to create camera sensor helper for s5k5e8yx
[0:05:08.199972457] [3631]  INFO Camera camera_manager.cpp:223 Adding camera '/base/soc@0/cci@1b0c000/i2c-bus@1/camera-sensor@2d' for pipeline handler simple
qt.multimedia.ffmpeg: Using Qt multimedia with FFmpeg version 8.1.2 GPL version 3 or later
PlasmaCameraManager::setFilenamePattern PlasmaCameraManager::FilenameNumericSequential
PlasmaCameraManager::setOutputPath PlasmaCameraManager::OutputPathDefault
qrc:/qt/qml/org/kde/kirigamiaddons/components/RadioSelector.qml:189:9: TypeError: Cannot read property 'width' of null
qrc:/qt/qml/org/kde/kirigamiaddons/components/RadioSelector.qml:184:9: TypeError: Cannot read property 'x' of null
Using camera:  "/base/soc@0/cci@1b0c000/i2c-bus@1/camera-sensor@2d"
Acquired 2 controls
Acquired 8 properties
         "SystemDevices"   "[ 20736, 20737, 20738, 20739, 20740, 20741 ]"
         "PipelineHandler"   "simple"
         "ColorFilterArrangement"   "1"
         "PixelArrayActiveAreas"   "[ (0, 0)/2592x1944 ]"
         "PixelArraySize"   "2592x1944"
         "Rotation"   "90"
         "Location"   "0"
         "Model"   "s5k5e8yx"
Loading settings:
         "Contrast" : min: "0.000000"  max: "2.000000"  default: "1.000000"
         "Gamma" : min: "0.100000"  max: "10.000000"  default: "2.200000"
         Unknown control:  "Gamma"  id:  45
Camera offset orientation: 90
Setting camera to "/base/soc@0/cci@1b0c000/i2c-bus@1/camera-sensor@2d"
Starting view finder in worker
Default camera configuration is:  "2584x1944-ABGR8888/sRGB"
Desired format:  "ABGR8888"
Desired format:  "XBGR8888"
Desired format:  "BGR888"
Desired format:  "RGB888"
Desired format:  "ARGB8888"
Desired format:  "XRGB8888"
Desired format:  "RGB565"
Got format:  "ABGR8888"
Viewfinder configuration is:  "2584x1944-ABGR8888/sRGB"
[0:05:08.995971117] [3632]  INFO Camera camera.cpp:1216 configuring streams: (0) 2584x1944-ABGR8888/sRGB
[0:05:08.996759197] [3631]  INFO IPASoft soft_simple.cpp:258 IPASoft: Exposure 8-1964, gain 32-512 (1)
[0:05:08.996932688] [3631]  INFO SoftwareIsp software_isp.cpp:291 Input 2592x1944-GRBG-10-CSI2P stride 3240
create req 0xffff706a12c8

Camera has already been started
Allocated 4 buffers for stream
Added new request:  "Request(0:P:1/1:0)"
Added new request:  "Request(0:P:1/1:0)"
Added new request:  "Request(0:P:1/1:0)"
Added new request:  "Request(0:P:1/1:0)"
PlasmaCameraManager::setReadyForCapture true
[0:05:12.381104160] [3646]  INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 1567759us, 52258 us/frame

qcom-msm8953:~$ v4l2-ctl -d /dev/video0 --stream-mmap --stream-to=/dev/null --stream-count=33
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 29.89 fps

qcom-msm8953:~$ media-ctl -p 0 -e "s5k5e8yx 4-002d"
Media controller API version 7.0.9

Media device information
------------------------
driver          qcom-camss
model           Qualcomm Camera Subsystem
serial          
bus info        platform:1b00020.camss
hw revision     0x0
driver version  7.0.9

- entity 184: s5k5e8yx 4-002d (1 pad, 1 link, 0 routes)
              type V4L2 subdev subtype Sensor flags 0
              device node name /dev/v4l-subdev16
        pad0: SOURCE
                [stream:0 fmt:SGRBG10_1X10/2592x1944 field:none colorspace:srgb xfer:none quantization:full-range
                 crop.bounds:(0,0)/2592x1944
                 crop:(0,0)/2592x1944]
                -> "msm_csiphy2":0 [ENABLED,IMMUTABLE]

Samsung S5K5E8YX is a 5MP CMOS image sensor that produces Bayer GRBG
frames in RAW10 output format, the maximum supported output resolution
is 2592x1944 at 30 frames per second.

Signed-off-by: Andrii Cherniavskyi <chernyav.a@gmail.com>
Add device tree bindings documentation for Samsung S5K5E8YX sensor.

Signed-off-by: Andrii Cherniavskyi <chernyav.a@gmail.com>
Signed-off-by: Andrii Cherniavskyi <chernyav.a@gmail.com>
Enable Qualcomm CAMSS subsystem device nodes and add its first connected
device: s5k5e8yx camera sensor which is tissot's front camera.

Signed-off-by: Andrii Cherniavskyi <chernyav.a@gmail.com>
@barni2000

Copy link
Copy Markdown
Member

Hi @obolon-svitle!

The driver should be sent to upstream first. How do you know tissot have s5k5e8yx?

@obolon-svitle

obolon-svitle commented Jul 18, 2026

Copy link
Copy Markdown
Author

How do you know tissot have s5k5e8yx?

The postmarketos wiki has figured this out already. And the i2c chip id that one can find in some leaked PDFs roaming in the Internet matches the "i2ctransfer -f -y 4 w2@0x2d 0x0 0x0 r2" output, which is "0x5e 0x80".

The driver should be sent to upstream first

Ok. I was somehow under the impression that the tissot dts is not in the upstream, hence its unique sensor driver couldn't be upstreamed. Blunder...

@barni2000

barni2000 commented Jul 18, 2026

Copy link
Copy Markdown
Member

How do you know tissot have s5k5e8yx?

The postmarketos wiki has figured this out already. And the i2c chip id that one can find in some leaked PDFs roaming in the Internet matches the "i2ctransfer -f -y 4 w2@0x2d 0x0 0x0 r2" output, which is "0x5e 0x80".

I mean how do you know it is yx variant.

The driver should be sent to upstream first

Ok. I was somehow under the impression that the tissot dts is not in the upstream, hence its unique sensor driver couldn't be upstreamed. Blunder...

I dont see why the driver cannot be upstreamed. dt changes are fine at downstream.

{ CCI_REG8(0x3311), 0xa7 },
{ CCI_REG8(0x3312), 0x03 },
{ CCI_REG8(0x3313), 0x01 },
{ CCI_REG8(0x0000), 0x00 },

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This writes CHIP_ID. I don't think this should be a part of reg sequence.

#define S5K5E8YX_REG_CHIP_ID CCI_REG16(0x0000)
#define S5K5E8YX_CHIP_ID 0x5e80

#define S5K5E8YX_REG_CTRL_MODE CCI_REG8(0x0100)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for your information many of those mobile s5k* sensors are implementing CCS/SMIA standard. Not properly but you can reuse some register definitions from ccs/ccs-regs.h or ccs/smiapp-reg-defs.h (for documentation too). I've been working on more generic driver for such sensors and got s5k5e8 working on it (but by skipping clock configuration) relatively easy today.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been working on more generic driver for such sensors and got s5k5e8 working on it (but by skipping clock configuration) relatively easy today.

Awesome. I was totally clueless that these sensors have that much in common (at least those existing s5k drivers in the upstream didn't look like this), and only wanted to get my phone camera work...
I'll try to play with mi a1 and your driver as well to see if this PR shall be abandoned right away.

fmt->width = mode->width;
fmt->height = mode->height;
fmt->field = V4L2_FIELD_NONE;
fmt->colorspace = V4L2_COLORSPACE_SRGB;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be V4L2_COLORSPACE_RAW, isn't it?

{
struct s5k5e8yx *s5k5e8yx = to_s5k5e8yx(sd);

if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

@obolon-svitle

obolon-svitle commented Jul 18, 2026

Copy link
Copy Markdown
Author

I mean how do you know it is yx variant.

Good question, that's another blunder, it shouldn't have been suffixed. It's a clumsiness due to starting this work on another phone and switching to tissot later on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants