.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Main USB camera driver |
---|
3 | 4 | * |
---|
.. | .. |
---|
5 | 6 | * |
---|
6 | 7 | * Camera button input handling by Márton Németh |
---|
7 | 8 | * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu> |
---|
8 | | - * |
---|
9 | | - * This program is free software; you can redistribute it and/or modify it |
---|
10 | | - * under the terms of the GNU General Public License as published by the |
---|
11 | | - * Free Software Foundation; either version 2 of the License, or (at your |
---|
12 | | - * option) any later version. |
---|
13 | | - * |
---|
14 | | - * This program is distributed in the hope that it will be useful, but |
---|
15 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
---|
16 | | - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
---|
17 | | - * for more details. |
---|
18 | 9 | */ |
---|
19 | 10 | |
---|
20 | 11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
---|
.. | .. |
---|
916 | 907 | } |
---|
917 | 908 | |
---|
918 | 909 | static int wxh_to_mode(struct gspca_dev *gspca_dev, |
---|
919 | | - int width, int height) |
---|
| 910 | + int width, int height, u32 pixelformat) |
---|
920 | 911 | { |
---|
921 | 912 | int i; |
---|
922 | 913 | |
---|
923 | 914 | for (i = 0; i < gspca_dev->cam.nmodes; i++) { |
---|
924 | 915 | if (width == gspca_dev->cam.cam_mode[i].width |
---|
925 | | - && height == gspca_dev->cam.cam_mode[i].height) |
---|
| 916 | + && height == gspca_dev->cam.cam_mode[i].height |
---|
| 917 | + && pixelformat == gspca_dev->cam.cam_mode[i].pixelformat) |
---|
926 | 918 | return i; |
---|
927 | 919 | } |
---|
928 | 920 | return -EINVAL; |
---|
929 | 921 | } |
---|
930 | 922 | |
---|
931 | 923 | static int wxh_to_nearest_mode(struct gspca_dev *gspca_dev, |
---|
932 | | - int width, int height) |
---|
| 924 | + int width, int height, u32 pixelformat) |
---|
933 | 925 | { |
---|
934 | 926 | int i; |
---|
935 | 927 | |
---|
| 928 | + for (i = gspca_dev->cam.nmodes; --i >= 0; ) { |
---|
| 929 | + if (width >= gspca_dev->cam.cam_mode[i].width |
---|
| 930 | + && height >= gspca_dev->cam.cam_mode[i].height |
---|
| 931 | + && pixelformat == gspca_dev->cam.cam_mode[i].pixelformat) |
---|
| 932 | + return i; |
---|
| 933 | + } |
---|
936 | 934 | for (i = gspca_dev->cam.nmodes; --i > 0; ) { |
---|
937 | 935 | if (width >= gspca_dev->cam.cam_mode[i].width |
---|
938 | 936 | && height >= gspca_dev->cam.cam_mode[i].height) |
---|
.. | .. |
---|
1026 | 1024 | return -EINVAL; /* no more format */ |
---|
1027 | 1025 | |
---|
1028 | 1026 | fmtdesc->pixelformat = fmt_tb[index]; |
---|
1029 | | - if (gspca_dev->cam.cam_mode[i].sizeimage < |
---|
1030 | | - gspca_dev->cam.cam_mode[i].width * |
---|
1031 | | - gspca_dev->cam.cam_mode[i].height) |
---|
1032 | | - fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED; |
---|
1033 | | - fmtdesc->description[0] = fmtdesc->pixelformat & 0xff; |
---|
1034 | | - fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff; |
---|
1035 | | - fmtdesc->description[2] = (fmtdesc->pixelformat >> 16) & 0xff; |
---|
1036 | | - fmtdesc->description[3] = fmtdesc->pixelformat >> 24; |
---|
1037 | | - fmtdesc->description[4] = '\0'; |
---|
1038 | 1027 | return 0; |
---|
1039 | 1028 | } |
---|
1040 | 1029 | |
---|
1041 | | -static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, |
---|
1042 | | - struct v4l2_format *fmt) |
---|
| 1030 | +static int vidioc_g_fmt_vid_cap(struct file *file, void *_priv, |
---|
| 1031 | + struct v4l2_format *fmt) |
---|
1043 | 1032 | { |
---|
1044 | 1033 | struct gspca_dev *gspca_dev = video_drvdata(file); |
---|
| 1034 | + u32 priv = fmt->fmt.pix.priv; |
---|
1045 | 1035 | |
---|
1046 | 1036 | fmt->fmt.pix = gspca_dev->pixfmt; |
---|
1047 | | - /* some drivers use priv internally, zero it before giving it back to |
---|
1048 | | - the core */ |
---|
1049 | | - fmt->fmt.pix.priv = 0; |
---|
| 1037 | + /* some drivers use priv internally, so keep the original value */ |
---|
| 1038 | + fmt->fmt.pix.priv = priv; |
---|
1050 | 1039 | return 0; |
---|
1051 | 1040 | } |
---|
1052 | 1041 | |
---|
.. | .. |
---|
1062 | 1051 | fmt->fmt.pix.pixelformat, w, h); |
---|
1063 | 1052 | |
---|
1064 | 1053 | /* search the nearest mode for width and height */ |
---|
1065 | | - mode = wxh_to_nearest_mode(gspca_dev, w, h); |
---|
| 1054 | + mode = wxh_to_nearest_mode(gspca_dev, w, h, fmt->fmt.pix.pixelformat); |
---|
1066 | 1055 | |
---|
1067 | 1056 | /* OK if right palette */ |
---|
1068 | 1057 | if (gspca_dev->cam.cam_mode[mode].pixelformat |
---|
.. | .. |
---|
1081 | 1070 | fmt->fmt.pix.height = h; |
---|
1082 | 1071 | gspca_dev->sd_desc->try_fmt(gspca_dev, fmt); |
---|
1083 | 1072 | } |
---|
1084 | | - /* some drivers use priv internally, zero it before giving it back to |
---|
1085 | | - the core */ |
---|
1086 | | - fmt->fmt.pix.priv = 0; |
---|
1087 | 1073 | return mode; /* used when s_fmt */ |
---|
1088 | 1074 | } |
---|
1089 | 1075 | |
---|
1090 | | -static int vidioc_try_fmt_vid_cap(struct file *file, |
---|
1091 | | - void *priv, |
---|
1092 | | - struct v4l2_format *fmt) |
---|
| 1076 | +static int vidioc_try_fmt_vid_cap(struct file *file, void *_priv, |
---|
| 1077 | + struct v4l2_format *fmt) |
---|
1093 | 1078 | { |
---|
1094 | 1079 | struct gspca_dev *gspca_dev = video_drvdata(file); |
---|
| 1080 | + u32 priv = fmt->fmt.pix.priv; |
---|
1095 | 1081 | |
---|
1096 | 1082 | if (try_fmt_vid_cap(gspca_dev, fmt) < 0) |
---|
1097 | 1083 | return -EINVAL; |
---|
| 1084 | + /* some drivers use priv internally, so keep the original value */ |
---|
| 1085 | + fmt->fmt.pix.priv = priv; |
---|
1098 | 1086 | return 0; |
---|
1099 | 1087 | } |
---|
1100 | 1088 | |
---|
1101 | | -static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, |
---|
1102 | | - struct v4l2_format *fmt) |
---|
| 1089 | +static int vidioc_s_fmt_vid_cap(struct file *file, void *_priv, |
---|
| 1090 | + struct v4l2_format *fmt) |
---|
1103 | 1091 | { |
---|
1104 | 1092 | struct gspca_dev *gspca_dev = video_drvdata(file); |
---|
| 1093 | + u32 priv = fmt->fmt.pix.priv; |
---|
1105 | 1094 | int mode; |
---|
1106 | 1095 | |
---|
1107 | 1096 | if (vb2_is_busy(&gspca_dev->queue)) |
---|
.. | .. |
---|
1117 | 1106 | gspca_dev->pixfmt = fmt->fmt.pix; |
---|
1118 | 1107 | else |
---|
1119 | 1108 | gspca_dev->pixfmt = gspca_dev->cam.cam_mode[mode]; |
---|
| 1109 | + /* some drivers use priv internally, so keep the original value */ |
---|
| 1110 | + fmt->fmt.pix.priv = priv; |
---|
1120 | 1111 | return 0; |
---|
1121 | 1112 | } |
---|
1122 | 1113 | |
---|
.. | .. |
---|
1156 | 1147 | int mode; |
---|
1157 | 1148 | __u32 i; |
---|
1158 | 1149 | |
---|
1159 | | - mode = wxh_to_mode(gspca_dev, fival->width, fival->height); |
---|
| 1150 | + mode = wxh_to_mode(gspca_dev, fival->width, fival->height, |
---|
| 1151 | + fival->pixel_format); |
---|
1160 | 1152 | if (mode < 0) |
---|
1161 | 1153 | return -EINVAL; |
---|
1162 | 1154 | |
---|
.. | .. |
---|
1197 | 1189 | { |
---|
1198 | 1190 | struct gspca_dev *gspca_dev = video_drvdata(file); |
---|
1199 | 1191 | |
---|
1200 | | - strlcpy((char *) cap->driver, gspca_dev->sd_desc->name, |
---|
1201 | | - sizeof cap->driver); |
---|
| 1192 | + strscpy((char *)cap->driver, gspca_dev->sd_desc->name, |
---|
| 1193 | + sizeof(cap->driver)); |
---|
1202 | 1194 | if (gspca_dev->dev->product != NULL) { |
---|
1203 | | - strlcpy((char *) cap->card, gspca_dev->dev->product, |
---|
1204 | | - sizeof cap->card); |
---|
| 1195 | + strscpy((char *)cap->card, gspca_dev->dev->product, |
---|
| 1196 | + sizeof(cap->card)); |
---|
1205 | 1197 | } else { |
---|
1206 | 1198 | snprintf((char *) cap->card, sizeof cap->card, |
---|
1207 | 1199 | "USB Camera (%04x:%04x)", |
---|
.. | .. |
---|
1210 | 1202 | } |
---|
1211 | 1203 | usb_make_path(gspca_dev->dev, (char *) cap->bus_info, |
---|
1212 | 1204 | sizeof(cap->bus_info)); |
---|
1213 | | - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
---|
1214 | | - | V4L2_CAP_STREAMING |
---|
1215 | | - | V4L2_CAP_READWRITE; |
---|
1216 | | - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; |
---|
1217 | 1205 | return 0; |
---|
1218 | 1206 | } |
---|
1219 | 1207 | |
---|
.. | .. |
---|
1226 | 1214 | return -EINVAL; |
---|
1227 | 1215 | input->type = V4L2_INPUT_TYPE_CAMERA; |
---|
1228 | 1216 | input->status = gspca_dev->cam.input_flags; |
---|
1229 | | - strlcpy(input->name, gspca_dev->sd_desc->name, |
---|
| 1217 | + strscpy(input->name, gspca_dev->sd_desc->name, |
---|
1230 | 1218 | sizeof input->name); |
---|
1231 | 1219 | return 0; |
---|
1232 | 1220 | } |
---|
.. | .. |
---|
1509 | 1497 | gspca_dev->empty_packet = -1; /* don't check the empty packets */ |
---|
1510 | 1498 | gspca_dev->vdev = gspca_template; |
---|
1511 | 1499 | gspca_dev->vdev.v4l2_dev = &gspca_dev->v4l2_dev; |
---|
| 1500 | + gspca_dev->vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | |
---|
| 1501 | + V4L2_CAP_STREAMING | V4L2_CAP_READWRITE; |
---|
1512 | 1502 | video_set_drvdata(&gspca_dev->vdev, gspca_dev); |
---|
1513 | 1503 | gspca_dev->module = module; |
---|
1514 | 1504 | |
---|
.. | .. |
---|
1565 | 1555 | |
---|
1566 | 1556 | /* init video stuff */ |
---|
1567 | 1557 | ret = video_register_device(&gspca_dev->vdev, |
---|
1568 | | - VFL_TYPE_GRABBER, |
---|
| 1558 | + VFL_TYPE_VIDEO, |
---|
1569 | 1559 | -1); |
---|
1570 | 1560 | if (ret < 0) { |
---|
1571 | 1561 | pr_err("video_register_device err %d\n", ret); |
---|