546a18b31328662490c8f54df8fa803e2bf915ba
[deliverable/linux.git] / drivers / staging / media / solo6x10 / v4l2-enc.c
1 /*
2 * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com>
3 *
4 * Original author:
5 * Ben Collins <bcollins@ubuntu.com>
6 *
7 * Additional work by:
8 * John Brooks <john.brooks@bluecherry.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 */
24
25 #include <linux/kernel.h>
26 #include <linux/module.h>
27 #include <linux/kthread.h>
28 #include <linux/freezer.h>
29
30 #include <media/v4l2-ioctl.h>
31 #include <media/v4l2-common.h>
32 #include <media/v4l2-event.h>
33 #include <media/videobuf-dma-sg.h>
34
35 #include "solo6x10.h"
36 #include "tw28.h"
37 #include "solo6x10-jpeg.h"
38
39 #define MIN_VID_BUFFERS 2
40 #define FRAME_BUF_SIZE (196 * 1024)
41 #define MP4_QS 16
42 #define DMA_ALIGN 4096
43
44 struct solo_videobuf {
45 struct videobuf_buffer vb;
46 unsigned int flags;
47 };
48
49 /* 6010 M4V */
50 static unsigned char vop_6010_ntsc_d1[] = {
51 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20,
52 0x02, 0x48, 0x1d, 0xc0, 0x00, 0x40, 0x00, 0x40,
53 0x00, 0x40, 0x00, 0x80, 0x00, 0x97, 0x53, 0x04,
54 0x1f, 0x4c, 0x58, 0x10, 0xf0, 0x71, 0x18, 0x3f,
55 };
56
57 static unsigned char vop_6010_ntsc_cif[] = {
58 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20,
59 0x02, 0x48, 0x1d, 0xc0, 0x00, 0x40, 0x00, 0x40,
60 0x00, 0x40, 0x00, 0x80, 0x00, 0x97, 0x53, 0x04,
61 0x1f, 0x4c, 0x2c, 0x10, 0x78, 0x51, 0x18, 0x3f,
62 };
63
64 static unsigned char vop_6010_pal_d1[] = {
65 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20,
66 0x02, 0x48, 0x15, 0xc0, 0x00, 0x40, 0x00, 0x40,
67 0x00, 0x40, 0x00, 0x80, 0x00, 0x97, 0x53, 0x04,
68 0x1f, 0x4c, 0x58, 0x11, 0x20, 0x71, 0x18, 0x3f,
69 };
70
71 static unsigned char vop_6010_pal_cif[] = {
72 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20,
73 0x02, 0x48, 0x15, 0xc0, 0x00, 0x40, 0x00, 0x40,
74 0x00, 0x40, 0x00, 0x80, 0x00, 0x97, 0x53, 0x04,
75 0x1f, 0x4c, 0x2c, 0x10, 0x90, 0x51, 0x18, 0x3f,
76 };
77
78 /* 6110 h.264 */
79 static unsigned char vop_6110_ntsc_d1[] = {
80 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0x00, 0x1e,
81 0x9a, 0x74, 0x05, 0x81, 0xec, 0x80, 0x00, 0x00,
82 0x00, 0x01, 0x68, 0xce, 0x32, 0x28, 0x00, 0x00,
83 };
84
85 static unsigned char vop_6110_ntsc_cif[] = {
86 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0x00, 0x1e,
87 0x9a, 0x74, 0x0b, 0x0f, 0xc8, 0x00, 0x00, 0x00,
88 0x01, 0x68, 0xce, 0x32, 0x28, 0x00, 0x00, 0x00,
89 };
90
91 static unsigned char vop_6110_pal_d1[] = {
92 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0x00, 0x1e,
93 0x9a, 0x74, 0x05, 0x80, 0x93, 0x20, 0x00, 0x00,
94 0x00, 0x01, 0x68, 0xce, 0x32, 0x28, 0x00, 0x00,
95 };
96
97 static unsigned char vop_6110_pal_cif[] = {
98 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0x00, 0x1e,
99 0x9a, 0x74, 0x0b, 0x04, 0xb2, 0x00, 0x00, 0x00,
100 0x01, 0x68, 0xce, 0x32, 0x28, 0x00, 0x00, 0x00,
101 };
102
103 struct vop_header {
104 /* VE_STATUS0 */
105 u32 mpeg_size:20, sad_motion_flag:1, video_motion_flag:1, vop_type:2,
106 channel:5, source_fl:1, interlace:1, progressive:1;
107
108 /* VE_STATUS1 */
109 u32 vsize:8, hsize:8, last_queue:4, nop0:8, scale:4;
110
111 /* VE_STATUS2 */
112 u32 mpeg_off;
113
114 /* VE_STATUS3 */
115 u32 jpeg_off;
116
117 /* VE_STATUS4 */
118 u32 jpeg_size:20, interval:10, nop1:2;
119
120 /* VE_STATUS5/6 */
121 u32 sec, usec;
122
123 /* VE_STATUS7/8/9 */
124 u32 nop2[3];
125
126 /* VE_STATUS10 */
127 u32 mpeg_size_alt:20, nop3:12;
128
129 u32 end_nops[5];
130 } __packed;
131
132 struct solo_enc_buf {
133 enum solo_enc_types type;
134 struct vop_header *vh;
135 int motion;
136 };
137
138 static int solo_is_motion_on(struct solo_enc_dev *solo_enc)
139 {
140 struct solo_dev *solo_dev = solo_enc->solo_dev;
141
142 return (solo_dev->motion_mask >> solo_enc->ch) & 1;
143 }
144
145 static int solo_motion_detected(struct solo_enc_dev *solo_enc)
146 {
147 struct solo_dev *solo_dev = solo_enc->solo_dev;
148 unsigned long flags;
149 u32 ch_mask = 1 << solo_enc->ch;
150 int ret = 0;
151
152 spin_lock_irqsave(&solo_enc->motion_lock, flags);
153 if (solo_reg_read(solo_dev, SOLO_VI_MOT_STATUS) & ch_mask) {
154 solo_reg_write(solo_dev, SOLO_VI_MOT_CLEAR, ch_mask);
155 ret = 1;
156 }
157 spin_unlock_irqrestore(&solo_enc->motion_lock, flags);
158
159 return ret;
160 }
161
162 static void solo_motion_toggle(struct solo_enc_dev *solo_enc, int on)
163 {
164 struct solo_dev *solo_dev = solo_enc->solo_dev;
165 u32 mask = 1 << solo_enc->ch;
166 unsigned long flags;
167
168 spin_lock_irqsave(&solo_enc->motion_lock, flags);
169
170 if (on)
171 solo_dev->motion_mask |= mask;
172 else
173 solo_dev->motion_mask &= ~mask;
174
175 solo_reg_write(solo_dev, SOLO_VI_MOT_CLEAR, mask);
176
177 solo_reg_write(solo_dev, SOLO_VI_MOT_ADR,
178 SOLO_VI_MOTION_EN(solo_dev->motion_mask) |
179 (SOLO_MOTION_EXT_ADDR(solo_dev) >> 16));
180
181 spin_unlock_irqrestore(&solo_enc->motion_lock, flags);
182 }
183
184 /* MUST be called with solo_enc->enable_lock held */
185 static void solo_update_mode(struct solo_enc_dev *solo_enc)
186 {
187 struct solo_dev *solo_dev = solo_enc->solo_dev;
188 int vop_len;
189 unsigned char *vop;
190
191 solo_enc->interlaced = (solo_enc->mode & 0x08) ? 1 : 0;
192 solo_enc->bw_weight = max(solo_dev->fps / solo_enc->interval, 1);
193
194 if (solo_enc->mode == SOLO_ENC_MODE_CIF) {
195 solo_enc->width = solo_dev->video_hsize >> 1;
196 solo_enc->height = solo_dev->video_vsize;
197 if (solo_dev->type == SOLO_DEV_6110) {
198 if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) {
199 vop = vop_6110_ntsc_cif;
200 vop_len = sizeof(vop_6110_ntsc_cif);
201 } else {
202 vop = vop_6110_pal_cif;
203 vop_len = sizeof(vop_6110_pal_cif);
204 }
205 } else {
206 if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) {
207 vop = vop_6010_ntsc_cif;
208 vop_len = sizeof(vop_6010_ntsc_cif);
209 } else {
210 vop = vop_6010_pal_cif;
211 vop_len = sizeof(vop_6010_pal_cif);
212 }
213 }
214 } else {
215 solo_enc->width = solo_dev->video_hsize;
216 solo_enc->height = solo_dev->video_vsize << 1;
217 solo_enc->bw_weight <<= 2;
218 if (solo_dev->type == SOLO_DEV_6110) {
219 if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) {
220 vop = vop_6110_ntsc_d1;
221 vop_len = sizeof(vop_6110_ntsc_d1);
222 } else {
223 vop = vop_6110_pal_d1;
224 vop_len = sizeof(vop_6110_pal_d1);
225 }
226 } else {
227 if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) {
228 vop = vop_6010_ntsc_d1;
229 vop_len = sizeof(vop_6010_ntsc_d1);
230 } else {
231 vop = vop_6010_pal_d1;
232 vop_len = sizeof(vop_6010_pal_d1);
233 }
234 }
235 }
236
237 memcpy(solo_enc->vop, vop, vop_len);
238
239 /* Some fixups for 6010/M4V */
240 if (solo_dev->type == SOLO_DEV_6010) {
241 u16 fps = solo_dev->fps * 1000;
242 u16 interval = solo_enc->interval * 1000;
243
244 vop = solo_enc->vop;
245
246 /* Frame rate and interval */
247 vop[22] = fps >> 4;
248 vop[23] = ((fps << 4) & 0xf0) | 0x0c
249 | ((interval >> 13) & 0x3);
250 vop[24] = (interval >> 5) & 0xff;
251 vop[25] = ((interval << 3) & 0xf8) | 0x04;
252 }
253
254 solo_enc->vop_len = vop_len;
255
256 /* Now handle the jpeg header */
257 vop = solo_enc->jpeg_header;
258 vop[SOF0_START + 5] = 0xff & (solo_enc->height >> 8);
259 vop[SOF0_START + 6] = 0xff & solo_enc->height;
260 vop[SOF0_START + 7] = 0xff & (solo_enc->width >> 8);
261 vop[SOF0_START + 8] = 0xff & solo_enc->width;
262
263 memcpy(vop + DQT_START,
264 jpeg_dqt[solo_g_jpeg_qp(solo_dev, solo_enc->ch)], DQT_LEN);
265 }
266
267 /* MUST be called with solo_enc->enable_lock held */
268 static int __solo_enc_on(struct solo_enc_dev *solo_enc)
269 {
270 u8 ch = solo_enc->ch;
271 struct solo_dev *solo_dev = solo_enc->solo_dev;
272 u8 interval;
273
274 BUG_ON(!mutex_is_locked(&solo_enc->enable_lock));
275
276 if (solo_enc->enc_on)
277 return 0;
278
279 solo_update_mode(solo_enc);
280
281 /* Make sure to bw check on first reader */
282 if (!atomic_read(&solo_enc->readers)) {
283 if (solo_enc->bw_weight > solo_dev->enc_bw_remain)
284 return -EBUSY;
285 else
286 solo_dev->enc_bw_remain -= solo_enc->bw_weight;
287 }
288
289 solo_enc->enc_on = 1;
290
291 if (solo_enc->type == SOLO_ENC_TYPE_EXT)
292 solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(ch), 1);
293
294 /* Reset the encoder if we are the first mpeg reader, else only reset
295 * on the first mjpeg reader. */
296 if (solo_enc->fmt == V4L2_PIX_FMT_MPEG) {
297 atomic_inc(&solo_enc->readers);
298 if (atomic_inc_return(&solo_enc->mpeg_readers) > 1)
299 return 0;
300 } else if (atomic_inc_return(&solo_enc->readers) > 1) {
301 return 0;
302 }
303
304 /* Disable all encoding for this channel */
305 solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(ch), 0);
306
307 /* Common for both std and ext encoding */
308 solo_reg_write(solo_dev, SOLO_VE_CH_INTL(ch),
309 solo_enc->interlaced ? 1 : 0);
310
311 if (solo_enc->interlaced)
312 interval = solo_enc->interval - 1;
313 else
314 interval = solo_enc->interval;
315
316 /* Standard encoding only */
317 solo_reg_write(solo_dev, SOLO_VE_CH_GOP(ch), solo_enc->gop);
318 solo_reg_write(solo_dev, SOLO_VE_CH_QP(ch), solo_enc->qp);
319 solo_reg_write(solo_dev, SOLO_CAP_CH_INTV(ch), interval);
320
321 /* Extended encoding only */
322 solo_reg_write(solo_dev, SOLO_VE_CH_GOP_E(ch), solo_enc->gop);
323 solo_reg_write(solo_dev, SOLO_VE_CH_QP_E(ch), solo_enc->qp);
324 solo_reg_write(solo_dev, SOLO_CAP_CH_INTV_E(ch), interval);
325
326 /* Enables the standard encoder */
327 solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(ch), solo_enc->mode);
328
329 return 0;
330 }
331
332 static int solo_enc_on(struct solo_enc_dev *solo_enc)
333 {
334 int ret;
335
336 mutex_lock(&solo_enc->enable_lock);
337 ret = __solo_enc_on(solo_enc);
338 mutex_unlock(&solo_enc->enable_lock);
339
340 return ret;
341 }
342
343 static void __solo_enc_off(struct solo_enc_dev *solo_enc)
344 {
345 struct solo_dev *solo_dev = solo_enc->solo_dev;
346
347 BUG_ON(!mutex_is_locked(&solo_enc->enable_lock));
348
349 if (!solo_enc->enc_on)
350 return;
351
352 solo_enc->enc_on = 0;
353
354 if (solo_enc->fmt == V4L2_PIX_FMT_MPEG)
355 atomic_dec(&solo_enc->mpeg_readers);
356
357 if (atomic_dec_return(&solo_enc->readers) > 0)
358 return;
359
360 solo_dev->enc_bw_remain += solo_enc->bw_weight;
361
362 solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(solo_enc->ch), 0);
363 solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(solo_enc->ch), 0);
364 }
365
366 static void solo_enc_off(struct solo_enc_dev *solo_enc)
367 {
368 mutex_lock(&solo_enc->enable_lock);
369 __solo_enc_off(solo_enc);
370 mutex_unlock(&solo_enc->enable_lock);
371 }
372
373 static int enc_get_mpeg_dma(struct solo_dev *solo_dev, dma_addr_t dma,
374 unsigned int off, unsigned int size)
375 {
376 int ret;
377
378 if (off > SOLO_MP4E_EXT_SIZE(solo_dev))
379 return -EINVAL;
380
381 /* Single shot */
382 if (off + size <= SOLO_MP4E_EXT_SIZE(solo_dev)) {
383 return solo_p2m_dma_t(solo_dev, 0, dma,
384 SOLO_MP4E_EXT_ADDR(solo_dev) + off, size,
385 0, 0);
386 }
387
388 /* Buffer wrap */
389 ret = solo_p2m_dma_t(solo_dev, 0, dma,
390 SOLO_MP4E_EXT_ADDR(solo_dev) + off,
391 SOLO_MP4E_EXT_SIZE(solo_dev) - off, 0, 0);
392
393 if (!ret) {
394 ret = solo_p2m_dma_t(solo_dev, 0,
395 dma + SOLO_MP4E_EXT_SIZE(solo_dev) - off,
396 SOLO_MP4E_EXT_ADDR(solo_dev),
397 size + off - SOLO_MP4E_EXT_SIZE(solo_dev), 0, 0);
398 }
399
400 return ret;
401 }
402
403 /* Build a descriptor queue out of an SG list and send it to the P2M for
404 * processing. */
405 static int solo_send_desc(struct solo_enc_dev *solo_enc, int skip,
406 struct videobuf_dmabuf *vbuf, int off, int size,
407 unsigned int base, unsigned int base_size)
408 {
409 struct solo_dev *solo_dev = solo_enc->solo_dev;
410 struct scatterlist *sg;
411 int i;
412 int ret;
413
414 if (WARN_ON_ONCE(size > FRAME_BUF_SIZE))
415 return -EINVAL;
416
417 solo_enc->desc_count = 1;
418
419 for_each_sg(vbuf->sglist, sg, vbuf->sglen, i) {
420 struct solo_p2m_desc *desc;
421 dma_addr_t dma;
422 int len;
423 int left = base_size - off;
424
425 desc = &solo_enc->desc_items[solo_enc->desc_count++];
426 dma = sg_dma_address(sg);
427 len = sg_dma_len(sg);
428
429 /* We assume this is smaller than the scatter size */
430 BUG_ON(skip >= len);
431 if (skip) {
432 len -= skip;
433 dma += skip;
434 size -= skip;
435 skip = 0;
436 }
437
438 len = min(len, size);
439
440 if (len <= left) {
441 /* Single descriptor */
442 solo_p2m_fill_desc(desc, 0, dma, base + off,
443 len, 0, 0);
444 } else {
445 /* Buffer wrap */
446 /* XXX: Do these as separate DMA requests, to avoid
447 timeout errors triggered by awkwardly sized
448 descriptors. See
449 <https://github.com/bluecherrydvr/solo6x10/issues/8>
450 */
451 ret = solo_p2m_dma_t(solo_dev, 0, dma, base + off,
452 left, 0, 0);
453 if (ret)
454 return ret;
455
456 ret = solo_p2m_dma_t(solo_dev, 0, dma + left, base,
457 len - left, 0, 0);
458 if (ret)
459 return ret;
460
461 solo_enc->desc_count--;
462 }
463
464 size -= len;
465 if (size <= 0)
466 break;
467
468 off += len;
469 if (off >= base_size)
470 off -= base_size;
471
472 /* Because we may use two descriptors per loop */
473 if (solo_enc->desc_count >= (solo_enc->desc_nelts - 1)) {
474 ret = solo_p2m_dma_desc(solo_dev, solo_enc->desc_items,
475 solo_enc->desc_dma,
476 solo_enc->desc_count - 1);
477 if (ret)
478 return ret;
479 solo_enc->desc_count = 1;
480 }
481 }
482
483 if (solo_enc->desc_count <= 1)
484 return 0;
485
486 return solo_p2m_dma_desc(solo_dev, solo_enc->desc_items, solo_enc->desc_dma,
487 solo_enc->desc_count - 1);
488 }
489
490 static int solo_fill_jpeg(struct solo_enc_dev *solo_enc, struct videobuf_buffer *vb,
491 struct videobuf_dmabuf *vbuf, struct vop_header *vh)
492 {
493 struct solo_dev *solo_dev = solo_enc->solo_dev;
494 struct solo_videobuf *svb = (struct solo_videobuf *)vb;
495 int frame_size;
496
497 svb->flags |= V4L2_BUF_FLAG_KEYFRAME;
498
499 if (vb->bsize < (vh->jpeg_size + solo_enc->jpeg_len))
500 return -EIO;
501
502 vb->width = solo_enc->width;
503 vb->height = solo_enc->height;
504 vb->size = vh->jpeg_size + solo_enc->jpeg_len;
505
506 sg_copy_from_buffer(vbuf->sglist, vbuf->sglen,
507 solo_enc->jpeg_header,
508 solo_enc->jpeg_len);
509
510 frame_size = (vh->jpeg_size + solo_enc->jpeg_len + (DMA_ALIGN - 1))
511 & ~(DMA_ALIGN - 1);
512
513 return solo_send_desc(solo_enc, solo_enc->jpeg_len, vbuf, vh->jpeg_off,
514 frame_size, SOLO_JPEG_EXT_ADDR(solo_dev),
515 SOLO_JPEG_EXT_SIZE(solo_dev));
516 }
517
518 static int solo_fill_mpeg(struct solo_enc_dev *solo_enc, struct videobuf_buffer *vb,
519 struct videobuf_dmabuf *vbuf, struct vop_header *vh)
520 {
521 struct solo_dev *solo_dev = solo_enc->solo_dev;
522 struct solo_videobuf *svb = (struct solo_videobuf *)vb;
523 int frame_off, frame_size;
524 int skip = 0;
525
526 if (vb->bsize < vh->mpeg_size)
527 return -EIO;
528
529 vb->width = vh->hsize << 4;
530 vb->height = vh->vsize << 4;
531 vb->size = vh->mpeg_size;
532
533 /* If this is a key frame, add extra header */
534 if (!vh->vop_type) {
535 sg_copy_from_buffer(vbuf->sglist, vbuf->sglen,
536 solo_enc->vop,
537 solo_enc->vop_len);
538
539 skip = solo_enc->vop_len;
540 vb->size += solo_enc->vop_len;
541
542 svb->flags |= V4L2_BUF_FLAG_KEYFRAME;
543 } else {
544 svb->flags |= V4L2_BUF_FLAG_PFRAME;
545 }
546
547 /* Now get the actual mpeg payload */
548 frame_off = (vh->mpeg_off + sizeof(*vh))
549 % SOLO_MP4E_EXT_SIZE(solo_dev);
550 frame_size = (vh->mpeg_size + skip + (DMA_ALIGN - 1))
551 & ~(DMA_ALIGN - 1);
552
553 return solo_send_desc(solo_enc, skip, vbuf, frame_off, frame_size,
554 SOLO_MP4E_EXT_ADDR(solo_dev),
555 SOLO_MP4E_EXT_SIZE(solo_dev));
556 }
557
558 static int solo_enc_fillbuf(struct solo_enc_dev *solo_enc,
559 struct videobuf_buffer *vb,
560 struct solo_enc_buf *enc_buf)
561 {
562 struct solo_videobuf *svb = (struct solo_videobuf *)vb;
563 struct videobuf_dmabuf *vbuf = NULL;
564 struct vop_header *vh = enc_buf->vh;
565 int ret;
566
567 vbuf = videobuf_to_dma(vb);
568 if (WARN_ON_ONCE(!vbuf)) {
569 ret = -EIO;
570 goto vbuf_error;
571 }
572
573 /* Setup some common flags for both types */
574 svb->flags = V4L2_BUF_FLAG_TIMECODE;
575 vb->ts.tv_sec = vh->sec;
576 vb->ts.tv_usec = vh->usec;
577
578 /* Check for motion flags */
579 if (solo_is_motion_on(solo_enc)) {
580 svb->flags |= V4L2_BUF_FLAG_MOTION_ON;
581 if (enc_buf->motion)
582 svb->flags |= V4L2_BUF_FLAG_MOTION_DETECTED;
583 }
584
585 if (solo_enc->fmt == V4L2_PIX_FMT_MPEG)
586 ret = solo_fill_mpeg(solo_enc, vb, vbuf, vh);
587 else
588 ret = solo_fill_jpeg(solo_enc, vb, vbuf, vh);
589
590 vbuf_error:
591 /* On error, we push this buffer back into the queue. The
592 * videobuf-core doesn't handle error packets very well. Plus
593 * we recover nicely internally anyway. */
594 if (ret) {
595 unsigned long flags;
596
597 spin_lock_irqsave(&solo_enc->av_lock, flags);
598 list_add(&vb->queue, &solo_enc->vidq_active);
599 vb->state = VIDEOBUF_QUEUED;
600 spin_unlock_irqrestore(&solo_enc->av_lock, flags);
601 } else {
602 vb->state = VIDEOBUF_DONE;
603 vb->field_count++;
604 vb->width = solo_enc->width;
605 vb->height = solo_enc->height;
606
607 wake_up(&vb->done);
608 }
609
610 return ret;
611 }
612
613 static void solo_enc_handle_one(struct solo_enc_dev *solo_enc,
614 struct solo_enc_buf *enc_buf)
615 {
616 struct videobuf_buffer *vb;
617 unsigned long flags;
618
619 mutex_lock(&solo_enc->enable_lock);
620
621 if (solo_enc->type != enc_buf->type)
622 goto unlock;
623
624 if (list_empty(&solo_enc->vidq_active))
625 goto unlock;
626
627 spin_lock_irqsave(&solo_enc->av_lock, flags);
628
629 vb = list_first_entry(&solo_enc->vidq_active,
630 struct videobuf_buffer, queue);
631
632 list_del(&vb->queue);
633 vb->state = VIDEOBUF_ACTIVE;
634
635 spin_unlock_irqrestore(&solo_enc->av_lock, flags);
636
637 solo_enc_fillbuf(solo_enc, vb, enc_buf);
638 unlock:
639 mutex_unlock(&solo_enc->enable_lock);
640 }
641
642 void solo_enc_v4l2_isr(struct solo_dev *solo_dev)
643 {
644 wake_up_interruptible_all(&solo_dev->ring_thread_wait);
645 }
646
647 static void solo_handle_ring(struct solo_dev *solo_dev)
648 {
649 for (;;) {
650 struct solo_enc_dev *solo_enc;
651 struct solo_enc_buf enc_buf;
652 u32 mpeg_current, off;
653 u8 ch;
654 u8 cur_q;
655
656 /* Check if the hardware has any new ones in the queue */
657 cur_q = solo_reg_read(solo_dev, SOLO_VE_STATE(11)) & 0xff;
658 if (cur_q == solo_dev->enc_idx)
659 break;
660
661 mpeg_current = solo_reg_read(solo_dev,
662 SOLO_VE_MPEG4_QUE(solo_dev->enc_idx));
663 solo_dev->enc_idx = (solo_dev->enc_idx + 1) % MP4_QS;
664
665 ch = (mpeg_current >> 24) & 0x1f;
666 off = mpeg_current & 0x00ffffff;
667
668 if (ch >= SOLO_MAX_CHANNELS) {
669 ch -= SOLO_MAX_CHANNELS;
670 enc_buf.type = SOLO_ENC_TYPE_EXT;
671 } else
672 enc_buf.type = SOLO_ENC_TYPE_STD;
673
674 solo_enc = solo_dev->v4l2_enc[ch];
675 if (solo_enc == NULL) {
676 dev_err(&solo_dev->pdev->dev,
677 "Got spurious packet for channel %d\n", ch);
678 continue;
679 }
680
681 /* FAIL... */
682 if (enc_get_mpeg_dma(solo_dev, solo_dev->vh_dma, off,
683 sizeof(struct vop_header)))
684 continue;
685
686 enc_buf.vh = (struct vop_header *)solo_dev->vh_buf;
687 enc_buf.vh->mpeg_off -= SOLO_MP4E_EXT_ADDR(solo_dev);
688 enc_buf.vh->jpeg_off -= SOLO_JPEG_EXT_ADDR(solo_dev);
689
690 /* Sanity check */
691 if (enc_buf.vh->mpeg_off != off)
692 continue;
693
694 if (solo_motion_detected(solo_enc))
695 enc_buf.motion = 1;
696 else
697 enc_buf.motion = 0;
698
699 solo_enc_handle_one(solo_enc, &enc_buf);
700 }
701 }
702
703 static int solo_ring_thread(void *data)
704 {
705 struct solo_dev *solo_dev = data;
706 DECLARE_WAITQUEUE(wait, current);
707
708 set_freezable();
709 add_wait_queue(&solo_dev->ring_thread_wait, &wait);
710
711 for (;;) {
712 long timeout = schedule_timeout_interruptible(HZ);
713 if (timeout == -ERESTARTSYS || kthread_should_stop())
714 break;
715 solo_irq_off(solo_dev, SOLO_IRQ_ENCODER);
716 solo_handle_ring(solo_dev);
717 solo_irq_on(solo_dev, SOLO_IRQ_ENCODER);
718 try_to_freeze();
719 }
720
721 remove_wait_queue(&solo_dev->ring_thread_wait, &wait);
722
723 return 0;
724 }
725
726 static int solo_enc_buf_setup(struct videobuf_queue *vq, unsigned int *count,
727 unsigned int *size)
728 {
729 *size = FRAME_BUF_SIZE;
730
731 if (*count < MIN_VID_BUFFERS)
732 *count = MIN_VID_BUFFERS;
733
734 return 0;
735 }
736
737 static int solo_enc_buf_prepare(struct videobuf_queue *vq,
738 struct videobuf_buffer *vb,
739 enum v4l2_field field)
740 {
741 vb->size = FRAME_BUF_SIZE;
742 if (vb->baddr != 0 && vb->bsize < vb->size)
743 return -EINVAL;
744
745 /* This property only change when queue is idle */
746 vb->field = field;
747
748 if (vb->state == VIDEOBUF_NEEDS_INIT) {
749 int rc = videobuf_iolock(vq, vb, NULL);
750 if (rc < 0) {
751 struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
752 videobuf_dma_unmap(vq->dev, dma);
753 videobuf_dma_free(dma);
754
755 return rc;
756 }
757 }
758 vb->state = VIDEOBUF_PREPARED;
759
760 return 0;
761 }
762
763 static void solo_enc_buf_queue(struct videobuf_queue *vq,
764 struct videobuf_buffer *vb)
765 {
766 struct solo_enc_dev *solo_enc = vq->priv_data;
767
768 vb->state = VIDEOBUF_QUEUED;
769 list_add_tail(&vb->queue, &solo_enc->vidq_active);
770 }
771
772 static void solo_enc_buf_release(struct videobuf_queue *vq,
773 struct videobuf_buffer *vb)
774 {
775 struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
776 videobuf_dma_unmap(vq->dev, dma);
777 videobuf_dma_free(dma);
778 vb->state = VIDEOBUF_NEEDS_INIT;
779 }
780
781 static const struct videobuf_queue_ops solo_enc_video_qops = {
782 .buf_setup = solo_enc_buf_setup,
783 .buf_prepare = solo_enc_buf_prepare,
784 .buf_queue = solo_enc_buf_queue,
785 .buf_release = solo_enc_buf_release,
786 };
787
788 static unsigned int solo_enc_poll(struct file *file,
789 struct poll_table_struct *wait)
790 {
791 struct solo_enc_dev *solo_enc = video_drvdata(file);
792 unsigned long req_events = poll_requested_events(wait);
793 unsigned res = v4l2_ctrl_poll(file, wait);
794
795 if (!(req_events & (POLLIN | POLLRDNORM)))
796 return res;
797 return videobuf_poll_stream(file, &solo_enc->vidq, wait);
798 }
799
800 static int solo_enc_mmap(struct file *file, struct vm_area_struct *vma)
801 {
802 struct solo_enc_dev *solo_enc = video_drvdata(file);
803
804 return videobuf_mmap_mapper(&solo_enc->vidq, vma);
805 }
806
807 static int solo_ring_start(struct solo_dev *solo_dev)
808 {
809 if (atomic_inc_return(&solo_dev->enc_users) > 1)
810 return 0;
811
812 solo_dev->ring_thread = kthread_run(solo_ring_thread, solo_dev,
813 SOLO6X10_NAME "_ring");
814 if (IS_ERR(solo_dev->ring_thread)) {
815 int err = PTR_ERR(solo_dev->ring_thread);
816 solo_dev->ring_thread = NULL;
817 return err;
818 }
819
820 solo_irq_on(solo_dev, SOLO_IRQ_ENCODER);
821
822 return 0;
823 }
824
825 static void solo_ring_stop(struct solo_dev *solo_dev)
826 {
827 if (atomic_dec_return(&solo_dev->enc_users) > 0)
828 return;
829
830 if (solo_dev->ring_thread) {
831 kthread_stop(solo_dev->ring_thread);
832 solo_dev->ring_thread = NULL;
833 }
834
835 solo_irq_off(solo_dev, SOLO_IRQ_ENCODER);
836 }
837
838 static int solo_enc_open(struct file *file)
839 {
840 struct solo_enc_dev *solo_enc = video_drvdata(file);
841 struct solo_dev *solo_dev = solo_enc->solo_dev;
842 int ret = v4l2_fh_open(file);
843
844 if (ret)
845 return ret;
846 ret = solo_ring_start(solo_dev);
847 if (ret) {
848 v4l2_fh_release(file);
849 return ret;
850 }
851 return 0;
852 }
853
854 static ssize_t solo_enc_read(struct file *file, char __user *data,
855 size_t count, loff_t *ppos)
856 {
857 struct solo_enc_dev *solo_enc = video_drvdata(file);
858 int ret;
859
860 /* Make sure the encoder is on */
861 ret = solo_enc_on(solo_enc);
862 if (ret)
863 return ret;
864
865 return videobuf_read_stream(&solo_enc->vidq, data, count, ppos, 0,
866 file->f_flags & O_NONBLOCK);
867 }
868
869 static int solo_enc_release(struct file *file)
870 {
871 struct solo_enc_dev *solo_enc = video_drvdata(file);
872 struct solo_dev *solo_dev = solo_enc->solo_dev;
873
874 solo_enc_off(solo_enc);
875 videobuf_stop(&solo_enc->vidq);
876 videobuf_mmap_free(&solo_enc->vidq);
877 solo_ring_stop(solo_dev);
878
879 return v4l2_fh_release(file);
880 }
881
882 static int solo_enc_querycap(struct file *file, void *priv,
883 struct v4l2_capability *cap)
884 {
885 struct solo_enc_dev *solo_enc = video_drvdata(file);
886 struct solo_dev *solo_dev = solo_enc->solo_dev;
887
888 strcpy(cap->driver, SOLO6X10_NAME);
889 snprintf(cap->card, sizeof(cap->card), "Softlogic 6x10 Enc %d",
890 solo_enc->ch);
891 snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
892 pci_name(solo_dev->pdev));
893 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
894 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
895 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
896 return 0;
897 }
898
899 static int solo_enc_enum_input(struct file *file, void *priv,
900 struct v4l2_input *input)
901 {
902 struct solo_enc_dev *solo_enc = video_drvdata(file);
903 struct solo_dev *solo_dev = solo_enc->solo_dev;
904
905 if (input->index)
906 return -EINVAL;
907
908 snprintf(input->name, sizeof(input->name), "Encoder %d",
909 solo_enc->ch + 1);
910 input->type = V4L2_INPUT_TYPE_CAMERA;
911
912 if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC)
913 input->std = V4L2_STD_NTSC_M;
914 else
915 input->std = V4L2_STD_PAL_B;
916
917 if (!tw28_get_video_status(solo_dev, solo_enc->ch))
918 input->status = V4L2_IN_ST_NO_SIGNAL;
919
920 return 0;
921 }
922
923 static int solo_enc_set_input(struct file *file, void *priv,
924 unsigned int index)
925 {
926 if (index)
927 return -EINVAL;
928
929 return 0;
930 }
931
932 static int solo_enc_get_input(struct file *file, void *priv,
933 unsigned int *index)
934 {
935 *index = 0;
936
937 return 0;
938 }
939
940 static int solo_enc_enum_fmt_cap(struct file *file, void *priv,
941 struct v4l2_fmtdesc *f)
942 {
943 switch (f->index) {
944 case 0:
945 f->pixelformat = V4L2_PIX_FMT_MPEG;
946 strcpy(f->description, "MPEG-4 AVC");
947 break;
948 case 1:
949 f->pixelformat = V4L2_PIX_FMT_MJPEG;
950 strcpy(f->description, "MJPEG");
951 break;
952 default:
953 return -EINVAL;
954 }
955
956 f->flags = V4L2_FMT_FLAG_COMPRESSED;
957
958 return 0;
959 }
960
961 static int solo_enc_try_fmt_cap(struct file *file, void *priv,
962 struct v4l2_format *f)
963 {
964 struct solo_enc_dev *solo_enc = video_drvdata(file);
965 struct solo_dev *solo_dev = solo_enc->solo_dev;
966 struct v4l2_pix_format *pix = &f->fmt.pix;
967
968 if (pix->pixelformat != V4L2_PIX_FMT_MPEG &&
969 pix->pixelformat != V4L2_PIX_FMT_MJPEG)
970 return -EINVAL;
971
972 if (pix->width < solo_dev->video_hsize ||
973 pix->height < solo_dev->video_vsize << 1) {
974 /* Default to CIF 1/2 size */
975 pix->width = solo_dev->video_hsize >> 1;
976 pix->height = solo_dev->video_vsize;
977 } else {
978 /* Full frame */
979 pix->width = solo_dev->video_hsize;
980 pix->height = solo_dev->video_vsize << 1;
981 }
982
983 switch (pix->field) {
984 case V4L2_FIELD_NONE:
985 case V4L2_FIELD_INTERLACED:
986 break;
987 case V4L2_FIELD_ANY:
988 default:
989 pix->field = V4L2_FIELD_INTERLACED;
990 break;
991 }
992
993 /* Just set these */
994 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
995 pix->sizeimage = FRAME_BUF_SIZE;
996 pix->bytesperline = 0;
997 pix->priv = 0;
998
999 return 0;
1000 }
1001
1002 static int solo_enc_set_fmt_cap(struct file *file, void *priv,
1003 struct v4l2_format *f)
1004 {
1005 struct solo_enc_dev *solo_enc = video_drvdata(file);
1006 struct solo_dev *solo_dev = solo_enc->solo_dev;
1007 struct v4l2_pix_format *pix = &f->fmt.pix;
1008 int ret;
1009
1010 mutex_lock(&solo_enc->enable_lock);
1011
1012 ret = solo_enc_try_fmt_cap(file, priv, f);
1013 if (ret)
1014 return ret;
1015
1016 /* We cannot change width/height in mid read */
1017 if (!ret && atomic_read(&solo_enc->readers) > 0) {
1018 if (pix->width != solo_enc->width ||
1019 pix->height != solo_enc->height)
1020 ret = -EBUSY;
1021 }
1022 if (ret) {
1023 mutex_unlock(&solo_enc->enable_lock);
1024 return ret;
1025 }
1026
1027 if (pix->width == solo_dev->video_hsize)
1028 solo_enc->mode = SOLO_ENC_MODE_D1;
1029 else
1030 solo_enc->mode = SOLO_ENC_MODE_CIF;
1031
1032 /* This does not change the encoder at all */
1033 solo_enc->fmt = pix->pixelformat;
1034
1035 if (pix->priv)
1036 solo_enc->type = SOLO_ENC_TYPE_EXT;
1037
1038 mutex_unlock(&solo_enc->enable_lock);
1039
1040 return 0;
1041 }
1042
1043 static int solo_enc_get_fmt_cap(struct file *file, void *priv,
1044 struct v4l2_format *f)
1045 {
1046 struct solo_enc_dev *solo_enc = video_drvdata(file);
1047 struct v4l2_pix_format *pix = &f->fmt.pix;
1048
1049 pix->width = solo_enc->width;
1050 pix->height = solo_enc->height;
1051 pix->pixelformat = solo_enc->fmt;
1052 pix->field = solo_enc->interlaced ? V4L2_FIELD_INTERLACED :
1053 V4L2_FIELD_NONE;
1054 pix->sizeimage = FRAME_BUF_SIZE;
1055 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
1056 pix->priv = 0;
1057
1058 return 0;
1059 }
1060
1061 static int solo_enc_reqbufs(struct file *file, void *priv,
1062 struct v4l2_requestbuffers *req)
1063 {
1064 struct solo_enc_dev *solo_enc = video_drvdata(file);
1065
1066 return videobuf_reqbufs(&solo_enc->vidq, req);
1067 }
1068
1069 static int solo_enc_querybuf(struct file *file, void *priv,
1070 struct v4l2_buffer *buf)
1071 {
1072 struct solo_enc_dev *solo_enc = video_drvdata(file);
1073
1074 return videobuf_querybuf(&solo_enc->vidq, buf);
1075 }
1076
1077 static int solo_enc_qbuf(struct file *file, void *priv,
1078 struct v4l2_buffer *buf)
1079 {
1080 struct solo_enc_dev *solo_enc = video_drvdata(file);
1081
1082 return videobuf_qbuf(&solo_enc->vidq, buf);
1083 }
1084
1085 static int solo_enc_dqbuf(struct file *file, void *priv,
1086 struct v4l2_buffer *buf)
1087 {
1088 struct solo_enc_dev *solo_enc = video_drvdata(file);
1089 struct solo_videobuf *svb;
1090 int ret;
1091
1092 /* Make sure the encoder is on */
1093 ret = solo_enc_on(solo_enc);
1094 if (ret)
1095 return ret;
1096
1097 ret = videobuf_dqbuf(&solo_enc->vidq, buf, file->f_flags & O_NONBLOCK);
1098 if (ret)
1099 return ret;
1100
1101 /* Copy over the flags */
1102 svb = (struct solo_videobuf *)solo_enc->vidq.bufs[buf->index];
1103 buf->flags |= svb->flags;
1104
1105 return 0;
1106 }
1107
1108 static int solo_enc_streamon(struct file *file, void *priv,
1109 enum v4l2_buf_type i)
1110 {
1111 struct solo_enc_dev *solo_enc = video_drvdata(file);
1112
1113 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1114 return -EINVAL;
1115
1116 return videobuf_streamon(&solo_enc->vidq);
1117 }
1118
1119 static int solo_enc_streamoff(struct file *file, void *priv,
1120 enum v4l2_buf_type i)
1121 {
1122 struct solo_enc_dev *solo_enc = video_drvdata(file);
1123 int ret;
1124
1125 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1126 return -EINVAL;
1127
1128 ret = videobuf_streamoff(&solo_enc->vidq);
1129 if (!ret)
1130 solo_enc_off(solo_enc);
1131
1132 return ret;
1133 }
1134
1135 static int solo_enc_s_std(struct file *file, void *priv, v4l2_std_id i)
1136 {
1137 return 0;
1138 }
1139
1140 static int solo_enum_framesizes(struct file *file, void *priv,
1141 struct v4l2_frmsizeenum *fsize)
1142 {
1143 struct solo_enc_dev *solo_enc = video_drvdata(file);
1144 struct solo_dev *solo_dev = solo_enc->solo_dev;
1145
1146 if (fsize->pixel_format != V4L2_PIX_FMT_MPEG &&
1147 fsize->pixel_format != V4L2_PIX_FMT_MJPEG)
1148 return -EINVAL;
1149
1150 switch (fsize->index) {
1151 case 0:
1152 fsize->discrete.width = solo_dev->video_hsize >> 1;
1153 fsize->discrete.height = solo_dev->video_vsize;
1154 break;
1155 case 1:
1156 fsize->discrete.width = solo_dev->video_hsize;
1157 fsize->discrete.height = solo_dev->video_vsize << 1;
1158 break;
1159 default:
1160 return -EINVAL;
1161 }
1162
1163 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1164
1165 return 0;
1166 }
1167
1168 static int solo_enum_frameintervals(struct file *file, void *priv,
1169 struct v4l2_frmivalenum *fintv)
1170 {
1171 struct solo_enc_dev *solo_enc = video_drvdata(file);
1172 struct solo_dev *solo_dev = solo_enc->solo_dev;
1173
1174 if (fintv->pixel_format != V4L2_PIX_FMT_MPEG &&
1175 fintv->pixel_format != V4L2_PIX_FMT_MJPEG)
1176 return -EINVAL;
1177 if (fintv->index)
1178 return -EINVAL;
1179 if ((fintv->width != solo_dev->video_hsize >> 1 ||
1180 fintv->height != solo_dev->video_vsize) &&
1181 (fintv->width != solo_dev->video_hsize ||
1182 fintv->height != solo_dev->video_vsize << 1))
1183 return -EINVAL;
1184
1185 fintv->type = V4L2_FRMIVAL_TYPE_STEPWISE;
1186
1187 fintv->stepwise.min.denominator = solo_dev->fps;
1188 fintv->stepwise.min.numerator = 15;
1189
1190 fintv->stepwise.max.denominator = solo_dev->fps;
1191 fintv->stepwise.max.numerator = 1;
1192
1193 fintv->stepwise.step.numerator = 1;
1194 fintv->stepwise.step.denominator = 1;
1195
1196 return 0;
1197 }
1198
1199 static int solo_g_parm(struct file *file, void *priv,
1200 struct v4l2_streamparm *sp)
1201 {
1202 struct solo_enc_dev *solo_enc = video_drvdata(file);
1203 struct solo_dev *solo_dev = solo_enc->solo_dev;
1204 struct v4l2_captureparm *cp = &sp->parm.capture;
1205
1206 cp->capability = V4L2_CAP_TIMEPERFRAME;
1207 cp->timeperframe.numerator = solo_enc->interval;
1208 cp->timeperframe.denominator = solo_dev->fps;
1209 cp->capturemode = 0;
1210 /* XXX: Shouldn't we be able to get/set this from videobuf? */
1211 cp->readbuffers = 2;
1212
1213 return 0;
1214 }
1215
1216 static int solo_s_parm(struct file *file, void *priv,
1217 struct v4l2_streamparm *sp)
1218 {
1219 struct solo_enc_dev *solo_enc = video_drvdata(file);
1220 struct solo_dev *solo_dev = solo_enc->solo_dev;
1221 struct v4l2_captureparm *cp = &sp->parm.capture;
1222
1223 mutex_lock(&solo_enc->enable_lock);
1224
1225 if (atomic_read(&solo_enc->mpeg_readers) > 0) {
1226 mutex_unlock(&solo_enc->enable_lock);
1227 return -EBUSY;
1228 }
1229
1230 if ((cp->timeperframe.numerator == 0) ||
1231 (cp->timeperframe.denominator == 0)) {
1232 /* reset framerate */
1233 cp->timeperframe.numerator = 1;
1234 cp->timeperframe.denominator = solo_dev->fps;
1235 }
1236
1237 if (cp->timeperframe.denominator != solo_dev->fps)
1238 cp->timeperframe.denominator = solo_dev->fps;
1239
1240 if (cp->timeperframe.numerator > 15)
1241 cp->timeperframe.numerator = 15;
1242
1243 solo_enc->interval = cp->timeperframe.numerator;
1244
1245 cp->capability = V4L2_CAP_TIMEPERFRAME;
1246 cp->readbuffers = 2;
1247
1248 solo_update_mode(solo_enc);
1249
1250 mutex_unlock(&solo_enc->enable_lock);
1251
1252 return 0;
1253 }
1254
1255 static int solo_s_ctrl(struct v4l2_ctrl *ctrl)
1256 {
1257 struct solo_enc_dev *solo_enc =
1258 container_of(ctrl->handler, struct solo_enc_dev, hdl);
1259 struct solo_dev *solo_dev = solo_enc->solo_dev;
1260 int err;
1261
1262 switch (ctrl->id) {
1263 case V4L2_CID_BRIGHTNESS:
1264 case V4L2_CID_CONTRAST:
1265 case V4L2_CID_SATURATION:
1266 case V4L2_CID_HUE:
1267 case V4L2_CID_SHARPNESS:
1268 return tw28_set_ctrl_val(solo_dev, ctrl->id, solo_enc->ch,
1269 ctrl->val);
1270 case V4L2_CID_MPEG_VIDEO_ENCODING:
1271 return 0;
1272 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
1273 solo_enc->gop = ctrl->val;
1274 return 0;
1275 case V4L2_CID_MOTION_THRESHOLD: {
1276 u16 block = (ctrl->val >> 16) & 0xffff;
1277 u16 value = ctrl->val & 0xffff;
1278
1279 /* Motion thresholds are in a table of 64x64 samples, with
1280 * each sample representing 16x16 pixels of the source. In
1281 * effect, 44x30 samples are used for NTSC, and 44x36 for PAL.
1282 * The 5th sample on the 10th row is (10*64)+5 = 645.
1283 *
1284 * Block is 0 to set the threshold globally, or any positive
1285 * number under 2049 to set block-1 individually. */
1286 /* Currently we limit support to block 0 only. A later patch
1287 * will add a new ioctl to set all other blocks. */
1288 if (block == 0) {
1289 solo_enc->motion_thresh = value;
1290 return solo_set_motion_threshold(solo_dev,
1291 solo_enc->ch, value);
1292 }
1293 return solo_set_motion_block(solo_dev, solo_enc->ch,
1294 value, block - 1);
1295 }
1296 case V4L2_CID_MOTION_ENABLE:
1297 solo_motion_toggle(solo_enc, ctrl->val);
1298 return 0;
1299 case V4L2_CID_OSD_TEXT:
1300 mutex_lock(&solo_enc->enable_lock);
1301 strcpy(solo_enc->osd_text, ctrl->string);
1302 err = solo_osd_print(solo_enc);
1303 mutex_unlock(&solo_enc->enable_lock);
1304 return err;
1305 default:
1306 return -EINVAL;
1307 }
1308
1309 return 0;
1310 }
1311
1312 static const struct v4l2_file_operations solo_enc_fops = {
1313 .owner = THIS_MODULE,
1314 .open = solo_enc_open,
1315 .release = solo_enc_release,
1316 .read = solo_enc_read,
1317 .poll = solo_enc_poll,
1318 .mmap = solo_enc_mmap,
1319 .ioctl = video_ioctl2,
1320 };
1321
1322 static const struct v4l2_ioctl_ops solo_enc_ioctl_ops = {
1323 .vidioc_querycap = solo_enc_querycap,
1324 .vidioc_s_std = solo_enc_s_std,
1325 /* Input callbacks */
1326 .vidioc_enum_input = solo_enc_enum_input,
1327 .vidioc_s_input = solo_enc_set_input,
1328 .vidioc_g_input = solo_enc_get_input,
1329 /* Video capture format callbacks */
1330 .vidioc_enum_fmt_vid_cap = solo_enc_enum_fmt_cap,
1331 .vidioc_try_fmt_vid_cap = solo_enc_try_fmt_cap,
1332 .vidioc_s_fmt_vid_cap = solo_enc_set_fmt_cap,
1333 .vidioc_g_fmt_vid_cap = solo_enc_get_fmt_cap,
1334 /* Streaming I/O */
1335 .vidioc_reqbufs = solo_enc_reqbufs,
1336 .vidioc_querybuf = solo_enc_querybuf,
1337 .vidioc_qbuf = solo_enc_qbuf,
1338 .vidioc_dqbuf = solo_enc_dqbuf,
1339 .vidioc_streamon = solo_enc_streamon,
1340 .vidioc_streamoff = solo_enc_streamoff,
1341 /* Frame size and interval */
1342 .vidioc_enum_framesizes = solo_enum_framesizes,
1343 .vidioc_enum_frameintervals = solo_enum_frameintervals,
1344 /* Video capture parameters */
1345 .vidioc_s_parm = solo_s_parm,
1346 .vidioc_g_parm = solo_g_parm,
1347 /* Logging and events */
1348 .vidioc_log_status = v4l2_ctrl_log_status,
1349 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1350 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1351 };
1352
1353 static const struct video_device solo_enc_template = {
1354 .name = SOLO6X10_NAME,
1355 .fops = &solo_enc_fops,
1356 .ioctl_ops = &solo_enc_ioctl_ops,
1357 .minor = -1,
1358 .release = video_device_release,
1359
1360 .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL_B,
1361 .current_norm = V4L2_STD_NTSC_M,
1362 };
1363
1364 static const struct v4l2_ctrl_ops solo_ctrl_ops = {
1365 .s_ctrl = solo_s_ctrl,
1366 };
1367
1368 static const struct v4l2_ctrl_config solo_motion_threshold_ctrl = {
1369 .ops = &solo_ctrl_ops,
1370 .id = V4L2_CID_MOTION_THRESHOLD,
1371 .name = "Motion Detection Threshold",
1372 .type = V4L2_CTRL_TYPE_INTEGER,
1373 .max = 0xffff,
1374 .def = SOLO_DEF_MOT_THRESH,
1375 .step = 1,
1376 .flags = V4L2_CTRL_FLAG_SLIDER,
1377 };
1378
1379 static const struct v4l2_ctrl_config solo_motion_enable_ctrl = {
1380 .ops = &solo_ctrl_ops,
1381 .id = V4L2_CID_MOTION_ENABLE,
1382 .name = "Motion Detection Enable",
1383 .type = V4L2_CTRL_TYPE_BOOLEAN,
1384 .max = 1,
1385 .step = 1,
1386 };
1387
1388 static const struct v4l2_ctrl_config solo_osd_text_ctrl = {
1389 .ops = &solo_ctrl_ops,
1390 .id = V4L2_CID_OSD_TEXT,
1391 .name = "OSD Text",
1392 .type = V4L2_CTRL_TYPE_STRING,
1393 .max = OSD_TEXT_MAX,
1394 .step = 1,
1395 };
1396
1397 static struct solo_enc_dev *solo_enc_alloc(struct solo_dev *solo_dev,
1398 u8 ch, unsigned nr)
1399 {
1400 struct solo_enc_dev *solo_enc;
1401 struct v4l2_ctrl_handler *hdl;
1402 int ret;
1403
1404 solo_enc = kzalloc(sizeof(*solo_enc), GFP_KERNEL);
1405 if (!solo_enc)
1406 return ERR_PTR(-ENOMEM);
1407
1408 hdl = &solo_enc->hdl;
1409 v4l2_ctrl_handler_init(hdl, 10);
1410 v4l2_ctrl_new_std(hdl, &solo_ctrl_ops,
1411 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1412 v4l2_ctrl_new_std(hdl, &solo_ctrl_ops,
1413 V4L2_CID_CONTRAST, 0, 255, 1, 128);
1414 v4l2_ctrl_new_std(hdl, &solo_ctrl_ops,
1415 V4L2_CID_SATURATION, 0, 255, 1, 128);
1416 v4l2_ctrl_new_std(hdl, &solo_ctrl_ops,
1417 V4L2_CID_HUE, 0, 255, 1, 128);
1418 if (tw28_has_sharpness(solo_dev, ch))
1419 v4l2_ctrl_new_std(hdl, &solo_ctrl_ops,
1420 V4L2_CID_SHARPNESS, 0, 15, 1, 0);
1421 v4l2_ctrl_new_std_menu(hdl, &solo_ctrl_ops,
1422 V4L2_CID_MPEG_VIDEO_ENCODING,
1423 V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 3,
1424 V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC);
1425 v4l2_ctrl_new_std(hdl, &solo_ctrl_ops,
1426 V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1, 255, 1, solo_dev->fps);
1427 v4l2_ctrl_new_custom(hdl, &solo_motion_threshold_ctrl, NULL);
1428 v4l2_ctrl_new_custom(hdl, &solo_motion_enable_ctrl, NULL);
1429 v4l2_ctrl_new_custom(hdl, &solo_osd_text_ctrl, NULL);
1430 if (hdl->error) {
1431 ret = hdl->error;
1432 goto hdl_free;
1433 }
1434
1435 solo_enc->solo_dev = solo_dev;
1436 solo_enc->ch = ch;
1437 spin_lock_init(&solo_enc->av_lock);
1438 INIT_LIST_HEAD(&solo_enc->vidq_active);
1439 solo_enc->fmt = V4L2_PIX_FMT_MPEG;
1440 solo_enc->type = SOLO_ENC_TYPE_STD;
1441
1442 atomic_set(&solo_enc->readers, 0);
1443
1444 solo_enc->qp = SOLO_DEFAULT_QP;
1445 solo_enc->gop = solo_dev->fps;
1446 solo_enc->interval = 1;
1447 solo_enc->mode = SOLO_ENC_MODE_CIF;
1448 solo_enc->motion_thresh = SOLO_DEF_MOT_THRESH;
1449
1450 spin_lock(&solo_enc->av_lock);
1451 solo_update_mode(solo_enc);
1452 spin_unlock(&solo_enc->av_lock);
1453
1454 mutex_init(&solo_enc->enable_lock);
1455 spin_lock_init(&solo_enc->motion_lock);
1456
1457 atomic_set(&solo_enc->readers, 0);
1458 atomic_set(&solo_enc->mpeg_readers, 0);
1459
1460 /* Initialize this per encoder */
1461 solo_enc->jpeg_len = sizeof(jpeg_header);
1462 memcpy(solo_enc->jpeg_header, jpeg_header, solo_enc->jpeg_len);
1463
1464 solo_enc->desc_nelts = 32;
1465 solo_enc->desc_items = pci_alloc_consistent(solo_dev->pdev,
1466 sizeof(struct solo_p2m_desc) *
1467 solo_enc->desc_nelts, &solo_enc->desc_dma);
1468 ret = -ENOMEM;
1469 if (solo_enc->desc_items == NULL)
1470 goto hdl_free;
1471
1472 videobuf_queue_sg_init(&solo_enc->vidq, &solo_enc_video_qops,
1473 &solo_dev->pdev->dev,
1474 &solo_enc->av_lock,
1475 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1476 V4L2_FIELD_INTERLACED,
1477 sizeof(struct solo_videobuf),
1478 solo_enc, NULL);
1479
1480 solo_enc->vfd = video_device_alloc();
1481 if (!solo_enc->vfd)
1482 goto pci_free;
1483
1484 *solo_enc->vfd = solo_enc_template;
1485 solo_enc->vfd->v4l2_dev = &solo_dev->v4l2_dev;
1486 solo_enc->vfd->ctrl_handler = hdl;
1487 set_bit(V4L2_FL_USE_FH_PRIO, &solo_enc->vfd->flags);
1488 video_set_drvdata(solo_enc->vfd, solo_enc);
1489 ret = video_register_device(solo_enc->vfd, VFL_TYPE_GRABBER, nr);
1490 if (ret < 0)
1491 goto vdev_release;
1492
1493 snprintf(solo_enc->vfd->name, sizeof(solo_enc->vfd->name),
1494 "%s-enc (%i/%i)", SOLO6X10_NAME, solo_dev->vfd->num,
1495 solo_enc->vfd->num);
1496
1497 return solo_enc;
1498
1499 vdev_release:
1500 video_device_release(solo_enc->vfd);
1501 pci_free:
1502 pci_free_consistent(solo_enc->solo_dev->pdev,
1503 sizeof(struct solo_p2m_desc) * solo_enc->desc_nelts,
1504 solo_enc->desc_items, solo_enc->desc_dma);
1505 hdl_free:
1506 v4l2_ctrl_handler_free(hdl);
1507 kfree(solo_enc);
1508 return ERR_PTR(ret);
1509 }
1510
1511 static void solo_enc_free(struct solo_enc_dev *solo_enc)
1512 {
1513 if (solo_enc == NULL)
1514 return;
1515
1516 video_unregister_device(solo_enc->vfd);
1517 v4l2_ctrl_handler_free(&solo_enc->hdl);
1518 kfree(solo_enc);
1519 }
1520
1521 int solo_enc_v4l2_init(struct solo_dev *solo_dev, unsigned nr)
1522 {
1523 int i;
1524
1525 atomic_set(&solo_dev->enc_users, 0);
1526 init_waitqueue_head(&solo_dev->ring_thread_wait);
1527
1528 solo_dev->vh_size = sizeof(struct vop_header);
1529 solo_dev->vh_buf = pci_alloc_consistent(solo_dev->pdev,
1530 solo_dev->vh_size,
1531 &solo_dev->vh_dma);
1532 if (solo_dev->vh_buf == NULL)
1533 return -ENOMEM;
1534
1535 for (i = 0; i < solo_dev->nr_chans; i++) {
1536 solo_dev->v4l2_enc[i] = solo_enc_alloc(solo_dev, i, nr);
1537 if (IS_ERR(solo_dev->v4l2_enc[i]))
1538 break;
1539 }
1540
1541 if (i != solo_dev->nr_chans) {
1542 int ret = PTR_ERR(solo_dev->v4l2_enc[i]);
1543 while (i--)
1544 solo_enc_free(solo_dev->v4l2_enc[i]);
1545 pci_free_consistent(solo_dev->pdev, solo_dev->vh_size,
1546 solo_dev->vh_buf, solo_dev->vh_dma);
1547 solo_dev->vh_buf = NULL;
1548 return ret;
1549 }
1550
1551 if (solo_dev->type == SOLO_DEV_6010)
1552 solo_dev->enc_bw_remain = solo_dev->fps * 4 * 4;
1553 else
1554 solo_dev->enc_bw_remain = solo_dev->fps * 4 * 5;
1555
1556 dev_info(&solo_dev->pdev->dev, "Encoders as /dev/video%d-%d\n",
1557 solo_dev->v4l2_enc[0]->vfd->num,
1558 solo_dev->v4l2_enc[solo_dev->nr_chans - 1]->vfd->num);
1559
1560 return 0;
1561 }
1562
1563 void solo_enc_v4l2_exit(struct solo_dev *solo_dev)
1564 {
1565 int i;
1566
1567 for (i = 0; i < solo_dev->nr_chans; i++)
1568 solo_enc_free(solo_dev->v4l2_enc[i]);
1569
1570 if (solo_dev->vh_buf)
1571 pci_free_consistent(solo_dev->pdev, solo_dev->vh_size,
1572 solo_dev->vh_buf, solo_dev->vh_dma);
1573 }
This page took 0.083934 seconds and 4 git commands to generate.