* [PATCH v4 0/2] Pinefeat cef168 lens control board driver
@ 2025-08-22 17:10 Aliaksandr Smirnou
2025-08-22 17:10 ` [PATCH v4 1/2] dt-bindings: Pinefeat cef168 lens control board Aliaksandr Smirnou
2025-08-22 17:10 ` [PATCH v4 2/2] media: i2c: Pinefeat cef168 lens control board driver Aliaksandr Smirnou
0 siblings, 2 replies; 9+ messages in thread
From: Aliaksandr Smirnou @ 2025-08-22 17:10 UTC (permalink / raw)
To: jacopo.mondi, hverkuil, mchehab, robh, krzk+dt, conor+dt
Cc: devicetree, linux-media, linux-kernel, Aliaksandr Smirnou
This patch series adds support for the Pinefeat adapter, which interfaces
Canon EF and EF-S lenses to non-Canon camera bodies. The cef168 circuit
control board provides an I2C interface for electronic focus and aperture
control. The driver integrates with the V4L2 sub-device API.
For more information about the product, see:
https://github.com/pinefeat/cef168
Changes in v4:
- removed driver mention from the hardware documentation;
- added named email in commit signed-off-by;
- added select CRC8 in Kconfig;
- removed header file;
- moved variable declaration at the beginning of the function;
- removed kerneldoc from structures;
- removed control id check as the core handles this for us;
- removed Power Management Runtime (pm_runtime_*) calls as redundant;
- reserved v4l2 controls in linux header file;
Link to v3: https://lore.kernel.org/all/20250817130549.7766-1-support@pinefeat.co.uk/
Patches:
dt-bindings: Pinefeat cef168 lens control board
media: i2c: Pinefeat cef168 lens control board driver
.../bindings/media/i2c/pinefeat,cef168.yaml | 47 +++
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
MAINTAINERS | 7 +
drivers/media/i2c/Kconfig | 9 +
drivers/media/i2c/Makefile | 1 +
drivers/media/i2c/cef168.c | 331 ++++++++++++++++++
include/uapi/linux/v4l2-controls.h | 6 +
7 files changed, 403 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/i2c/pinefeat,cef168.yaml
create mode 100644 drivers/media/i2c/cef168.c
base-commit: 2b38afce25c4e1b8f943ff4f0a2b51d6c40f2ed2
--
2.34.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v4 1/2] dt-bindings: Pinefeat cef168 lens control board
2025-08-22 17:10 [PATCH v4 0/2] Pinefeat cef168 lens control board driver Aliaksandr Smirnou
@ 2025-08-22 17:10 ` Aliaksandr Smirnou
2025-08-24 9:22 ` Krzysztof Kozlowski
2025-08-22 17:10 ` [PATCH v4 2/2] media: i2c: Pinefeat cef168 lens control board driver Aliaksandr Smirnou
1 sibling, 1 reply; 9+ messages in thread
From: Aliaksandr Smirnou @ 2025-08-22 17:10 UTC (permalink / raw)
To: jacopo.mondi, hverkuil, mchehab, robh, krzk+dt, conor+dt
Cc: devicetree, linux-media, linux-kernel, Aliaksandr Smirnou,
Aliaksandr Smirnou
Add the Device Tree schema and examples for the Pinefeat cef168 lens
control board. This board interfaces Canon EF & EF-S lenses with
non-Canon camera bodies, enabling electronic control of focus and
aperture via V4L2.
Power supply is derived from fixed supplies via connector or GPIO
header. Therefore, the driver does not manage any regulator, so
representing any supply in the binding is redundant.
Signed-off-by: Aliaksandr Smirnou <asmirnou@pinefeat.co.uk>
---
.../bindings/media/i2c/pinefeat,cef168.yaml | 47 +++++++++++++++++++
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
MAINTAINERS | 6 +++
3 files changed, 55 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/i2c/pinefeat,cef168.yaml
diff --git a/Documentation/devicetree/bindings/media/i2c/pinefeat,cef168.yaml b/Documentation/devicetree/bindings/media/i2c/pinefeat,cef168.yaml
new file mode 100644
index 000000000000..1295b1f4edeb
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/pinefeat,cef168.yaml
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (c) 2025 Pinefeat LLP
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/pinefeat,cef168.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Pinefeat cef168 lens driver
+
+maintainers:
+ - Aliaksandr Smirnou <support@pinefeat.co.uk>
+
+description: |
+ Pinefeat produces an adapter designed to interface between
+ Canon EF & EF-S lenses and non-Canon camera bodies, incorporating
+ features for electronic focus and aperture adjustment. The cef168
+ circuit board, included with the adapter, provides a software
+ programming interface that allows control of lens focus and
+ aperture positions.
+
+properties:
+ compatible:
+ enum:
+ - pinefeat,cef168
+
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ camera-lens@d {
+ compatible = "pinefeat,cef168";
+ reg = <0x0d>;
+ };
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 77160cd47f54..dab27f769b0a 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1195,6 +1195,8 @@ patternProperties:
description: Picochip Ltd
"^pine64,.*":
description: Pine64
+ "^pinefeat,.*":
+ description: Pinefeat LLP
"^pineriver,.*":
description: Shenzhen PineRiver Designs Co., Ltd.
"^pixcir,.*":
diff --git a/MAINTAINERS b/MAINTAINERS
index fe168477caa4..811c6a150029 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19985,6 +19985,12 @@ S: Supported
F: Documentation/devicetree/bindings/input/pine64,pinephone-keyboard.yaml
F: drivers/input/keyboard/pinephone-keyboard.c
+PINEFEAT CEF168 LENS DRIVER
+M: Aliaksandr Smirnou <support@pinefeat.co.uk>
+L: linux-media@vger.kernel.org
+S: Supported
+F: Documentation/devicetree/bindings/media/i2c/pinefeat,cef168.yaml
+
PLANTOWER PMS7003 AIR POLLUTION SENSOR DRIVER
M: Tomasz Duszynski <tduszyns@gmail.com>
S: Maintained
--
2.34.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v4 2/2] media: i2c: Pinefeat cef168 lens control board driver
2025-08-22 17:10 [PATCH v4 0/2] Pinefeat cef168 lens control board driver Aliaksandr Smirnou
2025-08-22 17:10 ` [PATCH v4 1/2] dt-bindings: Pinefeat cef168 lens control board Aliaksandr Smirnou
@ 2025-08-22 17:10 ` Aliaksandr Smirnou
1 sibling, 0 replies; 9+ messages in thread
From: Aliaksandr Smirnou @ 2025-08-22 17:10 UTC (permalink / raw)
To: jacopo.mondi, hverkuil, mchehab, robh, krzk+dt, conor+dt
Cc: devicetree, linux-media, linux-kernel, Aliaksandr Smirnou,
Aliaksandr Smirnou
Add support for the Pinefeat cef168 lens control board that provides
electronic focus and aperture control for Canon EF & EF-S lenses on
non-Canon camera bodies.
Signed-off-by: Aliaksandr Smirnou <asmirnou@pinefeat.co.uk>
---
MAINTAINERS | 1 +
drivers/media/i2c/Kconfig | 9 +
drivers/media/i2c/Makefile | 1 +
drivers/media/i2c/cef168.c | 331 +++++++++++++++++++++++++++++
include/uapi/linux/v4l2-controls.h | 6 +
5 files changed, 348 insertions(+)
create mode 100644 drivers/media/i2c/cef168.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 811c6a150029..a531fb05faa4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19990,6 +19990,7 @@ M: Aliaksandr Smirnou <support@pinefeat.co.uk>
L: linux-media@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/media/i2c/pinefeat,cef168.yaml
+F: drivers/media/i2c/cef168.c
PLANTOWER PMS7003 AIR POLLUTION SENSOR DRIVER
M: Tomasz Duszynski <tduszyns@gmail.com>
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 6237fe804a5c..df2b33f03ab7 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -791,6 +791,15 @@ config VIDEO_AK7375
capability. This is designed for linear control of
voice coil motors, controlled via I2C serial interface.
+config VIDEO_CEF168
+ tristate "CEF168 lens control support"
+ select CRC8
+ help
+ This is a driver for the CEF168 lens control board.
+ The board provides an I2C interface for electronic focus
+ and aperture control of EF and EF-S lenses. The driver
+ integrates with the V4L2 sub-device API.
+
config VIDEO_DW9714
tristate "DW9714 lens voice coil support"
depends on GPIOLIB
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index 5873d29433ee..75a95f850f18 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_VIDEO_BT856) += bt856.o
obj-$(CONFIG_VIDEO_BT866) += bt866.o
obj-$(CONFIG_VIDEO_CCS) += ccs/
obj-$(CONFIG_VIDEO_CCS_PLL) += ccs-pll.o
+obj-$(CONFIG_VIDEO_CEF168) += cef168.o
obj-$(CONFIG_VIDEO_CS3308) += cs3308.o
obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
diff --git a/drivers/media/i2c/cef168.c b/drivers/media/i2c/cef168.c
new file mode 100644
index 000000000000..cfcef476f09d
--- /dev/null
+++ b/drivers/media/i2c/cef168.c
@@ -0,0 +1,331 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2025 Pinefeat LLP
+
+#include <linux/crc8.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/v4l2-controls.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+
+#define CEF168_NAME "cef168"
+
+#define CEF168_V4L2_CID_CUSTOM(ctrl) \
+ (V4L2_CID_USER_CEF168_BASE + custom_##ctrl)
+
+enum { custom_lens_id, custom_data, custom_focus_range, custom_calibrate };
+
+#define INP_CALIBRATE 0x22
+#define INP_SET_FOCUS 0x80
+#define INP_SET_FOCUS_P 0x81
+#define INP_SET_FOCUS_N 0x82
+#define INP_SET_APERTURE 0x7A
+#define INP_SET_APERTURE_P 0x7B
+#define INP_SET_APERTURE_N 0x7C
+
+#define CEF_CRC8_POLYNOMIAL 168
+
+DECLARE_CRC8_TABLE(cef168_crc8_table);
+
+struct cef168_data {
+ __u8 lens_id;
+ __u8 moving : 1;
+ __u8 calibrating : 2;
+ __u16 moving_time;
+ __u16 focus_position_min;
+ __u16 focus_position_max;
+ __u16 focus_position_cur;
+ __u16 focus_distance_min;
+ __u16 focus_distance_max;
+ __u8 crc8;
+} __packed;
+
+struct cef168_device {
+ struct v4l2_ctrl_handler ctrls;
+ struct v4l2_subdev sd;
+};
+
+static inline struct cef168_device *to_cef168(struct v4l2_ctrl *ctrl)
+{
+ return container_of(ctrl->handler, struct cef168_device, ctrls);
+}
+
+static inline struct cef168_device *sd_to_cef168(struct v4l2_subdev *subdev)
+{
+ return container_of(subdev, struct cef168_device, sd);
+}
+
+static int cef168_i2c_write(struct cef168_device *cef168_dev, u8 cmd, u16 val)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&cef168_dev->sd);
+ int retry, ret;
+
+ __le16 le_data = cpu_to_le16(val);
+ char tx_data[4] = { cmd, ((u8 *)&le_data)[0], ((u8 *)&le_data)[1] };
+
+ tx_data[3] = crc8(cef168_crc8_table, tx_data, 3, CRC8_INIT_VALUE);
+
+ for (retry = 0; retry < 3; retry++) {
+ ret = i2c_master_send(client, tx_data, sizeof(tx_data));
+ if (ret == sizeof(tx_data))
+ return 0;
+ else if (ret != -EIO && ret != -EREMOTEIO)
+ break;
+ }
+
+ dev_err(&client->dev, "I2C write fail after %d retries, ret=%d\n",
+ retry, ret);
+ return -EIO;
+}
+
+static int cef168_i2c_read(struct cef168_device *cef168_dev,
+ struct cef168_data *rx_data)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&cef168_dev->sd);
+
+ int ret = i2c_master_recv(client, (char *)rx_data,
+ sizeof(struct cef168_data));
+ if (ret != sizeof(struct cef168_data)) {
+ dev_err(&client->dev, "I2C read fail, ret=%d\n", ret);
+ return -EIO;
+ }
+
+ u8 computed_crc = crc8(cef168_crc8_table, (const u8 *)rx_data,
+ sizeof(struct cef168_data) - 1, CRC8_INIT_VALUE);
+ if (computed_crc != rx_data->crc8) {
+ dev_err(&client->dev,
+ "CRC mismatch calculated=0x%02X read=0x%02X\n",
+ computed_crc, rx_data->crc8);
+ return -EIO;
+ }
+
+ rx_data->moving_time = le16_to_cpup((__le16 *)&rx_data->moving_time);
+ rx_data->focus_position_min = le16_to_cpup((__le16 *)&rx_data->focus_position_min);
+ rx_data->focus_position_max = le16_to_cpup((__le16 *)&rx_data->focus_position_max);
+ rx_data->focus_position_cur = le16_to_cpup((__le16 *)&rx_data->focus_position_cur);
+ rx_data->focus_distance_min = le16_to_cpup((__le16 *)&rx_data->focus_distance_min);
+ rx_data->focus_distance_max = le16_to_cpup((__le16 *)&rx_data->focus_distance_max);
+
+ return 0;
+}
+
+static int cef168_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct cef168_device *dev = to_cef168(ctrl);
+ u8 cmd;
+
+ switch (ctrl->id) {
+ case V4L2_CID_FOCUS_ABSOLUTE:
+ return cef168_i2c_write(dev, INP_SET_FOCUS, ctrl->val);
+ case V4L2_CID_FOCUS_RELATIVE:
+ cmd = ctrl->val < 0 ? INP_SET_FOCUS_N : INP_SET_FOCUS_P;
+ return cef168_i2c_write(dev, cmd, abs(ctrl->val));
+ case V4L2_CID_IRIS_ABSOLUTE:
+ return cef168_i2c_write(dev, INP_SET_APERTURE, ctrl->val);
+ case V4L2_CID_IRIS_RELATIVE:
+ cmd = ctrl->val < 0 ? INP_SET_APERTURE_N : INP_SET_APERTURE_P;
+ return cef168_i2c_write(dev, cmd, abs(ctrl->val));
+ case CEF168_V4L2_CID_CUSTOM(calibrate):
+ return cef168_i2c_write(dev, INP_CALIBRATE, 0);
+ }
+
+ return -EINVAL;
+}
+
+static int cef168_get_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct cef168_data data;
+ struct cef168_device *dev = to_cef168(ctrl);
+ int rval;
+
+ rval = cef168_i2c_read(dev, &data);
+ if (rval < 0)
+ return rval;
+
+ switch (ctrl->id) {
+ case V4L2_CID_FOCUS_ABSOLUTE:
+ ctrl->val = data.focus_position_cur;
+ return 0;
+ case CEF168_V4L2_CID_CUSTOM(focus_range):
+ ctrl->p_new.p_u32[0] = ((u32)data.focus_position_min << 16) |
+ (u32)data.focus_position_max;
+ return 0;
+ case CEF168_V4L2_CID_CUSTOM(lens_id):
+ ctrl->p_new.p_u8[0] = data.lens_id;
+ return 0;
+ case CEF168_V4L2_CID_CUSTOM(data):
+ memcpy(ctrl->p_new.p_u8, &data, sizeof(data));
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static const struct v4l2_ctrl_ops cef168_ctrl_ops = {
+ .g_volatile_ctrl = cef168_get_ctrl,
+ .s_ctrl = cef168_set_ctrl,
+};
+
+static const struct v4l2_ctrl_config cef168_lens_id_ctrl = {
+ .ops = &cef168_ctrl_ops,
+ .id = CEF168_V4L2_CID_CUSTOM(lens_id),
+ .type = V4L2_CTRL_TYPE_U8,
+ .name = "Lens ID",
+ .min = 0,
+ .max = U8_MAX,
+ .step = 1,
+ .def = 0,
+ .flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
+};
+
+static const struct v4l2_ctrl_config cef168_focus_range_ctrl = {
+ .ops = &cef168_ctrl_ops,
+ .id = CEF168_V4L2_CID_CUSTOM(focus_range),
+ .type = V4L2_CTRL_TYPE_U32,
+ .name = "Focus Range",
+ .min = 0,
+ .max = U32_MAX,
+ .step = 1,
+ .def = 0,
+ .flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
+};
+
+static const struct v4l2_ctrl_config cef168_data_ctrl = {
+ .ops = &cef168_ctrl_ops,
+ .id = CEF168_V4L2_CID_CUSTOM(data),
+ .type = V4L2_CTRL_TYPE_U8,
+ .name = "Data",
+ .min = 0,
+ .max = U8_MAX,
+ .step = 1,
+ .def = 0,
+ .dims = { sizeof(struct cef168_data) / sizeof(u8) },
+ .elem_size = sizeof(u8),
+ .flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
+};
+
+static const struct v4l2_ctrl_config cef168_calibrate_ctrl = {
+ .ops = &cef168_ctrl_ops,
+ .id = CEF168_V4L2_CID_CUSTOM(calibrate),
+ .type = V4L2_CTRL_TYPE_BUTTON,
+ .name = "Calibrate",
+};
+
+static const struct v4l2_subdev_core_ops cef168_core_ops = {
+ .log_status = v4l2_ctrl_subdev_log_status,
+ .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
+ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
+static const struct v4l2_subdev_ops cef168_ops = {
+ .core = &cef168_core_ops,
+};
+
+static int cef168_init_controls(struct cef168_device *dev)
+{
+ struct v4l2_ctrl *ctrl;
+ struct v4l2_ctrl_handler *hdl = &dev->ctrls;
+ const struct v4l2_ctrl_ops *ops = &cef168_ctrl_ops;
+
+ v4l2_ctrl_handler_init(hdl, 8);
+
+ ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FOCUS_ABSOLUTE, 0, S16_MAX,
+ 1, 0);
+ if (ctrl)
+ ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
+ V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
+ v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FOCUS_RELATIVE, S16_MIN, S16_MAX,
+ 1, 0);
+ ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_IRIS_ABSOLUTE, 0, S16_MAX,
+ 1, 0);
+ if (ctrl)
+ ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY |
+ V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
+ v4l2_ctrl_new_std(hdl, ops, V4L2_CID_IRIS_RELATIVE, S16_MIN, S16_MAX, 1,
+ 0);
+ ctrl = v4l2_ctrl_new_custom(hdl, &cef168_calibrate_ctrl, NULL);
+ if (ctrl)
+ ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY |
+ V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
+ v4l2_ctrl_new_custom(hdl, &cef168_focus_range_ctrl, NULL);
+ v4l2_ctrl_new_custom(hdl, &cef168_data_ctrl, NULL);
+ v4l2_ctrl_new_custom(hdl, &cef168_lens_id_ctrl, NULL);
+
+ if (hdl->error)
+ dev_err(dev->sd.dev, "%s fail error: 0x%x\n", __func__,
+ hdl->error);
+ dev->sd.ctrl_handler = hdl;
+ return hdl->error;
+}
+
+static int cef168_probe(struct i2c_client *client)
+{
+ struct cef168_device *cef168_dev;
+ int rval;
+
+ cef168_dev = devm_kzalloc(&client->dev, sizeof(*cef168_dev),
+ GFP_KERNEL);
+ if (!cef168_dev)
+ return -ENOMEM;
+
+ v4l2_i2c_subdev_init(&cef168_dev->sd, client, &cef168_ops);
+ cef168_dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+ V4L2_SUBDEV_FL_HAS_EVENTS;
+
+ rval = cef168_init_controls(cef168_dev);
+ if (rval)
+ goto err_cleanup;
+
+ rval = media_entity_pads_init(&cef168_dev->sd.entity, 0, NULL);
+ if (rval < 0)
+ goto err_cleanup;
+
+ cef168_dev->sd.entity.function = MEDIA_ENT_F_LENS;
+
+ rval = v4l2_async_register_subdev(&cef168_dev->sd);
+ if (rval < 0)
+ goto err_cleanup;
+
+ crc8_populate_msb(cef168_crc8_table, CEF_CRC8_POLYNOMIAL);
+
+ return 0;
+
+err_cleanup:
+ v4l2_ctrl_handler_free(&cef168_dev->ctrls);
+ media_entity_cleanup(&cef168_dev->sd.entity);
+
+ return rval;
+}
+
+static void cef168_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct cef168_device *cef168_dev = sd_to_cef168(sd);
+
+ v4l2_async_unregister_subdev(&cef168_dev->sd);
+ v4l2_ctrl_handler_free(&cef168_dev->ctrls);
+ media_entity_cleanup(&cef168_dev->sd.entity);
+}
+
+static const struct of_device_id cef168_of_table[] = {
+ { .compatible = "pinefeat,cef168" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, cef168_of_table);
+
+static struct i2c_driver cef168_i2c_driver = {
+ .driver = {
+ .name = CEF168_NAME,
+ .of_match_table = cef168_of_table,
+ },
+ .probe = cef168_probe,
+ .remove = cef168_remove,
+};
+
+module_i2c_driver(cef168_i2c_driver);
+
+MODULE_AUTHOR("support@pinefeat.co.uk>");
+MODULE_DESCRIPTION("CEF168 lens driver");
+MODULE_LICENSE("GPL");
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index f836512e9deb..7d6d026ef2ea 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -228,6 +228,12 @@ enum v4l2_colorfx {
*/
#define V4L2_CID_USER_RKISP1_BASE (V4L2_CID_USER_BASE + 0x1220)
+/*
+ * The base for Pinefeat CEF168 driver controls.
+ * We reserve 16 controls for this driver.
+ */
+#define V4L2_CID_USER_CEF168_BASE (V4L2_CID_USER_BASE + 0x1230)
+
/* MPEG-class control IDs */
/* The MPEG controls are applicable to all codec controls
* and the 'MPEG' part of the define is historical */
--
2.34.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v4 1/2] dt-bindings: Pinefeat cef168 lens control board
2025-08-22 17:10 ` [PATCH v4 1/2] dt-bindings: Pinefeat cef168 lens control board Aliaksandr Smirnou
@ 2025-08-24 9:22 ` Krzysztof Kozlowski
0 siblings, 0 replies; 9+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-24 9:22 UTC (permalink / raw)
To: Aliaksandr Smirnou
Cc: jacopo.mondi, hverkuil, mchehab, robh, krzk+dt, conor+dt,
devicetree, linux-media, linux-kernel, Aliaksandr Smirnou
On Fri, Aug 22, 2025 at 06:10:40PM +0100, Aliaksandr Smirnou wrote:
> Add the Device Tree schema and examples for the Pinefeat cef168 lens
> control board. This board interfaces Canon EF & EF-S lenses with
> non-Canon camera bodies, enabling electronic control of focus and
> aperture via V4L2.
>
> Power supply is derived from fixed supplies via connector or GPIO
> header. Therefore, the driver does not manage any regulator, so
> representing any supply in the binding is redundant.
>
> Signed-off-by: Aliaksandr Smirnou <asmirnou@pinefeat.co.uk>
From/SoB mismatch.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v4 1/2] dt-bindings: Pinefeat cef168 lens control board
2025-08-30 11:14 [PATCH v4 0/2] " Aliaksandr Smirnou
@ 2025-08-30 11:14 ` Aliaksandr Smirnou
2025-08-30 13:21 ` Krzysztof Kozlowski
0 siblings, 1 reply; 9+ messages in thread
From: Aliaksandr Smirnou @ 2025-08-30 11:14 UTC (permalink / raw)
To: jacopo.mondi, hverkuil, mchehab, robh, krzk+dt, conor+dt
Cc: devicetree, linux-media, linux-kernel, Aliaksandr Smirnou
Add the Device Tree schema and examples for the Pinefeat cef168 lens
control board. This board interfaces Canon EF & EF-S lenses with
non-Canon camera bodies, enabling electronic control of focus and
aperture via V4L2.
Power supply is derived from fixed supplies via connector or GPIO
header. Therefore, the driver does not manage any regulator, so
representing any supply in the binding is redundant.
Signed-off-by: Aliaksandr Smirnou <asmirnou@pinefeat.co.uk>
---
.../bindings/media/i2c/pinefeat,cef168.yaml | 47 +++++++++++++++++++
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
MAINTAINERS | 6 +++
3 files changed, 55 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/i2c/pinefeat,cef168.yaml
diff --git a/Documentation/devicetree/bindings/media/i2c/pinefeat,cef168.yaml b/Documentation/devicetree/bindings/media/i2c/pinefeat,cef168.yaml
new file mode 100644
index 000000000000..1295b1f4edeb
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/pinefeat,cef168.yaml
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (c) 2025 Pinefeat LLP
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/pinefeat,cef168.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Pinefeat cef168 lens driver
+
+maintainers:
+ - Aliaksandr Smirnou <support@pinefeat.co.uk>
+
+description: |
+ Pinefeat produces an adapter designed to interface between
+ Canon EF & EF-S lenses and non-Canon camera bodies, incorporating
+ features for electronic focus and aperture adjustment. The cef168
+ circuit board, included with the adapter, provides a software
+ programming interface that allows control of lens focus and
+ aperture positions.
+
+properties:
+ compatible:
+ enum:
+ - pinefeat,cef168
+
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ camera-lens@d {
+ compatible = "pinefeat,cef168";
+ reg = <0x0d>;
+ };
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 77160cd47f54..dab27f769b0a 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1195,6 +1195,8 @@ patternProperties:
description: Picochip Ltd
"^pine64,.*":
description: Pine64
+ "^pinefeat,.*":
+ description: Pinefeat LLP
"^pineriver,.*":
description: Shenzhen PineRiver Designs Co., Ltd.
"^pixcir,.*":
diff --git a/MAINTAINERS b/MAINTAINERS
index fe168477caa4..811c6a150029 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19985,6 +19985,12 @@ S: Supported
F: Documentation/devicetree/bindings/input/pine64,pinephone-keyboard.yaml
F: drivers/input/keyboard/pinephone-keyboard.c
+PINEFEAT CEF168 LENS DRIVER
+M: Aliaksandr Smirnou <support@pinefeat.co.uk>
+L: linux-media@vger.kernel.org
+S: Supported
+F: Documentation/devicetree/bindings/media/i2c/pinefeat,cef168.yaml
+
PLANTOWER PMS7003 AIR POLLUTION SENSOR DRIVER
M: Tomasz Duszynski <tduszyns@gmail.com>
S: Maintained
--
2.34.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v4 1/2] dt-bindings: Pinefeat cef168 lens control board
2025-08-30 11:14 ` [PATCH v4 1/2] dt-bindings: Pinefeat cef168 lens control board Aliaksandr Smirnou
@ 2025-08-30 13:21 ` Krzysztof Kozlowski
2025-08-30 14:24 ` Kieran Bingham
2025-08-30 15:58 ` Aliaksandr Smirnou
0 siblings, 2 replies; 9+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-30 13:21 UTC (permalink / raw)
To: Aliaksandr Smirnou, jacopo.mondi, hverkuil, mchehab, robh,
krzk+dt, conor+dt
Cc: devicetree, linux-media, linux-kernel
On 30/08/2025 13:14, Aliaksandr Smirnou wrote:
> Add the Device Tree schema and examples for the Pinefeat cef168 lens
> control board. This board interfaces Canon EF & EF-S lenses with
> non-Canon camera bodies, enabling electronic control of focus and
> aperture via V4L2.
>
> Power supply is derived from fixed supplies via connector or GPIO
> header. Therefore, the driver does not manage any regulator, so
> representing any supply in the binding is redundant.
>
> Signed-off-by: Aliaksandr Smirnou <asmirnou@pinefeat.co.uk>
b4 diff '<20250830111500.53169-2-asmirnou@pinefeat.co.uk>'
Grabbing thread from
lore.kernel.org/all/20250830111500.53169-2-asmirnou@pinefeat.co.uk/t.mbox.gz
Checking for older revisions
Grabbing search results from lore.kernel.org
---
Analyzing 9 messages in the thread
Could not find lower series to compare against.
You are not making it easier for us.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v4 1/2] dt-bindings: Pinefeat cef168 lens control board
2025-08-30 13:21 ` Krzysztof Kozlowski
@ 2025-08-30 14:24 ` Kieran Bingham
2025-08-30 15:53 ` Konstantin Ryabitsev
2025-08-30 15:58 ` Aliaksandr Smirnou
1 sibling, 1 reply; 9+ messages in thread
From: Kieran Bingham @ 2025-08-30 14:24 UTC (permalink / raw)
To: Aliaksandr Smirnou, Krzysztof Kozlowski, conor+dt, hverkuil,
jacopo.mondi, krzk+dt, mchehab, robh
Cc: devicetree, linux-media, linux-kernel
Quoting Krzysztof Kozlowski (2025-08-30 14:21:46)
> On 30/08/2025 13:14, Aliaksandr Smirnou wrote:
> > Add the Device Tree schema and examples for the Pinefeat cef168 lens
> > control board. This board interfaces Canon EF & EF-S lenses with
> > non-Canon camera bodies, enabling electronic control of focus and
> > aperture via V4L2.
> >
> > Power supply is derived from fixed supplies via connector or GPIO
> > header. Therefore, the driver does not manage any regulator, so
> > representing any supply in the binding is redundant.
> >
> > Signed-off-by: Aliaksandr Smirnou <asmirnou@pinefeat.co.uk>
>
>
> b4 diff '<20250830111500.53169-2-asmirnou@pinefeat.co.uk>'
> Grabbing thread from
> lore.kernel.org/all/20250830111500.53169-2-asmirnou@pinefeat.co.uk/t.mbox.gz
> Checking for older revisions
> Grabbing search results from lore.kernel.org
> ---
> Analyzing 9 messages in the thread
> Could not find lower series to compare against.
>
> You are not making it easier for us.
Could you explain what's required to tell b4 to know about earlier
versions please? (Or point to the documentation?)
I don't know ... so I don't think a first time contributor would
implicitly know either.
--
Kieran
>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
>
> Best regards,
> Krzysztof
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v4 1/2] dt-bindings: Pinefeat cef168 lens control board
2025-08-30 14:24 ` Kieran Bingham
@ 2025-08-30 15:53 ` Konstantin Ryabitsev
0 siblings, 0 replies; 9+ messages in thread
From: Konstantin Ryabitsev @ 2025-08-30 15:53 UTC (permalink / raw)
To: Kieran Bingham
Cc: Aliaksandr Smirnou, Krzysztof Kozlowski, conor+dt, hverkuil,
jacopo.mondi, krzk+dt, mchehab, robh, devicetree, linux-media,
linux-kernel
On Sat, Aug 30, 2025 at 03:24:37PM +0100, Kieran Bingham wrote:
> > b4 diff '<20250830111500.53169-2-asmirnou@pinefeat.co.uk>'
> > Grabbing thread from
> > lore.kernel.org/all/20250830111500.53169-2-asmirnou@pinefeat.co.uk/t.mbox.gz
> > Checking for older revisions
> > Grabbing search results from lore.kernel.org
> > ---
> > Analyzing 9 messages in the thread
> > Could not find lower series to compare against.
> >
> > You are not making it easier for us.
>
> Could you explain what's required to tell b4 to know about earlier
> versions please? (Or point to the documentation?)
Oh, it's an interesting case, glad I looked into it. For one, there was a bug
in b4 that limited the lookups by wrong author (mea culpa!). However, there is
a complication here. This identical series was sent several times, with a
different From address:
https://lore.kernel.org/all/20250830111500.53169-1-asmirnou@pinefeat.co.uk/
https://lore.kernel.org/all/20250822171041.7340-1-support@pinefeat.co.uk/
Since this series wasn't prepared with b4, it doesn't have a change-id, and
therefore when looking for previous revisions we limit by subject and same
author. Depending on which v4 you pick from the two above, you will either
find v3 or not find a v3. :)
This command succeeds with the latest master and stable-0.14.y:
b4 diff 20250822171041.7340-1-support@pinefeat.co.uk
> I don't know ... so I don't think a first time contributor would
> implicitly know either.
I know it's an easy thing to mess up, but in general sending the same series
twice with a different From address will result in confusion.
-K
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v4 1/2] dt-bindings: Pinefeat cef168 lens control board
2025-08-30 13:21 ` Krzysztof Kozlowski
2025-08-30 14:24 ` Kieran Bingham
@ 2025-08-30 15:58 ` Aliaksandr Smirnou
1 sibling, 0 replies; 9+ messages in thread
From: Aliaksandr Smirnou @ 2025-08-30 15:58 UTC (permalink / raw)
To: krzk
Cc: asmirnou, conor+dt, devicetree, hverkuil, jacopo.mondi, krzk+dt,
linux-kernel, linux-media, mchehab, robh
On Sat, 30 Aug 2025 15:21:46 +0200, Krzysztof Kozlowski wrote:
> b4 diff '<20250830111500.53169-2-asmirnou@pinefeat.co.uk>'
> Grabbing thread from
> lore.kernel.org/all/20250830111500.53169-2-asmirnou@pinefeat.co.uk/t.mbox.gz
> Checking for older revisions
> Grabbing search results from lore.kernel.org
> ---
> Analyzing 9 messages in the thread
> Could not find lower series to compare against.
>
> You are not making it easier for us.
Sorry, I know how hard the reviewing process can be.
To compare the differences, the mbox files can be created manually
and then a range-diff can be run against the previous series revision.
b4 am -T '<20250822171041.7340-1-support@pinefeat.co.uk>'
b4 am -T '<20250830111500.53169-1-asmirnou@pinefeat.co.uk>'
b4 diff -m \
v4_20250822_support_pinefeat_cef168_lens_control_board_driver.mbx \
v4_20250830_asmirnou_pinefeat_cef168_lens_control_board_driver.mbx
Let me know if you'd prefer that I submit a v5 instead.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-08-30 15:58 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-22 17:10 [PATCH v4 0/2] Pinefeat cef168 lens control board driver Aliaksandr Smirnou
2025-08-22 17:10 ` [PATCH v4 1/2] dt-bindings: Pinefeat cef168 lens control board Aliaksandr Smirnou
2025-08-24 9:22 ` Krzysztof Kozlowski
2025-08-22 17:10 ` [PATCH v4 2/2] media: i2c: Pinefeat cef168 lens control board driver Aliaksandr Smirnou
-- strict thread matches above, loose matches on Subject: below --
2025-08-30 11:14 [PATCH v4 0/2] " Aliaksandr Smirnou
2025-08-30 11:14 ` [PATCH v4 1/2] dt-bindings: Pinefeat cef168 lens control board Aliaksandr Smirnou
2025-08-30 13:21 ` Krzysztof Kozlowski
2025-08-30 14:24 ` Kieran Bingham
2025-08-30 15:53 ` Konstantin Ryabitsev
2025-08-30 15:58 ` Aliaksandr Smirnou
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).