starfive: add new target for StarFive JH7100/7110 SoC
[openwrt/staging/981213.git] / target / linux / starfive / patches-6.1 / 0083-media-starfive-Add-basic-driver.patch
1 From 0dc93c9321ba947ac429baeb58202496e4b0f219 Mon Sep 17 00:00:00 2001
2 From: Jack Zhu <jack.zhu@starfivetech.com>
3 Date: Fri, 12 May 2023 18:28:41 +0800
4 Subject: [PATCH 083/122] media: starfive: Add basic driver
5
6 Add basic platform driver for StarFive Camera Subsystem.
7
8 Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
9 Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
10 ---
11 drivers/media/platform/Kconfig | 1 +
12 drivers/media/platform/Makefile | 1 +
13 drivers/media/platform/starfive/Kconfig | 19 +
14 drivers/media/platform/starfive/Makefile | 9 +
15 drivers/media/platform/starfive/stf_camss.c | 372 +++++++++++++++++++
16 drivers/media/platform/starfive/stf_camss.h | 153 ++++++++
17 drivers/media/platform/starfive/stf_common.h | 18 +
18 7 files changed, 573 insertions(+)
19 create mode 100644 drivers/media/platform/starfive/Kconfig
20 create mode 100644 drivers/media/platform/starfive/Makefile
21 create mode 100644 drivers/media/platform/starfive/stf_camss.c
22 create mode 100644 drivers/media/platform/starfive/stf_camss.h
23 create mode 100644 drivers/media/platform/starfive/stf_common.h
24
25 --- a/drivers/media/platform/Kconfig
26 +++ b/drivers/media/platform/Kconfig
27 @@ -79,6 +79,7 @@ source "drivers/media/platform/renesas/K
28 source "drivers/media/platform/rockchip/Kconfig"
29 source "drivers/media/platform/samsung/Kconfig"
30 source "drivers/media/platform/st/Kconfig"
31 +source "drivers/media/platform/starfive/Kconfig"
32 source "drivers/media/platform/sunxi/Kconfig"
33 source "drivers/media/platform/ti/Kconfig"
34 source "drivers/media/platform/verisilicon/Kconfig"
35 --- a/drivers/media/platform/Makefile
36 +++ b/drivers/media/platform/Makefile
37 @@ -22,6 +22,7 @@ obj-y += renesas/
38 obj-y += rockchip/
39 obj-y += samsung/
40 obj-y += st/
41 +obj-y += starfive/
42 obj-y += sunxi/
43 obj-y += ti/
44 obj-y += verisilicon/
45 --- /dev/null
46 +++ b/drivers/media/platform/starfive/Kconfig
47 @@ -0,0 +1,19 @@
48 +# SPDX-License-Identifier: GPL-2.0-only
49 +
50 +comment "Starfive media platform drivers"
51 +
52 +config VIDEO_STARFIVE_CAMSS
53 + tristate "Starfive Camera Subsystem driver"
54 + depends on V4L_PLATFORM_DRIVERS
55 + depends on VIDEO_DEV && OF
56 + depends on DMA_CMA
57 + select MEDIA_CONTROLLER
58 + select VIDEO_V4L2_SUBDEV_API
59 + select VIDEOBUF2_DMA_CONTIG
60 + select V4L2_FWNODE
61 + help
62 + Enable this to support for the Starfive Camera subsystem
63 + found on Starfive JH7110 SoC.
64 +
65 + To compile this driver as a module, choose M here: the
66 + module will be called stf-camss.
67 --- /dev/null
68 +++ b/drivers/media/platform/starfive/Makefile
69 @@ -0,0 +1,9 @@
70 +# SPDX-License-Identifier: GPL-2.0
71 +#
72 +# Makefile for StarFive camera subsystem driver.
73 +#
74 +
75 +starfive-camss-objs += \
76 + stf_camss.o
77 +
78 +obj-$(CONFIG_VIDEO_STARFIVE_CAMSS) += starfive-camss.o \
79 --- /dev/null
80 +++ b/drivers/media/platform/starfive/stf_camss.c
81 @@ -0,0 +1,372 @@
82 +// SPDX-License-Identifier: GPL-2.0
83 +/*
84 + * stf_camss.c
85 + *
86 + * Starfive Camera Subsystem driver
87 + *
88 + * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
89 + */
90 +#include <linux/module.h>
91 +#include <linux/of.h>
92 +#include <linux/of_graph.h>
93 +#include <linux/platform_device.h>
94 +#include <linux/pm_runtime.h>
95 +#include <linux/videodev2.h>
96 +#include <media/media-device.h>
97 +#include <media/v4l2-async.h>
98 +#include <media/v4l2-fwnode.h>
99 +#include <media/v4l2-mc.h>
100 +
101 +#include "stf_camss.h"
102 +
103 +static const char * const stfcamss_clocks[] = {
104 + "clk_apb_func",
105 + "clk_wrapper_clk_c",
106 + "clk_dvp_inv",
107 + "clk_axiwr",
108 + "clk_mipi_rx0_pxl",
109 + "clk_ispcore_2x",
110 + "clk_isp_axi",
111 +};
112 +
113 +static const char * const stfcamss_resets[] = {
114 + "rst_wrapper_p",
115 + "rst_wrapper_c",
116 + "rst_axird",
117 + "rst_axiwr",
118 + "rst_isp_top_n",
119 + "rst_isp_top_axi",
120 +};
121 +
122 +static int stfcamss_get_mem_res(struct platform_device *pdev,
123 + struct stfcamss *stfcamss)
124 +{
125 + stfcamss->syscon_base =
126 + devm_platform_ioremap_resource_byname(pdev, "syscon");
127 + if (IS_ERR(stfcamss->syscon_base))
128 + return PTR_ERR(stfcamss->syscon_base);
129 +
130 + stfcamss->isp_base =
131 + devm_platform_ioremap_resource_byname(pdev, "isp");
132 + if (IS_ERR(stfcamss->isp_base))
133 + return PTR_ERR(stfcamss->isp_base);
134 +
135 + return 0;
136 +}
137 +
138 +/*
139 + * stfcamss_of_parse_endpoint_node - Parse port endpoint node
140 + * @dev: Device
141 + * @node: Device node to be parsed
142 + * @csd: Parsed data from port endpoint node
143 + *
144 + * Return 0 on success or a negative error code on failure
145 + */
146 +static int stfcamss_of_parse_endpoint_node(struct device *dev,
147 + struct device_node *node,
148 + struct stfcamss_async_subdev *csd)
149 +{
150 + struct v4l2_fwnode_endpoint vep = { { 0 } };
151 +
152 + v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep);
153 + dev_dbg(dev, "vep.base.port = 0x%x, id = 0x%x\n",
154 + vep.base.port, vep.base.id);
155 +
156 + csd->port = vep.base.port;
157 +
158 + return 0;
159 +}
160 +
161 +/*
162 + * stfcamss_of_parse_ports - Parse ports node
163 + * @stfcamss: STFCAMSS device
164 + *
165 + * Return number of "port" nodes found in "ports" node
166 + */
167 +static int stfcamss_of_parse_ports(struct stfcamss *stfcamss)
168 +{
169 + struct device *dev = stfcamss->dev;
170 + struct device_node *node = NULL;
171 + struct device_node *remote = NULL;
172 + int ret, num_subdevs = 0;
173 +
174 + for_each_endpoint_of_node(dev->of_node, node) {
175 + struct stfcamss_async_subdev *csd;
176 +
177 + if (!of_device_is_available(node))
178 + continue;
179 +
180 + remote = of_graph_get_remote_port_parent(node);
181 + if (!remote) {
182 + dev_err(dev, "Cannot get remote parent\n");
183 + ret = -EINVAL;
184 + goto err_cleanup;
185 + }
186 +
187 + csd = v4l2_async_nf_add_fwnode(&stfcamss->notifier,
188 + of_fwnode_handle(remote),
189 + struct stfcamss_async_subdev);
190 + of_node_put(remote);
191 + if (IS_ERR(csd)) {
192 + ret = PTR_ERR(csd);
193 + goto err_cleanup;
194 + }
195 +
196 + ret = stfcamss_of_parse_endpoint_node(dev, node, csd);
197 + if (ret < 0)
198 + goto err_cleanup;
199 +
200 + num_subdevs++;
201 + }
202 +
203 + return num_subdevs;
204 +
205 +err_cleanup:
206 + of_node_put(node);
207 + return ret;
208 +}
209 +
210 +static int stfcamss_subdev_notifier_bound(struct v4l2_async_notifier *async,
211 + struct v4l2_subdev *subdev,
212 + struct v4l2_async_subdev *asd)
213 +{
214 + struct stfcamss *stfcamss =
215 + container_of(async, struct stfcamss, notifier);
216 + struct host_data *host_data = &stfcamss->host_data;
217 + struct media_entity *source;
218 + int i, j;
219 +
220 + source = &subdev->entity;
221 +
222 + for (i = 0; i < source->num_pads; i++) {
223 + if (source->pads[i].flags & MEDIA_PAD_FL_SOURCE)
224 + break;
225 + }
226 +
227 + if (i == source->num_pads) {
228 + dev_err(stfcamss->dev, "No source pad in external entity\n");
229 + return -EINVAL;
230 + }
231 +
232 + for (j = 0; host_data->host_entity[j] && (j < HOST_ENTITY_MAX); j++) {
233 + struct media_entity *input;
234 + int ret;
235 +
236 + input = host_data->host_entity[j];
237 +
238 + ret = media_create_pad_link(
239 + source,
240 + i,
241 + input,
242 + STF_PAD_SINK,
243 + source->function == MEDIA_ENT_F_CAM_SENSOR ?
244 + MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED :
245 + 0);
246 + if (ret < 0) {
247 + dev_err(stfcamss->dev,
248 + "Failed to link %s->%s entities: %d\n",
249 + source->name, input->name, ret);
250 + return ret;
251 + }
252 + }
253 +
254 + return 0;
255 +}
256 +
257 +static int stfcamss_subdev_notifier_complete(struct v4l2_async_notifier *ntf)
258 +{
259 + struct stfcamss *stfcamss =
260 + container_of(ntf, struct stfcamss, notifier);
261 +
262 + return v4l2_device_register_subdev_nodes(&stfcamss->v4l2_dev);
263 +}
264 +
265 +static const struct v4l2_async_notifier_operations
266 +stfcamss_subdev_notifier_ops = {
267 + .bound = stfcamss_subdev_notifier_bound,
268 + .complete = stfcamss_subdev_notifier_complete,
269 +};
270 +
271 +static const struct media_device_ops stfcamss_media_ops = {
272 + .link_notify = v4l2_pipeline_link_notify,
273 +};
274 +
275 +static void stfcamss_mc_init(struct platform_device *pdev,
276 + struct stfcamss *stfcamss)
277 +{
278 + stfcamss->media_dev.dev = stfcamss->dev;
279 + strscpy(stfcamss->media_dev.model, "Starfive Camera Subsystem",
280 + sizeof(stfcamss->media_dev.model));
281 + snprintf(stfcamss->media_dev.bus_info,
282 + sizeof(stfcamss->media_dev.bus_info),
283 + "%s:%s", dev_bus_name(&pdev->dev), pdev->name);
284 + stfcamss->media_dev.hw_revision = 0x01;
285 + stfcamss->media_dev.ops = &stfcamss_media_ops;
286 + media_device_init(&stfcamss->media_dev);
287 +
288 + stfcamss->v4l2_dev.mdev = &stfcamss->media_dev;
289 +}
290 +
291 +/*
292 + * stfcamss_probe - Probe STFCAMSS platform device
293 + * @pdev: Pointer to STFCAMSS platform device
294 + *
295 + * Return 0 on success or a negative error code on failure
296 + */
297 +static int stfcamss_probe(struct platform_device *pdev)
298 +{
299 + struct stfcamss *stfcamss;
300 + struct device *dev = &pdev->dev;
301 + int ret = 0, i, num_subdevs;
302 +
303 + stfcamss = devm_kzalloc(dev, sizeof(*stfcamss), GFP_KERNEL);
304 + if (!stfcamss)
305 + return -ENOMEM;
306 +
307 + for (i = 0; i < ARRAY_SIZE(stfcamss->irq); ++i) {
308 + stfcamss->irq[i] = platform_get_irq(pdev, i);
309 + if (stfcamss->irq[i] < 0)
310 + return dev_err_probe(&pdev->dev, stfcamss->irq[i],
311 + "Failed to get clock%d", i);
312 + }
313 +
314 + stfcamss->nclks = ARRAY_SIZE(stfcamss->sys_clk);
315 + for (i = 0; i < ARRAY_SIZE(stfcamss->sys_clk); ++i)
316 + stfcamss->sys_clk[i].id = stfcamss_clocks[i];
317 + ret = devm_clk_bulk_get(dev, stfcamss->nclks, stfcamss->sys_clk);
318 + if (ret) {
319 + dev_err(dev, "Failed to get clk controls\n");
320 + return ret;
321 + }
322 +
323 + stfcamss->nrsts = ARRAY_SIZE(stfcamss->sys_rst);
324 + for (i = 0; i < ARRAY_SIZE(stfcamss->sys_rst); ++i)
325 + stfcamss->sys_rst[i].id = stfcamss_resets[i];
326 + ret = devm_reset_control_bulk_get_shared(dev, stfcamss->nrsts,
327 + stfcamss->sys_rst);
328 + if (ret) {
329 + dev_err(dev, "Failed to get reset controls\n");
330 + return ret;
331 + }
332 +
333 + ret = stfcamss_get_mem_res(pdev, stfcamss);
334 + if (ret) {
335 + dev_err(dev, "Could not map registers\n");
336 + return ret;
337 + }
338 +
339 + stfcamss->dev = dev;
340 + platform_set_drvdata(pdev, stfcamss);
341 +
342 + v4l2_async_nf_init(&stfcamss->notifier);
343 +
344 + num_subdevs = stfcamss_of_parse_ports(stfcamss);
345 + if (num_subdevs < 0) {
346 + dev_err(dev, "Failed to find subdevices\n");
347 + return -ENODEV;
348 + }
349 +
350 + stfcamss_mc_init(pdev, stfcamss);
351 +
352 + ret = v4l2_device_register(stfcamss->dev, &stfcamss->v4l2_dev);
353 + if (ret < 0) {
354 + dev_err(dev, "Failed to register V4L2 device: %d\n", ret);
355 + goto err_cleanup_notifier;
356 + }
357 +
358 + ret = media_device_register(&stfcamss->media_dev);
359 + if (ret) {
360 + dev_err(dev, "Failed to register media device: %d\n", ret);
361 + goto err_unregister_device;
362 + }
363 +
364 + stfcamss->notifier.ops = &stfcamss_subdev_notifier_ops;
365 + ret = v4l2_async_nf_register(&stfcamss->v4l2_dev, &stfcamss->notifier);
366 + if (ret) {
367 + dev_err(dev, "Failed to register async subdev nodes: %d\n",
368 + ret);
369 + goto err_unregister_media_dev;
370 + }
371 +
372 + pm_runtime_enable(dev);
373 +
374 + return 0;
375 +
376 +err_unregister_media_dev:
377 + media_device_unregister(&stfcamss->media_dev);
378 +err_unregister_device:
379 + v4l2_device_unregister(&stfcamss->v4l2_dev);
380 +err_cleanup_notifier:
381 + v4l2_async_nf_cleanup(&stfcamss->notifier);
382 + return ret;
383 +}
384 +
385 +/*
386 + * stfcamss_remove - Remove STFCAMSS platform device
387 + * @pdev: Pointer to STFCAMSS platform device
388 + *
389 + * Always returns 0.
390 + */
391 +static int stfcamss_remove(struct platform_device *pdev)
392 +{
393 + struct stfcamss *stfcamss = platform_get_drvdata(pdev);
394 +
395 + v4l2_device_unregister(&stfcamss->v4l2_dev);
396 + media_device_cleanup(&stfcamss->media_dev);
397 + pm_runtime_disable(&pdev->dev);
398 +
399 + return 0;
400 +}
401 +
402 +static const struct of_device_id stfcamss_of_match[] = {
403 + { .compatible = "starfive,jh7110-camss" },
404 + { /* sentinel */ },
405 +};
406 +
407 +MODULE_DEVICE_TABLE(of, stfcamss_of_match);
408 +
409 +static int __maybe_unused stfcamss_runtime_suspend(struct device *dev)
410 +{
411 + struct stfcamss *stfcamss = dev_get_drvdata(dev);
412 +
413 + reset_control_assert(stfcamss->sys_rst[STF_RST_ISP_TOP_AXI].rstc);
414 + reset_control_assert(stfcamss->sys_rst[STF_RST_ISP_TOP_N].rstc);
415 + clk_disable_unprepare(stfcamss->sys_clk[STF_CLK_ISP_AXI].clk);
416 + clk_disable_unprepare(stfcamss->sys_clk[STF_CLK_ISPCORE_2X].clk);
417 +
418 + return 0;
419 +}
420 +
421 +static int __maybe_unused stfcamss_runtime_resume(struct device *dev)
422 +{
423 + struct stfcamss *stfcamss = dev_get_drvdata(dev);
424 +
425 + clk_prepare_enable(stfcamss->sys_clk[STF_CLK_ISPCORE_2X].clk);
426 + clk_prepare_enable(stfcamss->sys_clk[STF_CLK_ISP_AXI].clk);
427 + reset_control_deassert(stfcamss->sys_rst[STF_RST_ISP_TOP_N].rstc);
428 + reset_control_deassert(stfcamss->sys_rst[STF_RST_ISP_TOP_AXI].rstc);
429 +
430 + return 0;
431 +}
432 +
433 +static const struct dev_pm_ops stfcamss_pm_ops = {
434 + SET_RUNTIME_PM_OPS(stfcamss_runtime_suspend,
435 + stfcamss_runtime_resume,
436 + NULL)
437 +};
438 +
439 +static struct platform_driver stfcamss_driver = {
440 + .probe = stfcamss_probe,
441 + .remove = stfcamss_remove,
442 + .driver = {
443 + .name = DRV_NAME,
444 + .pm = &stfcamss_pm_ops,
445 + .of_match_table = of_match_ptr(stfcamss_of_match),
446 + },
447 +};
448 +
449 +module_platform_driver(stfcamss_driver);
450 +
451 +MODULE_AUTHOR("StarFive Corporation");
452 +MODULE_DESCRIPTION("StarFive Camera Subsystem driver");
453 +MODULE_LICENSE("GPL");
454 --- /dev/null
455 +++ b/drivers/media/platform/starfive/stf_camss.h
456 @@ -0,0 +1,153 @@
457 +/* SPDX-License-Identifier: GPL-2.0 */
458 +/*
459 + * stf_camss.h
460 + *
461 + * Starfive Camera Subsystem driver
462 + *
463 + * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
464 + */
465 +
466 +#ifndef STF_CAMSS_H
467 +#define STF_CAMSS_H
468 +
469 +#include <linux/clk.h>
470 +#include <linux/delay.h>
471 +#include <linux/reset.h>
472 +#include <media/v4l2-device.h>
473 +
474 +#include "stf_common.h"
475 +
476 +#define DRV_NAME "starfive-camss"
477 +#define STF_DVP_NAME "stf_dvp"
478 +#define STF_CSI_NAME "cdns_csi2rx"
479 +#define STF_ISP_NAME "stf_isp"
480 +#define STF_VIN_NAME "stf_vin"
481 +
482 +#define STF_PAD_SINK 0
483 +#define STF_PAD_SRC 1
484 +#define STF_PADS_NUM 2
485 +
486 +enum port_num {
487 + PORT_NUMBER_DVP_SENSOR = 0,
488 + PORT_NUMBER_CSI2RX
489 +};
490 +
491 +enum stf_clk {
492 + STF_CLK_APB_FUNC = 0,
493 + STF_CLK_WRAPPER_CLK_C,
494 + STF_CLK_DVP_INV,
495 + STF_CLK_AXIWR,
496 + STF_CLK_MIPI_RX0_PXL,
497 + STF_CLK_ISPCORE_2X,
498 + STF_CLK_ISP_AXI,
499 + STF_CLK_NUM
500 +};
501 +
502 +enum stf_rst {
503 + STF_RST_WRAPPER_P = 0,
504 + STF_RST_WRAPPER_C,
505 + STF_RST_AXIRD,
506 + STF_RST_AXIWR,
507 + STF_RST_ISP_TOP_N,
508 + STF_RST_ISP_TOP_AXI,
509 + STF_RST_NUM
510 +};
511 +
512 +enum stf_irq {
513 + STF_IRQ_VINWR = 0,
514 + STF_IRQ_ISP,
515 + STF_IRQ_ISPCSIL,
516 + STF_IRQ_NUM
517 +};
518 +
519 +#define HOST_ENTITY_MAX 2
520 +
521 +struct host_data {
522 + struct media_entity *host_entity[HOST_ENTITY_MAX];
523 +};
524 +
525 +struct stfcamss {
526 + struct v4l2_device v4l2_dev;
527 + struct media_device media_dev;
528 + struct media_pipeline pipe;
529 + struct device *dev;
530 + struct v4l2_async_notifier notifier;
531 + struct host_data host_data;
532 + void __iomem *syscon_base;
533 + void __iomem *isp_base;
534 + int irq[STF_IRQ_NUM];
535 + struct clk_bulk_data sys_clk[STF_CLK_NUM];
536 + int nclks;
537 + struct reset_control_bulk_data sys_rst[STF_RST_NUM];
538 + int nrsts;
539 +};
540 +
541 +struct stfcamss_async_subdev {
542 + struct v4l2_async_subdev asd; /* must be first */
543 + enum port_num port;
544 +};
545 +
546 +static inline u32 stf_isp_reg_read(struct stfcamss *stfcamss, u32 reg)
547 +{
548 + return ioread32(stfcamss->isp_base + reg);
549 +}
550 +
551 +static inline void stf_isp_reg_write(struct stfcamss *stfcamss,
552 + u32 reg, u32 val)
553 +{
554 + iowrite32(val, stfcamss->isp_base + reg);
555 +}
556 +
557 +static inline void stf_isp_reg_write_delay(struct stfcamss *stfcamss,
558 + u32 reg, u32 val, u32 delay)
559 +{
560 + iowrite32(val, stfcamss->isp_base + reg);
561 + usleep_range(1000 * delay, 1000 * delay + 100);
562 +}
563 +
564 +static inline void stf_isp_reg_set_bit(struct stfcamss *stfcamss,
565 + u32 reg, u32 mask, u32 val)
566 +{
567 + u32 value;
568 +
569 + value = ioread32(stfcamss->isp_base + reg) & ~mask;
570 + val &= mask;
571 + val |= value;
572 + iowrite32(val, stfcamss->isp_base + reg);
573 +}
574 +
575 +static inline void stf_isp_reg_set(struct stfcamss *stfcamss, u32 reg, u32 mask)
576 +{
577 + iowrite32(ioread32(stfcamss->isp_base + reg) | mask,
578 + stfcamss->isp_base + reg);
579 +}
580 +
581 +static inline u32 stf_syscon_reg_read(struct stfcamss *stfcamss, u32 reg)
582 +{
583 + return ioread32(stfcamss->syscon_base + reg);
584 +}
585 +
586 +static inline void stf_syscon_reg_write(struct stfcamss *stfcamss,
587 + u32 reg, u32 val)
588 +{
589 + iowrite32(val, stfcamss->syscon_base + reg);
590 +}
591 +
592 +static inline void stf_syscon_reg_set_bit(struct stfcamss *stfcamss,
593 + u32 reg, u32 bit_mask)
594 +{
595 + u32 value;
596 +
597 + value = ioread32(stfcamss->syscon_base + reg);
598 + iowrite32(value | bit_mask, stfcamss->syscon_base + reg);
599 +}
600 +
601 +static inline void stf_syscon_reg_clear_bit(struct stfcamss *stfcamss,
602 + u32 reg, u32 bit_mask)
603 +{
604 + u32 value;
605 +
606 + value = ioread32(stfcamss->syscon_base + reg);
607 + iowrite32(value & ~bit_mask, stfcamss->syscon_base + reg);
608 +}
609 +#endif /* STF_CAMSS_H */
610 --- /dev/null
611 +++ b/drivers/media/platform/starfive/stf_common.h
612 @@ -0,0 +1,18 @@
613 +/* SPDX-License-Identifier: GPL-2.0 */
614 +/*
615 + * stf_common.h
616 + *
617 + * StarFive Camera Subsystem - Common definitions
618 + *
619 + * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
620 + */
621 +
622 +#ifndef STF_COMMON_H
623 +#define STF_COMMON_H
624 +
625 +enum stf_subdev_type {
626 + STF_SUBDEV_TYPE_VIN,
627 + STF_SUBDEV_TYPE_ISP,
628 +};
629 +
630 +#endif /* STF_COMMON_H */