aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/zoran/zoran.h2
-rw-r--r--drivers/media/video/zoran/zoran_driver.c2553
2 files changed, 1112 insertions, 1443 deletions
diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h
index e873a916250..1bf540cb546 100644
--- a/drivers/media/video/zoran/zoran.h
+++ b/drivers/media/video/zoran/zoran.h
@@ -312,7 +312,6 @@ struct zoran_jpg_struct {
312 struct zoran_jpg_buffer buffer[BUZ_MAX_FRAME]; /* buffers */ 312 struct zoran_jpg_buffer buffer[BUZ_MAX_FRAME]; /* buffers */
313 int num_buffers, buffer_size; 313 int num_buffers, buffer_size;
314 u8 allocated; /* Flag if buffers are allocated */ 314 u8 allocated; /* Flag if buffers are allocated */
315 u8 ready_to_be_freed; /* hack - see zoran_driver.c */
316 u8 need_contiguous; /* Flag if contiguous buffers are needed */ 315 u8 need_contiguous; /* Flag if contiguous buffers are needed */
317}; 316};
318 317
@@ -321,7 +320,6 @@ struct zoran_v4l_struct {
321 struct zoran_v4l_buffer buffer[VIDEO_MAX_FRAME]; /* buffers */ 320 struct zoran_v4l_buffer buffer[VIDEO_MAX_FRAME]; /* buffers */
322 int num_buffers, buffer_size; 321 int num_buffers, buffer_size;
323 u8 allocated; /* Flag if buffers are allocated */ 322 u8 allocated; /* Flag if buffers are allocated */
324 u8 ready_to_be_freed; /* hack - see zoran_driver.c */
325}; 323};
326 324
327struct zoran; 325struct zoran;
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index b81e20912fa..dc6ba554597 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -309,11 +309,6 @@ v4l_fbuffer_alloc (struct file *file)
309 unsigned char *mem; 309 unsigned char *mem;
310 unsigned long pmem = 0; 310 unsigned long pmem = 0;
311 311
312 /* we might have old buffers lying around... */
313 if (fh->v4l_buffers.ready_to_be_freed) {
314 v4l_fbuffer_free(file);
315 }
316
317 for (i = 0; i < fh->v4l_buffers.num_buffers; i++) { 312 for (i = 0; i < fh->v4l_buffers.num_buffers; i++) {
318 if (fh->v4l_buffers.buffer[i].fbuffer) 313 if (fh->v4l_buffers.buffer[i].fbuffer)
319 dprintk(2, 314 dprintk(2,
@@ -421,7 +416,6 @@ v4l_fbuffer_free (struct file *file)
421 } 416 }
422 417
423 fh->v4l_buffers.allocated = 0; 418 fh->v4l_buffers.allocated = 0;
424 fh->v4l_buffers.ready_to_be_freed = 0;
425} 419}
426 420
427/* 421/*
@@ -466,11 +460,6 @@ jpg_fbuffer_alloc (struct file *file)
466 int i, j, off; 460 int i, j, off;
467 unsigned long mem; 461 unsigned long mem;
468 462
469 /* we might have old buffers lying around */
470 if (fh->jpg_buffers.ready_to_be_freed) {
471 jpg_fbuffer_free(file);
472 }
473
474 for (i = 0; i < fh->jpg_buffers.num_buffers; i++) { 463 for (i = 0; i < fh->jpg_buffers.num_buffers; i++) {
475 if (fh->jpg_buffers.buffer[i].frag_tab) 464 if (fh->jpg_buffers.buffer[i].frag_tab)
476 dprintk(2, 465 dprintk(2,
@@ -613,7 +602,6 @@ jpg_fbuffer_free (struct file *file)
613 } 602 }
614 603
615 fh->jpg_buffers.allocated = 0; 604 fh->jpg_buffers.allocated = 0;
616 fh->jpg_buffers.ready_to_be_freed = 0;
617} 605}
618 606
619/* 607/*
@@ -657,7 +645,7 @@ zoran_v4l_set_format (struct file *file,
657 if ((bpp == 2 && (width & 1)) || (bpp == 3 && (width & 3))) { 645 if ((bpp == 2 && (width & 1)) || (bpp == 3 && (width & 3))) {
658 dprintk(1, 646 dprintk(1,
659 KERN_ERR 647 KERN_ERR
660 "%s: v4l_set_format() - wrong frame alingment\n", 648 "%s: v4l_set_format() - wrong frame alignment\n",
661 ZR_DEVNAME(zr)); 649 ZR_DEVNAME(zr));
662 return -EINVAL; 650 return -EINVAL;
663 } 651 }
@@ -1122,7 +1110,6 @@ zoran_open_init_session (struct file *file)
1122 fh->v4l_buffers.buffer[i].bs.frame = i; 1110 fh->v4l_buffers.buffer[i].bs.frame = i;
1123 } 1111 }
1124 fh->v4l_buffers.allocated = 0; 1112 fh->v4l_buffers.allocated = 0;
1125 fh->v4l_buffers.ready_to_be_freed = 0;
1126 fh->v4l_buffers.active = ZORAN_FREE; 1113 fh->v4l_buffers.active = ZORAN_FREE;
1127 fh->v4l_buffers.buffer_size = v4l_bufsize; 1114 fh->v4l_buffers.buffer_size = v4l_bufsize;
1128 fh->v4l_buffers.num_buffers = v4l_nbufs; 1115 fh->v4l_buffers.num_buffers = v4l_nbufs;
@@ -1138,7 +1125,6 @@ zoran_open_init_session (struct file *file)
1138 } 1125 }
1139 fh->jpg_buffers.need_contiguous = zr->jpg_buffers.need_contiguous; 1126 fh->jpg_buffers.need_contiguous = zr->jpg_buffers.need_contiguous;
1140 fh->jpg_buffers.allocated = 0; 1127 fh->jpg_buffers.allocated = 0;
1141 fh->jpg_buffers.ready_to_be_freed = 0;
1142 fh->jpg_buffers.active = ZORAN_FREE; 1128 fh->jpg_buffers.active = ZORAN_FREE;
1143 fh->jpg_buffers.buffer_size = jpg_bufsize; 1129 fh->jpg_buffers.buffer_size = jpg_bufsize;
1144 fh->jpg_buffers.num_buffers = jpg_nbufs; 1130 fh->jpg_buffers.num_buffers = jpg_nbufs;
@@ -1172,10 +1158,8 @@ zoran_close_end_session (struct file *file)
1172 } 1158 }
1173 1159
1174 /* v4l buffers */ 1160 /* v4l buffers */
1175 if (fh->v4l_buffers.allocated || 1161 if (fh->v4l_buffers.allocated)
1176 fh->v4l_buffers.ready_to_be_freed) {
1177 v4l_fbuffer_free(file); 1162 v4l_fbuffer_free(file);
1178 }
1179 1163
1180 /* jpg capture */ 1164 /* jpg capture */
1181 if (fh->jpg_buffers.active != ZORAN_FREE) { 1165 if (fh->jpg_buffers.active != ZORAN_FREE) {
@@ -1186,10 +1170,8 @@ zoran_close_end_session (struct file *file)
1186 } 1170 }
1187 1171
1188 /* jpg buffers */ 1172 /* jpg buffers */
1189 if (fh->jpg_buffers.allocated || 1173 if (fh->jpg_buffers.allocated)
1190 fh->jpg_buffers.ready_to_be_freed) {
1191 jpg_fbuffer_free(file); 1174 jpg_fbuffer_free(file);
1192 }
1193} 1175}
1194 1176
1195/* 1177/*
@@ -1903,38 +1885,13 @@ zoran_set_input (struct zoran *zr,
1903 * ioctl routine 1885 * ioctl routine
1904 */ 1886 */
1905 1887
1906static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) 1888static long zoran_default(struct file *file, void *__fh, int cmd, void *arg)
1907{ 1889{
1908 struct zoran_fh *fh = file->private_data; 1890 struct zoran_fh *fh = __fh;
1909 struct zoran *zr = fh->zr; 1891 struct zoran *zr = fh->zr;
1910 /* CAREFUL: used in multiple places here */
1911 struct zoran_jpg_settings settings; 1892 struct zoran_jpg_settings settings;
1912 1893
1913 /* we might have older buffers lying around... We don't want
1914 * to wait, but we do want to try cleaning them up ASAP. So
1915 * we try to obtain the lock and free them. If that fails, we
1916 * don't do anything and wait for the next turn. In the end,
1917 * zoran_close() or a new allocation will still free them...
1918 * This is just a 'the sooner the better' extra 'feature'
1919 *
1920 * We don't free the buffers right on munmap() because that
1921 * causes oopses (kfree() inside munmap() oopses for no
1922 * apparent reason - it's also not reproduceable in any way,
1923 * but moving the free code outside the munmap() handler fixes
1924 * all this... If someone knows why, please explain me (Ronald)
1925 */
1926 if (mutex_trylock(&zr->resource_lock)) {
1927 /* we obtained it! Let's try to free some things */
1928 if (fh->jpg_buffers.ready_to_be_freed)
1929 jpg_fbuffer_free(file);
1930 if (fh->v4l_buffers.ready_to_be_freed)
1931 v4l_fbuffer_free(file);
1932
1933 mutex_unlock(&zr->resource_lock);
1934 }
1935
1936 switch (cmd) { 1894 switch (cmd) {
1937
1938 case VIDIOCGCAP: 1895 case VIDIOCGCAP:
1939 { 1896 {
1940 struct video_capability *vcap = arg; 1897 struct video_capability *vcap = arg;
@@ -1956,7 +1913,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1956 1913
1957 return 0; 1914 return 0;
1958 } 1915 }
1959 break;
1960 1916
1961 case VIDIOCGCHAN: 1917 case VIDIOCGCHAN:
1962 { 1918 {
@@ -1987,7 +1943,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1987 1943
1988 return 0; 1944 return 0;
1989 } 1945 }
1990 break;
1991 1946
1992 /* RJ: the documentation at http://roadrunner.swansea.linux.org.uk/v4lapi.shtml says: 1947 /* RJ: the documentation at http://roadrunner.swansea.linux.org.uk/v4lapi.shtml says:
1993 * 1948 *
@@ -2017,11 +1972,10 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2017 1972
2018 /* Make sure the changes come into effect */ 1973 /* Make sure the changes come into effect */
2019 res = wait_grab_pending(zr); 1974 res = wait_grab_pending(zr);
2020 schan_unlock_and_return: 1975schan_unlock_and_return:
2021 mutex_unlock(&zr->resource_lock); 1976 mutex_unlock(&zr->resource_lock);
2022 return res; 1977 return res;
2023 } 1978 }
2024 break;
2025 1979
2026 case VIDIOCGPICT: 1980 case VIDIOCGPICT:
2027 { 1981 {
@@ -2045,7 +1999,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2045 1999
2046 return 0; 2000 return 0;
2047 } 2001 }
2048 break;
2049 2002
2050 case VIDIOCSPICT: 2003 case VIDIOCSPICT:
2051 { 2004 {
@@ -2091,7 +2044,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2091 2044
2092 return 0; 2045 return 0;
2093 } 2046 }
2094 break;
2095 2047
2096 case VIDIOCCAPTURE: 2048 case VIDIOCCAPTURE:
2097 { 2049 {
@@ -2106,7 +2058,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2106 2058
2107 return res; 2059 return res;
2108 } 2060 }
2109 break;
2110 2061
2111 case VIDIOCGWIN: 2062 case VIDIOCGWIN:
2112 { 2063 {
@@ -2124,7 +2075,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2124 vwin->clipcount = 0; 2075 vwin->clipcount = 0;
2125 return 0; 2076 return 0;
2126 } 2077 }
2127 break;
2128 2078
2129 case VIDIOCSWIN: 2079 case VIDIOCSWIN:
2130 { 2080 {
@@ -2146,7 +2096,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2146 2096
2147 return res; 2097 return res;
2148 } 2098 }
2149 break;
2150 2099
2151 case VIDIOCGFBUF: 2100 case VIDIOCGFBUF:
2152 { 2101 {
@@ -2159,7 +2108,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2159 mutex_unlock(&zr->resource_lock); 2108 mutex_unlock(&zr->resource_lock);
2160 return 0; 2109 return 0;
2161 } 2110 }
2162 break;
2163 2111
2164 case VIDIOCSFBUF: 2112 case VIDIOCSFBUF:
2165 { 2113 {
@@ -2192,7 +2140,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2192 2140
2193 return res; 2141 return res;
2194 } 2142 }
2195 break;
2196 2143
2197 case VIDIOCSYNC: 2144 case VIDIOCSYNC:
2198 { 2145 {
@@ -2208,7 +2155,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2208 zr->v4l_sync_tail++; 2155 zr->v4l_sync_tail++;
2209 return res; 2156 return res;
2210 } 2157 }
2211 break;
2212 2158
2213 case VIDIOCMCAPTURE: 2159 case VIDIOCMCAPTURE:
2214 { 2160 {
@@ -2226,7 +2172,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2226 mutex_unlock(&zr->resource_lock); 2172 mutex_unlock(&zr->resource_lock);
2227 return res; 2173 return res;
2228 } 2174 }
2229 break;
2230 2175
2231 case VIDIOCGMBUF: 2176 case VIDIOCGMBUF:
2232 { 2177 {
@@ -2262,12 +2207,11 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2262 2207
2263 /* The next mmap will map the V4L buffers */ 2208 /* The next mmap will map the V4L buffers */
2264 fh->map_mode = ZORAN_MAP_MODE_RAW; 2209 fh->map_mode = ZORAN_MAP_MODE_RAW;
2265 v4l1reqbuf_unlock_and_return: 2210v4l1reqbuf_unlock_and_return:
2266 mutex_unlock(&zr->resource_lock); 2211 mutex_unlock(&zr->resource_lock);
2267 2212
2268 return res; 2213 return res;
2269 } 2214 }
2270 break;
2271 2215
2272 case VIDIOCGUNIT: 2216 case VIDIOCGUNIT:
2273 { 2217 {
@@ -2283,7 +2227,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2283 2227
2284 return 0; 2228 return 0;
2285 } 2229 }
2286 break;
2287 2230
2288 /* 2231 /*
2289 * RJ: In principal we could support subcaptures for V4L grabbing. 2232 * RJ: In principal we could support subcaptures for V4L grabbing.
@@ -2297,7 +2240,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2297 ZR_DEVNAME(zr)); 2240 ZR_DEVNAME(zr));
2298 return -EINVAL; 2241 return -EINVAL;
2299 } 2242 }
2300 break;
2301 2243
2302 case VIDIOCSCAPTURE: 2244 case VIDIOCSCAPTURE:
2303 { 2245 {
@@ -2305,7 +2247,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2305 ZR_DEVNAME(zr)); 2247 ZR_DEVNAME(zr));
2306 return -EINVAL; 2248 return -EINVAL;
2307 } 2249 }
2308 break;
2309 2250
2310 case BUZIOC_G_PARAMS: 2251 case BUZIOC_G_PARAMS:
2311 { 2252 {
@@ -2352,7 +2293,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2352 2293
2353 return 0; 2294 return 0;
2354 } 2295 }
2355 break;
2356 2296
2357 case BUZIOC_S_PARAMS: 2297 case BUZIOC_S_PARAMS:
2358 { 2298 {
@@ -2401,12 +2341,11 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2401 } 2341 }
2402 2342
2403 fh->jpg_settings = settings; 2343 fh->jpg_settings = settings;
2404 sparams_unlock_and_return: 2344sparams_unlock_and_return:
2405 mutex_unlock(&zr->resource_lock); 2345 mutex_unlock(&zr->resource_lock);
2406 2346
2407 return res; 2347 return res;
2408 } 2348 }
2409 break;
2410 2349
2411 case BUZIOC_REQBUFS: 2350 case BUZIOC_REQBUFS:
2412 { 2351 {
@@ -2456,12 +2395,11 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2456 /* The next mmap will map the MJPEG buffers - could 2395 /* The next mmap will map the MJPEG buffers - could
2457 * also be *_PLAY, but it doesn't matter here */ 2396 * also be *_PLAY, but it doesn't matter here */
2458 fh->map_mode = ZORAN_MAP_MODE_JPG_REC; 2397 fh->map_mode = ZORAN_MAP_MODE_JPG_REC;
2459 jpgreqbuf_unlock_and_return: 2398jpgreqbuf_unlock_and_return:
2460 mutex_unlock(&zr->resource_lock); 2399 mutex_unlock(&zr->resource_lock);
2461 2400
2462 return res; 2401 return res;
2463 } 2402 }
2464 break;
2465 2403
2466 case BUZIOC_QBUF_CAPT: 2404 case BUZIOC_QBUF_CAPT:
2467 { 2405 {
@@ -2476,7 +2414,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2476 2414
2477 return res; 2415 return res;
2478 } 2416 }
2479 break;
2480 2417
2481 case BUZIOC_QBUF_PLAY: 2418 case BUZIOC_QBUF_PLAY:
2482 { 2419 {
@@ -2491,7 +2428,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2491 2428
2492 return res; 2429 return res;
2493 } 2430 }
2494 break;
2495 2431
2496 case BUZIOC_SYNC: 2432 case BUZIOC_SYNC:
2497 { 2433 {
@@ -2506,7 +2442,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2506 2442
2507 return res; 2443 return res;
2508 } 2444 }
2509 break;
2510 2445
2511 case BUZIOC_G_STATUS: 2446 case BUZIOC_G_STATUS:
2512 { 2447 {
@@ -2550,7 +2485,7 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2550 input = zr->card.input[zr->input].muxsel; 2485 input = zr->card.input[zr->input].muxsel;
2551 decoder_command(zr, DECODER_SET_INPUT, &input); 2486 decoder_command(zr, DECODER_SET_INPUT, &input);
2552 decoder_command(zr, DECODER_SET_NORM, &zr->norm); 2487 decoder_command(zr, DECODER_SET_NORM, &zr->norm);
2553 gstat_unlock_and_return: 2488gstat_unlock_and_return:
2554 mutex_unlock(&zr->resource_lock); 2489 mutex_unlock(&zr->resource_lock);
2555 2490
2556 if (!res) { 2491 if (!res) {
@@ -2569,1599 +2504,1297 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
2569 2504
2570 return res; 2505 return res;
2571 } 2506 }
2572 break;
2573
2574 /* The new video4linux2 capture interface - much nicer than video4linux1, since
2575 * it allows for integrating the JPEG capturing calls inside standard v4l2
2576 */
2577 2507
2578 case VIDIOC_QUERYCAP: 2508 default:
2579 { 2509 return -EINVAL;
2580 struct v4l2_capability *cap = arg;
2581
2582 dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCAP\n", ZR_DEVNAME(zr));
2583
2584 memset(cap, 0, sizeof(*cap));
2585 strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1);
2586 strncpy(cap->driver, "zoran", sizeof(cap->driver)-1);
2587 snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
2588 pci_name(zr->pci_dev));
2589 cap->version =
2590 KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION,
2591 RELEASE_VERSION);
2592 cap->capabilities = ZORAN_V4L2_VID_FLAGS;
2593
2594 return 0;
2595 } 2510 }
2596 break; 2511}
2597
2598 case VIDIOC_ENUM_FMT:
2599 {
2600 struct v4l2_fmtdesc *fmt = arg;
2601 int index = fmt->index, num = -1, i, flag = 0, type =
2602 fmt->type;
2603 2512
2604 dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUM_FMT - index=%d\n", 2513static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap)
2605 ZR_DEVNAME(zr), fmt->index); 2514{
2515 struct zoran_fh *fh = __fh;
2516 struct zoran *zr = fh->zr;
2606 2517
2607 switch (fmt->type) { 2518 memset(cap, 0, sizeof(*cap));
2608 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 2519 strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1);
2609 flag = ZORAN_FORMAT_CAPTURE; 2520 strncpy(cap->driver, "zoran", sizeof(cap->driver)-1);
2610 break; 2521 snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
2611 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 2522 pci_name(zr->pci_dev));
2612 flag = ZORAN_FORMAT_PLAYBACK; 2523 cap->version =
2613 break; 2524 KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION,
2614 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 2525 RELEASE_VERSION);
2615 flag = ZORAN_FORMAT_OVERLAY; 2526 cap->capabilities = ZORAN_V4L2_VID_FLAGS;
2616 break;
2617 default:
2618 dprintk(1,
2619 KERN_ERR
2620 "%s: VIDIOC_ENUM_FMT - unknown type %d\n",
2621 ZR_DEVNAME(zr), fmt->type);
2622 return -EINVAL;
2623 }
2624 2527
2625 for (i = 0; i < NUM_FORMATS; i++) { 2528 return 0;
2626 if (zoran_formats[i].flags & flag) 2529}
2627 num++;
2628 if (num == fmt->index)
2629 break;
2630 }
2631 if (fmt->index < 0 /* late, but not too late */ ||
2632 i == NUM_FORMATS)
2633 return -EINVAL;
2634 2530
2635 memset(fmt, 0, sizeof(*fmt)); 2531static int zoran_enum_fmt(struct zoran *zr, struct v4l2_fmtdesc *fmt, int flag)
2636 fmt->index = index; 2532{
2637 fmt->type = type; 2533 int num = -1, i;
2638 strncpy(fmt->description, zoran_formats[i].name, sizeof(fmt->description)-1);
2639 fmt->pixelformat = zoran_formats[i].fourcc;
2640 if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)
2641 fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
2642 2534
2643 return 0; 2535 for (i = 0; i < NUM_FORMATS; i++) {
2536 if (zoran_formats[i].flags & flag)
2537 num++;
2538 if (num == fmt->index)
2539 break;
2644 } 2540 }
2645 break; 2541 if (fmt->index < 0 /* late, but not too late */ || i == NUM_FORMATS)
2646 2542 return -EINVAL;
2647 case VIDIOC_G_FMT:
2648 {
2649 struct v4l2_format *fmt = arg;
2650 int type = fmt->type;
2651 2543
2652 dprintk(5, KERN_DEBUG "%s: VIDIOC_G_FMT\n", ZR_DEVNAME(zr)); 2544 strncpy(fmt->description, zoran_formats[i].name, sizeof(fmt->description)-1);
2545 fmt->pixelformat = zoran_formats[i].fourcc;
2546 if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)
2547 fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
2548 return 0;
2549}
2653 2550
2654 memset(fmt, 0, sizeof(*fmt)); 2551static int zoran_enum_fmt_vid_cap(struct file *file, void *__fh,
2655 fmt->type = type; 2552 struct v4l2_fmtdesc *f)
2553{
2554 struct zoran_fh *fh = __fh;
2555 struct zoran *zr = fh->zr;
2656 2556
2657 switch (fmt->type) { 2557 return zoran_enum_fmt(zr, f, ZORAN_FORMAT_CAPTURE);
2658 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 2558}
2659 2559
2660 mutex_lock(&zr->resource_lock); 2560static int zoran_enum_fmt_vid_out(struct file *file, void *__fh,
2561 struct v4l2_fmtdesc *f)
2562{
2563 struct zoran_fh *fh = __fh;
2564 struct zoran *zr = fh->zr;
2661 2565
2662 fmt->fmt.win.w.left = fh->overlay_settings.x; 2566 return zoran_enum_fmt(zr, f, ZORAN_FORMAT_PLAYBACK);
2663 fmt->fmt.win.w.top = fh->overlay_settings.y; 2567}
2664 fmt->fmt.win.w.width = fh->overlay_settings.width;
2665 fmt->fmt.win.w.height =
2666 fh->overlay_settings.height;
2667 if (fh->overlay_settings.width * 2 >
2668 BUZ_MAX_HEIGHT)
2669 fmt->fmt.win.field = V4L2_FIELD_INTERLACED;
2670 else
2671 fmt->fmt.win.field = V4L2_FIELD_TOP;
2672 2568
2673 mutex_unlock(&zr->resource_lock); 2569static int zoran_enum_fmt_vid_overlay(struct file *file, void *__fh,
2570 struct v4l2_fmtdesc *f)
2571{
2572 struct zoran_fh *fh = __fh;
2573 struct zoran *zr = fh->zr;
2674 2574
2675 break; 2575 return zoran_enum_fmt(zr, f, ZORAN_FORMAT_OVERLAY);
2576}
2676 2577
2677 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 2578static int zoran_g_fmt_vid_out(struct file *file, void *__fh,
2678 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 2579 struct v4l2_format *fmt)
2679 2580{
2680 mutex_lock(&zr->resource_lock); 2581 struct zoran_fh *fh = __fh;
2681 2582 struct zoran *zr = fh->zr;
2682 if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
2683 fh->map_mode == ZORAN_MAP_MODE_RAW) {
2684
2685 fmt->fmt.pix.width =
2686 fh->v4l_settings.width;
2687 fmt->fmt.pix.height =
2688 fh->v4l_settings.height;
2689 fmt->fmt.pix.sizeimage =
2690 fh->v4l_settings.bytesperline *
2691 fh->v4l_settings.height;
2692 fmt->fmt.pix.pixelformat =
2693 fh->v4l_settings.format->fourcc;
2694 fmt->fmt.pix.colorspace =
2695 fh->v4l_settings.format->colorspace;
2696 fmt->fmt.pix.bytesperline =
2697 fh->v4l_settings.bytesperline;
2698 if (BUZ_MAX_HEIGHT <
2699 (fh->v4l_settings.height * 2))
2700 fmt->fmt.pix.field =
2701 V4L2_FIELD_INTERLACED;
2702 else
2703 fmt->fmt.pix.field =
2704 V4L2_FIELD_TOP;
2705 2583
2706 } else { 2584 mutex_lock(&zr->resource_lock);
2707 2585
2708 fmt->fmt.pix.width = 2586 fmt->fmt.pix.width = fh->jpg_settings.img_width / fh->jpg_settings.HorDcm;
2709 fh->jpg_settings.img_width / 2587 fmt->fmt.pix.height = fh->jpg_settings.img_height /
2710 fh->jpg_settings.HorDcm; 2588 (fh->jpg_settings.VerDcm * fh->jpg_settings.TmpDcm);
2711 fmt->fmt.pix.height = 2589 fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&fh->jpg_settings);
2712 fh->jpg_settings.img_height / 2590 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
2713 (fh->jpg_settings.VerDcm * 2591 if (fh->jpg_settings.TmpDcm == 1)
2714 fh->jpg_settings.TmpDcm); 2592 fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
2715 fmt->fmt.pix.sizeimage = 2593 V4L2_FIELD_SEQ_BT : V4L2_FIELD_SEQ_BT);
2716 zoran_v4l2_calc_bufsize(&fh-> 2594 else
2717 jpg_settings); 2595 fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
2718 fmt->fmt.pix.pixelformat = 2596 V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
2719 V4L2_PIX_FMT_MJPEG; 2597 fmt->fmt.pix.bytesperline = 0;
2720 if (fh->jpg_settings.TmpDcm == 1) 2598 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
2721 fmt->fmt.pix.field =
2722 (fh->jpg_settings.
2723 odd_even ? V4L2_FIELD_SEQ_BT :
2724 V4L2_FIELD_SEQ_BT);
2725 else
2726 fmt->fmt.pix.field =
2727 (fh->jpg_settings.
2728 odd_even ? V4L2_FIELD_TOP :
2729 V4L2_FIELD_BOTTOM);
2730
2731 fmt->fmt.pix.bytesperline = 0;
2732 fmt->fmt.pix.colorspace =
2733 V4L2_COLORSPACE_SMPTE170M;
2734 }
2735 2599
2736 mutex_unlock(&zr->resource_lock); 2600 mutex_unlock(&zr->resource_lock);
2601 return 0;
2602}
2737 2603
2738 break; 2604static int zoran_g_fmt_vid_cap(struct file *file, void *__fh,
2605 struct v4l2_format *fmt)
2606{
2607 struct zoran_fh *fh = __fh;
2608 struct zoran *zr = fh->zr;
2739 2609
2740 default: 2610 if (fh->map_mode != ZORAN_MAP_MODE_RAW)
2741 dprintk(1, 2611 return zoran_g_fmt_vid_out(file, fh, fmt);
2742 KERN_ERR
2743 "%s: VIDIOC_G_FMT - unsupported type %d\n",
2744 ZR_DEVNAME(zr), fmt->type);
2745 return -EINVAL;
2746 }
2747 return 0;
2748 }
2749 break;
2750 2612
2751 case VIDIOC_S_FMT: 2613 mutex_lock(&zr->resource_lock);
2752 { 2614 fmt->fmt.pix.width = fh->v4l_settings.width;
2753 struct v4l2_format *fmt = arg; 2615 fmt->fmt.pix.height = fh->v4l_settings.height;
2754 int i, res = 0; 2616 fmt->fmt.pix.sizeimage = fh->v4l_settings.bytesperline *
2755 __le32 printformat; 2617 fh->v4l_settings.height;
2756 2618 fmt->fmt.pix.pixelformat = fh->v4l_settings.format->fourcc;
2757 dprintk(3, KERN_DEBUG "%s: VIDIOC_S_FMT - type=%d, ", 2619 fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace;
2758 ZR_DEVNAME(zr), fmt->type); 2620 fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline;
2759 2621 if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2))
2760 switch (fmt->type) { 2622 fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
2761 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 2623 else
2762 2624 fmt->fmt.pix.field = V4L2_FIELD_TOP;
2763 dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n", 2625 mutex_unlock(&zr->resource_lock);
2764 fmt->fmt.win.w.left, fmt->fmt.win.w.top, 2626 return 0;
2765 fmt->fmt.win.w.width, 2627}
2766 fmt->fmt.win.w.height,
2767 fmt->fmt.win.clipcount,
2768 fmt->fmt.win.bitmap);
2769 mutex_lock(&zr->resource_lock);
2770 res =
2771 setup_window(file, fmt->fmt.win.w.left,
2772 fmt->fmt.win.w.top,
2773 fmt->fmt.win.w.width,
2774 fmt->fmt.win.w.height,
2775 (struct video_clip __user *)
2776 fmt->fmt.win.clips,
2777 fmt->fmt.win.clipcount,
2778 fmt->fmt.win.bitmap);
2779 mutex_unlock(&zr->resource_lock);
2780 return res;
2781 break;
2782 2628
2783 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 2629static int zoran_g_fmt_vid_overlay(struct file *file, void *__fh,
2784 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 2630 struct v4l2_format *fmt)
2785 2631{
2786 printformat = 2632 struct zoran_fh *fh = __fh;
2787 __cpu_to_le32(fmt->fmt.pix.pixelformat); 2633 struct zoran *zr = fh->zr;
2788 dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n",
2789 fmt->fmt.pix.width, fmt->fmt.pix.height,
2790 fmt->fmt.pix.pixelformat,
2791 (char *) &printformat);
2792
2793 /* we can be requested to do JPEG/raw playback/capture */
2794 if (!
2795 (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2796 (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
2797 fmt->fmt.pix.pixelformat ==
2798 V4L2_PIX_FMT_MJPEG))) {
2799 dprintk(1,
2800 KERN_ERR
2801 "%s: VIDIOC_S_FMT - unknown type %d/0x%x(%4.4s) combination\n",
2802 ZR_DEVNAME(zr), fmt->type,
2803 fmt->fmt.pix.pixelformat,
2804 (char *) &printformat);
2805 return -EINVAL;
2806 }
2807 2634
2808 if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) { 2635 mutex_lock(&zr->resource_lock);
2809 mutex_lock(&zr->resource_lock);
2810 2636
2811 settings = fh->jpg_settings; 2637 fmt->fmt.win.w.left = fh->overlay_settings.x;
2638 fmt->fmt.win.w.top = fh->overlay_settings.y;
2639 fmt->fmt.win.w.width = fh->overlay_settings.width;
2640 fmt->fmt.win.w.height = fh->overlay_settings.height;
2641 if (fh->overlay_settings.width * 2 > BUZ_MAX_HEIGHT)
2642 fmt->fmt.win.field = V4L2_FIELD_INTERLACED;
2643 else
2644 fmt->fmt.win.field = V4L2_FIELD_TOP;
2812 2645
2813 if (fh->v4l_buffers.allocated || 2646 mutex_unlock(&zr->resource_lock);
2814 fh->jpg_buffers.allocated) { 2647 return 0;
2815 dprintk(1, 2648}
2816 KERN_ERR
2817 "%s: VIDIOC_S_FMT - cannot change capture mode\n",
2818 ZR_DEVNAME(zr));
2819 res = -EBUSY;
2820 goto sfmtjpg_unlock_and_return;
2821 }
2822 2649
2823 /* we actually need to set 'real' parameters now */ 2650static int zoran_try_fmt_vid_overlay(struct file *file, void *__fh,
2824 if ((fmt->fmt.pix.height * 2) > 2651 struct v4l2_format *fmt)
2825 BUZ_MAX_HEIGHT) 2652{
2826 settings.TmpDcm = 1; 2653 struct zoran_fh *fh = __fh;
2827 else 2654 struct zoran *zr = fh->zr;
2828 settings.TmpDcm = 2;
2829 settings.decimation = 0;
2830 if (fmt->fmt.pix.height <=
2831 fh->jpg_settings.img_height / 2)
2832 settings.VerDcm = 2;
2833 else
2834 settings.VerDcm = 1;
2835 if (fmt->fmt.pix.width <=
2836 fh->jpg_settings.img_width / 4)
2837 settings.HorDcm = 4;
2838 else if (fmt->fmt.pix.width <=
2839 fh->jpg_settings.img_width / 2)
2840 settings.HorDcm = 2;
2841 else
2842 settings.HorDcm = 1;
2843 if (settings.TmpDcm == 1)
2844 settings.field_per_buff = 2;
2845 else
2846 settings.field_per_buff = 1;
2847
2848 /* check */
2849 if ((res =
2850 zoran_check_jpg_settings(zr,
2851 &settings)))
2852 goto sfmtjpg_unlock_and_return;
2853
2854 /* it's ok, so set them */
2855 fh->jpg_settings = settings;
2856
2857 /* tell the user what we actually did */
2858 fmt->fmt.pix.width =
2859 settings.img_width / settings.HorDcm;
2860 fmt->fmt.pix.height =
2861 settings.img_height * 2 /
2862 (settings.TmpDcm * settings.VerDcm);
2863 if (settings.TmpDcm == 1)
2864 fmt->fmt.pix.field =
2865 (fh->jpg_settings.
2866 odd_even ? V4L2_FIELD_SEQ_TB :
2867 V4L2_FIELD_SEQ_BT);
2868 else
2869 fmt->fmt.pix.field =
2870 (fh->jpg_settings.
2871 odd_even ? V4L2_FIELD_TOP :
2872 V4L2_FIELD_BOTTOM);
2873 fh->jpg_buffers.buffer_size =
2874 zoran_v4l2_calc_bufsize(&fh->
2875 jpg_settings);
2876 fmt->fmt.pix.bytesperline = 0;
2877 fmt->fmt.pix.sizeimage =
2878 fh->jpg_buffers.buffer_size;
2879 fmt->fmt.pix.colorspace =
2880 V4L2_COLORSPACE_SMPTE170M;
2881
2882 /* we hereby abuse this variable to show that
2883 * we're gonna do mjpeg capture */
2884 fh->map_mode =
2885 (fmt->type ==
2886 V4L2_BUF_TYPE_VIDEO_CAPTURE) ?
2887 ZORAN_MAP_MODE_JPG_REC :
2888 ZORAN_MAP_MODE_JPG_PLAY;
2889 sfmtjpg_unlock_and_return:
2890 mutex_unlock(&zr->resource_lock);
2891 } else {
2892 for (i = 0; i < NUM_FORMATS; i++)
2893 if (fmt->fmt.pix.pixelformat ==
2894 zoran_formats[i].fourcc)
2895 break;
2896 if (i == NUM_FORMATS) {
2897 dprintk(1,
2898 KERN_ERR
2899 "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x (%4.4s)\n",
2900 ZR_DEVNAME(zr),
2901 fmt->fmt.pix.pixelformat,
2902 (char *) &printformat);
2903 return -EINVAL;
2904 }
2905 mutex_lock(&zr->resource_lock);
2906 if (fh->jpg_buffers.allocated ||
2907 (fh->v4l_buffers.allocated &&
2908 fh->v4l_buffers.active !=
2909 ZORAN_FREE)) {
2910 dprintk(1,
2911 KERN_ERR
2912 "%s: VIDIOC_S_FMT - cannot change capture mode\n",
2913 ZR_DEVNAME(zr));
2914 res = -EBUSY;
2915 goto sfmtv4l_unlock_and_return;
2916 }
2917 if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
2918 fmt->fmt.pix.height =
2919 BUZ_MAX_HEIGHT;
2920 if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
2921 fmt->fmt.pix.width = BUZ_MAX_WIDTH;
2922
2923 if ((res =
2924 zoran_v4l_set_format(file,
2925 fmt->fmt.pix.
2926 width,
2927 fmt->fmt.pix.
2928 height,
2929 &zoran_formats
2930 [i])))
2931 goto sfmtv4l_unlock_and_return;
2932
2933 /* tell the user the
2934 * results/missing stuff */
2935 fmt->fmt.pix.bytesperline =
2936 fh->v4l_settings.bytesperline;
2937 fmt->fmt.pix.sizeimage =
2938 fh->v4l_settings.height *
2939 fh->v4l_settings.bytesperline;
2940 fmt->fmt.pix.colorspace =
2941 fh->v4l_settings.format->colorspace;
2942 if (BUZ_MAX_HEIGHT <
2943 (fh->v4l_settings.height * 2))
2944 fmt->fmt.pix.field =
2945 V4L2_FIELD_INTERLACED;
2946 else
2947 fmt->fmt.pix.field =
2948 V4L2_FIELD_TOP;
2949
2950 fh->map_mode = ZORAN_MAP_MODE_RAW;
2951 sfmtv4l_unlock_and_return:
2952 mutex_unlock(&zr->resource_lock);
2953 }
2954 2655
2955 break; 2656 mutex_lock(&zr->resource_lock);
2956 2657
2957 default: 2658 if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH)
2958 dprintk(1, 2659 fmt->fmt.win.w.width = BUZ_MAX_WIDTH;
2959 KERN_ERR 2660 if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH)
2960 "%s: VIDIOC_S_FMT - unsupported type %d\n", 2661 fmt->fmt.win.w.width = BUZ_MIN_WIDTH;
2961 ZR_DEVNAME(zr), fmt->type); 2662 if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT)
2962 return -EINVAL; 2663 fmt->fmt.win.w.height = BUZ_MAX_HEIGHT;
2963 } 2664 if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT)
2665 fmt->fmt.win.w.height = BUZ_MIN_HEIGHT;
2964 2666
2965 return res; 2667 mutex_unlock(&zr->resource_lock);
2966 } 2668 return 0;
2967 break; 2669}
2968 2670
2969 case VIDIOC_G_FBUF: 2671static int zoran_try_fmt_vid_out(struct file *file, void *__fh,
2970 { 2672 struct v4l2_format *fmt)
2971 struct v4l2_framebuffer *fb = arg; 2673{
2674 struct zoran_fh *fh = __fh;
2675 struct zoran *zr = fh->zr;
2676 struct zoran_jpg_settings settings;
2677 int res = 0;
2972 2678
2973 dprintk(3, KERN_DEBUG "%s: VIDIOC_G_FBUF\n", ZR_DEVNAME(zr)); 2679 if (fmt->fmt.pix.bytesperline > 0)
2680 return -EINVAL;
2974 2681
2975 memset(fb, 0, sizeof(*fb)); 2682 if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
2976 mutex_lock(&zr->resource_lock); 2683 return -EINVAL;
2977 fb->base = zr->buffer.base;
2978 fb->fmt.width = zr->buffer.width;
2979 fb->fmt.height = zr->buffer.height;
2980 if (zr->overlay_settings.format) {
2981 fb->fmt.pixelformat =
2982 fh->overlay_settings.format->fourcc;
2983 }
2984 fb->fmt.bytesperline = zr->buffer.bytesperline;
2985 mutex_unlock(&zr->resource_lock);
2986 fb->fmt.colorspace = V4L2_COLORSPACE_SRGB;
2987 fb->fmt.field = V4L2_FIELD_INTERLACED;
2988 fb->flags = V4L2_FBUF_FLAG_OVERLAY;
2989 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
2990 2684
2991 return 0; 2685 mutex_lock(&zr->resource_lock);
2992 } 2686 settings = fh->jpg_settings;
2993 break;
2994 2687
2995 case VIDIOC_S_FBUF: 2688 /* we actually need to set 'real' parameters now */
2996 { 2689 if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT)
2997 int i, res = 0; 2690 settings.TmpDcm = 1;
2998 struct v4l2_framebuffer *fb = arg; 2691 else
2999 __le32 printformat = __cpu_to_le32(fb->fmt.pixelformat); 2692 settings.TmpDcm = 2;
2693 settings.decimation = 0;
2694 if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2)
2695 settings.VerDcm = 2;
2696 else
2697 settings.VerDcm = 1;
2698 if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4)
2699 settings.HorDcm = 4;
2700 else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2)
2701 settings.HorDcm = 2;
2702 else
2703 settings.HorDcm = 1;
2704 if (settings.TmpDcm == 1)
2705 settings.field_per_buff = 2;
2706 else
2707 settings.field_per_buff = 1;
2708
2709 /* check */
2710 res = zoran_check_jpg_settings(zr, &settings);
2711 if (res)
2712 goto tryfmt_unlock_and_return;
2713
2714 /* tell the user what we actually did */
2715 fmt->fmt.pix.width = settings.img_width / settings.HorDcm;
2716 fmt->fmt.pix.height = settings.img_height * 2 /
2717 (settings.TmpDcm * settings.VerDcm);
2718 if (settings.TmpDcm == 1)
2719 fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
2720 V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
2721 else
2722 fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
2723 V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
3000 2724
3001 dprintk(3, 2725 fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&settings);
3002 KERN_DEBUG 2726tryfmt_unlock_and_return:
3003 "%s: VIDIOC_S_FBUF - base=0x%p, size=%dx%d, bpl=%d, fmt=0x%x (%4.4s)\n", 2727 mutex_unlock(&zr->resource_lock);
3004 ZR_DEVNAME(zr), fb->base, fb->fmt.width, fb->fmt.height, 2728 return res;
3005 fb->fmt.bytesperline, fb->fmt.pixelformat, 2729}
3006 (char *) &printformat);
3007 2730
3008 for (i = 0; i < NUM_FORMATS; i++) 2731static int zoran_try_fmt_vid_cap(struct file *file, void *__fh,
3009 if (zoran_formats[i].fourcc == fb->fmt.pixelformat) 2732 struct v4l2_format *fmt)
3010 break; 2733{
3011 if (i == NUM_FORMATS) { 2734 struct zoran_fh *fh = __fh;
3012 dprintk(1, 2735 struct zoran *zr = fh->zr;
3013 KERN_ERR 2736 int i;
3014 "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n",
3015 ZR_DEVNAME(zr), fb->fmt.pixelformat,
3016 (char *) &printformat);
3017 return -EINVAL;
3018 }
3019 2737
3020 mutex_lock(&zr->resource_lock); 2738 if (fmt->fmt.pix.bytesperline > 0)
3021 res = 2739 return -EINVAL;
3022 setup_fbuffer(file, fb->base, &zoran_formats[i],
3023 fb->fmt.width, fb->fmt.height,
3024 fb->fmt.bytesperline);
3025 mutex_unlock(&zr->resource_lock);
3026 2740
3027 return res; 2741 if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
3028 } 2742 return zoran_try_fmt_vid_out(file, fh, fmt);
3029 break;
3030 2743
3031 case VIDIOC_OVERLAY: 2744 mutex_lock(&zr->resource_lock);
3032 {
3033 int *on = arg, res;
3034 2745
3035 dprintk(3, KERN_DEBUG "%s: VIDIOC_PREVIEW - on=%d\n", 2746 for (i = 0; i < NUM_FORMATS; i++)
3036 ZR_DEVNAME(zr), *on); 2747 if (zoran_formats[i].fourcc == fmt->fmt.pix.pixelformat)
2748 break;
3037 2749
3038 mutex_lock(&zr->resource_lock); 2750 if (i == NUM_FORMATS) {
3039 res = setup_overlay(file, *on);
3040 mutex_unlock(&zr->resource_lock); 2751 mutex_unlock(&zr->resource_lock);
3041 2752 return -EINVAL;
3042 return res;
3043 } 2753 }
3044 break;
3045
3046 case VIDIOC_REQBUFS:
3047 {
3048 struct v4l2_requestbuffers *req = arg;
3049 int res = 0;
3050
3051 dprintk(3, KERN_DEBUG "%s: VIDIOC_REQBUFS - type=%d\n",
3052 ZR_DEVNAME(zr), req->type);
3053 2754
3054 if (req->memory != V4L2_MEMORY_MMAP) { 2755 if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
3055 dprintk(1, 2756 fmt->fmt.pix.width = BUZ_MAX_WIDTH;
3056 KERN_ERR 2757 if (fmt->fmt.pix.width < BUZ_MIN_WIDTH)
3057 "%s: only MEMORY_MMAP capture is supported, not %d\n", 2758 fmt->fmt.pix.width = BUZ_MIN_WIDTH;
3058 ZR_DEVNAME(zr), req->memory); 2759 if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
3059 return -EINVAL; 2760 fmt->fmt.pix.height = BUZ_MAX_HEIGHT;
3060 } 2761 if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT)
3061 2762 fmt->fmt.pix.height = BUZ_MIN_HEIGHT;
3062 mutex_lock(&zr->resource_lock); 2763 mutex_unlock(&zr->resource_lock);
3063
3064 if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) {
3065 dprintk(1,
3066 KERN_ERR
3067 "%s: VIDIOC_REQBUFS - buffers allready allocated\n",
3068 ZR_DEVNAME(zr));
3069 res = -EBUSY;
3070 goto v4l2reqbuf_unlock_and_return;
3071 }
3072
3073 if (fh->map_mode == ZORAN_MAP_MODE_RAW &&
3074 req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
3075
3076 /* control user input */
3077 if (req->count < 2)
3078 req->count = 2;
3079 if (req->count > v4l_nbufs)
3080 req->count = v4l_nbufs;
3081 fh->v4l_buffers.num_buffers = req->count;
3082
3083 if (v4l_fbuffer_alloc(file)) {
3084 res = -ENOMEM;
3085 goto v4l2reqbuf_unlock_and_return;
3086 }
3087 2764
3088 /* The next mmap will map the V4L buffers */ 2765 return 0;
3089 fh->map_mode = ZORAN_MAP_MODE_RAW; 2766}
3090 2767
3091 } else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC || 2768static int zoran_s_fmt_vid_overlay(struct file *file, void *__fh,
3092 fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { 2769 struct v4l2_format *fmt)
2770{
2771 struct zoran_fh *fh = __fh;
2772 struct zoran *zr = fh->zr;
2773 int res;
2774
2775 dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n",
2776 fmt->fmt.win.w.left, fmt->fmt.win.w.top,
2777 fmt->fmt.win.w.width,
2778 fmt->fmt.win.w.height,
2779 fmt->fmt.win.clipcount,
2780 fmt->fmt.win.bitmap);
2781 mutex_lock(&zr->resource_lock);
2782 res = setup_window(file, fmt->fmt.win.w.left,
2783 fmt->fmt.win.w.top,
2784 fmt->fmt.win.w.width,
2785 fmt->fmt.win.w.height,
2786 (struct video_clip __user *)
2787 fmt->fmt.win.clips,
2788 fmt->fmt.win.clipcount,
2789 fmt->fmt.win.bitmap);
2790 mutex_unlock(&zr->resource_lock);
2791 return res;
2792}
3093 2793
3094 /* we need to calculate size ourselves now */ 2794static int zoran_s_fmt_vid_out(struct file *file, void *__fh,
3095 if (req->count < 4) 2795 struct v4l2_format *fmt)
3096 req->count = 4; 2796{
3097 if (req->count > jpg_nbufs) 2797 struct zoran_fh *fh = __fh;
3098 req->count = jpg_nbufs; 2798 struct zoran *zr = fh->zr;
3099 fh->jpg_buffers.num_buffers = req->count; 2799 __le32 printformat = __cpu_to_le32(fmt->fmt.pix.pixelformat);
3100 fh->jpg_buffers.buffer_size = 2800 struct zoran_jpg_settings settings;
3101 zoran_v4l2_calc_bufsize(&fh->jpg_settings); 2801 int res = 0;
3102 2802
3103 if (jpg_fbuffer_alloc(file)) { 2803 dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n",
3104 res = -ENOMEM; 2804 fmt->fmt.pix.width, fmt->fmt.pix.height,
3105 goto v4l2reqbuf_unlock_and_return; 2805 fmt->fmt.pix.pixelformat,
3106 } 2806 (char *) &printformat);
2807 if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
2808 return -EINVAL;
3107 2809
3108 /* The next mmap will map the MJPEG buffers */ 2810 mutex_lock(&zr->resource_lock);
3109 if (req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
3110 fh->map_mode = ZORAN_MAP_MODE_JPG_REC;
3111 else
3112 fh->map_mode = ZORAN_MAP_MODE_JPG_PLAY;
3113 2811
3114 } else { 2812 settings = fh->jpg_settings;
3115 dprintk(1,
3116 KERN_ERR
3117 "%s: VIDIOC_REQBUFS - unknown type %d\n",
3118 ZR_DEVNAME(zr), req->type);
3119 res = -EINVAL;
3120 goto v4l2reqbuf_unlock_and_return;
3121 }
3122 v4l2reqbuf_unlock_and_return:
3123 mutex_unlock(&zr->resource_lock);
3124 2813
3125 return 0; 2814 if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) {
2815 dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n",
2816 ZR_DEVNAME(zr));
2817 res = -EBUSY;
2818 goto sfmtjpg_unlock_and_return;
3126 } 2819 }
3127 break;
3128 2820
3129 case VIDIOC_QUERYBUF: 2821 /* we actually need to set 'real' parameters now */
3130 { 2822 if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT)
3131 struct v4l2_buffer *buf = arg; 2823 settings.TmpDcm = 1;
3132 __u32 type = buf->type; 2824 else
3133 int index = buf->index, res; 2825 settings.TmpDcm = 2;
3134 2826 settings.decimation = 0;
3135 dprintk(3, 2827 if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2)
3136 KERN_DEBUG 2828 settings.VerDcm = 2;
3137 "%s: VIDIOC_QUERYBUF - index=%d, type=%d\n", 2829 else
3138 ZR_DEVNAME(zr), buf->index, buf->type); 2830 settings.VerDcm = 1;
2831 if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4)
2832 settings.HorDcm = 4;
2833 else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2)
2834 settings.HorDcm = 2;
2835 else
2836 settings.HorDcm = 1;
2837 if (settings.TmpDcm == 1)
2838 settings.field_per_buff = 2;
2839 else
2840 settings.field_per_buff = 1;
2841
2842 /* check */
2843 res = zoran_check_jpg_settings(zr, &settings);
2844 if (res)
2845 goto sfmtjpg_unlock_and_return;
2846
2847 /* it's ok, so set them */
2848 fh->jpg_settings = settings;
2849
2850 /* tell the user what we actually did */
2851 fmt->fmt.pix.width = settings.img_width / settings.HorDcm;
2852 fmt->fmt.pix.height = settings.img_height * 2 /
2853 (settings.TmpDcm * settings.VerDcm);
2854 if (settings.TmpDcm == 1)
2855 fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
2856 V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
2857 else
2858 fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
2859 V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
2860 fh->jpg_buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings);
2861 fmt->fmt.pix.bytesperline = 0;
2862 fmt->fmt.pix.sizeimage = fh->jpg_buffers.buffer_size;
2863 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
2864
2865 /* we hereby abuse this variable to show that
2866 * we're gonna do mjpeg capture */
2867 fh->map_mode = (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ?
2868 ZORAN_MAP_MODE_JPG_REC : ZORAN_MAP_MODE_JPG_PLAY;
2869sfmtjpg_unlock_and_return:
2870 mutex_unlock(&zr->resource_lock);
2871 return res;
2872}
3139 2873
3140 memset(buf, 0, sizeof(*buf)); 2874static int zoran_s_fmt_vid_cap(struct file *file, void *__fh,
3141 buf->type = type; 2875 struct v4l2_format *fmt)
3142 buf->index = index; 2876{
2877 struct zoran_fh *fh = __fh;
2878 struct zoran *zr = fh->zr;
2879 int i;
2880 int res = 0;
3143 2881
3144 mutex_lock(&zr->resource_lock); 2882 if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
3145 res = zoran_v4l2_buffer_status(file, buf, buf->index); 2883 return zoran_s_fmt_vid_out(file, fh, fmt);
3146 mutex_unlock(&zr->resource_lock);
3147 2884
3148 return res; 2885 for (i = 0; i < NUM_FORMATS; i++)
2886 if (fmt->fmt.pix.pixelformat == zoran_formats[i].fourcc)
2887 break;
2888 if (i == NUM_FORMATS) {
2889 dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x\n",
2890 ZR_DEVNAME(zr), fmt->fmt.pix.pixelformat);
2891 return -EINVAL;
3149 } 2892 }
3150 break; 2893 mutex_lock(&zr->resource_lock);
3151 2894 if (fh->jpg_buffers.allocated ||
3152 case VIDIOC_QBUF: 2895 (fh->v4l_buffers.allocated && fh->v4l_buffers.active != ZORAN_FREE)) {
3153 { 2896 dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n",
3154 struct v4l2_buffer *buf = arg; 2897 ZR_DEVNAME(zr));
3155 int res = 0, codec_mode, buf_type; 2898 res = -EBUSY;
3156 2899 goto sfmtv4l_unlock_and_return;
3157 dprintk(3, 2900 }
3158 KERN_DEBUG "%s: VIDIOC_QBUF - type=%d, index=%d\n", 2901 if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
3159 ZR_DEVNAME(zr), buf->type, buf->index); 2902 fmt->fmt.pix.height = BUZ_MAX_HEIGHT;
2903 if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
2904 fmt->fmt.pix.width = BUZ_MAX_WIDTH;
2905
2906 res = zoran_v4l_set_format(file, fmt->fmt.pix.width,
2907 fmt->fmt.pix.height, &zoran_formats[i]);
2908 if (res)
2909 goto sfmtv4l_unlock_and_return;
2910
2911 /* tell the user the
2912 * results/missing stuff */
2913 fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline;
2914 fmt->fmt.pix.sizeimage = fh->v4l_settings.height * fh->v4l_settings.bytesperline;
2915 fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace;
2916 if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2))
2917 fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
2918 else
2919 fmt->fmt.pix.field = V4L2_FIELD_TOP;
3160 2920
3161 mutex_lock(&zr->resource_lock); 2921 fh->map_mode = ZORAN_MAP_MODE_RAW;
2922sfmtv4l_unlock_and_return:
2923 mutex_unlock(&zr->resource_lock);
2924 return res;
2925}
3162 2926
3163 switch (fh->map_mode) { 2927static int zoran_g_fbuf(struct file *file, void *__fh,
3164 case ZORAN_MAP_MODE_RAW: 2928 struct v4l2_framebuffer *fb)
3165 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 2929{
3166 dprintk(1, 2930 struct zoran_fh *fh = __fh;
3167 KERN_ERR 2931 struct zoran *zr = fh->zr;
3168 "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
3169 ZR_DEVNAME(zr), buf->type, fh->map_mode);
3170 res = -EINVAL;
3171 goto qbuf_unlock_and_return;
3172 }
3173 2932
3174 res = zoran_v4l_queue_frame(file, buf->index); 2933 memset(fb, 0, sizeof(*fb));
3175 if (res) 2934 mutex_lock(&zr->resource_lock);
3176 goto qbuf_unlock_and_return; 2935 fb->base = zr->buffer.base;
3177 if (!zr->v4l_memgrab_active && 2936 fb->fmt.width = zr->buffer.width;
3178 fh->v4l_buffers.active == ZORAN_LOCKED) 2937 fb->fmt.height = zr->buffer.height;
3179 zr36057_set_memgrab(zr, 1); 2938 if (zr->overlay_settings.format)
3180 break; 2939 fb->fmt.pixelformat = fh->overlay_settings.format->fourcc;
2940 fb->fmt.bytesperline = zr->buffer.bytesperline;
2941 mutex_unlock(&zr->resource_lock);
2942 fb->fmt.colorspace = V4L2_COLORSPACE_SRGB;
2943 fb->fmt.field = V4L2_FIELD_INTERLACED;
2944 fb->flags = V4L2_FBUF_FLAG_OVERLAY;
2945 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
3181 2946
3182 case ZORAN_MAP_MODE_JPG_REC: 2947 return 0;
3183 case ZORAN_MAP_MODE_JPG_PLAY: 2948}
3184 if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
3185 buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
3186 codec_mode = BUZ_MODE_MOTION_DECOMPRESS;
3187 } else {
3188 buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
3189 codec_mode = BUZ_MODE_MOTION_COMPRESS;
3190 }
3191 2949
3192 if (buf->type != buf_type) { 2950static int zoran_s_fbuf(struct file *file, void *__fh,
3193 dprintk(1, 2951 struct v4l2_framebuffer *fb)
3194 KERN_ERR 2952{
3195 "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", 2953 struct zoran_fh *fh = __fh;
3196 ZR_DEVNAME(zr), buf->type, fh->map_mode); 2954 struct zoran *zr = fh->zr;
3197 res = -EINVAL; 2955 int i, res = 0;
3198 goto qbuf_unlock_and_return; 2956 __le32 printformat = __cpu_to_le32(fb->fmt.pixelformat);
3199 }
3200 2957
3201 res = 2958 for (i = 0; i < NUM_FORMATS; i++)
3202 zoran_jpg_queue_frame(file, buf->index, 2959 if (zoran_formats[i].fourcc == fb->fmt.pixelformat)
3203 codec_mode);
3204 if (res != 0)
3205 goto qbuf_unlock_and_return;
3206 if (zr->codec_mode == BUZ_MODE_IDLE &&
3207 fh->jpg_buffers.active == ZORAN_LOCKED) {
3208 zr36057_enable_jpg(zr, codec_mode);
3209 }
3210 break; 2960 break;
3211 2961 if (i == NUM_FORMATS) {
3212 default: 2962 dprintk(1, KERN_ERR "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n",
3213 dprintk(1, 2963 ZR_DEVNAME(zr), fb->fmt.pixelformat,
3214 KERN_ERR 2964 (char *)&printformat);
3215 "%s: VIDIOC_QBUF - unsupported type %d\n", 2965 return -EINVAL;
3216 ZR_DEVNAME(zr), buf->type);
3217 res = -EINVAL;
3218 goto qbuf_unlock_and_return;
3219 }
3220 qbuf_unlock_and_return:
3221 mutex_unlock(&zr->resource_lock);
3222
3223 return res;
3224 } 2966 }
3225 break;
3226
3227 case VIDIOC_DQBUF:
3228 {
3229 struct v4l2_buffer *buf = arg;
3230 int res = 0, buf_type, num = -1; /* compiler borks here (?) */
3231
3232 dprintk(3, KERN_DEBUG "%s: VIDIOC_DQBUF - type=%d\n",
3233 ZR_DEVNAME(zr), buf->type);
3234 2967
3235 mutex_lock(&zr->resource_lock); 2968 mutex_lock(&zr->resource_lock);
2969 res = setup_fbuffer(file, fb->base, &zoran_formats[i],
2970 fb->fmt.width, fb->fmt.height,
2971 fb->fmt.bytesperline);
2972 mutex_unlock(&zr->resource_lock);
3236 2973
3237 switch (fh->map_mode) { 2974 return res;
3238 case ZORAN_MAP_MODE_RAW: 2975}
3239 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
3240 dprintk(1,
3241 KERN_ERR
3242 "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
3243 ZR_DEVNAME(zr), buf->type, fh->map_mode);
3244 res = -EINVAL;
3245 goto dqbuf_unlock_and_return;
3246 }
3247 2976
3248 num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME]; 2977static int zoran_overlay(struct file *file, void *__fh, unsigned int on)
3249 if (file->f_flags & O_NONBLOCK && 2978{
3250 zr->v4l_buffers.buffer[num].state != 2979 struct zoran_fh *fh = __fh;
3251 BUZ_STATE_DONE) { 2980 struct zoran *zr = fh->zr;
3252 res = -EAGAIN; 2981 int res;
3253 goto dqbuf_unlock_and_return;
3254 }
3255 res = v4l_sync(file, num);
3256 if (res)
3257 goto dqbuf_unlock_and_return;
3258 else
3259 zr->v4l_sync_tail++;
3260 res = zoran_v4l2_buffer_status(file, buf, num);
3261 break;
3262 2982
3263 case ZORAN_MAP_MODE_JPG_REC: 2983 mutex_lock(&zr->resource_lock);
3264 case ZORAN_MAP_MODE_JPG_PLAY: 2984 res = setup_overlay(file, on);
3265 { 2985 mutex_unlock(&zr->resource_lock);
3266 struct zoran_sync bs;
3267 2986
3268 if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) 2987 return res;
3269 buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 2988}
3270 else
3271 buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
3272 2989
3273 if (buf->type != buf_type) { 2990static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *req)
3274 dprintk(1, 2991{
3275 KERN_ERR 2992 struct zoran_fh *fh = __fh;
3276 "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", 2993 struct zoran *zr = fh->zr;
3277 ZR_DEVNAME(zr), buf->type, fh->map_mode); 2994 int res = 0;
3278 res = -EINVAL;
3279 goto dqbuf_unlock_and_return;
3280 }
3281 2995
3282 num = 2996 if (req->memory != V4L2_MEMORY_MMAP) {
3283 zr->jpg_pend[zr-> 2997 dprintk(1,
3284 jpg_que_tail & BUZ_MASK_FRAME]; 2998 KERN_ERR
2999 "%s: only MEMORY_MMAP capture is supported, not %d\n",
3000 ZR_DEVNAME(zr), req->memory);
3001 return -EINVAL;
3002 }
3285 3003
3286 if (file->f_flags & O_NONBLOCK && 3004 mutex_lock(&zr->resource_lock);
3287 zr->jpg_buffers.buffer[num].state !=
3288 BUZ_STATE_DONE) {
3289 res = -EAGAIN;
3290 goto dqbuf_unlock_and_return;
3291 }
3292 res = jpg_sync(file, &bs);
3293 if (res)
3294 goto dqbuf_unlock_and_return;
3295 res =
3296 zoran_v4l2_buffer_status(file, buf, bs.frame);
3297 break;
3298 }
3299 3005
3300 default: 3006 if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) {
3301 dprintk(1, 3007 dprintk(1,
3302 KERN_ERR 3008 KERN_ERR
3303 "%s: VIDIOC_DQBUF - unsupported type %d\n", 3009 "%s: VIDIOC_REQBUFS - buffers allready allocated\n",
3304 ZR_DEVNAME(zr), buf->type); 3010 ZR_DEVNAME(zr));
3305 res = -EINVAL; 3011 res = -EBUSY;
3306 goto dqbuf_unlock_and_return; 3012 goto v4l2reqbuf_unlock_and_return;
3307 }
3308 dqbuf_unlock_and_return:
3309 mutex_unlock(&zr->resource_lock);
3310
3311 return res;
3312 } 3013 }
3313 break;
3314 3014
3315 case VIDIOC_STREAMON: 3015 if (fh->map_mode == ZORAN_MAP_MODE_RAW &&
3316 { 3016 req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
3317 int res = 0;
3318
3319 dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMON\n", ZR_DEVNAME(zr));
3320 3017
3321 mutex_lock(&zr->resource_lock); 3018 /* control user input */
3019 if (req->count < 2)
3020 req->count = 2;
3021 if (req->count > v4l_nbufs)
3022 req->count = v4l_nbufs;
3023 fh->v4l_buffers.num_buffers = req->count;
3322 3024
3323 switch (fh->map_mode) { 3025 if (v4l_fbuffer_alloc(file)) {
3324 case ZORAN_MAP_MODE_RAW: /* raw capture */ 3026 res = -ENOMEM;
3325 if (zr->v4l_buffers.active != ZORAN_ACTIVE || 3027 goto v4l2reqbuf_unlock_and_return;
3326 fh->v4l_buffers.active != ZORAN_ACTIVE) { 3028 }
3327 res = -EBUSY;
3328 goto strmon_unlock_and_return;
3329 }
3330 3029
3331 zr->v4l_buffers.active = fh->v4l_buffers.active = 3030 /* The next mmap will map the V4L buffers */
3332 ZORAN_LOCKED; 3031 fh->map_mode = ZORAN_MAP_MODE_RAW;
3333 zr->v4l_settings = fh->v4l_settings;
3334 3032
3335 zr->v4l_sync_tail = zr->v4l_pend_tail; 3033 } else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC ||
3336 if (!zr->v4l_memgrab_active && 3034 fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
3337 zr->v4l_pend_head != zr->v4l_pend_tail) {
3338 zr36057_set_memgrab(zr, 1);
3339 }
3340 break;
3341 3035
3342 case ZORAN_MAP_MODE_JPG_REC: 3036 /* we need to calculate size ourselves now */
3343 case ZORAN_MAP_MODE_JPG_PLAY: 3037 if (req->count < 4)
3344 /* what is the codec mode right now? */ 3038 req->count = 4;
3345 if (zr->jpg_buffers.active != ZORAN_ACTIVE || 3039 if (req->count > jpg_nbufs)
3346 fh->jpg_buffers.active != ZORAN_ACTIVE) { 3040 req->count = jpg_nbufs;
3347 res = -EBUSY; 3041 fh->jpg_buffers.num_buffers = req->count;
3348 goto strmon_unlock_and_return; 3042 fh->jpg_buffers.buffer_size =
3349 } 3043 zoran_v4l2_calc_bufsize(&fh->jpg_settings);
3350 3044
3351 zr->jpg_buffers.active = fh->jpg_buffers.active = 3045 if (jpg_fbuffer_alloc(file)) {
3352 ZORAN_LOCKED; 3046 res = -ENOMEM;
3047 goto v4l2reqbuf_unlock_and_return;
3048 }
3353 3049
3354 if (zr->jpg_que_head != zr->jpg_que_tail) { 3050 /* The next mmap will map the MJPEG buffers */
3355 /* Start the jpeg codec when the first frame is queued */ 3051 if (req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
3356 jpeg_start(zr); 3052 fh->map_mode = ZORAN_MAP_MODE_JPG_REC;
3357 } 3053 else
3054 fh->map_mode = ZORAN_MAP_MODE_JPG_PLAY;
3358 3055
3359 break; 3056 } else {
3360 default: 3057 dprintk(1,
3361 dprintk(1,
3362 KERN_ERR 3058 KERN_ERR
3363 "%s: VIDIOC_STREAMON - invalid map mode %d\n", 3059 "%s: VIDIOC_REQBUFS - unknown type %d\n",
3364 ZR_DEVNAME(zr), fh->map_mode); 3060 ZR_DEVNAME(zr), req->type);
3365 res = -EINVAL; 3061 res = -EINVAL;
3366 goto strmon_unlock_and_return; 3062 goto v4l2reqbuf_unlock_and_return;
3367 }
3368 strmon_unlock_and_return:
3369 mutex_unlock(&zr->resource_lock);
3370
3371 return res;
3372 } 3063 }
3373 break; 3064v4l2reqbuf_unlock_and_return:
3374 3065 mutex_unlock(&zr->resource_lock);
3375 case VIDIOC_STREAMOFF:
3376 {
3377 int i, res = 0;
3378
3379 dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMOFF\n", ZR_DEVNAME(zr));
3380
3381 mutex_lock(&zr->resource_lock);
3382 3066
3383 switch (fh->map_mode) { 3067 return res;
3384 case ZORAN_MAP_MODE_RAW: /* raw capture */ 3068}
3385 if (fh->v4l_buffers.active == ZORAN_FREE &&
3386 zr->v4l_buffers.active != ZORAN_FREE) {
3387 res = -EPERM; /* stay off other's settings! */
3388 goto strmoff_unlock_and_return;
3389 }
3390 if (zr->v4l_buffers.active == ZORAN_FREE)
3391 goto strmoff_unlock_and_return;
3392 3069
3393 /* unload capture */ 3070static int zoran_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
3394 if (zr->v4l_memgrab_active) { 3071{
3395 unsigned long flags; 3072 struct zoran_fh *fh = __fh;
3073 struct zoran *zr = fh->zr;
3074 __u32 type = buf->type;
3075 int index = buf->index, res;
3396 3076
3397 spin_lock_irqsave(&zr->spinlock, flags); 3077 memset(buf, 0, sizeof(*buf));
3398 zr36057_set_memgrab(zr, 0); 3078 buf->type = type;
3399 spin_unlock_irqrestore(&zr->spinlock, flags); 3079 buf->index = index;
3400 }
3401 3080
3402 for (i = 0; i < fh->v4l_buffers.num_buffers; i++) 3081 mutex_lock(&zr->resource_lock);
3403 zr->v4l_buffers.buffer[i].state = 3082 res = zoran_v4l2_buffer_status(file, buf, buf->index);
3404 BUZ_STATE_USER; 3083 mutex_unlock(&zr->resource_lock);
3405 fh->v4l_buffers = zr->v4l_buffers;
3406 3084
3407 zr->v4l_buffers.active = fh->v4l_buffers.active = 3085 return res;
3408 ZORAN_FREE; 3086}
3409 3087
3410 zr->v4l_grab_seq = 0; 3088static int zoran_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
3411 zr->v4l_pend_head = zr->v4l_pend_tail = 0; 3089{
3412 zr->v4l_sync_tail = 0; 3090 struct zoran_fh *fh = __fh;
3091 struct zoran *zr = fh->zr;
3092 int res = 0, codec_mode, buf_type;
3413 3093
3414 break; 3094 mutex_lock(&zr->resource_lock);
3415 3095
3416 case ZORAN_MAP_MODE_JPG_REC: 3096 switch (fh->map_mode) {
3417 case ZORAN_MAP_MODE_JPG_PLAY: 3097 case ZORAN_MAP_MODE_RAW:
3418 if (fh->jpg_buffers.active == ZORAN_FREE && 3098 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
3419 zr->jpg_buffers.active != ZORAN_FREE) { 3099 dprintk(1, KERN_ERR
3420 res = -EPERM; /* stay off other's settings! */ 3100 "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
3421 goto strmoff_unlock_and_return; 3101 ZR_DEVNAME(zr), buf->type, fh->map_mode);
3422 }
3423 if (zr->jpg_buffers.active == ZORAN_FREE)
3424 goto strmoff_unlock_and_return;
3425
3426 res =
3427 jpg_qbuf(file, -1,
3428 (fh->map_mode ==
3429 ZORAN_MAP_MODE_JPG_REC) ?
3430 BUZ_MODE_MOTION_COMPRESS :
3431 BUZ_MODE_MOTION_DECOMPRESS);
3432 if (res)
3433 goto strmoff_unlock_and_return;
3434 break;
3435 default:
3436 dprintk(1,
3437 KERN_ERR
3438 "%s: VIDIOC_STREAMOFF - invalid map mode %d\n",
3439 ZR_DEVNAME(zr), fh->map_mode);
3440 res = -EINVAL; 3102 res = -EINVAL;
3441 goto strmoff_unlock_and_return; 3103 goto qbuf_unlock_and_return;
3442 } 3104 }
3443 strmoff_unlock_and_return:
3444 mutex_unlock(&zr->resource_lock);
3445 3105
3446 return res; 3106 res = zoran_v4l_queue_frame(file, buf->index);
3447 } 3107 if (res)
3108 goto qbuf_unlock_and_return;
3109 if (!zr->v4l_memgrab_active &&
3110 fh->v4l_buffers.active == ZORAN_LOCKED)
3111 zr36057_set_memgrab(zr, 1);
3448 break; 3112 break;
3449 3113
3450 case VIDIOC_QUERYCTRL: 3114 case ZORAN_MAP_MODE_JPG_REC:
3451 { 3115 case ZORAN_MAP_MODE_JPG_PLAY:
3452 struct v4l2_queryctrl *ctrl = arg; 3116 if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
3453 3117 buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
3454 dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCTRL - id=%d\n", 3118 codec_mode = BUZ_MODE_MOTION_DECOMPRESS;
3455 ZR_DEVNAME(zr), ctrl->id); 3119 } else {
3456 3120 buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
3457 /* we only support hue/saturation/contrast/brightness */ 3121 codec_mode = BUZ_MODE_MOTION_COMPRESS;
3458 if (ctrl->id < V4L2_CID_BRIGHTNESS ||
3459 ctrl->id > V4L2_CID_HUE)
3460 return -EINVAL;
3461 else {
3462 int id = ctrl->id;
3463 memset(ctrl, 0, sizeof(*ctrl));
3464 ctrl->id = id;
3465 } 3122 }
3466 3123
3467 switch (ctrl->id) { 3124 if (buf->type != buf_type) {
3468 case V4L2_CID_BRIGHTNESS: 3125 dprintk(1, KERN_ERR
3469 strncpy(ctrl->name, "Brightness", sizeof(ctrl->name)-1); 3126 "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
3470 break; 3127 ZR_DEVNAME(zr), buf->type, fh->map_mode);
3471 case V4L2_CID_CONTRAST: 3128 res = -EINVAL;
3472 strncpy(ctrl->name, "Contrast", sizeof(ctrl->name)-1); 3129 goto qbuf_unlock_and_return;
3473 break;
3474 case V4L2_CID_SATURATION:
3475 strncpy(ctrl->name, "Saturation", sizeof(ctrl->name)-1);
3476 break;
3477 case V4L2_CID_HUE:
3478 strncpy(ctrl->name, "Hue", sizeof(ctrl->name)-1);
3479 break;
3480 } 3130 }
3481 3131
3482 ctrl->minimum = 0; 3132 res = zoran_jpg_queue_frame(file, buf->index,
3483 ctrl->maximum = 65535; 3133 codec_mode);
3484 ctrl->step = 1; 3134 if (res != 0)
3485 ctrl->default_value = 32768; 3135 goto qbuf_unlock_and_return;
3486 ctrl->type = V4L2_CTRL_TYPE_INTEGER; 3136 if (zr->codec_mode == BUZ_MODE_IDLE &&
3487 3137 fh->jpg_buffers.active == ZORAN_LOCKED) {
3488 return 0; 3138 zr36057_enable_jpg(zr, codec_mode);
3489 }
3490 break;
3491
3492 case VIDIOC_G_CTRL:
3493 {
3494 struct v4l2_control *ctrl = arg;
3495
3496 dprintk(3, KERN_DEBUG "%s: VIDIOC_G_CTRL - id=%d\n",
3497 ZR_DEVNAME(zr), ctrl->id);
3498
3499 /* we only support hue/saturation/contrast/brightness */
3500 if (ctrl->id < V4L2_CID_BRIGHTNESS ||
3501 ctrl->id > V4L2_CID_HUE)
3502 return -EINVAL;
3503
3504 mutex_lock(&zr->resource_lock);
3505 switch (ctrl->id) {
3506 case V4L2_CID_BRIGHTNESS:
3507 ctrl->value = zr->brightness;
3508 break;
3509 case V4L2_CID_CONTRAST:
3510 ctrl->value = zr->contrast;
3511 break;
3512 case V4L2_CID_SATURATION:
3513 ctrl->value = zr->saturation;
3514 break;
3515 case V4L2_CID_HUE:
3516 ctrl->value = zr->hue;
3517 break;
3518 } 3139 }
3519 mutex_unlock(&zr->resource_lock); 3140 break;
3520 3141
3521 return 0; 3142 default:
3522 } 3143 dprintk(1, KERN_ERR
3144 "%s: VIDIOC_QBUF - unsupported type %d\n",
3145 ZR_DEVNAME(zr), buf->type);
3146 res = -EINVAL;
3523 break; 3147 break;
3148 }
3149qbuf_unlock_and_return:
3150 mutex_unlock(&zr->resource_lock);
3524 3151
3525 case VIDIOC_S_CTRL: 3152 return res;
3526 { 3153}
3527 struct v4l2_control *ctrl = arg;
3528 struct video_picture pict;
3529 3154
3530 dprintk(3, KERN_DEBUG "%s: VIDIOC_S_CTRL - id=%d\n", 3155static int zoran_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
3531 ZR_DEVNAME(zr), ctrl->id); 3156{
3157 struct zoran_fh *fh = __fh;
3158 struct zoran *zr = fh->zr;
3159 int res = 0, buf_type, num = -1; /* compiler borks here (?) */
3532 3160
3533 /* we only support hue/saturation/contrast/brightness */ 3161 mutex_lock(&zr->resource_lock);
3534 if (ctrl->id < V4L2_CID_BRIGHTNESS ||
3535 ctrl->id > V4L2_CID_HUE)
3536 return -EINVAL;
3537 3162
3538 if (ctrl->value < 0 || ctrl->value > 65535) { 3163 switch (fh->map_mode) {
3539 dprintk(1, 3164 case ZORAN_MAP_MODE_RAW:
3540 KERN_ERR 3165 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
3541 "%s: VIDIOC_S_CTRL - invalid value %d for id=%d\n", 3166 dprintk(1, KERN_ERR
3542 ZR_DEVNAME(zr), ctrl->value, ctrl->id); 3167 "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
3543 return -EINVAL; 3168 ZR_DEVNAME(zr), buf->type, fh->map_mode);
3169 res = -EINVAL;
3170 goto dqbuf_unlock_and_return;
3544 } 3171 }
3545 3172
3546 mutex_lock(&zr->resource_lock); 3173 num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME];
3547 switch (ctrl->id) { 3174 if (file->f_flags & O_NONBLOCK &&
3548 case V4L2_CID_BRIGHTNESS: 3175 zr->v4l_buffers.buffer[num].state != BUZ_STATE_DONE) {
3549 zr->brightness = ctrl->value; 3176 res = -EAGAIN;
3550 break; 3177 goto dqbuf_unlock_and_return;
3551 case V4L2_CID_CONTRAST:
3552 zr->contrast = ctrl->value;
3553 break;
3554 case V4L2_CID_SATURATION:
3555 zr->saturation = ctrl->value;
3556 break;
3557 case V4L2_CID_HUE:
3558 zr->hue = ctrl->value;
3559 break;
3560 } 3178 }
3561 pict.brightness = zr->brightness; 3179 res = v4l_sync(file, num);
3562 pict.contrast = zr->contrast; 3180 if (res)
3563 pict.colour = zr->saturation; 3181 goto dqbuf_unlock_and_return;
3564 pict.hue = zr->hue; 3182 zr->v4l_sync_tail++;
3565 3183 res = zoran_v4l2_buffer_status(file, buf, num);
3566 decoder_command(zr, DECODER_SET_PICTURE, &pict);
3567
3568 mutex_unlock(&zr->resource_lock);
3569
3570 return 0;
3571 }
3572 break; 3184 break;
3573 3185
3574 case VIDIOC_ENUMSTD: 3186 case ZORAN_MAP_MODE_JPG_REC:
3187 case ZORAN_MAP_MODE_JPG_PLAY:
3575 { 3188 {
3576 struct v4l2_standard *std = arg; 3189 struct zoran_sync bs;
3577 3190
3578 dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMSTD - index=%d\n", 3191 if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY)
3579 ZR_DEVNAME(zr), std->index); 3192 buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
3193 else
3194 buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
3580 3195
3581 if (std->index < 0 || std->index >= (zr->card.norms + 1)) 3196 if (buf->type != buf_type) {
3582 return -EINVAL; 3197 dprintk(1, KERN_ERR
3583 else { 3198 "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
3584 int id = std->index; 3199 ZR_DEVNAME(zr), buf->type, fh->map_mode);
3585 memset(std, 0, sizeof(*std)); 3200 res = -EINVAL;
3586 std->index = id; 3201 goto dqbuf_unlock_and_return;
3587 } 3202 }
3588 3203
3589 if (std->index == zr->card.norms) { 3204 num = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME];
3590 /* if we have autodetect, ... */
3591 struct video_decoder_capability caps;
3592 decoder_command(zr, DECODER_GET_CAPABILITIES,
3593 &caps);
3594 if (caps.flags & VIDEO_DECODER_AUTO) {
3595 std->id = V4L2_STD_ALL;
3596 strncpy(std->name, "Autodetect", sizeof(std->name)-1);
3597 return 0;
3598 } else
3599 return -EINVAL;
3600 }
3601 switch (std->index) {
3602 case 0:
3603 std->id = V4L2_STD_PAL;
3604 strncpy(std->name, "PAL", sizeof(std->name)-1);
3605 std->frameperiod.numerator = 1;
3606 std->frameperiod.denominator = 25;
3607 std->framelines = zr->card.tvn[0]->Ht;
3608 break;
3609 case 1:
3610 std->id = V4L2_STD_NTSC;
3611 strncpy(std->name, "NTSC", sizeof(std->name)-1);
3612 std->frameperiod.numerator = 1001;
3613 std->frameperiod.denominator = 30000;
3614 std->framelines = zr->card.tvn[1]->Ht;
3615 break;
3616 case 2:
3617 std->id = V4L2_STD_SECAM;
3618 strncpy(std->name, "SECAM", sizeof(std->name)-1);
3619 std->frameperiod.numerator = 1;
3620 std->frameperiod.denominator = 25;
3621 std->framelines = zr->card.tvn[2]->Ht;
3622 break;
3623 }
3624 3205
3625 return 0; 3206 if (file->f_flags & O_NONBLOCK &&
3207 zr->jpg_buffers.buffer[num].state != BUZ_STATE_DONE) {
3208 res = -EAGAIN;
3209 goto dqbuf_unlock_and_return;
3210 }
3211 res = jpg_sync(file, &bs);
3212 if (res)
3213 goto dqbuf_unlock_and_return;
3214 res = zoran_v4l2_buffer_status(file, buf, bs.frame);
3215 break;
3626 } 3216 }
3217
3218 default:
3219 dprintk(1, KERN_ERR
3220 "%s: VIDIOC_DQBUF - unsupported type %d\n",
3221 ZR_DEVNAME(zr), buf->type);
3222 res = -EINVAL;
3627 break; 3223 break;
3224 }
3225dqbuf_unlock_and_return:
3226 mutex_unlock(&zr->resource_lock);
3628 3227
3629 case VIDIOC_G_STD: 3228 return res;
3630 { 3229}
3631 v4l2_std_id *std = arg;
3632 int norm;
3633 3230
3634 dprintk(3, KERN_DEBUG "%s: VIDIOC_G_STD\n", ZR_DEVNAME(zr)); 3231static int zoran_streamon(struct file *file, void *__fh, enum v4l2_buf_type type)
3232{
3233 struct zoran_fh *fh = __fh;
3234 struct zoran *zr = fh->zr;
3235 int res = 0;
3635 3236
3636 mutex_lock(&zr->resource_lock); 3237 mutex_lock(&zr->resource_lock);
3637 norm = zr->norm;
3638 mutex_unlock(&zr->resource_lock);
3639 3238
3640 switch (norm) { 3239 switch (fh->map_mode) {
3641 case VIDEO_MODE_PAL: 3240 case ZORAN_MAP_MODE_RAW: /* raw capture */
3642 *std = V4L2_STD_PAL; 3241 if (zr->v4l_buffers.active != ZORAN_ACTIVE ||
3643 break; 3242 fh->v4l_buffers.active != ZORAN_ACTIVE) {
3644 case VIDEO_MODE_NTSC: 3243 res = -EBUSY;
3645 *std = V4L2_STD_NTSC; 3244 goto strmon_unlock_and_return;
3646 break;
3647 case VIDEO_MODE_SECAM:
3648 *std = V4L2_STD_SECAM;
3649 break;
3650 } 3245 }
3651 3246
3652 return 0; 3247 zr->v4l_buffers.active = fh->v4l_buffers.active = ZORAN_LOCKED;
3653 } 3248 zr->v4l_settings = fh->v4l_settings;
3249
3250 zr->v4l_sync_tail = zr->v4l_pend_tail;
3251 if (!zr->v4l_memgrab_active &&
3252 zr->v4l_pend_head != zr->v4l_pend_tail) {
3253 zr36057_set_memgrab(zr, 1);
3254 }
3654 break; 3255 break;
3655 3256
3656 case VIDIOC_S_STD: 3257 case ZORAN_MAP_MODE_JPG_REC:
3657 { 3258 case ZORAN_MAP_MODE_JPG_PLAY:
3658 int norm = -1, res = 0; 3259 /* what is the codec mode right now? */
3659 v4l2_std_id *std = arg; 3260 if (zr->jpg_buffers.active != ZORAN_ACTIVE ||
3261 fh->jpg_buffers.active != ZORAN_ACTIVE) {
3262 res = -EBUSY;
3263 goto strmon_unlock_and_return;
3264 }
3660 3265
3661 dprintk(3, KERN_DEBUG "%s: VIDIOC_S_STD - norm=0x%llx\n", 3266 zr->jpg_buffers.active = fh->jpg_buffers.active = ZORAN_LOCKED;
3662 ZR_DEVNAME(zr), (unsigned long long)*std);
3663 3267
3664 if ((*std & V4L2_STD_PAL) && !(*std & ~V4L2_STD_PAL)) 3268 if (zr->jpg_que_head != zr->jpg_que_tail) {
3665 norm = VIDEO_MODE_PAL; 3269 /* Start the jpeg codec when the first frame is queued */
3666 else if ((*std & V4L2_STD_NTSC) && !(*std & ~V4L2_STD_NTSC)) 3270 jpeg_start(zr);
3667 norm = VIDEO_MODE_NTSC;
3668 else if ((*std & V4L2_STD_SECAM) && !(*std & ~V4L2_STD_SECAM))
3669 norm = VIDEO_MODE_SECAM;
3670 else if (*std == V4L2_STD_ALL)
3671 norm = VIDEO_MODE_AUTO;
3672 else {
3673 dprintk(1,
3674 KERN_ERR
3675 "%s: VIDIOC_S_STD - invalid norm 0x%llx\n",
3676 ZR_DEVNAME(zr), (unsigned long long)*std);
3677 return -EINVAL;
3678 } 3271 }
3272 break;
3679 3273
3680 mutex_lock(&zr->resource_lock); 3274 default:
3681 if ((res = zoran_set_norm(zr, norm))) 3275 dprintk(1,
3682 goto sstd_unlock_and_return; 3276 KERN_ERR
3683 3277 "%s: VIDIOC_STREAMON - invalid map mode %d\n",
3684 res = wait_grab_pending(zr); 3278 ZR_DEVNAME(zr), fh->map_mode);
3685 sstd_unlock_and_return: 3279 res = -EINVAL;
3686 mutex_unlock(&zr->resource_lock);
3687 return res;
3688 }
3689 break; 3280 break;
3281 }
3282strmon_unlock_and_return:
3283 mutex_unlock(&zr->resource_lock);
3690 3284
3691 case VIDIOC_ENUMINPUT: 3285 return res;
3692 { 3286}
3693 struct v4l2_input *inp = arg;
3694 int status;
3695 3287
3696 dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMINPUT - index=%d\n", 3288static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type)
3697 ZR_DEVNAME(zr), inp->index); 3289{
3290 struct zoran_fh *fh = __fh;
3291 struct zoran *zr = fh->zr;
3292 int i, res = 0;
3698 3293
3699 if (inp->index < 0 || inp->index >= zr->card.inputs) 3294 mutex_lock(&zr->resource_lock);
3700 return -EINVAL;
3701 else {
3702 int id = inp->index;
3703 memset(inp, 0, sizeof(*inp));
3704 inp->index = id;
3705 }
3706 3295
3707 strncpy(inp->name, zr->card.input[inp->index].name, 3296 switch (fh->map_mode) {
3708 sizeof(inp->name) - 1); 3297 case ZORAN_MAP_MODE_RAW: /* raw capture */
3709 inp->type = V4L2_INPUT_TYPE_CAMERA; 3298 if (fh->v4l_buffers.active == ZORAN_FREE &&
3710 inp->std = V4L2_STD_ALL; 3299 zr->v4l_buffers.active != ZORAN_FREE) {
3300 res = -EPERM; /* stay off other's settings! */
3301 goto strmoff_unlock_and_return;
3302 }
3303 if (zr->v4l_buffers.active == ZORAN_FREE)
3304 goto strmoff_unlock_and_return;
3711 3305
3712 /* Get status of video decoder */ 3306 /* unload capture */
3713 mutex_lock(&zr->resource_lock); 3307 if (zr->v4l_memgrab_active) {
3714 decoder_command(zr, DECODER_GET_STATUS, &status); 3308 unsigned long flags;
3715 mutex_unlock(&zr->resource_lock);
3716 3309
3717 if (!(status & DECODER_STATUS_GOOD)) { 3310 spin_lock_irqsave(&zr->spinlock, flags);
3718 inp->status |= V4L2_IN_ST_NO_POWER; 3311 zr36057_set_memgrab(zr, 0);
3719 inp->status |= V4L2_IN_ST_NO_SIGNAL; 3312 spin_unlock_irqrestore(&zr->spinlock, flags);
3720 } 3313 }
3721 if (!(status & DECODER_STATUS_COLOR))
3722 inp->status |= V4L2_IN_ST_NO_COLOR;
3723
3724 return 0;
3725 }
3726 break;
3727 3314
3728 case VIDIOC_G_INPUT: 3315 for (i = 0; i < fh->v4l_buffers.num_buffers; i++)
3729 { 3316 zr->v4l_buffers.buffer[i].state = BUZ_STATE_USER;
3730 int *input = arg; 3317 fh->v4l_buffers = zr->v4l_buffers;
3731 3318
3732 dprintk(3, KERN_DEBUG "%s: VIDIOC_G_INPUT\n", ZR_DEVNAME(zr)); 3319 zr->v4l_buffers.active = fh->v4l_buffers.active = ZORAN_FREE;
3733 3320
3734 mutex_lock(&zr->resource_lock); 3321 zr->v4l_grab_seq = 0;
3735 *input = zr->input; 3322 zr->v4l_pend_head = zr->v4l_pend_tail = 0;
3736 mutex_unlock(&zr->resource_lock); 3323 zr->v4l_sync_tail = 0;
3737 3324
3738 return 0;
3739 }
3740 break; 3325 break;
3741 3326
3742 case VIDIOC_S_INPUT: 3327 case ZORAN_MAP_MODE_JPG_REC:
3743 { 3328 case ZORAN_MAP_MODE_JPG_PLAY:
3744 int *input = arg, res = 0; 3329 if (fh->jpg_buffers.active == ZORAN_FREE &&
3330 zr->jpg_buffers.active != ZORAN_FREE) {
3331 res = -EPERM; /* stay off other's settings! */
3332 goto strmoff_unlock_and_return;
3333 }
3334 if (zr->jpg_buffers.active == ZORAN_FREE)
3335 goto strmoff_unlock_and_return;
3745 3336
3746 dprintk(3, KERN_DEBUG "%s: VIDIOC_S_INPUT - input=%d\n", 3337 res = jpg_qbuf(file, -1,
3747 ZR_DEVNAME(zr), *input); 3338 (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ?
3339 BUZ_MODE_MOTION_COMPRESS :
3340 BUZ_MODE_MOTION_DECOMPRESS);
3341 if (res)
3342 goto strmoff_unlock_and_return;
3343 break;
3344 default:
3345 dprintk(1, KERN_ERR
3346 "%s: VIDIOC_STREAMOFF - invalid map mode %d\n",
3347 ZR_DEVNAME(zr), fh->map_mode);
3348 res = -EINVAL;
3349 break;
3350 }
3351strmoff_unlock_and_return:
3352 mutex_unlock(&zr->resource_lock);
3748 3353
3749 mutex_lock(&zr->resource_lock); 3354 return res;
3750 if ((res = zoran_set_input(zr, *input))) 3355}
3751 goto sinput_unlock_and_return;
3752 3356
3753 /* Make sure the changes come into effect */ 3357static int zoran_queryctrl(struct file *file, void *__fh,
3754 res = wait_grab_pending(zr); 3358 struct v4l2_queryctrl *ctrl)
3755 sinput_unlock_and_return: 3359{
3756 mutex_unlock(&zr->resource_lock); 3360 /* we only support hue/saturation/contrast/brightness */
3757 return res; 3361 if (ctrl->id < V4L2_CID_BRIGHTNESS ||
3362 ctrl->id > V4L2_CID_HUE)
3363 return -EINVAL;
3364 else {
3365 int id = ctrl->id;
3366 memset(ctrl, 0, sizeof(*ctrl));
3367 ctrl->id = id;
3758 } 3368 }
3369
3370 switch (ctrl->id) {
3371 case V4L2_CID_BRIGHTNESS:
3372 strncpy(ctrl->name, "Brightness", sizeof(ctrl->name)-1);
3373 break;
3374 case V4L2_CID_CONTRAST:
3375 strncpy(ctrl->name, "Contrast", sizeof(ctrl->name)-1);
3376 break;
3377 case V4L2_CID_SATURATION:
3378 strncpy(ctrl->name, "Saturation", sizeof(ctrl->name)-1);
3759 break; 3379 break;
3380 case V4L2_CID_HUE:
3381 strncpy(ctrl->name, "Hue", sizeof(ctrl->name)-1);
3382 break;
3383 }
3760 3384
3761 case VIDIOC_ENUMOUTPUT: 3385 ctrl->minimum = 0;
3762 { 3386 ctrl->maximum = 65535;
3763 struct v4l2_output *outp = arg; 3387 ctrl->step = 1;
3388 ctrl->default_value = 32768;
3389 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
3764 3390
3765 dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMOUTPUT - index=%d\n", 3391 return 0;
3766 ZR_DEVNAME(zr), outp->index); 3392}
3767 3393
3768 if (outp->index != 0) 3394static int zoran_g_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl)
3769 return -EINVAL; 3395{
3396 struct zoran_fh *fh = __fh;
3397 struct zoran *zr = fh->zr;
3770 3398
3771 memset(outp, 0, sizeof(*outp)); 3399 /* we only support hue/saturation/contrast/brightness */
3772 outp->index = 0; 3400 if (ctrl->id < V4L2_CID_BRIGHTNESS ||
3773 outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY; 3401 ctrl->id > V4L2_CID_HUE)
3774 strncpy(outp->name, "Autodetect", sizeof(outp->name)-1); 3402 return -EINVAL;
3775 3403
3776 return 0; 3404 mutex_lock(&zr->resource_lock);
3777 } 3405 switch (ctrl->id) {
3406 case V4L2_CID_BRIGHTNESS:
3407 ctrl->value = zr->brightness;
3408 break;
3409 case V4L2_CID_CONTRAST:
3410 ctrl->value = zr->contrast;
3411 break;
3412 case V4L2_CID_SATURATION:
3413 ctrl->value = zr->saturation;
3778 break; 3414 break;
3415 case V4L2_CID_HUE:
3416 ctrl->value = zr->hue;
3417 break;
3418 }
3419 mutex_unlock(&zr->resource_lock);
3779 3420
3780 case VIDIOC_G_OUTPUT: 3421 return 0;
3781 { 3422}
3782 int *output = arg;
3783 3423
3784 dprintk(3, KERN_DEBUG "%s: VIDIOC_G_OUTPUT\n", ZR_DEVNAME(zr)); 3424static int zoran_s_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl)
3425{
3426 struct zoran_fh *fh = __fh;
3427 struct zoran *zr = fh->zr;
3428 struct video_picture pict;
3785 3429
3786 *output = 0; 3430 /* we only support hue/saturation/contrast/brightness */
3431 if (ctrl->id < V4L2_CID_BRIGHTNESS ||
3432 ctrl->id > V4L2_CID_HUE)
3433 return -EINVAL;
3787 3434
3788 return 0; 3435 if (ctrl->value < 0 || ctrl->value > 65535) {
3436 dprintk(1, KERN_ERR
3437 "%s: VIDIOC_S_CTRL - invalid value %d for id=%d\n",
3438 ZR_DEVNAME(zr), ctrl->value, ctrl->id);
3439 return -EINVAL;
3789 } 3440 }
3441
3442 mutex_lock(&zr->resource_lock);
3443 switch (ctrl->id) {
3444 case V4L2_CID_BRIGHTNESS:
3445 zr->brightness = ctrl->value;
3446 break;
3447 case V4L2_CID_CONTRAST:
3448 zr->contrast = ctrl->value;
3449 break;
3450 case V4L2_CID_SATURATION:
3451 zr->saturation = ctrl->value;
3790 break; 3452 break;
3453 case V4L2_CID_HUE:
3454 zr->hue = ctrl->value;
3455 break;
3456 }
3457 pict.brightness = zr->brightness;
3458 pict.contrast = zr->contrast;
3459 pict.colour = zr->saturation;
3460 pict.hue = zr->hue;
3791 3461
3792 case VIDIOC_S_OUTPUT: 3462 decoder_command(zr, DECODER_SET_PICTURE, &pict);
3793 {
3794 int *output = arg;
3795 3463
3796 dprintk(3, KERN_DEBUG "%s: VIDIOC_S_OUTPUT - output=%d\n", 3464 mutex_unlock(&zr->resource_lock);
3797 ZR_DEVNAME(zr), *output);
3798 3465
3799 if (*output != 0) 3466 return 0;
3800 return -EINVAL; 3467}
3801 3468
3802 return 0; 3469static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std)
3803 } 3470{
3471 struct zoran_fh *fh = __fh;
3472 struct zoran *zr = fh->zr;
3473 int norm;
3474
3475 mutex_lock(&zr->resource_lock);
3476 norm = zr->norm;
3477 mutex_unlock(&zr->resource_lock);
3478
3479 switch (norm) {
3480 case VIDEO_MODE_PAL:
3481 *std = V4L2_STD_PAL;
3482 break;
3483 case VIDEO_MODE_NTSC:
3484 *std = V4L2_STD_NTSC;
3485 break;
3486 case VIDEO_MODE_SECAM:
3487 *std = V4L2_STD_SECAM;
3804 break; 3488 break;
3489 }
3805 3490
3806 /* cropping (sub-frame capture) */ 3491 return 0;
3807 case VIDIOC_CROPCAP: 3492}
3808 {
3809 struct v4l2_cropcap *cropcap = arg;
3810 int type = cropcap->type, res = 0;
3811 3493
3812 dprintk(3, KERN_ERR "%s: VIDIOC_CROPCAP - type=%d\n", 3494static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id *std)
3813 ZR_DEVNAME(zr), cropcap->type); 3495{
3496 struct zoran_fh *fh = __fh;
3497 struct zoran *zr = fh->zr;
3498 int norm = -1, res = 0;
3499
3500 if ((*std & V4L2_STD_PAL) && !(*std & ~V4L2_STD_PAL))
3501 norm = VIDEO_MODE_PAL;
3502 else if ((*std & V4L2_STD_NTSC) && !(*std & ~V4L2_STD_NTSC))
3503 norm = VIDEO_MODE_NTSC;
3504 else if ((*std & V4L2_STD_SECAM) && !(*std & ~V4L2_STD_SECAM))
3505 norm = VIDEO_MODE_SECAM;
3506 else if (*std == V4L2_STD_ALL)
3507 norm = VIDEO_MODE_AUTO;
3508 else {
3509 dprintk(1, KERN_ERR
3510 "%s: VIDIOC_S_STD - invalid norm 0x%llx\n",
3511 ZR_DEVNAME(zr), (unsigned long long)*std);
3512 return -EINVAL;
3513 }
3814 3514
3815 memset(cropcap, 0, sizeof(*cropcap)); 3515 mutex_lock(&zr->resource_lock);
3816 cropcap->type = type; 3516 res = zoran_set_norm(zr, norm);
3517 if (res)
3518 goto sstd_unlock_and_return;
3817 3519
3818 mutex_lock(&zr->resource_lock); 3520 res = wait_grab_pending(zr);
3521sstd_unlock_and_return:
3522 mutex_unlock(&zr->resource_lock);
3523 return res;
3524}
3819 3525
3820 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && 3526static int zoran_enum_input(struct file *file, void *__fh,
3821 (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 3527 struct v4l2_input *inp)
3822 fh->map_mode == ZORAN_MAP_MODE_RAW)) { 3528{
3823 dprintk(1, 3529 struct zoran_fh *fh = __fh;
3824 KERN_ERR 3530 struct zoran *zr = fh->zr;
3825 "%s: VIDIOC_CROPCAP - subcapture only supported for compressed capture\n", 3531 int status;
3826 ZR_DEVNAME(zr));
3827 res = -EINVAL;
3828 goto cropcap_unlock_and_return;
3829 }
3830 3532
3831 cropcap->bounds.top = cropcap->bounds.left = 0; 3533 if (inp->index < 0 || inp->index >= zr->card.inputs)
3832 cropcap->bounds.width = BUZ_MAX_WIDTH; 3534 return -EINVAL;
3833 cropcap->bounds.height = BUZ_MAX_HEIGHT; 3535 else {
3834 cropcap->defrect.top = cropcap->defrect.left = 0; 3536 int id = inp->index;
3835 cropcap->defrect.width = BUZ_MIN_WIDTH; 3537 memset(inp, 0, sizeof(*inp));
3836 cropcap->defrect.height = BUZ_MIN_HEIGHT; 3538 inp->index = id;
3837 cropcap_unlock_and_return:
3838 mutex_unlock(&zr->resource_lock);
3839 return res;
3840 } 3539 }
3841 break;
3842 3540
3843 case VIDIOC_G_CROP: 3541 strncpy(inp->name, zr->card.input[inp->index].name,
3844 { 3542 sizeof(inp->name) - 1);
3845 struct v4l2_crop *crop = arg; 3543 inp->type = V4L2_INPUT_TYPE_CAMERA;
3846 int type = crop->type, res = 0; 3544 inp->std = V4L2_STD_ALL;
3847 3545
3848 dprintk(3, KERN_ERR "%s: VIDIOC_G_CROP - type=%d\n", 3546 /* Get status of video decoder */
3849 ZR_DEVNAME(zr), crop->type); 3547 mutex_lock(&zr->resource_lock);
3548 decoder_command(zr, DECODER_GET_STATUS, &status);
3549 mutex_unlock(&zr->resource_lock);
3850 3550
3851 memset(crop, 0, sizeof(*crop)); 3551 if (!(status & DECODER_STATUS_GOOD)) {
3852 crop->type = type; 3552 inp->status |= V4L2_IN_ST_NO_POWER;
3553 inp->status |= V4L2_IN_ST_NO_SIGNAL;
3554 }
3555 if (!(status & DECODER_STATUS_COLOR))
3556 inp->status |= V4L2_IN_ST_NO_COLOR;
3853 3557
3854 mutex_lock(&zr->resource_lock); 3558 return 0;
3559}
3855 3560
3856 if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && 3561static int zoran_g_input(struct file *file, void *__fh, unsigned int *input)
3857 (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 3562{
3858 fh->map_mode == ZORAN_MAP_MODE_RAW)) { 3563 struct zoran_fh *fh = __fh;
3859 dprintk(1, 3564 struct zoran *zr = fh->zr;
3860 KERN_ERR
3861 "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
3862 ZR_DEVNAME(zr));
3863 res = -EINVAL;
3864 goto gcrop_unlock_and_return;
3865 }
3866 3565
3867 crop->c.top = fh->jpg_settings.img_y; 3566 mutex_lock(&zr->resource_lock);
3868 crop->c.left = fh->jpg_settings.img_x; 3567 *input = zr->input;
3869 crop->c.width = fh->jpg_settings.img_width; 3568 mutex_unlock(&zr->resource_lock);
3870 crop->c.height = fh->jpg_settings.img_height;
3871 3569
3872 gcrop_unlock_and_return: 3570 return 0;
3873 mutex_unlock(&zr->resource_lock); 3571}
3874 3572
3875 return res; 3573static int zoran_s_input(struct file *file, void *__fh, unsigned int input)
3876 } 3574{
3877 break; 3575 struct zoran_fh *fh = __fh;
3576 struct zoran *zr = fh->zr;
3577 int res;
3878 3578
3879 case VIDIOC_S_CROP: 3579 mutex_lock(&zr->resource_lock);
3880 { 3580 res = zoran_set_input(zr, input);
3881 struct v4l2_crop *crop = arg; 3581 if (res)
3882 int res = 0; 3582 goto sinput_unlock_and_return;
3883 3583
3884 settings = fh->jpg_settings; 3584 /* Make sure the changes come into effect */
3585 res = wait_grab_pending(zr);
3586sinput_unlock_and_return:
3587 mutex_unlock(&zr->resource_lock);
3588 return res;
3589}
3885 3590
3886 dprintk(3, 3591static int zoran_enum_output(struct file *file, void *__fh,
3887 KERN_ERR 3592 struct v4l2_output *outp)
3888 "%s: VIDIOC_S_CROP - type=%d, x=%d,y=%d,w=%d,h=%d\n", 3593{
3889 ZR_DEVNAME(zr), crop->type, crop->c.left, crop->c.top, 3594 if (outp->index != 0)
3890 crop->c.width, crop->c.height); 3595 return -EINVAL;
3891 3596
3892 mutex_lock(&zr->resource_lock); 3597 memset(outp, 0, sizeof(*outp));
3598 outp->index = 0;
3599 outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY;
3600 strncpy(outp->name, "Autodetect", sizeof(outp->name)-1);
3893 3601
3894 if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { 3602 return 0;
3895 dprintk(1, 3603}
3896 KERN_ERR
3897 "%s: VIDIOC_S_CROP - cannot change settings while active\n",
3898 ZR_DEVNAME(zr));
3899 res = -EBUSY;
3900 goto scrop_unlock_and_return;
3901 }
3902 3604
3903 if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && 3605static int zoran_g_output(struct file *file, void *__fh, unsigned int *output)
3904 (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 3606{
3905 fh->map_mode == ZORAN_MAP_MODE_RAW)) { 3607 *output = 0;
3906 dprintk(1, 3608
3907 KERN_ERR 3609 return 0;
3908 "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n", 3610}
3909 ZR_DEVNAME(zr));
3910 res = -EINVAL;
3911 goto scrop_unlock_and_return;
3912 }
3913 3611
3914 /* move into a form that we understand */ 3612static int zoran_s_output(struct file *file, void *__fh, unsigned int output)
3915 settings.img_x = crop->c.left; 3613{
3916 settings.img_y = crop->c.top; 3614 if (output != 0)
3917 settings.img_width = crop->c.width; 3615 return -EINVAL;
3918 settings.img_height = crop->c.height;
3919 3616
3920 /* check validity */ 3617 return 0;
3921 if ((res = zoran_check_jpg_settings(zr, &settings))) 3618}
3922 goto scrop_unlock_and_return;
3923 3619
3924 /* accept */ 3620/* cropping (sub-frame capture) */
3925 fh->jpg_settings = settings; 3621static int zoran_cropcap(struct file *file, void *__fh,
3622 struct v4l2_cropcap *cropcap)
3623{
3624 struct zoran_fh *fh = __fh;
3625 struct zoran *zr = fh->zr;
3626 int type = cropcap->type, res = 0;
3926 3627
3927 scrop_unlock_and_return: 3628 memset(cropcap, 0, sizeof(*cropcap));
3928 mutex_unlock(&zr->resource_lock); 3629 cropcap->type = type;
3929 return res;
3930 }
3931 break;
3932 3630
3933 case VIDIOC_G_JPEGCOMP: 3631 mutex_lock(&zr->resource_lock);
3934 {
3935 struct v4l2_jpegcompression *params = arg;
3936 3632
3937 dprintk(3, KERN_DEBUG "%s: VIDIOC_G_JPEGCOMP\n", 3633 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
3634 (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
3635 fh->map_mode == ZORAN_MAP_MODE_RAW)) {
3636 dprintk(1, KERN_ERR
3637 "%s: VIDIOC_CROPCAP - subcapture only supported for compressed capture\n",
3938 ZR_DEVNAME(zr)); 3638 ZR_DEVNAME(zr));
3639 res = -EINVAL;
3640 goto cropcap_unlock_and_return;
3641 }
3939 3642
3940 memset(params, 0, sizeof(*params)); 3643 cropcap->bounds.top = cropcap->bounds.left = 0;
3644 cropcap->bounds.width = BUZ_MAX_WIDTH;
3645 cropcap->bounds.height = BUZ_MAX_HEIGHT;
3646 cropcap->defrect.top = cropcap->defrect.left = 0;
3647 cropcap->defrect.width = BUZ_MIN_WIDTH;
3648 cropcap->defrect.height = BUZ_MIN_HEIGHT;
3649cropcap_unlock_and_return:
3650 mutex_unlock(&zr->resource_lock);
3651 return res;
3652}
3941 3653
3942 mutex_lock(&zr->resource_lock); 3654static int zoran_g_crop(struct file *file, void *__fh, struct v4l2_crop *crop)
3655{
3656 struct zoran_fh *fh = __fh;
3657 struct zoran *zr = fh->zr;
3658 int type = crop->type, res = 0;
3943 3659
3944 params->quality = fh->jpg_settings.jpg_comp.quality; 3660 memset(crop, 0, sizeof(*crop));
3945 params->APPn = fh->jpg_settings.jpg_comp.APPn; 3661 crop->type = type;
3946 memcpy(params->APP_data,
3947 fh->jpg_settings.jpg_comp.APP_data,
3948 fh->jpg_settings.jpg_comp.APP_len);
3949 params->APP_len = fh->jpg_settings.jpg_comp.APP_len;
3950 memcpy(params->COM_data,
3951 fh->jpg_settings.jpg_comp.COM_data,
3952 fh->jpg_settings.jpg_comp.COM_len);
3953 params->COM_len = fh->jpg_settings.jpg_comp.COM_len;
3954 params->jpeg_markers =
3955 fh->jpg_settings.jpg_comp.jpeg_markers;
3956 3662
3957 mutex_unlock(&zr->resource_lock); 3663 mutex_lock(&zr->resource_lock);
3958 3664
3959 return 0; 3665 if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
3666 (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
3667 fh->map_mode == ZORAN_MAP_MODE_RAW)) {
3668 dprintk(1,
3669 KERN_ERR
3670 "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
3671 ZR_DEVNAME(zr));
3672 res = -EINVAL;
3673 goto gcrop_unlock_and_return;
3960 } 3674 }
3961 break;
3962
3963 case VIDIOC_S_JPEGCOMP:
3964 {
3965 struct v4l2_jpegcompression *params = arg;
3966 int res = 0;
3967 3675
3968 settings = fh->jpg_settings; 3676 crop->c.top = fh->jpg_settings.img_y;
3677 crop->c.left = fh->jpg_settings.img_x;
3678 crop->c.width = fh->jpg_settings.img_width;
3679 crop->c.height = fh->jpg_settings.img_height;
3969 3680
3970 dprintk(3, 3681gcrop_unlock_and_return:
3971 KERN_DEBUG 3682 mutex_unlock(&zr->resource_lock);
3972 "%s: VIDIOC_S_JPEGCOMP - quality=%d, APPN=%d, APP_len=%d, COM_len=%d\n",
3973 ZR_DEVNAME(zr), params->quality, params->APPn,
3974 params->APP_len, params->COM_len);
3975 3683
3976 settings.jpg_comp = *params; 3684 return res;
3685}
3977 3686
3978 mutex_lock(&zr->resource_lock); 3687static int zoran_s_crop(struct file *file, void *__fh, struct v4l2_crop *crop)
3688{
3689 struct zoran_fh *fh = __fh;
3690 struct zoran *zr = fh->zr;
3691 int res = 0;
3692 struct zoran_jpg_settings settings;
3979 3693
3980 if (fh->v4l_buffers.active != ZORAN_FREE || 3694 settings = fh->jpg_settings;
3981 fh->jpg_buffers.active != ZORAN_FREE) {
3982 dprintk(1,
3983 KERN_WARNING
3984 "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n",
3985 ZR_DEVNAME(zr));
3986 res = -EBUSY;
3987 goto sjpegc_unlock_and_return;
3988 }
3989 3695
3990 if ((res = zoran_check_jpg_settings(zr, &settings))) 3696 mutex_lock(&zr->resource_lock);
3991 goto sjpegc_unlock_and_return;
3992 if (!fh->jpg_buffers.allocated)
3993 fh->jpg_buffers.buffer_size =
3994 zoran_v4l2_calc_bufsize(&fh->jpg_settings);
3995 fh->jpg_settings.jpg_comp = *params = settings.jpg_comp;
3996 sjpegc_unlock_and_return:
3997 mutex_unlock(&zr->resource_lock);
3998 3697
3999 return 0; 3698 if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) {
3699 dprintk(1, KERN_ERR
3700 "%s: VIDIOC_S_CROP - cannot change settings while active\n",
3701 ZR_DEVNAME(zr));
3702 res = -EBUSY;
3703 goto scrop_unlock_and_return;
4000 } 3704 }
4001 break;
4002 3705
4003 case VIDIOC_QUERYSTD: /* why is this useful? */ 3706 if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
4004 { 3707 (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
4005 v4l2_std_id *std = arg; 3708 fh->map_mode == ZORAN_MAP_MODE_RAW)) {
3709 dprintk(1, KERN_ERR
3710 "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
3711 ZR_DEVNAME(zr));
3712 res = -EINVAL;
3713 goto scrop_unlock_and_return;
3714 }
4006 3715
4007 dprintk(3, 3716 /* move into a form that we understand */
4008 KERN_DEBUG "%s: VIDIOC_QUERY_STD - std=0x%llx\n", 3717 settings.img_x = crop->c.left;
4009 ZR_DEVNAME(zr), (unsigned long long)*std); 3718 settings.img_y = crop->c.top;
3719 settings.img_width = crop->c.width;
3720 settings.img_height = crop->c.height;
4010 3721
4011 if (*std == V4L2_STD_ALL || *std == V4L2_STD_NTSC || 3722 /* check validity */
4012 *std == V4L2_STD_PAL || (*std == V4L2_STD_SECAM && 3723 res = zoran_check_jpg_settings(zr, &settings);
4013 zr->card.norms == 3)) { 3724 if (res)
4014 return 0; 3725 goto scrop_unlock_and_return;
4015 }
4016 3726
4017 return -EINVAL; 3727 /* accept */
4018 } 3728 fh->jpg_settings = settings;
4019 break;
4020 3729
4021 case VIDIOC_TRY_FMT: 3730scrop_unlock_and_return:
4022 { 3731 mutex_unlock(&zr->resource_lock);
4023 struct v4l2_format *fmt = arg; 3732 return res;
4024 int res = 0; 3733}
4025 3734
4026 dprintk(3, KERN_DEBUG "%s: VIDIOC_TRY_FMT - type=%d\n", 3735static int zoran_g_jpegcomp(struct file *file, void *__fh,
4027 ZR_DEVNAME(zr), fmt->type); 3736 struct v4l2_jpegcompression *params)
3737{
3738 struct zoran_fh *fh = __fh;
3739 struct zoran *zr = fh->zr;
3740 memset(params, 0, sizeof(*params));
4028 3741
4029 switch (fmt->type) { 3742 mutex_lock(&zr->resource_lock);
4030 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
4031 mutex_lock(&zr->resource_lock);
4032 3743
4033 if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH) 3744 params->quality = fh->jpg_settings.jpg_comp.quality;
4034 fmt->fmt.win.w.width = BUZ_MAX_WIDTH; 3745 params->APPn = fh->jpg_settings.jpg_comp.APPn;
4035 if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH) 3746 memcpy(params->APP_data,
4036 fmt->fmt.win.w.width = BUZ_MIN_WIDTH; 3747 fh->jpg_settings.jpg_comp.APP_data,
4037 if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT) 3748 fh->jpg_settings.jpg_comp.APP_len);
4038 fmt->fmt.win.w.height = BUZ_MAX_HEIGHT; 3749 params->APP_len = fh->jpg_settings.jpg_comp.APP_len;
4039 if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT) 3750 memcpy(params->COM_data,
4040 fmt->fmt.win.w.height = BUZ_MIN_HEIGHT; 3751 fh->jpg_settings.jpg_comp.COM_data,
3752 fh->jpg_settings.jpg_comp.COM_len);
3753 params->COM_len = fh->jpg_settings.jpg_comp.COM_len;
3754 params->jpeg_markers =
3755 fh->jpg_settings.jpg_comp.jpeg_markers;
4041 3756
4042 mutex_unlock(&zr->resource_lock); 3757 mutex_unlock(&zr->resource_lock);
4043 break;
4044 3758
4045 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 3759 return 0;
4046 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 3760}
4047 if (fmt->fmt.pix.bytesperline > 0)
4048 return -EINVAL;
4049 3761
4050 mutex_lock(&zr->resource_lock); 3762static int zoran_s_jpegcomp(struct file *file, void *__fh,
4051 3763 struct v4l2_jpegcompression *params)
4052 if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) { 3764{
4053 settings = fh->jpg_settings; 3765 struct zoran_fh *fh = __fh;
4054 3766 struct zoran *zr = fh->zr;
4055 /* we actually need to set 'real' parameters now */ 3767 int res = 0;
4056 if ((fmt->fmt.pix.height * 2) > 3768 struct zoran_jpg_settings settings;
4057 BUZ_MAX_HEIGHT)
4058 settings.TmpDcm = 1;
4059 else
4060 settings.TmpDcm = 2;
4061 settings.decimation = 0;
4062 if (fmt->fmt.pix.height <=
4063 fh->jpg_settings.img_height / 2)
4064 settings.VerDcm = 2;
4065 else
4066 settings.VerDcm = 1;
4067 if (fmt->fmt.pix.width <=
4068 fh->jpg_settings.img_width / 4)
4069 settings.HorDcm = 4;
4070 else if (fmt->fmt.pix.width <=
4071 fh->jpg_settings.img_width / 2)
4072 settings.HorDcm = 2;
4073 else
4074 settings.HorDcm = 1;
4075 if (settings.TmpDcm == 1)
4076 settings.field_per_buff = 2;
4077 else
4078 settings.field_per_buff = 1;
4079
4080 /* check */
4081 if ((res =
4082 zoran_check_jpg_settings(zr,
4083 &settings)))
4084 goto tryfmt_unlock_and_return;
4085
4086 /* tell the user what we actually did */
4087 fmt->fmt.pix.width =
4088 settings.img_width / settings.HorDcm;
4089 fmt->fmt.pix.height =
4090 settings.img_height * 2 /
4091 (settings.TmpDcm * settings.VerDcm);
4092 if (settings.TmpDcm == 1)
4093 fmt->fmt.pix.field =
4094 (fh->jpg_settings.
4095 odd_even ? V4L2_FIELD_SEQ_TB :
4096 V4L2_FIELD_SEQ_BT);
4097 else
4098 fmt->fmt.pix.field =
4099 (fh->jpg_settings.
4100 odd_even ? V4L2_FIELD_TOP :
4101 V4L2_FIELD_BOTTOM);
4102
4103 fmt->fmt.pix.sizeimage =
4104 zoran_v4l2_calc_bufsize(&settings);
4105 } else if (fmt->type ==
4106 V4L2_BUF_TYPE_VIDEO_CAPTURE) {
4107 int i;
4108
4109 for (i = 0; i < NUM_FORMATS; i++)
4110 if (zoran_formats[i].fourcc ==
4111 fmt->fmt.pix.pixelformat)
4112 break;
4113 if (i == NUM_FORMATS) {
4114 res = -EINVAL;
4115 goto tryfmt_unlock_and_return;
4116 }
4117 3769
4118 if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) 3770 settings = fh->jpg_settings;
4119 fmt->fmt.pix.width = BUZ_MAX_WIDTH;
4120 if (fmt->fmt.pix.width < BUZ_MIN_WIDTH)
4121 fmt->fmt.pix.width = BUZ_MIN_WIDTH;
4122 if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
4123 fmt->fmt.pix.height =
4124 BUZ_MAX_HEIGHT;
4125 if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT)
4126 fmt->fmt.pix.height =
4127 BUZ_MIN_HEIGHT;
4128 } else {
4129 res = -EINVAL;
4130 goto tryfmt_unlock_and_return;
4131 }
4132 tryfmt_unlock_and_return:
4133 mutex_unlock(&zr->resource_lock);
4134 3771
4135 return res; 3772 settings.jpg_comp = *params;
4136 break;
4137 3773
4138 default: 3774 mutex_lock(&zr->resource_lock);
4139 return -EINVAL;
4140 }
4141 3775
4142 return 0; 3776 if (fh->v4l_buffers.active != ZORAN_FREE ||
3777 fh->jpg_buffers.active != ZORAN_FREE) {
3778 dprintk(1, KERN_WARNING
3779 "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n",
3780 ZR_DEVNAME(zr));
3781 res = -EBUSY;
3782 goto sjpegc_unlock_and_return;
4143 } 3783 }
4144 break;
4145 3784
4146 default: 3785 res = zoran_check_jpg_settings(zr, &settings);
4147 dprintk(1, KERN_DEBUG "%s: UNKNOWN ioctl cmd: 0x%x\n", 3786 if (res)
4148 ZR_DEVNAME(zr), cmd); 3787 goto sjpegc_unlock_and_return;
4149 return -ENOIOCTLCMD; 3788 if (!fh->jpg_buffers.allocated)
4150 break; 3789 fh->jpg_buffers.buffer_size =
3790 zoran_v4l2_calc_bufsize(&fh->jpg_settings);
3791 fh->jpg_settings.jpg_comp = *params = settings.jpg_comp;
3792sjpegc_unlock_and_return:
3793 mutex_unlock(&zr->resource_lock);
4151 3794
4152 }
4153 return 0; 3795 return 0;
4154} 3796}
4155 3797
4156
4157static long
4158zoran_ioctl(struct file *file,
4159 unsigned int cmd,
4160 unsigned long arg)
4161{
4162 return video_usercopy(file, cmd, arg, zoran_do_ioctl);
4163}
4164
4165static unsigned int 3798static unsigned int
4166zoran_poll (struct file *file, 3799zoran_poll (struct file *file,
4167 poll_table *wait) 3800 poll_table *wait)
@@ -4300,10 +3933,7 @@ zoran_vm_close (struct vm_area_struct *vma)
4300 fh->jpg_buffers.active = 3933 fh->jpg_buffers.active =
4301 ZORAN_FREE; 3934 ZORAN_FREE;
4302 } 3935 }
4303 //jpg_fbuffer_free(file); 3936 jpg_fbuffer_free(file);
4304 fh->jpg_buffers.allocated = 0;
4305 fh->jpg_buffers.ready_to_be_freed = 1;
4306
4307 mutex_unlock(&zr->resource_lock); 3937 mutex_unlock(&zr->resource_lock);
4308 } 3938 }
4309 3939
@@ -4340,10 +3970,7 @@ zoran_vm_close (struct vm_area_struct *vma)
4340 ZORAN_FREE; 3970 ZORAN_FREE;
4341 spin_unlock_irqrestore(&zr->spinlock, flags); 3971 spin_unlock_irqrestore(&zr->spinlock, flags);
4342 } 3972 }
4343 //v4l_fbuffer_free(file); 3973 v4l_fbuffer_free(file);
4344 fh->v4l_buffers.allocated = 0;
4345 fh->v4l_buffers.ready_to_be_freed = 1;
4346
4347 mutex_unlock(&zr->resource_lock); 3974 mutex_unlock(&zr->resource_lock);
4348 } 3975 }
4349 3976
@@ -4582,11 +4209,53 @@ zoran_mmap (struct file *file,
4582 return 0; 4209 return 0;
4583} 4210}
4584 4211
4212static const struct v4l2_ioctl_ops zoran_ioctl_ops = {
4213 .vidioc_querycap = zoran_querycap,
4214 .vidioc_cropcap = zoran_cropcap,
4215 .vidioc_s_crop = zoran_s_crop,
4216 .vidioc_g_crop = zoran_g_crop,
4217 .vidioc_enum_input = zoran_enum_input,
4218 .vidioc_g_input = zoran_g_input,
4219 .vidioc_s_input = zoran_s_input,
4220 .vidioc_enum_output = zoran_enum_output,
4221 .vidioc_g_output = zoran_g_output,
4222 .vidioc_s_output = zoran_s_output,
4223 .vidioc_g_fbuf = zoran_g_fbuf,
4224 .vidioc_s_fbuf = zoran_s_fbuf,
4225 .vidioc_g_std = zoran_g_std,
4226 .vidioc_s_std = zoran_s_std,
4227 .vidioc_g_jpegcomp = zoran_g_jpegcomp,
4228 .vidioc_s_jpegcomp = zoran_s_jpegcomp,
4229 .vidioc_overlay = zoran_overlay,
4230 .vidioc_reqbufs = zoran_reqbufs,
4231 .vidioc_querybuf = zoran_querybuf,
4232 .vidioc_qbuf = zoran_qbuf,
4233 .vidioc_dqbuf = zoran_dqbuf,
4234 .vidioc_streamon = zoran_streamon,
4235 .vidioc_streamoff = zoran_streamoff,
4236 .vidioc_enum_fmt_vid_cap = zoran_enum_fmt_vid_cap,
4237 .vidioc_enum_fmt_vid_out = zoran_enum_fmt_vid_out,
4238 .vidioc_enum_fmt_vid_overlay = zoran_enum_fmt_vid_overlay,
4239 .vidioc_g_fmt_vid_cap = zoran_g_fmt_vid_cap,
4240 .vidioc_g_fmt_vid_out = zoran_g_fmt_vid_out,
4241 .vidioc_g_fmt_vid_overlay = zoran_g_fmt_vid_overlay,
4242 .vidioc_s_fmt_vid_cap = zoran_s_fmt_vid_cap,
4243 .vidioc_s_fmt_vid_out = zoran_s_fmt_vid_out,
4244 .vidioc_s_fmt_vid_overlay = zoran_s_fmt_vid_overlay,
4245 .vidioc_try_fmt_vid_cap = zoran_try_fmt_vid_cap,
4246 .vidioc_try_fmt_vid_out = zoran_try_fmt_vid_out,
4247 .vidioc_try_fmt_vid_overlay = zoran_try_fmt_vid_overlay,
4248 .vidioc_queryctrl = zoran_queryctrl,
4249 .vidioc_s_ctrl = zoran_s_ctrl,
4250 .vidioc_g_ctrl = zoran_g_ctrl,
4251 .vidioc_default = zoran_default,
4252};
4253
4585static const struct v4l2_file_operations zoran_fops = { 4254static const struct v4l2_file_operations zoran_fops = {
4586 .owner = THIS_MODULE, 4255 .owner = THIS_MODULE,
4587 .open = zoran_open, 4256 .open = zoran_open,
4588 .release = zoran_close, 4257 .release = zoran_close,
4589 .ioctl = zoran_ioctl, 4258 .ioctl = video_ioctl2,
4590 .read = zoran_read, 4259 .read = zoran_read,
4591 .write = zoran_write, 4260 .write = zoran_write,
4592 .mmap = zoran_mmap, 4261 .mmap = zoran_mmap,
@@ -4596,7 +4265,9 @@ static const struct v4l2_file_operations zoran_fops = {
4596struct video_device zoran_template __devinitdata = { 4265struct video_device zoran_template __devinitdata = {
4597 .name = ZORAN_NAME, 4266 .name = ZORAN_NAME,
4598 .fops = &zoran_fops, 4267 .fops = &zoran_fops,
4268 .ioctl_ops = &zoran_ioctl_ops,
4599 .release = &zoran_vdev_release, 4269 .release = &zoran_vdev_release,
4270 .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
4600 .minor = -1 4271 .minor = -1
4601}; 4272};
4602 4273