1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Zoran zr36057/zr36067 PCI controller driver, for the 4 * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux 5 * Media Labs LML33/LML33R10. 6 * 7 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx> 8 * 9 * Changes for BUZ by Wolfgang Scherr <scherr@net4you.net> 10 * 11 * Changes for DC10/DC30 by Laurent Pinchart <laurent.pinchart@skynet.be> 12 * 13 * Changes for LML33R10 by Maxim Yevtyushkin <max@linuxmedialabs.com> 14 * 15 * Changes for videodev2/v4l2 by Ronald Bultje <rbultje@ronald.bitfreak.net> 16 * 17 * Based on 18 * 19 * Miro DC10 driver 20 * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net> 21 * 22 * Iomega Buz driver version 1.0 23 * Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de> 24 * 25 * buz.0.0.3 26 * Copyright (C) 1998 Dave Perks <dperks@ibm.net> 27 * 28 * bttv - Bt848 frame grabber driver 29 * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 30 * & Marcus Metzler (mocm@thp.uni-koeln.de) 31 */ 32 33 #include <linux/init.h> 34 #include <linux/module.h> 35 #include <linux/delay.h> 36 #include <linux/slab.h> 37 #include <linux/pci.h> 38 #include <linux/wait.h> 39 40 #include <linux/interrupt.h> 41 #include <linux/i2c.h> 42 #include <linux/i2c-algo-bit.h> 43 44 #include <linux/spinlock.h> 45 46 #include <linux/videodev2.h> 47 #include <media/v4l2-common.h> 48 #include <media/v4l2-ioctl.h> 49 #include <media/v4l2-event.h> 50 #include "videocodec.h" 51 52 #include <linux/io.h> 53 #include <linux/uaccess.h> 54 55 #include <linux/mutex.h> 56 #include "zoran.h" 57 #include "zoran_device.h" 58 #include "zoran_card.h" 59 60 const struct zoran_format zoran_formats[] = { 61 { 62 .name = "15-bit RGB LE", 63 .fourcc = V4L2_PIX_FMT_RGB555, 64 .colorspace = V4L2_COLORSPACE_SRGB, 65 .depth = 15, 66 .flags = ZORAN_FORMAT_CAPTURE, 67 .vfespfr = ZR36057_VFESPFR_RGB555 | ZR36057_VFESPFR_ERR_DIF | 68 ZR36057_VFESPFR_LITTLE_ENDIAN, 69 }, { 70 .name = "15-bit RGB BE", 71 .fourcc = V4L2_PIX_FMT_RGB555X, 72 .colorspace = V4L2_COLORSPACE_SRGB, 73 .depth = 15, 74 .flags = ZORAN_FORMAT_CAPTURE, 75 .vfespfr = ZR36057_VFESPFR_RGB555 | ZR36057_VFESPFR_ERR_DIF, 76 }, { 77 .name = "16-bit RGB LE", 78 .fourcc = V4L2_PIX_FMT_RGB565, 79 .colorspace = V4L2_COLORSPACE_SRGB, 80 .depth = 16, 81 .flags = ZORAN_FORMAT_CAPTURE, 82 .vfespfr = ZR36057_VFESPFR_RGB565 | ZR36057_VFESPFR_ERR_DIF | 83 ZR36057_VFESPFR_LITTLE_ENDIAN, 84 }, { 85 .name = "16-bit RGB BE", 86 .fourcc = V4L2_PIX_FMT_RGB565X, 87 .colorspace = V4L2_COLORSPACE_SRGB, 88 .depth = 16, 89 .flags = ZORAN_FORMAT_CAPTURE, 90 .vfespfr = ZR36057_VFESPFR_RGB565 | ZR36057_VFESPFR_ERR_DIF, 91 }, { 92 .name = "24-bit RGB", 93 .fourcc = V4L2_PIX_FMT_BGR24, 94 .colorspace = V4L2_COLORSPACE_SRGB, 95 .depth = 24, 96 .flags = ZORAN_FORMAT_CAPTURE, 97 .vfespfr = ZR36057_VFESPFR_RGB888 | ZR36057_VFESPFR_PACK24, 98 }, { 99 .name = "32-bit RGB LE", 100 .fourcc = V4L2_PIX_FMT_BGR32, 101 .colorspace = V4L2_COLORSPACE_SRGB, 102 .depth = 32, 103 .flags = ZORAN_FORMAT_CAPTURE, 104 .vfespfr = ZR36057_VFESPFR_RGB888 | ZR36057_VFESPFR_LITTLE_ENDIAN, 105 }, { 106 .name = "32-bit RGB BE", 107 .fourcc = V4L2_PIX_FMT_RGB32, 108 .colorspace = V4L2_COLORSPACE_SRGB, 109 .depth = 32, 110 .flags = ZORAN_FORMAT_CAPTURE, 111 .vfespfr = ZR36057_VFESPFR_RGB888, 112 }, { 113 .name = "4:2:2, packed, YUYV", 114 .fourcc = V4L2_PIX_FMT_YUYV, 115 .colorspace = V4L2_COLORSPACE_SMPTE170M, 116 .depth = 16, 117 .flags = ZORAN_FORMAT_CAPTURE, 118 .vfespfr = ZR36057_VFESPFR_YUV422, 119 }, { 120 .name = "4:2:2, packed, UYVY", 121 .fourcc = V4L2_PIX_FMT_UYVY, 122 .colorspace = V4L2_COLORSPACE_SMPTE170M, 123 .depth = 16, 124 .flags = ZORAN_FORMAT_CAPTURE, 125 .vfespfr = ZR36057_VFESPFR_YUV422 | ZR36057_VFESPFR_LITTLE_ENDIAN, 126 }, { 127 .name = "Hardware-encoded Motion-JPEG", 128 .fourcc = V4L2_PIX_FMT_MJPEG, 129 .colorspace = V4L2_COLORSPACE_SMPTE170M, 130 .depth = 0, 131 .flags = ZORAN_FORMAT_CAPTURE | 132 ZORAN_FORMAT_PLAYBACK | 133 ZORAN_FORMAT_COMPRESSED, 134 } 135 }; 136 137 #define NUM_FORMATS ARRAY_SIZE(zoran_formats) 138 139 /* 140 * small helper function for calculating buffersizes for v4l2 141 * we calculate the nearest higher power-of-two, which 142 * will be the recommended buffersize 143 */ 144 static __u32 zoran_v4l2_calc_bufsize(struct zoran_jpg_settings *settings) 145 { 146 __u8 div = settings->ver_dcm * settings->hor_dcm * settings->tmp_dcm; 147 __u32 num = (1024 * 512) / (div); 148 __u32 result = 2; 149 150 num--; 151 while (num) { 152 num >>= 1; 153 result <<= 1; 154 } 155 156 if (result < 8192) 157 return 8192; 158 159 return result; 160 } 161 162 /* 163 * V4L Buffer grabbing 164 */ 165 static int zoran_v4l_set_format(struct zoran *zr, int width, int height, 166 const struct zoran_format *format) 167 { 168 int bpp; 169 170 /* Check size and format of the grab wanted */ 171 172 if (height < BUZ_MIN_HEIGHT || width < BUZ_MIN_WIDTH || 173 height > BUZ_MAX_HEIGHT || width > BUZ_MAX_WIDTH) { 174 pci_dbg(zr->pci_dev, "%s - wrong frame size (%dx%d)\n", __func__, width, height); 175 return -EINVAL; 176 } 177 178 bpp = (format->depth + 7) / 8; 179 180 zr->buffer_size = height * width * bpp; 181 182 /* Check against available buffer size */ 183 if (height * width * bpp > zr->buffer_size) { 184 pci_dbg(zr->pci_dev, "%s - video buffer size (%d kB) is too small\n", 185 __func__, zr->buffer_size >> 10); 186 return -EINVAL; 187 } 188 189 /* The video front end needs 4-byte alinged line sizes */ 190 191 if ((bpp == 2 && (width & 1)) || (bpp == 3 && (width & 3))) { 192 pci_dbg(zr->pci_dev, "%s - wrong frame alignment\n", __func__); 193 return -EINVAL; 194 } 195 196 zr->v4l_settings.width = width; 197 zr->v4l_settings.height = height; 198 zr->v4l_settings.format = format; 199 zr->v4l_settings.bytesperline = bpp * zr->v4l_settings.width; 200 201 return 0; 202 } 203 204 static int zoran_set_norm(struct zoran *zr, v4l2_std_id norm) 205 { 206 if (!(norm & zr->card.norms)) { 207 pci_dbg(zr->pci_dev, "%s - unsupported norm %llx\n", __func__, norm); 208 return -EINVAL; 209 } 210 211 if (norm & V4L2_STD_SECAM) 212 zr->timing = zr->card.tvn[ZR_NORM_SECAM]; 213 else if (norm & V4L2_STD_NTSC) 214 zr->timing = zr->card.tvn[ZR_NORM_NTSC]; 215 else 216 zr->timing = zr->card.tvn[ZR_NORM_PAL]; 217 218 decoder_call(zr, video, s_std, norm); 219 encoder_call(zr, video, s_std_output, norm); 220 221 /* Make sure the changes come into effect */ 222 zr->norm = norm; 223 224 return 0; 225 } 226 227 static int zoran_set_input(struct zoran *zr, int input) 228 { 229 if (input == zr->input) 230 return 0; 231 232 if (input < 0 || input >= zr->card.inputs) { 233 pci_dbg(zr->pci_dev, "%s - unsupported input %d\n", __func__, input); 234 return -EINVAL; 235 } 236 237 zr->input = input; 238 239 decoder_call(zr, video, s_routing, zr->card.input[input].muxsel, 0, 0); 240 241 return 0; 242 } 243 244 /* 245 * ioctl routine 246 */ 247 248 static int zoran_querycap(struct file *file, void *fh, struct v4l2_capability *cap) 249 { 250 struct zoran *zr = video_drvdata(file); 251 252 strscpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)); 253 strscpy(cap->driver, "zoran", sizeof(cap->driver)); 254 snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", pci_name(zr->pci_dev)); 255 return 0; 256 } 257 258 static int zoran_enum_fmt(struct zoran *zr, struct v4l2_fmtdesc *fmt, int flag) 259 { 260 unsigned int num, i; 261 262 if (fmt->index >= ARRAY_SIZE(zoran_formats)) 263 return -EINVAL; 264 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 265 return -EINVAL; 266 267 for (num = i = 0; i < NUM_FORMATS; i++) { 268 if (zoran_formats[i].flags & flag && num++ == fmt->index) { 269 strscpy(fmt->description, zoran_formats[i].name, 270 sizeof(fmt->description)); 271 /* fmt struct pre-zeroed, so adding '\0' not needed */ 272 fmt->pixelformat = zoran_formats[i].fourcc; 273 if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED) 274 fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; 275 return 0; 276 } 277 } 278 return -EINVAL; 279 } 280 281 static int zoran_enum_fmt_vid_cap(struct file *file, void *fh, 282 struct v4l2_fmtdesc *f) 283 { 284 struct zoran *zr = video_drvdata(file); 285 286 return zoran_enum_fmt(zr, f, ZORAN_FORMAT_CAPTURE); 287 } 288 289 static int zoran_g_fmt_vid_out(struct file *file, void *fh, 290 struct v4l2_format *fmt) 291 { 292 struct zoran *zr = video_drvdata(file); 293 294 fmt->fmt.pix.width = zr->jpg_settings.img_width / zr->jpg_settings.hor_dcm; 295 fmt->fmt.pix.height = zr->jpg_settings.img_height * 2 / 296 (zr->jpg_settings.ver_dcm * zr->jpg_settings.tmp_dcm); 297 fmt->fmt.pix.sizeimage = zr->buffer_size; 298 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; 299 if (zr->jpg_settings.tmp_dcm == 1) 300 fmt->fmt.pix.field = (zr->jpg_settings.odd_even ? 301 V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT); 302 else 303 fmt->fmt.pix.field = (zr->jpg_settings.odd_even ? 304 V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); 305 fmt->fmt.pix.bytesperline = 0; 306 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 307 308 return 0; 309 } 310 311 static int zoran_g_fmt_vid_cap(struct file *file, void *fh, 312 struct v4l2_format *fmt) 313 { 314 struct zoran *zr = video_drvdata(file); 315 316 if (zr->map_mode != ZORAN_MAP_MODE_RAW) 317 return zoran_g_fmt_vid_out(file, fh, fmt); 318 fmt->fmt.pix.width = zr->v4l_settings.width; 319 fmt->fmt.pix.height = zr->v4l_settings.height; 320 fmt->fmt.pix.sizeimage = zr->buffer_size; 321 fmt->fmt.pix.pixelformat = zr->v4l_settings.format->fourcc; 322 fmt->fmt.pix.colorspace = zr->v4l_settings.format->colorspace; 323 fmt->fmt.pix.bytesperline = zr->v4l_settings.bytesperline; 324 if (BUZ_MAX_HEIGHT < (zr->v4l_settings.height * 2)) 325 fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; 326 else 327 fmt->fmt.pix.field = V4L2_FIELD_TOP; 328 return 0; 329 } 330 331 static int zoran_try_fmt_vid_out(struct file *file, void *fh, 332 struct v4l2_format *fmt) 333 { 334 struct zoran *zr = video_drvdata(file); 335 struct zoran_jpg_settings settings; 336 int res = 0; 337 338 if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) 339 return -EINVAL; 340 341 settings = zr->jpg_settings; 342 343 /* we actually need to set 'real' parameters now */ 344 if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT) 345 settings.tmp_dcm = 1; 346 else 347 settings.tmp_dcm = 2; 348 settings.decimation = 0; 349 if (fmt->fmt.pix.height <= zr->jpg_settings.img_height / 2) 350 settings.ver_dcm = 2; 351 else 352 settings.ver_dcm = 1; 353 if (fmt->fmt.pix.width <= zr->jpg_settings.img_width / 4) 354 settings.hor_dcm = 4; 355 else if (fmt->fmt.pix.width <= zr->jpg_settings.img_width / 2) 356 settings.hor_dcm = 2; 357 else 358 settings.hor_dcm = 1; 359 if (settings.tmp_dcm == 1) 360 settings.field_per_buff = 2; 361 else 362 settings.field_per_buff = 1; 363 364 if (settings.hor_dcm > 1) { 365 settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0; 366 settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH; 367 } else { 368 settings.img_x = 0; 369 settings.img_width = BUZ_MAX_WIDTH; 370 } 371 372 /* check */ 373 res = zoran_check_jpg_settings(zr, &settings, 1); 374 if (res) 375 return res; 376 377 /* tell the user what we actually did */ 378 fmt->fmt.pix.width = settings.img_width / settings.hor_dcm; 379 fmt->fmt.pix.height = settings.img_height * 2 / 380 (settings.tmp_dcm * settings.ver_dcm); 381 if (settings.tmp_dcm == 1) 382 fmt->fmt.pix.field = (zr->jpg_settings.odd_even ? 383 V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT); 384 else 385 fmt->fmt.pix.field = (zr->jpg_settings.odd_even ? 386 V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); 387 388 fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&settings); 389 fmt->fmt.pix.bytesperline = 0; 390 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 391 return res; 392 } 393 394 static int zoran_try_fmt_vid_cap(struct file *file, void *fh, 395 struct v4l2_format *fmt) 396 { 397 struct zoran *zr = video_drvdata(file); 398 int bpp; 399 int i; 400 401 if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) 402 return zoran_try_fmt_vid_out(file, fh, fmt); 403 404 for (i = 0; i < NUM_FORMATS; i++) 405 if (zoran_formats[i].fourcc == fmt->fmt.pix.pixelformat) 406 break; 407 408 if (i == NUM_FORMATS) { 409 /* TODO do not return here to fix the TRY_FMT cannot handle an invalid pixelformat*/ 410 return -EINVAL; 411 } 412 413 fmt->fmt.pix.pixelformat = zoran_formats[i].fourcc; 414 fmt->fmt.pix.colorspace = zoran_formats[i].colorspace; 415 if (BUZ_MAX_HEIGHT < (fmt->fmt.pix.height * 2)) 416 fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; 417 else 418 fmt->fmt.pix.field = V4L2_FIELD_TOP; 419 420 bpp = DIV_ROUND_UP(zoran_formats[i].depth, 8); 421 v4l_bound_align_image(&fmt->fmt.pix.width, BUZ_MIN_WIDTH, BUZ_MAX_WIDTH, 422 bpp == 2 ? 1 : 2, 423 &fmt->fmt.pix.height, BUZ_MIN_HEIGHT, BUZ_MAX_HEIGHT, 424 0, 0); 425 fmt->fmt.pix.bytesperline = fmt->fmt.pix.width * bpp; 426 fmt->fmt.pix.sizeimage = fmt->fmt.pix.bytesperline * fmt->fmt.pix.height; 427 return 0; 428 } 429 430 static int zoran_s_fmt_vid_out(struct file *file, void *fh, 431 struct v4l2_format *fmt) 432 { 433 struct zoran *zr = video_drvdata(file); 434 __le32 printformat = __cpu_to_le32(fmt->fmt.pix.pixelformat); 435 struct zoran_jpg_settings settings; 436 int res = 0; 437 438 pci_dbg(zr->pci_dev, "size=%dx%d, fmt=0x%x (%4.4s)\n", 439 fmt->fmt.pix.width, fmt->fmt.pix.height, 440 fmt->fmt.pix.pixelformat, 441 (char *)&printformat); 442 if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) 443 return -EINVAL; 444 445 if (!fmt->fmt.pix.height || !fmt->fmt.pix.width) 446 return -EINVAL; 447 448 settings = zr->jpg_settings; 449 450 /* we actually need to set 'real' parameters now */ 451 if (fmt->fmt.pix.height * 2 > BUZ_MAX_HEIGHT) 452 settings.tmp_dcm = 1; 453 else 454 settings.tmp_dcm = 2; 455 settings.decimation = 0; 456 if (fmt->fmt.pix.height <= zr->jpg_settings.img_height / 2) 457 settings.ver_dcm = 2; 458 else 459 settings.ver_dcm = 1; 460 if (fmt->fmt.pix.width <= zr->jpg_settings.img_width / 4) 461 settings.hor_dcm = 4; 462 else if (fmt->fmt.pix.width <= zr->jpg_settings.img_width / 2) 463 settings.hor_dcm = 2; 464 else 465 settings.hor_dcm = 1; 466 if (settings.tmp_dcm == 1) 467 settings.field_per_buff = 2; 468 else 469 settings.field_per_buff = 1; 470 471 if (settings.hor_dcm > 1) { 472 settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0; 473 settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH; 474 } else { 475 settings.img_x = 0; 476 settings.img_width = BUZ_MAX_WIDTH; 477 } 478 479 /* check */ 480 res = zoran_check_jpg_settings(zr, &settings, 0); 481 if (res) 482 return res; 483 484 /* it's ok, so set them */ 485 zr->jpg_settings = settings; 486 487 if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) 488 zr->map_mode = ZORAN_MAP_MODE_JPG_REC; 489 else 490 zr->map_mode = ZORAN_MAP_MODE_JPG_PLAY; 491 492 zr->buffer_size = zoran_v4l2_calc_bufsize(&zr->jpg_settings); 493 494 /* tell the user what we actually did */ 495 fmt->fmt.pix.width = settings.img_width / settings.hor_dcm; 496 fmt->fmt.pix.height = settings.img_height * 2 / 497 (settings.tmp_dcm * settings.ver_dcm); 498 if (settings.tmp_dcm == 1) 499 fmt->fmt.pix.field = (zr->jpg_settings.odd_even ? 500 V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT); 501 else 502 fmt->fmt.pix.field = (zr->jpg_settings.odd_even ? 503 V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); 504 fmt->fmt.pix.bytesperline = 0; 505 fmt->fmt.pix.sizeimage = zr->buffer_size; 506 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 507 return res; 508 } 509 510 static int zoran_s_fmt_vid_cap(struct file *file, void *fh, 511 struct v4l2_format *fmt) 512 { 513 struct zoran *zr = video_drvdata(file); 514 int i; 515 int res = 0; 516 517 if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) 518 return zoran_s_fmt_vid_out(file, fh, fmt); 519 520 for (i = 0; i < NUM_FORMATS; i++) 521 if (fmt->fmt.pix.pixelformat == zoran_formats[i].fourcc) 522 break; 523 if (i == NUM_FORMATS) { 524 pci_dbg(zr->pci_dev, "VIDIOC_S_FMT - unknown/unsupported format 0x%x\n", 525 fmt->fmt.pix.pixelformat); 526 /* TODO do not return here to fix the TRY_FMT cannot handle an invalid pixelformat*/ 527 return -EINVAL; 528 } 529 530 fmt->fmt.pix.pixelformat = zoran_formats[i].fourcc; 531 if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT) 532 fmt->fmt.pix.height = BUZ_MAX_HEIGHT; 533 if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) 534 fmt->fmt.pix.width = BUZ_MAX_WIDTH; 535 if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT) 536 fmt->fmt.pix.height = BUZ_MIN_HEIGHT; 537 if (fmt->fmt.pix.width < BUZ_MIN_WIDTH) 538 fmt->fmt.pix.width = BUZ_MIN_WIDTH; 539 540 zr->map_mode = ZORAN_MAP_MODE_RAW; 541 542 res = zoran_v4l_set_format(zr, fmt->fmt.pix.width, fmt->fmt.pix.height, 543 &zoran_formats[i]); 544 if (res) 545 return res; 546 547 /* tell the user the results/missing stuff */ 548 fmt->fmt.pix.bytesperline = zr->v4l_settings.bytesperline; 549 fmt->fmt.pix.sizeimage = zr->buffer_size; 550 fmt->fmt.pix.colorspace = zr->v4l_settings.format->colorspace; 551 if (BUZ_MAX_HEIGHT < (zr->v4l_settings.height * 2)) 552 fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; 553 else 554 fmt->fmt.pix.field = V4L2_FIELD_TOP; 555 return res; 556 } 557 558 static int zoran_g_std(struct file *file, void *fh, v4l2_std_id *std) 559 { 560 struct zoran *zr = video_drvdata(file); 561 562 *std = zr->norm; 563 return 0; 564 } 565 566 static int zoran_s_std(struct file *file, void *fh, v4l2_std_id std) 567 { 568 struct zoran *zr = video_drvdata(file); 569 int res = 0; 570 571 if (zr->norm == std) 572 return 0; 573 574 if (zr->running != ZORAN_MAP_MODE_NONE) 575 return -EBUSY; 576 577 res = zoran_set_norm(zr, std); 578 return res; 579 } 580 581 static int zoran_enum_input(struct file *file, void *fh, 582 struct v4l2_input *inp) 583 { 584 struct zoran *zr = video_drvdata(file); 585 586 if (inp->index >= zr->card.inputs) 587 return -EINVAL; 588 589 strscpy(inp->name, zr->card.input[inp->index].name, sizeof(inp->name)); 590 inp->type = V4L2_INPUT_TYPE_CAMERA; 591 inp->std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM; 592 593 /* Get status of video decoder */ 594 decoder_call(zr, video, g_input_status, &inp->status); 595 return 0; 596 } 597 598 static int zoran_g_input(struct file *file, void *fh, unsigned int *input) 599 { 600 struct zoran *zr = video_drvdata(file); 601 602 *input = zr->input; 603 604 return 0; 605 } 606 607 static int zoran_s_input(struct file *file, void *fh, unsigned int input) 608 { 609 struct zoran *zr = video_drvdata(file); 610 int res; 611 612 if (zr->running != ZORAN_MAP_MODE_NONE) 613 return -EBUSY; 614 615 res = zoran_set_input(zr, input); 616 return res; 617 } 618 619 /* cropping (sub-frame capture) */ 620 static int zoran_g_selection(struct file *file, void *fh, struct v4l2_selection *sel) 621 { 622 struct zoran *zr = video_drvdata(file); 623 624 if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && 625 sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 626 pci_dbg(zr->pci_dev, "%s invalid selection type combination\n", __func__); 627 return -EINVAL; 628 } 629 630 switch (sel->target) { 631 case V4L2_SEL_TGT_CROP: 632 sel->r.top = zr->jpg_settings.img_y; 633 sel->r.left = zr->jpg_settings.img_x; 634 sel->r.width = zr->jpg_settings.img_width; 635 sel->r.height = zr->jpg_settings.img_height; 636 break; 637 case V4L2_SEL_TGT_CROP_DEFAULT: 638 sel->r.top = 0; 639 sel->r.left = 0; 640 sel->r.width = BUZ_MIN_WIDTH; 641 sel->r.height = BUZ_MIN_HEIGHT; 642 break; 643 case V4L2_SEL_TGT_CROP_BOUNDS: 644 sel->r.top = 0; 645 sel->r.left = 0; 646 sel->r.width = BUZ_MAX_WIDTH; 647 sel->r.height = BUZ_MAX_HEIGHT; 648 break; 649 default: 650 return -EINVAL; 651 } 652 return 0; 653 } 654 655 static int zoran_s_selection(struct file *file, void *fh, struct v4l2_selection *sel) 656 { 657 struct zoran *zr = video_drvdata(file); 658 struct zoran_jpg_settings settings; 659 int res; 660 661 if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && 662 sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 663 return -EINVAL; 664 665 if (!sel->r.width || !sel->r.height) 666 return -EINVAL; 667 668 if (sel->target != V4L2_SEL_TGT_CROP) 669 return -EINVAL; 670 671 if (zr->map_mode == ZORAN_MAP_MODE_RAW) { 672 pci_dbg(zr->pci_dev, "VIDIOC_S_SELECTION - subcapture only supported for compressed capture\n"); 673 return -EINVAL; 674 } 675 676 settings = zr->jpg_settings; 677 678 /* move into a form that we understand */ 679 settings.img_x = sel->r.left; 680 settings.img_y = sel->r.top; 681 settings.img_width = sel->r.width; 682 settings.img_height = sel->r.height; 683 684 /* check validity */ 685 res = zoran_check_jpg_settings(zr, &settings, 0); 686 if (res) 687 return res; 688 689 /* accept */ 690 zr->jpg_settings = settings; 691 return res; 692 } 693 694 /* 695 * Output is disabled temporarily 696 * Zoran is picky about jpeg data it accepts. At least it seems to unsupport COM and APPn. 697 * So until a way to filter data will be done, disable output. 698 */ 699 static const struct v4l2_ioctl_ops zoran_ioctl_ops = { 700 .vidioc_querycap = zoran_querycap, 701 .vidioc_s_selection = zoran_s_selection, 702 .vidioc_g_selection = zoran_g_selection, 703 .vidioc_enum_input = zoran_enum_input, 704 .vidioc_g_input = zoran_g_input, 705 .vidioc_s_input = zoran_s_input, 706 .vidioc_g_std = zoran_g_std, 707 .vidioc_s_std = zoran_s_std, 708 .vidioc_create_bufs = vb2_ioctl_create_bufs, 709 .vidioc_reqbufs = vb2_ioctl_reqbufs, 710 .vidioc_querybuf = vb2_ioctl_querybuf, 711 .vidioc_qbuf = vb2_ioctl_qbuf, 712 .vidioc_dqbuf = vb2_ioctl_dqbuf, 713 .vidioc_expbuf = vb2_ioctl_expbuf, 714 .vidioc_streamon = vb2_ioctl_streamon, 715 .vidioc_streamoff = vb2_ioctl_streamoff, 716 .vidioc_enum_fmt_vid_cap = zoran_enum_fmt_vid_cap, 717 .vidioc_g_fmt_vid_cap = zoran_g_fmt_vid_cap, 718 .vidioc_s_fmt_vid_cap = zoran_s_fmt_vid_cap, 719 .vidioc_try_fmt_vid_cap = zoran_try_fmt_vid_cap, 720 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 721 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 722 }; 723 724 static const struct v4l2_file_operations zoran_fops = { 725 .owner = THIS_MODULE, 726 .unlocked_ioctl = video_ioctl2, 727 .open = v4l2_fh_open, 728 .release = vb2_fop_release, 729 .mmap = vb2_fop_mmap, 730 .poll = vb2_fop_poll, 731 }; 732 733 const struct video_device zoran_template = { 734 .name = ZORAN_NAME, 735 .fops = &zoran_fops, 736 .ioctl_ops = &zoran_ioctl_ops, 737 .release = &zoran_vdev_release, 738 .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, 739 }; 740 741 static int zr_vb2_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, unsigned int *nplanes, 742 unsigned int sizes[], struct device *alloc_devs[]) 743 { 744 struct zoran *zr = vb2_get_drv_priv(vq); 745 unsigned int size = zr->buffer_size; 746 747 pci_dbg(zr->pci_dev, "%s nbuf=%u nplanes=%u", __func__, *nbuffers, *nplanes); 748 749 zr->buf_in_reserve = 0; 750 751 if (*nbuffers < vq->min_queued_buffers) 752 *nbuffers = vq->min_queued_buffers; 753 754 if (*nplanes) { 755 if (sizes[0] < size) 756 return -EINVAL; 757 else 758 return 0; 759 } 760 761 *nplanes = 1; 762 sizes[0] = size; 763 764 return 0; 765 } 766 767 static void zr_vb2_queue(struct vb2_buffer *vb) 768 { 769 struct zoran *zr = vb2_get_drv_priv(vb->vb2_queue); 770 struct zr_buffer *buf = vb2_to_zr_buffer(vb); 771 unsigned long flags; 772 773 spin_lock_irqsave(&zr->queued_bufs_lock, flags); 774 list_add_tail(&buf->queue, &zr->queued_bufs); 775 zr->buf_in_reserve++; 776 spin_unlock_irqrestore(&zr->queued_bufs_lock, flags); 777 if (zr->running == ZORAN_MAP_MODE_JPG_REC) 778 zoran_feed_stat_com(zr); 779 zr->queued++; 780 } 781 782 static int zr_vb2_prepare(struct vb2_buffer *vb) 783 { 784 struct zoran *zr = vb2_get_drv_priv(vb->vb2_queue); 785 786 if (vb2_plane_size(vb, 0) < zr->buffer_size) 787 return -EINVAL; 788 zr->prepared++; 789 790 return 0; 791 } 792 793 int zr_set_buf(struct zoran *zr) 794 { 795 struct zr_buffer *buf; 796 struct vb2_v4l2_buffer *vbuf; 797 dma_addr_t phys_addr; 798 unsigned long flags; 799 u32 reg; 800 801 if (zr->running == ZORAN_MAP_MODE_NONE) 802 return 0; 803 804 if (zr->inuse[0]) { 805 buf = zr->inuse[0]; 806 buf->vbuf.vb2_buf.timestamp = ktime_get_ns(); 807 buf->vbuf.sequence = zr->vbseq++; 808 vbuf = &buf->vbuf; 809 810 buf->vbuf.field = V4L2_FIELD_INTERLACED; 811 if (BUZ_MAX_HEIGHT < (zr->v4l_settings.height * 2)) 812 buf->vbuf.field = V4L2_FIELD_INTERLACED; 813 else 814 buf->vbuf.field = V4L2_FIELD_TOP; 815 vb2_set_plane_payload(&buf->vbuf.vb2_buf, 0, zr->buffer_size); 816 vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_DONE); 817 zr->inuse[0] = NULL; 818 } 819 820 spin_lock_irqsave(&zr->queued_bufs_lock, flags); 821 if (list_empty(&zr->queued_bufs)) { 822 btand(~ZR36057_ICR_INT_PIN_EN, ZR36057_ICR); 823 vb2_queue_error(zr->video_dev->queue); 824 spin_unlock_irqrestore(&zr->queued_bufs_lock, flags); 825 return -EINVAL; 826 } 827 buf = list_first_entry_or_null(&zr->queued_bufs, struct zr_buffer, queue); 828 if (!buf) { 829 btand(~ZR36057_ICR_INT_PIN_EN, ZR36057_ICR); 830 vb2_queue_error(zr->video_dev->queue); 831 spin_unlock_irqrestore(&zr->queued_bufs_lock, flags); 832 return -EINVAL; 833 } 834 list_del(&buf->queue); 835 zr->buf_in_reserve--; 836 spin_unlock_irqrestore(&zr->queued_bufs_lock, flags); 837 838 vbuf = &buf->vbuf; 839 vbuf->vb2_buf.state = VB2_BUF_STATE_ACTIVE; 840 phys_addr = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0); 841 842 if (!phys_addr) 843 return -EINVAL; 844 845 zr->inuse[0] = buf; 846 847 reg = phys_addr; 848 btwrite(reg, ZR36057_VDTR); 849 if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2) 850 reg += zr->v4l_settings.bytesperline; 851 btwrite(reg, ZR36057_VDBR); 852 853 reg = 0; 854 if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2) 855 reg += zr->v4l_settings.bytesperline; 856 reg = (reg << ZR36057_VSSFGR_DISP_STRIDE); 857 reg |= ZR36057_VSSFGR_VID_OVF; 858 reg |= ZR36057_VSSFGR_SNAP_SHOT; 859 reg |= ZR36057_VSSFGR_FRAME_GRAB; 860 btwrite(reg, ZR36057_VSSFGR); 861 862 btor(ZR36057_VDCR_VID_EN, ZR36057_VDCR); 863 return 0; 864 } 865 866 static int zr_vb2_start_streaming(struct vb2_queue *vq, unsigned int count) 867 { 868 struct zoran *zr = vq->drv_priv; 869 int j; 870 871 for (j = 0; j < BUZ_NUM_STAT_COM; j++) { 872 zr->stat_com[j] = cpu_to_le32(1); 873 zr->inuse[j] = NULL; 874 } 875 zr->vbseq = 0; 876 877 if (zr->map_mode != ZORAN_MAP_MODE_RAW) { 878 pci_dbg(zr->pci_dev, "START JPG\n"); 879 zr36057_restart(zr); 880 zoran_init_hardware(zr); 881 if (zr->map_mode == ZORAN_MAP_MODE_JPG_REC) 882 zr36057_enable_jpg(zr, BUZ_MODE_MOTION_DECOMPRESS); 883 else 884 zr36057_enable_jpg(zr, BUZ_MODE_MOTION_COMPRESS); 885 zoran_feed_stat_com(zr); 886 jpeg_start(zr); 887 zr->running = zr->map_mode; 888 btor(ZR36057_ICR_INT_PIN_EN, ZR36057_ICR); 889 return 0; 890 } 891 892 pci_dbg(zr->pci_dev, "START RAW\n"); 893 zr36057_restart(zr); 894 zoran_init_hardware(zr); 895 896 zr36057_enable_jpg(zr, BUZ_MODE_IDLE); 897 zr36057_set_memgrab(zr, 1); 898 zr->running = zr->map_mode; 899 btor(ZR36057_ICR_INT_PIN_EN, ZR36057_ICR); 900 return 0; 901 } 902 903 static void zr_vb2_stop_streaming(struct vb2_queue *vq) 904 { 905 struct zoran *zr = vq->drv_priv; 906 struct zr_buffer *buf; 907 unsigned long flags; 908 int j; 909 910 btand(~ZR36057_ICR_INT_PIN_EN, ZR36057_ICR); 911 if (zr->map_mode != ZORAN_MAP_MODE_RAW) 912 zr36057_enable_jpg(zr, BUZ_MODE_IDLE); 913 zr36057_set_memgrab(zr, 0); 914 zr->running = ZORAN_MAP_MODE_NONE; 915 916 zoran_set_pci_master(zr, 0); 917 918 if (!pass_through) { /* Switch to color bar */ 919 decoder_call(zr, video, s_stream, 0); 920 encoder_call(zr, video, s_routing, 2, 0, 0); 921 } 922 923 for (j = 0; j < BUZ_NUM_STAT_COM; j++) { 924 zr->stat_com[j] = cpu_to_le32(1); 925 if (!zr->inuse[j]) 926 continue; 927 buf = zr->inuse[j]; 928 pci_dbg(zr->pci_dev, "%s clean buf %d\n", __func__, j); 929 vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_ERROR); 930 zr->inuse[j] = NULL; 931 } 932 933 spin_lock_irqsave(&zr->queued_bufs_lock, flags); 934 while (!list_empty(&zr->queued_bufs)) { 935 buf = list_entry(zr->queued_bufs.next, struct zr_buffer, queue); 936 list_del(&buf->queue); 937 vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_ERROR); 938 zr->buf_in_reserve--; 939 } 940 spin_unlock_irqrestore(&zr->queued_bufs_lock, flags); 941 if (zr->buf_in_reserve) 942 pci_dbg(zr->pci_dev, "Buffer remaining %d\n", zr->buf_in_reserve); 943 zr->map_mode = ZORAN_MAP_MODE_RAW; 944 } 945 946 static const struct vb2_ops zr_video_qops = { 947 .queue_setup = zr_vb2_queue_setup, 948 .buf_queue = zr_vb2_queue, 949 .buf_prepare = zr_vb2_prepare, 950 .start_streaming = zr_vb2_start_streaming, 951 .stop_streaming = zr_vb2_stop_streaming, 952 }; 953 954 int zoran_queue_init(struct zoran *zr, struct vb2_queue *vq, int dir) 955 { 956 int err; 957 958 spin_lock_init(&zr->queued_bufs_lock); 959 INIT_LIST_HEAD(&zr->queued_bufs); 960 961 vq->dev = &zr->pci_dev->dev; 962 vq->type = dir; 963 964 vq->io_modes = VB2_DMABUF | VB2_MMAP; 965 vq->drv_priv = zr; 966 vq->buf_struct_size = sizeof(struct zr_buffer); 967 vq->ops = &zr_video_qops; 968 vq->mem_ops = &vb2_dma_contig_memops; 969 vq->gfp_flags = GFP_DMA32; 970 vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 971 vq->min_queued_buffers = 9; 972 vq->lock = &zr->lock; 973 err = vb2_queue_init(vq); 974 if (err) 975 return err; 976 zr->video_dev->queue = vq; 977 return 0; 978 } 979 980 void zoran_queue_exit(struct zoran *zr) 981 { 982 vb2_queue_release(zr->video_dev->queue); 983 } 984