hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/media/platform/atmel/atmel-isi.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2011 Atmel Corporation
34 * Josh Wu, <josh.wu@atmel.com>
....@@ -5,10 +6,6 @@
56 * Based on previous work by Lars Haring, <lars.haring@atmel.com>
67 * and Sedji Gaouaou
78 * Based on the bttv driver for Bt848 with respective copyright holders
8
- *
9
- * This program is free software; you can redistribute it and/or modify
10
- * it under the terms of the GNU General Public License version 2 as
11
- * published by the Free Software Foundation.
129 */
1310
1411 #include <linux/clk.h>
....@@ -110,7 +107,7 @@
110107 bool enable_preview_path;
111108
112109 struct completion complete;
113
- /* ISI peripherial clock */
110
+ /* ISI peripheral clock */
114111 struct clk *pclk;
115112 unsigned int irq;
116113
....@@ -151,7 +148,8 @@
151148 u32 fourcc = isi->current_fmt->fourcc;
152149
153150 isi->enable_preview_path = fourcc == V4L2_PIX_FMT_RGB565 ||
154
- fourcc == V4L2_PIX_FMT_RGB32;
151
+ fourcc == V4L2_PIX_FMT_RGB32 ||
152
+ fourcc == V4L2_PIX_FMT_Y16;
155153
156154 /* According to sensor's output format to set cfg2 */
157155 cfg2 = isi->current_fmt->swap;
....@@ -557,12 +555,36 @@
557555 return NULL;
558556 }
559557
558
+static void isi_try_fse(struct atmel_isi *isi, const struct isi_format *isi_fmt,
559
+ struct v4l2_subdev_pad_config *pad_cfg)
560
+{
561
+ int ret;
562
+ struct v4l2_subdev_frame_size_enum fse = {
563
+ .code = isi_fmt->mbus_code,
564
+ .which = V4L2_SUBDEV_FORMAT_TRY,
565
+ };
566
+
567
+ ret = v4l2_subdev_call(isi->entity.subdev, pad, enum_frame_size,
568
+ pad_cfg, &fse);
569
+ /*
570
+ * Attempt to obtain format size from subdev. If not available,
571
+ * just use the maximum ISI can receive.
572
+ */
573
+ if (ret) {
574
+ pad_cfg->try_crop.width = MAX_SUPPORT_WIDTH;
575
+ pad_cfg->try_crop.height = MAX_SUPPORT_HEIGHT;
576
+ } else {
577
+ pad_cfg->try_crop.width = fse.max_width;
578
+ pad_cfg->try_crop.height = fse.max_height;
579
+ }
580
+}
581
+
560582 static int isi_try_fmt(struct atmel_isi *isi, struct v4l2_format *f,
561583 const struct isi_format **current_fmt)
562584 {
563585 const struct isi_format *isi_fmt;
564586 struct v4l2_pix_format *pixfmt = &f->fmt.pix;
565
- struct v4l2_subdev_pad_config pad_cfg;
587
+ struct v4l2_subdev_pad_config pad_cfg = {};
566588 struct v4l2_subdev_format format = {
567589 .which = V4L2_SUBDEV_FORMAT_TRY,
568590 };
....@@ -579,6 +601,9 @@
579601 pixfmt->height = clamp(pixfmt->height, 0U, MAX_SUPPORT_HEIGHT);
580602
581603 v4l2_fill_mbus_format(&format.format, pixfmt, isi_fmt->mbus_code);
604
+
605
+ isi_try_fse(isi, isi_fmt, &pad_cfg);
606
+
582607 ret = v4l2_subdev_call(isi->entity.subdev, pad, set_fmt,
583608 &pad_cfg, &format);
584609 if (ret < 0)
....@@ -655,9 +680,9 @@
655680 static int isi_querycap(struct file *file, void *priv,
656681 struct v4l2_capability *cap)
657682 {
658
- strlcpy(cap->driver, "atmel-isi", sizeof(cap->driver));
659
- strlcpy(cap->card, "Atmel Image Sensor Interface", sizeof(cap->card));
660
- strlcpy(cap->bus_info, "platform:isi", sizeof(cap->bus_info));
683
+ strscpy(cap->driver, "atmel-isi", sizeof(cap->driver));
684
+ strscpy(cap->card, "Atmel Image Sensor Interface", sizeof(cap->card));
685
+ strscpy(cap->bus_info, "platform:isi", sizeof(cap->bus_info));
661686 return 0;
662687 }
663688
....@@ -668,7 +693,7 @@
668693 return -EINVAL;
669694
670695 i->type = V4L2_INPUT_TYPE_CAMERA;
671
- strlcpy(i->name, "Camera", sizeof(i->name));
696
+ strscpy(i->name, "Camera", sizeof(i->name));
672697 return 0;
673698 }
674699
....@@ -790,7 +815,7 @@
790815 struct platform_device *pdev)
791816 {
792817 struct device_node *np = pdev->dev.of_node;
793
- struct v4l2_fwnode_endpoint ep;
818
+ struct v4l2_fwnode_endpoint ep = { .bus_type = 0 };
794819 int err;
795820
796821 /* Default settings for ISI */
....@@ -993,6 +1018,16 @@
9931018 .mbus_code = MEDIA_BUS_FMT_VYUY8_2X8,
9941019 .bpp = 2,
9951020 .swap = ISI_CFG2_YCC_SWAP_MODE_1,
1021
+ }, {
1022
+ .fourcc = V4L2_PIX_FMT_GREY,
1023
+ .mbus_code = MEDIA_BUS_FMT_Y10_1X10,
1024
+ .bpp = 1,
1025
+ .swap = ISI_CFG2_GS_MODE_2_PIXEL | ISI_CFG2_GRAYSCALE,
1026
+ }, {
1027
+ .fourcc = V4L2_PIX_FMT_Y16,
1028
+ .mbus_code = MEDIA_BUS_FMT_Y10_1X10,
1029
+ .bpp = 2,
1030
+ .swap = ISI_CFG2_GS_MODE_2_PIXEL | ISI_CFG2_GRAYSCALE,
9961031 },
9971032 };
9981033
....@@ -1059,7 +1094,7 @@
10591094 return ret;
10601095 }
10611096
1062
- ret = video_register_device(isi->vdev, VFL_TYPE_GRABBER, -1);
1097
+ ret = video_register_device(isi->vdev, VFL_TYPE_VIDEO, -1);
10631098 if (ret) {
10641099 dev_err(isi->dev, "Failed to register video device\n");
10651100 return ret;
....@@ -1078,7 +1113,7 @@
10781113
10791114 dev_dbg(isi->dev, "Removing %s\n", video_device_node_name(isi->vdev));
10801115
1081
- /* Checks internaly if vdev have been init or not */
1116
+ /* Checks internally if vdev have been init or not */
10821117 video_unregister_device(isi->vdev);
10831118 }
10841119
....@@ -1124,7 +1159,6 @@
11241159
11251160 static int isi_graph_init(struct atmel_isi *isi)
11261161 {
1127
- struct v4l2_async_subdev **subdevs = NULL;
11281162 int ret;
11291163
11301164 /* Parse the graph to extract a list of subdevice DT nodes. */
....@@ -1134,23 +1168,20 @@
11341168 return ret;
11351169 }
11361170
1137
- /* Register the subdevices notifier. */
1138
- subdevs = devm_kzalloc(isi->dev, sizeof(*subdevs), GFP_KERNEL);
1139
- if (!subdevs) {
1171
+ v4l2_async_notifier_init(&isi->notifier);
1172
+
1173
+ ret = v4l2_async_notifier_add_subdev(&isi->notifier, &isi->entity.asd);
1174
+ if (ret) {
11401175 of_node_put(isi->entity.node);
1141
- return -ENOMEM;
1176
+ return ret;
11421177 }
11431178
1144
- subdevs[0] = &isi->entity.asd;
1145
-
1146
- isi->notifier.subdevs = subdevs;
1147
- isi->notifier.num_subdevs = 1;
11481179 isi->notifier.ops = &isi_graph_notify_ops;
11491180
11501181 ret = v4l2_async_notifier_register(&isi->v4l2_dev, &isi->notifier);
11511182 if (ret < 0) {
11521183 dev_err(isi->dev, "Notifier registration failed\n");
1153
- of_node_put(isi->entity.node);
1184
+ v4l2_async_notifier_cleanup(&isi->notifier);
11541185 return ret;
11551186 }
11561187
....@@ -1202,7 +1233,7 @@
12021233 isi->vdev->fops = &isi_fops;
12031234 isi->vdev->v4l2_dev = &isi->v4l2_dev;
12041235 isi->vdev->queue = &isi->queue;
1205
- strlcpy(isi->vdev->name, KBUILD_MODNAME, sizeof(isi->vdev->name));
1236
+ strscpy(isi->vdev->name, KBUILD_MODNAME, sizeof(isi->vdev->name));
12061237 isi->vdev->release = video_device_release;
12071238 isi->vdev->ioctl_ops = &isi_ioctl_ops;
12081239 isi->vdev->lock = &isi->lock;
....@@ -1303,6 +1334,7 @@
13031334 isi->fb_descriptors_phys);
13041335 pm_runtime_disable(&pdev->dev);
13051336 v4l2_async_notifier_unregister(&isi->notifier);
1337
+ v4l2_async_notifier_cleanup(&isi->notifier);
13061338 v4l2_device_unregister(&isi->v4l2_dev);
13071339
13081340 return 0;