]> Pileus Git - ~andy/linux/blob - drivers/staging/solo6x10/solo6010-v4l2-enc.c
staging: Solo6x10: Build MPEG4 headers on the fly.
[~andy/linux] / drivers / staging / solo6x10 / solo6010-v4l2-enc.c
1 /*
2  * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com
3  * Copyright (C) 2010 Ben Collins <bcollins@bluecherry.net>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <linux/kthread.h>
23 #include <linux/freezer.h>
24
25 #include <media/v4l2-ioctl.h>
26 #include <media/v4l2-common.h>
27 #include <media/videobuf-dma-sg.h>
28
29 #include "solo6010.h"
30 #include "solo6010-tw28.h"
31 #include "solo6010-jpeg.h"
32
33 #define MIN_VID_BUFFERS         4
34 #define FRAME_BUF_SIZE          (128 * 1024)
35 #define MP4_QS                  16
36
37 static int solo_enc_thread(void *data);
38
39 extern unsigned video_nr;
40
41 struct solo_enc_fh {
42         struct                  solo_enc_dev *enc;
43         u32                     fmt;
44         u16                     rd_idx;
45         u8                      enc_on;
46         enum solo_enc_types     type;
47         struct videobuf_queue   vidq;
48         struct list_head        vidq_active;
49         struct task_struct      *kthread;
50         struct p2m_desc         desc[SOLO_NR_P2M_DESC];
51 };
52
53 static const u32 solo_user_ctrls[] = {
54         V4L2_CID_BRIGHTNESS,
55         V4L2_CID_CONTRAST,
56         V4L2_CID_SATURATION,
57         V4L2_CID_HUE,
58         V4L2_CID_SHARPNESS,
59         0
60 };
61
62 static const u32 solo_mpeg_ctrls[] = {
63         V4L2_CID_MPEG_VIDEO_ENCODING,
64         V4L2_CID_MPEG_VIDEO_GOP_SIZE,
65         0
66 };
67
68 static const u32 solo_private_ctrls[] = {
69         V4L2_CID_MOTION_ENABLE,
70         V4L2_CID_MOTION_THRESHOLD,
71         0
72 };
73
74 static const u32 solo_fmtx_ctrls[] = {
75         V4L2_CID_RDS_TX_RADIO_TEXT,
76         0
77 };
78
79 static const u32 *solo_ctrl_classes[] = {
80         solo_user_ctrls,
81         solo_mpeg_ctrls,
82         solo_fmtx_ctrls,
83         solo_private_ctrls,
84         NULL
85 };
86
87 static int solo_is_motion_on(struct solo_enc_dev *solo_enc)
88 {
89         struct solo6010_dev *solo_dev = solo_enc->solo_dev;
90         u8 ch = solo_enc->ch;
91
92         if (solo_dev->motion_mask & (1 << ch))
93                 return 1;
94         return 0;
95 }
96
97 static void solo_motion_toggle(struct solo_enc_dev *solo_enc, int on)
98 {
99         struct solo6010_dev *solo_dev = solo_enc->solo_dev;
100         u8 ch = solo_enc->ch;
101
102         spin_lock(&solo_enc->lock);
103
104         if (on)
105                 solo_dev->motion_mask |= (1 << ch);
106         else
107                 solo_dev->motion_mask &= ~(1 << ch);
108
109         /* Do this regardless of if we are turning on or off */
110         solo_reg_write(solo_enc->solo_dev, SOLO_VI_MOT_CLEAR,
111                        1 << solo_enc->ch);
112         solo_enc->motion_detected = 0;
113
114         solo_reg_write(solo_dev, SOLO_VI_MOT_ADR,
115                        SOLO_VI_MOTION_EN(solo_dev->motion_mask) |
116                        (SOLO_MOTION_EXT_ADDR(solo_dev) >> 16));
117
118         if (solo_dev->motion_mask)
119                 solo6010_irq_on(solo_dev, SOLO_IRQ_MOTION);
120         else
121                 solo6010_irq_off(solo_dev, SOLO_IRQ_MOTION);
122
123         spin_unlock(&solo_enc->lock);
124 }
125
126 /* Should be called with solo_enc->lock held */
127 static void solo_update_mode(struct solo_enc_dev *solo_enc)
128 {
129         struct solo6010_dev *solo_dev = solo_enc->solo_dev;
130
131         assert_spin_locked(&solo_enc->lock);
132
133         solo_enc->interlaced = (solo_enc->mode & 0x08) ? 1 : 0;
134         solo_enc->bw_weight = max(solo_dev->fps / solo_enc->interval, 1);
135
136         switch (solo_enc->mode) {
137         case SOLO_ENC_MODE_CIF:
138                 solo_enc->width = solo_dev->video_hsize >> 1;
139                 solo_enc->height = solo_dev->video_vsize;
140                 break;
141         case SOLO_ENC_MODE_D1:
142                 solo_enc->width = solo_dev->video_hsize;
143                 solo_enc->height = solo_dev->video_vsize << 1;
144                 solo_enc->bw_weight <<= 2;
145                 break;
146         default:
147                 WARN(1, "mode is unknown\n");
148         }
149 }
150
151 /* Should be called with solo_enc->lock held */
152 static int solo_enc_on(struct solo_enc_fh *fh)
153 {
154         struct solo_enc_dev *solo_enc = fh->enc;
155         u8 ch = solo_enc->ch;
156         struct solo6010_dev *solo_dev = solo_enc->solo_dev;
157         u8 interval;
158
159         assert_spin_locked(&solo_enc->lock);
160
161         if (fh->enc_on)
162                 return 0;
163
164         solo_update_mode(solo_enc);
165
166         /* Make sure to bw check on first reader */
167         if (!atomic_read(&solo_enc->readers)) {
168                 if (solo_enc->bw_weight > solo_dev->enc_bw_remain)
169                         return -EBUSY;
170                 else
171                         solo_dev->enc_bw_remain -= solo_enc->bw_weight;
172         }
173
174         fh->enc_on = 1;
175         fh->rd_idx = solo_enc->solo_dev->enc_wr_idx;
176
177         if (fh->type == SOLO_ENC_TYPE_EXT)
178                 solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(ch), 1);
179
180         if (atomic_inc_return(&solo_enc->readers) > 1)
181                 return 0;
182
183         /* Disable all encoding for this channel */
184         solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(ch), 0);
185
186         /* Common for both std and ext encoding */
187         solo_reg_write(solo_dev, SOLO_VE_CH_INTL(ch),
188                        solo_enc->interlaced ? 1 : 0);
189
190         if (solo_enc->interlaced)
191                 interval = solo_enc->interval - 1;
192         else
193                 interval = solo_enc->interval;
194
195         /* Standard encoding only */
196         solo_reg_write(solo_dev, SOLO_VE_CH_GOP(ch), solo_enc->gop);
197         solo_reg_write(solo_dev, SOLO_VE_CH_QP(ch), solo_enc->qp);
198         solo_reg_write(solo_dev, SOLO_CAP_CH_INTV(ch), interval);
199
200         /* Extended encoding only */
201         solo_reg_write(solo_dev, SOLO_VE_CH_GOP_E(ch), solo_enc->gop);
202         solo_reg_write(solo_dev, SOLO_VE_CH_QP_E(ch), solo_enc->qp);
203         solo_reg_write(solo_dev, SOLO_CAP_CH_INTV_E(ch), interval);
204
205         /* Enables the standard encoder */
206         solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(ch), solo_enc->mode);
207
208         /* Settle down Beavis... */
209         mdelay(10);
210
211         return 0;
212 }
213
214 static void solo_enc_off(struct solo_enc_fh *fh)
215 {
216         struct solo_enc_dev *solo_enc = fh->enc;
217         struct solo6010_dev *solo_dev = solo_enc->solo_dev;
218
219         if (!fh->enc_on)
220                 return;
221
222         if (fh->kthread) {
223                 kthread_stop(fh->kthread);
224                 fh->kthread = NULL;
225         }
226
227         solo_dev->enc_bw_remain += solo_enc->bw_weight;
228         fh->enc_on = 0;
229
230         if (atomic_dec_return(&solo_enc->readers) > 0)
231                 return;
232
233         solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(solo_enc->ch), 0);
234         solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(solo_enc->ch), 0);
235 }
236
237 static int solo_start_fh_thread(struct solo_enc_fh *fh)
238 {
239         struct solo_enc_dev *solo_enc = fh->enc;
240
241         fh->kthread = kthread_run(solo_enc_thread, fh, SOLO6010_NAME "_enc");
242
243         /* Oops, we had a problem */
244         if (IS_ERR(fh->kthread)) {
245                 spin_lock(&solo_enc->lock);
246                 solo_enc_off(fh);
247                 spin_unlock(&solo_enc->lock);
248
249                 return PTR_ERR(fh->kthread);
250         }
251
252         return 0;
253 }
254
255 static void enc_reset_gop(struct solo6010_dev *solo_dev, u8 ch)
256 {
257         BUG_ON(ch >= solo_dev->nr_chans);
258         solo_reg_write(solo_dev, SOLO_VE_CH_GOP(ch), 1);
259         solo_dev->v4l2_enc[ch]->reset_gop = 1;
260 }
261
262 static int enc_gop_reset(struct solo6010_dev *solo_dev, u8 ch, u8 vop)
263 {
264         BUG_ON(ch >= solo_dev->nr_chans);
265         if (!solo_dev->v4l2_enc[ch]->reset_gop)
266                 return 0;
267         if (vop)
268                 return 1;
269         solo_dev->v4l2_enc[ch]->reset_gop = 0;
270         solo_reg_write(solo_dev, SOLO_VE_CH_GOP(ch),
271                        solo_dev->v4l2_enc[ch]->gop);
272         return 0;
273 }
274
275 static void enc_write_sg(struct scatterlist *sglist, void *buf, int size)
276 {
277         struct scatterlist *sg;
278         u8 *src = buf;
279
280         for (sg = sglist; sg && size > 0; sg = sg_next(sg)) {
281                 u8 *p = sg_virt(sg);
282                 size_t len = sg_dma_len(sg);
283                 int i;
284
285                 for (i = 0; i < len && size; i++)
286                         p[i] = *(src++);
287         }
288 }
289
290 static int enc_get_mpeg_dma_sg(struct solo6010_dev *solo_dev,
291                                struct p2m_desc *desc,
292                                struct scatterlist *sglist, int skip,
293                                unsigned int off, unsigned int size)
294 {
295         int ret;
296
297         if (off > SOLO_MP4E_EXT_SIZE(solo_dev))
298                 return -EINVAL;
299
300         if (off + size <= SOLO_MP4E_EXT_SIZE(solo_dev)) {
301                 return solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_MP4E,
302                                        desc, 0, sglist, skip,
303                                        SOLO_MP4E_EXT_ADDR(solo_dev) + off, size);
304         }
305
306         /* Buffer wrap */
307         ret = solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_MP4E, desc, 0,
308                               sglist, skip, SOLO_MP4E_EXT_ADDR(solo_dev) + off,
309                               SOLO_MP4E_EXT_SIZE(solo_dev) - off);
310
311         ret |= solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_MP4E, desc, 0,
312                                sglist, skip + SOLO_MP4E_EXT_SIZE(solo_dev) - off,
313                                SOLO_MP4E_EXT_ADDR(solo_dev),
314                                size + off - SOLO_MP4E_EXT_SIZE(solo_dev));
315
316         return ret;
317 }
318
319 static int enc_get_mpeg_dma_t(struct solo6010_dev *solo_dev,
320                               dma_addr_t buf, unsigned int off,
321                               unsigned int size)
322 {
323         int ret;
324
325         if (off > SOLO_MP4E_EXT_SIZE(solo_dev))
326                 return -EINVAL;
327
328         if (off + size <= SOLO_MP4E_EXT_SIZE(solo_dev)) {
329                 return solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_MP4E, 0, buf,
330                                       SOLO_MP4E_EXT_ADDR(solo_dev) + off, size);
331         }
332
333         /* Buffer wrap */
334         ret = solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_MP4E, 0, buf,
335                              SOLO_MP4E_EXT_ADDR(solo_dev) + off,
336                              SOLO_MP4E_EXT_SIZE(solo_dev) - off);
337
338         ret |= solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_MP4E, 0,
339                               buf + SOLO_MP4E_EXT_SIZE(solo_dev) - off,
340                               SOLO_MP4E_EXT_ADDR(solo_dev),
341                               size + off - SOLO_MP4E_EXT_SIZE(solo_dev));
342
343         return ret;
344 }
345
346 static int enc_get_mpeg_dma(struct solo6010_dev *solo_dev, void *buf,
347                             unsigned int off, unsigned int size)
348 {
349         int ret;
350
351         dma_addr_t dma_addr = pci_map_single(solo_dev->pdev, buf, size,
352                                              PCI_DMA_FROMDEVICE);
353         ret = enc_get_mpeg_dma_t(solo_dev, dma_addr, off, size);
354         pci_unmap_single(solo_dev->pdev, dma_addr, size, PCI_DMA_FROMDEVICE);
355
356         return ret;
357 }
358
359 static int enc_get_jpeg_dma_sg(struct solo6010_dev *solo_dev,
360                                struct p2m_desc *desc,
361                                struct scatterlist *sglist, int skip,
362                                unsigned int off, unsigned int size)
363 {
364         int ret;
365
366         if (off > SOLO_JPEG_EXT_SIZE(solo_dev))
367                 return -EINVAL;
368
369         if (off + size <= SOLO_JPEG_EXT_SIZE(solo_dev)) {
370                 return solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_JPEG,
371                                        desc, 0, sglist, skip,
372                                        SOLO_JPEG_EXT_ADDR(solo_dev) + off, size);
373         }
374
375         /* Buffer wrap */
376         ret = solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_JPEG, desc, 0,
377                               sglist, skip, SOLO_JPEG_EXT_ADDR(solo_dev) + off,
378                               SOLO_JPEG_EXT_SIZE(solo_dev) - off);
379
380         ret |= solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_JPEG, desc, 0,
381                                sglist, skip + SOLO_JPEG_EXT_SIZE(solo_dev) - off,
382                                SOLO_JPEG_EXT_ADDR(solo_dev),
383                                size + off - SOLO_JPEG_EXT_SIZE(solo_dev));
384
385         return ret;
386 }
387
388 /* Returns true of __chk is within the first __range bytes of __off */
389 #define OFF_IN_RANGE(__off, __range, __chk) \
390         ((__off <= __chk) && ((__off + __range) >= __chk))
391
392 static void solo_jpeg_header(struct solo_enc_dev *solo_enc,
393                              struct videobuf_dmabuf *vbuf)
394 {
395         struct scatterlist *sg;
396         void *src = jpeg_header;
397         size_t copied = 0;
398         size_t to_copy = sizeof(jpeg_header);
399
400         for (sg = vbuf->sglist; sg && copied < to_copy; sg = sg_next(sg)) {
401                 size_t this_copy = min(sg_dma_len(sg),
402                                        (unsigned int)(to_copy - copied));
403                 u8 *p = sg_virt(sg);
404
405                 memcpy(p, src + copied, this_copy);
406
407                 if (OFF_IN_RANGE(copied, this_copy, SOF0_START + 5))
408                         p[(SOF0_START + 5) - copied] =
409                                 0xff & (solo_enc->height >> 8);
410                 if (OFF_IN_RANGE(copied, this_copy, SOF0_START + 6))
411                         p[(SOF0_START + 6) - copied] = 0xff & solo_enc->height;
412                 if (OFF_IN_RANGE(copied, this_copy, SOF0_START + 7))
413                         p[(SOF0_START + 7) - copied] =
414                                 0xff & (solo_enc->width >> 8);
415                 if (OFF_IN_RANGE(copied, this_copy, SOF0_START + 8))
416                         p[(SOF0_START + 8) - copied] = 0xff & solo_enc->width;
417
418                 copied += this_copy;
419         }
420 }
421
422 static int solo_fill_jpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf,
423                           struct videobuf_buffer *vb,
424                           struct videobuf_dmabuf *vbuf)
425 {
426         struct solo6010_dev *solo_dev = fh->enc->solo_dev;
427         int size = enc_buf->jpeg_size;
428
429         /* Copy the header first (direct write) */
430         solo_jpeg_header(fh->enc, vbuf);
431
432         vb->size = size + sizeof(jpeg_header);
433
434         /* Grab the jpeg frame */
435         return enc_get_jpeg_dma_sg(solo_dev, fh->desc, vbuf->sglist,
436                                    sizeof(jpeg_header),
437                                    enc_buf->jpeg_off, size);
438 }
439
440 static inline int vop_interlaced(__le32 *vh)
441 {
442         return (__le32_to_cpu(vh[0]) >> 30) & 1;
443 }
444
445 static inline u32 vop_size(__le32 *vh)
446 {
447         return __le32_to_cpu(vh[0]) & 0xFFFFF;
448 }
449
450 static inline u8 vop_hsize(__le32 *vh)
451 {
452         return (__le32_to_cpu(vh[1]) >> 8) & 0xFF;
453 }
454
455 static inline u8 vop_vsize(__le32 *vh)
456 {
457         return __le32_to_cpu(vh[1]) & 0xFF;
458 }
459
460 /* must be called with *bits % 8 = 0 */
461 static void write_bytes(u8 **out, unsigned *bits, const u8 *src, unsigned count)
462 {
463         memcpy(*out, src, count);
464         *out += count;
465         *bits += count * 8;
466 }
467
468 static void write_bits(u8 **out, unsigned *bits, u32 value, unsigned count)
469 {
470
471         value <<= 32 - count; // shift to the right
472
473         while (count--) {
474                 **out <<= 1;
475                 **out |= !!(value & (1 << 31)); /* MSB */
476                 value <<= 1;
477                 if (++(*bits) % 8 == 0)
478                         (*out)++;
479         }
480 }
481
482 static void write_mpeg4_end(u8 **out, unsigned *bits)
483 {
484         write_bits(out, bits, 0, 1);
485         /* align on 32-bit boundary */
486         if (*bits % 32)
487                 write_bits(out, bits, 0xFFFFFFFF, 32 - *bits % 32);
488 }
489
490 static void mpeg4_write_vol(u8 **out, struct solo6010_dev *solo_dev,
491                             __le32 *vh, unsigned fps, unsigned interval)
492 {
493         static const u8 hdr[] = {
494                 0, 0, 1, 0x00 /* video_object_start_code */,
495                 0, 0, 1, 0x20 /* video_object_layer_start_code */
496         };
497         unsigned bits = 0;
498         unsigned width = vop_hsize(vh) << 4;
499         unsigned height = vop_vsize(vh) << 4;
500         unsigned interlaced = vop_interlaced(vh);
501
502         write_bytes(out, &bits, hdr, sizeof(hdr));
503         write_bits(out, &bits,    0,  1); /* random_accessible_vol */
504         write_bits(out, &bits, 0x04,  8); /* video_object_type_indication: main */
505         write_bits(out, &bits,    1,  1); /* is_object_layer_identifier */
506         write_bits(out, &bits,    2,  4); /* video_object_layer_verid: table V2-39 */
507         write_bits(out, &bits,    0,  3); /* video_object_layer_priority */
508         if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC)
509                 write_bits(out, &bits,  3,  4); /* aspect_ratio_info, assuming 4:3 */
510         else
511                 write_bits(out, &bits,  2,  4);
512         write_bits(out, &bits,    1,  1); /* vol_control_parameters */
513         write_bits(out, &bits,    1,  2); /* chroma_format: 4:2:0 */
514         write_bits(out, &bits,    1,  1); /* low_delay */
515         write_bits(out, &bits,    0,  1); /* vbv_parameters */
516         write_bits(out, &bits,    0,  2); /* video_object_layer_shape: rectangular */
517         write_bits(out, &bits,    1,  1); /* marker_bit */
518         write_bits(out, &bits,  fps, 16); /* vop_time_increment_resolution */
519         write_bits(out, &bits,    1,  1); /* marker_bit */
520         write_bits(out, &bits,    1,  1); /* fixed_vop_rate */
521         write_bits(out, &bits, interval, 15); /* fixed_vop_time_increment */
522         write_bits(out, &bits,    1,  1); /* marker_bit */
523         write_bits(out, &bits, width, 13); /* video_object_layer_width */
524         write_bits(out, &bits,    1,  1); /* marker_bit */
525         write_bits(out, &bits, height, 13); /* video_object_layer_height */
526         write_bits(out, &bits,    1,  1); /* marker_bit */
527         write_bits(out, &bits, interlaced, 1); /* interlaced */
528         write_bits(out, &bits,    1,  1); /* obmc_disable */
529         write_bits(out, &bits,    0,  2); /* sprite_enable */
530         write_bits(out, &bits,    0,  1); /* not_8_bit */
531         write_bits(out, &bits,    1,  0); /* quant_type */
532         write_bits(out, &bits,    0,  1); /* load_intra_quant_mat */
533         write_bits(out, &bits,    0,  1); /* load_nonintra_quant_mat */
534         write_bits(out, &bits,    0,  1); /* quarter_sample */
535         write_bits(out, &bits,    1,  1); /* complexity_estimation_disable */
536         write_bits(out, &bits,    1,  1); /* resync_marker_disable */
537         write_bits(out, &bits,    0,  1); /* data_partitioned */
538         write_bits(out, &bits,    0,  1); /* newpred_enable */
539         write_bits(out, &bits,    0,  1); /* reduced_resolution_vop_enable */
540         write_bits(out, &bits,    0,  1); /* scalability */
541         write_mpeg4_end(out, &bits);
542 }
543
544 static int solo_fill_mpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf,
545                           struct videobuf_buffer *vb,
546                           struct videobuf_dmabuf *vbuf)
547 {
548         struct solo_enc_dev *solo_enc = fh->enc;
549         struct solo6010_dev *solo_dev = solo_enc->solo_dev;
550
551 #define VH_WORDS 16
552 #define MAX_VOL_HEADER_LENGTH 64
553
554         __le32 vh[VH_WORDS];
555         int ret;
556         int frame_size, frame_off;
557         int skip = 0;
558
559         if (WARN_ON_ONCE(enc_buf->size <= sizeof(vh)))
560                 return -EINVAL;
561
562         /* First get the hardware vop header (not real mpeg) */
563         ret = enc_get_mpeg_dma(solo_dev, vh, enc_buf->off, sizeof(vh));
564         if (WARN_ON_ONCE(ret))
565                 return ret;
566
567         if (WARN_ON_ONCE(vop_size(vh) > enc_buf->size))
568                 return -EINVAL;
569
570         vb->width = vop_hsize(vh) << 4;
571         vb->height = vop_vsize(vh) << 4;
572         vb->size = vop_size(vh);
573
574         /* If this is a key frame, add extra m4v header */
575         if (!enc_buf->vop) {
576                 u8 header[MAX_VOL_HEADER_LENGTH], *out = header;
577
578                 mpeg4_write_vol(&out, solo_dev, vh, solo_dev->fps * 1000,
579                                 solo_enc->interval * 1000);
580                 skip = out - header;
581                 enc_write_sg(vbuf->sglist, header, skip);
582                 /* Adjust the dma buffer past this header */
583                 vb->size += skip;
584         }
585
586         /* Now get the actual mpeg payload */
587         frame_off = (enc_buf->off + sizeof(vh)) % SOLO_MP4E_EXT_SIZE(solo_dev);
588         frame_size = enc_buf->size - sizeof(vh);
589
590         ret = enc_get_mpeg_dma_sg(solo_dev, fh->desc, vbuf->sglist,
591                                   skip, frame_off, frame_size);
592         WARN_ON_ONCE(ret);
593
594         return ret;
595 }
596
597 static void solo_enc_fillbuf(struct solo_enc_fh *fh,
598                             struct videobuf_buffer *vb)
599 {
600         struct solo_enc_dev *solo_enc = fh->enc;
601         struct solo6010_dev *solo_dev = solo_enc->solo_dev;
602         struct solo_enc_buf *enc_buf = NULL;
603         struct videobuf_dmabuf *vbuf;
604         int ret;
605         int error = 1;
606         u16 idx = fh->rd_idx;
607
608         while (idx != solo_dev->enc_wr_idx) {
609                 struct solo_enc_buf *ebuf = &solo_dev->enc_buf[idx];
610
611                 idx = (idx + 1) % SOLO_NR_RING_BUFS;
612
613                 if (ebuf->ch != solo_enc->ch)
614                         continue;
615
616                 if (fh->fmt == V4L2_PIX_FMT_MPEG) {
617                         if (fh->type == ebuf->type) {
618                                 enc_buf = ebuf;
619                                 break;
620                         }
621                 } else {
622                         /* For mjpeg, keep reading to the newest frame */
623                         enc_buf = ebuf;
624                 }
625         }
626
627         fh->rd_idx = idx;
628
629         if (WARN_ON_ONCE(!enc_buf))
630                 goto buf_err;
631
632         if ((fh->fmt == V4L2_PIX_FMT_MPEG &&
633              vb->bsize < enc_buf->size) ||
634             (fh->fmt == V4L2_PIX_FMT_MJPEG &&
635              vb->bsize < (enc_buf->jpeg_size + sizeof(jpeg_header)))) {
636                 WARN_ON_ONCE(1);
637                 goto buf_err;
638         }
639
640         vbuf = videobuf_to_dma(vb);
641         if (WARN_ON_ONCE(!vbuf))
642                 goto buf_err;
643
644         if (fh->fmt == V4L2_PIX_FMT_MPEG)
645                 ret = solo_fill_mpeg(fh, enc_buf, vb, vbuf);
646         else
647                 ret = solo_fill_jpeg(fh, enc_buf, vb, vbuf);
648
649         if (!ret)
650                 error = 0;
651
652 buf_err:
653         if (error) {
654                 vb->state = VIDEOBUF_ERROR;
655         } else {
656                 vb->field_count++;
657                 vb->ts = enc_buf->ts;
658                 vb->state = VIDEOBUF_DONE;
659         }
660
661         wake_up(&vb->done);
662
663         return;
664 }
665
666 static void solo_enc_thread_try(struct solo_enc_fh *fh)
667 {
668         struct solo_enc_dev *solo_enc = fh->enc;
669         struct solo6010_dev *solo_dev = solo_enc->solo_dev;
670         struct videobuf_buffer *vb;
671
672         for (;;) {
673                 spin_lock(&solo_enc->lock);
674
675                 if (fh->rd_idx == solo_dev->enc_wr_idx)
676                         break;
677
678                 if (list_empty(&fh->vidq_active))
679                         break;
680
681                 vb = list_first_entry(&fh->vidq_active,
682                                       struct videobuf_buffer, queue);
683
684                 if (!waitqueue_active(&vb->done))
685                         break;
686
687                 list_del(&vb->queue);
688
689                 spin_unlock(&solo_enc->lock);
690
691                 solo_enc_fillbuf(fh, vb);
692         }
693
694         assert_spin_locked(&solo_enc->lock);
695         spin_unlock(&solo_enc->lock);
696 }
697
698 static int solo_enc_thread(void *data)
699 {
700         struct solo_enc_fh *fh = data;
701         struct solo_enc_dev *solo_enc = fh->enc;
702         DECLARE_WAITQUEUE(wait, current);
703
704         set_freezable();
705         add_wait_queue(&solo_enc->thread_wait, &wait);
706
707         for (;;) {
708                 long timeout = schedule_timeout_interruptible(HZ);
709                 if (timeout == -ERESTARTSYS || kthread_should_stop())
710                         break;
711                 solo_enc_thread_try(fh);
712                 try_to_freeze();
713         }
714
715         remove_wait_queue(&solo_enc->thread_wait, &wait);
716
717         return 0;
718 }
719
720 void solo_motion_isr(struct solo6010_dev *solo_dev)
721 {
722         u32 status;
723         int i;
724
725         solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_MOTION);
726
727         status = solo_reg_read(solo_dev, SOLO_VI_MOT_STATUS);
728
729         for (i = 0; i < solo_dev->nr_chans; i++) {
730                 struct solo_enc_dev *solo_enc = solo_dev->v4l2_enc[i];
731
732                 BUG_ON(solo_enc == NULL);
733
734                 if (solo_enc->motion_detected)
735                         continue;
736                 if (!(status & (1 << i)))
737                         continue;
738
739                 solo_enc->motion_detected = 1;
740         }
741 }
742
743 void solo_enc_v4l2_isr(struct solo6010_dev *solo_dev)
744 {
745         struct solo_enc_buf *enc_buf;
746         u32 mpeg_current, mpeg_next, mpeg_size;
747         u32 jpeg_current, jpeg_next, jpeg_size;
748         u32 reg_mpeg_size;
749         u8 cur_q, vop_type;
750         u8 ch;
751         enum solo_enc_types enc_type;
752
753         solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_ENCODER);
754
755         cur_q = ((solo_reg_read(solo_dev, SOLO_VE_STATE(11)) & 0xF) + 1) % MP4_QS;
756
757         reg_mpeg_size = ((solo_reg_read(solo_dev, SOLO_VE_STATE(0)) & 0xFFFFF) + 64 + 32) & ~31;
758
759         while (solo_dev->enc_idx != cur_q) {
760                 mpeg_current = solo_reg_read(solo_dev,
761                                         SOLO_VE_MPEG4_QUE(solo_dev->enc_idx));
762                 jpeg_current = solo_reg_read(solo_dev,
763                                         SOLO_VE_JPEG_QUE(solo_dev->enc_idx));
764                 solo_dev->enc_idx = (solo_dev->enc_idx + 1) % MP4_QS;
765                 mpeg_next = solo_reg_read(solo_dev,
766                                         SOLO_VE_MPEG4_QUE(solo_dev->enc_idx));
767                 jpeg_next = solo_reg_read(solo_dev,
768                                         SOLO_VE_JPEG_QUE(solo_dev->enc_idx));
769
770                 ch = (mpeg_current >> 24) & 0x1f;
771                 if (ch >= SOLO_MAX_CHANNELS) {
772                         ch -= SOLO_MAX_CHANNELS;
773                         enc_type = SOLO_ENC_TYPE_EXT;
774                 } else
775                         enc_type = SOLO_ENC_TYPE_STD;
776
777                 vop_type = (mpeg_current >> 29) & 3;
778
779                 mpeg_current &= 0x00ffffff;
780                 mpeg_next    &= 0x00ffffff;
781                 jpeg_current &= 0x00ffffff;
782                 jpeg_next    &= 0x00ffffff;
783
784                 mpeg_size = (SOLO_MP4E_EXT_SIZE(solo_dev) +
785                              mpeg_next - mpeg_current) %
786                             SOLO_MP4E_EXT_SIZE(solo_dev);
787
788                 jpeg_size = (SOLO_JPEG_EXT_SIZE(solo_dev) +
789                              jpeg_next - jpeg_current) %
790                             SOLO_JPEG_EXT_SIZE(solo_dev);
791
792                 /* XXX I think this means we had a ring overflow? */
793                 if (mpeg_current > mpeg_next && mpeg_size != reg_mpeg_size) {
794                         enc_reset_gop(solo_dev, ch);
795                         continue;
796                 }
797
798                 /* When resetting the GOP, skip frames until I-frame */
799                 if (enc_gop_reset(solo_dev, ch, vop_type))
800                         continue;
801
802                 enc_buf = &solo_dev->enc_buf[solo_dev->enc_wr_idx];
803
804                 enc_buf->vop = vop_type;
805                 enc_buf->ch = ch;
806                 enc_buf->off = mpeg_current;
807                 enc_buf->size = mpeg_size;
808                 enc_buf->jpeg_off = jpeg_current;
809                 enc_buf->jpeg_size = jpeg_size;
810                 enc_buf->type = enc_type;
811
812                 do_gettimeofday(&enc_buf->ts);
813
814                 solo_dev->enc_wr_idx = (solo_dev->enc_wr_idx + 1) %
815                                         SOLO_NR_RING_BUFS;
816
817                 wake_up_interruptible(&solo_dev->v4l2_enc[ch]->thread_wait);
818         }
819
820         return;
821 }
822
823 static int solo_enc_buf_setup(struct videobuf_queue *vq, unsigned int *count,
824                               unsigned int *size)
825 {
826         *size = FRAME_BUF_SIZE;
827
828         if (*count < MIN_VID_BUFFERS)
829                 *count = MIN_VID_BUFFERS;
830
831         return 0;
832 }
833
834 static int solo_enc_buf_prepare(struct videobuf_queue *vq,
835                                 struct videobuf_buffer *vb,
836                                 enum v4l2_field field)
837 {
838         struct solo_enc_fh *fh = vq->priv_data;
839         struct solo_enc_dev *solo_enc = fh->enc;
840
841         vb->size = FRAME_BUF_SIZE;
842         if (vb->baddr != 0 && vb->bsize < vb->size)
843                 return -EINVAL;
844
845         /* These properties only change when queue is idle */
846         vb->width = solo_enc->width;
847         vb->height = solo_enc->height;
848         vb->field  = field;
849
850         if (vb->state == VIDEOBUF_NEEDS_INIT) {
851                 int rc = videobuf_iolock(vq, vb, NULL);
852                 if (rc < 0) {
853                         struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
854                         videobuf_dma_unmap(vq->dev, dma);
855                         videobuf_dma_free(dma);
856                         vb->state = VIDEOBUF_NEEDS_INIT;
857                         return rc;
858                 }
859         }
860         vb->state = VIDEOBUF_PREPARED;
861
862         return 0;
863 }
864
865 static void solo_enc_buf_queue(struct videobuf_queue *vq,
866                                struct videobuf_buffer *vb)
867 {
868         struct solo_enc_fh *fh = vq->priv_data;
869
870         vb->state = VIDEOBUF_QUEUED;
871         list_add_tail(&vb->queue, &fh->vidq_active);
872         wake_up_interruptible(&fh->enc->thread_wait);
873 }
874
875 static void solo_enc_buf_release(struct videobuf_queue *vq,
876                                  struct videobuf_buffer *vb)
877 {
878         struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
879
880         videobuf_dma_unmap(vq->dev, dma);
881         videobuf_dma_free(dma);
882         vb->state = VIDEOBUF_NEEDS_INIT;
883 }
884
885 static struct videobuf_queue_ops solo_enc_video_qops = {
886         .buf_setup      = solo_enc_buf_setup,
887         .buf_prepare    = solo_enc_buf_prepare,
888         .buf_queue      = solo_enc_buf_queue,
889         .buf_release    = solo_enc_buf_release,
890 };
891
892 static unsigned int solo_enc_poll(struct file *file,
893                                   struct poll_table_struct *wait)
894 {
895         struct solo_enc_fh *fh = file->private_data;
896
897         return videobuf_poll_stream(file, &fh->vidq, wait);
898 }
899
900 static int solo_enc_mmap(struct file *file, struct vm_area_struct *vma)
901 {
902         struct solo_enc_fh *fh = file->private_data;
903
904         return videobuf_mmap_mapper(&fh->vidq, vma);
905 }
906
907 static int solo_enc_open(struct file *file)
908 {
909         struct solo_enc_dev *solo_enc = video_drvdata(file);
910         struct solo_enc_fh *fh;
911
912         fh = kzalloc(sizeof(*fh), GFP_KERNEL);
913         if (fh == NULL)
914                 return -ENOMEM;
915
916         fh->enc = solo_enc;
917         file->private_data = fh;
918         INIT_LIST_HEAD(&fh->vidq_active);
919         fh->fmt = V4L2_PIX_FMT_MPEG;
920         fh->type = SOLO_ENC_TYPE_STD;
921
922         videobuf_queue_sg_init(&fh->vidq, &solo_enc_video_qops,
923                                &solo_enc->solo_dev->pdev->dev,
924                                &solo_enc->lock,
925                                V4L2_BUF_TYPE_VIDEO_CAPTURE,
926                                V4L2_FIELD_INTERLACED,
927                                sizeof(struct videobuf_buffer), fh, NULL);
928
929         return 0;
930 }
931
932 static ssize_t solo_enc_read(struct file *file, char __user *data,
933                              size_t count, loff_t *ppos)
934 {
935         struct solo_enc_fh *fh = file->private_data;
936         struct solo_enc_dev *solo_enc = fh->enc;
937
938         /* Make sure the encoder is on */
939         if (!fh->enc_on) {
940                 int ret;
941
942                 spin_lock(&solo_enc->lock);
943                 ret = solo_enc_on(fh);
944                 spin_unlock(&solo_enc->lock);
945                 if (ret)
946                         return ret;
947
948                 ret = solo_start_fh_thread(fh);
949                 if (ret)
950                         return ret;
951         }
952
953         return videobuf_read_stream(&fh->vidq, data, count, ppos, 0,
954                                     file->f_flags & O_NONBLOCK);
955 }
956
957 static int solo_enc_release(struct file *file)
958 {
959         struct solo_enc_fh *fh = file->private_data;
960         struct solo_enc_dev *solo_enc = fh->enc;
961
962         videobuf_stop(&fh->vidq);
963         videobuf_mmap_free(&fh->vidq);
964
965         spin_lock(&solo_enc->lock);
966         solo_enc_off(fh);
967         spin_unlock(&solo_enc->lock);
968
969         kfree(fh);
970
971         return 0;
972 }
973
974 static int solo_enc_querycap(struct file *file, void  *priv,
975                              struct v4l2_capability *cap)
976 {
977         struct solo_enc_fh *fh = priv;
978         struct solo_enc_dev *solo_enc = fh->enc;
979         struct solo6010_dev *solo_dev = solo_enc->solo_dev;
980
981         strcpy(cap->driver, SOLO6010_NAME);
982         snprintf(cap->card, sizeof(cap->card), "Softlogic 6010 Enc %d",
983                  solo_enc->ch);
984         snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI %s",
985                  pci_name(solo_dev->pdev));
986         cap->version = SOLO6010_VER_NUM;
987         cap->capabilities =     V4L2_CAP_VIDEO_CAPTURE |
988                                 V4L2_CAP_READWRITE |
989                                 V4L2_CAP_STREAMING;
990         return 0;
991 }
992
993 static int solo_enc_enum_input(struct file *file, void *priv,
994                                struct v4l2_input *input)
995 {
996         struct solo_enc_fh *fh = priv;
997         struct solo_enc_dev *solo_enc = fh->enc;
998         struct solo6010_dev *solo_dev = solo_enc->solo_dev;
999
1000         if (input->index)
1001                 return -EINVAL;
1002
1003         snprintf(input->name, sizeof(input->name), "Encoder %d",
1004                  solo_enc->ch + 1);
1005         input->type = V4L2_INPUT_TYPE_CAMERA;
1006
1007         if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC)
1008                 input->std = V4L2_STD_NTSC_M;
1009         else
1010                 input->std = V4L2_STD_PAL_B;
1011
1012         if (!tw28_get_video_status(solo_dev, solo_enc->ch))
1013                 input->status = V4L2_IN_ST_NO_SIGNAL;
1014
1015         return 0;
1016 }
1017
1018 static int solo_enc_set_input(struct file *file, void *priv, unsigned int index)
1019 {
1020         if (index)
1021                 return -EINVAL;
1022
1023         return 0;
1024 }
1025
1026 static int solo_enc_get_input(struct file *file, void *priv,
1027                               unsigned int *index)
1028 {
1029         *index = 0;
1030
1031         return 0;
1032 }
1033
1034 static int solo_enc_enum_fmt_cap(struct file *file, void *priv,
1035                                  struct v4l2_fmtdesc *f)
1036 {
1037         switch (f->index) {
1038         case 0:
1039                 f->pixelformat = V4L2_PIX_FMT_MPEG;
1040                 strcpy(f->description, "MPEG-4 AVC");
1041                 break;
1042         case 1:
1043                 f->pixelformat = V4L2_PIX_FMT_MJPEG;
1044                 strcpy(f->description, "MJPEG");
1045                 break;
1046         default:
1047                 return -EINVAL;
1048         }
1049
1050         f->flags = V4L2_FMT_FLAG_COMPRESSED;
1051
1052         return 0;
1053 }
1054
1055 static int solo_enc_try_fmt_cap(struct file *file, void *priv,
1056                             struct v4l2_format *f)
1057 {
1058         struct solo_enc_fh *fh = priv;
1059         struct solo_enc_dev *solo_enc = fh->enc;
1060         struct solo6010_dev *solo_dev = solo_enc->solo_dev;
1061         struct v4l2_pix_format *pix = &f->fmt.pix;
1062
1063         if (pix->pixelformat != V4L2_PIX_FMT_MPEG &&
1064             pix->pixelformat != V4L2_PIX_FMT_MJPEG)
1065                 return -EINVAL;
1066
1067         /* We cannot change width/height in mid read */
1068         if (atomic_read(&solo_enc->readers) > 0) {
1069                 if (pix->width != solo_enc->width ||
1070                     pix->height != solo_enc->height)
1071                         return -EBUSY;
1072         }
1073
1074         if (pix->width < solo_dev->video_hsize ||
1075             pix->height < solo_dev->video_vsize << 1) {
1076                 /* Default to CIF 1/2 size */
1077                 pix->width = solo_dev->video_hsize >> 1;
1078                 pix->height = solo_dev->video_vsize;
1079         } else {
1080                 /* Full frame */
1081                 pix->width = solo_dev->video_hsize;
1082                 pix->height = solo_dev->video_vsize << 1;
1083         }
1084
1085         if (pix->field == V4L2_FIELD_ANY)
1086                 pix->field = V4L2_FIELD_INTERLACED;
1087         else if (pix->field != V4L2_FIELD_INTERLACED)
1088                 pix->field = V4L2_FIELD_INTERLACED;
1089
1090         /* Just set these */
1091         pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
1092         pix->sizeimage = FRAME_BUF_SIZE;
1093
1094         return 0;
1095 }
1096
1097 static int solo_enc_set_fmt_cap(struct file *file, void *priv,
1098                                 struct v4l2_format *f)
1099 {
1100         struct solo_enc_fh *fh = priv;
1101         struct solo_enc_dev *solo_enc = fh->enc;
1102         struct solo6010_dev *solo_dev = solo_enc->solo_dev;
1103         struct v4l2_pix_format *pix = &f->fmt.pix;
1104         int ret;
1105
1106         spin_lock(&solo_enc->lock);
1107
1108         ret = solo_enc_try_fmt_cap(file, priv, f);
1109         if (ret) {
1110                 spin_unlock(&solo_enc->lock);
1111                 return ret;
1112         }
1113
1114         if (pix->width == solo_dev->video_hsize)
1115                 solo_enc->mode = SOLO_ENC_MODE_D1;
1116         else
1117                 solo_enc->mode = SOLO_ENC_MODE_CIF;
1118
1119         /* This does not change the encoder at all */
1120         fh->fmt = pix->pixelformat;
1121
1122         if (pix->priv)
1123                 fh->type = SOLO_ENC_TYPE_EXT;
1124         ret = solo_enc_on(fh);
1125
1126         spin_unlock(&solo_enc->lock);
1127
1128         if (ret)
1129                 return ret;
1130
1131         return solo_start_fh_thread(fh);
1132 }
1133
1134 static int solo_enc_get_fmt_cap(struct file *file, void *priv,
1135                                 struct v4l2_format *f)
1136 {
1137         struct solo_enc_fh *fh = priv;
1138         struct solo_enc_dev *solo_enc = fh->enc;
1139         struct v4l2_pix_format *pix = &f->fmt.pix;
1140
1141         pix->width = solo_enc->width;
1142         pix->height = solo_enc->height;
1143         pix->pixelformat = fh->fmt;
1144         pix->field = solo_enc->interlaced ? V4L2_FIELD_INTERLACED :
1145                      V4L2_FIELD_NONE;
1146         pix->sizeimage = FRAME_BUF_SIZE;
1147         pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
1148
1149         return 0;
1150 }
1151
1152 static int solo_enc_reqbufs(struct file *file, void *priv,
1153                             struct v4l2_requestbuffers *req)
1154 {
1155         struct solo_enc_fh *fh = priv;
1156
1157         return videobuf_reqbufs(&fh->vidq, req);
1158 }
1159
1160 static int solo_enc_querybuf(struct file *file, void *priv,
1161                              struct v4l2_buffer *buf)
1162 {
1163         struct solo_enc_fh *fh = priv;
1164
1165         return videobuf_querybuf(&fh->vidq, buf);
1166 }
1167
1168 static int solo_enc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
1169 {
1170         struct solo_enc_fh *fh = priv;
1171
1172         return videobuf_qbuf(&fh->vidq, buf);
1173 }
1174
1175 static int solo_enc_dqbuf(struct file *file, void *priv,
1176                           struct v4l2_buffer *buf)
1177 {
1178         struct solo_enc_fh *fh = priv;
1179         struct solo_enc_dev *solo_enc = fh->enc;
1180         int ret;
1181
1182         /* Make sure the encoder is on */
1183         if (!fh->enc_on) {
1184                 spin_lock(&solo_enc->lock);
1185                 ret = solo_enc_on(fh);
1186                 spin_unlock(&solo_enc->lock);
1187                 if (ret)
1188                         return ret;
1189
1190                 ret = solo_start_fh_thread(fh);
1191                 if (ret)
1192                         return ret;
1193         }
1194
1195         ret = videobuf_dqbuf(&fh->vidq, buf, file->f_flags & O_NONBLOCK);
1196         if (ret)
1197                 return ret;
1198
1199         /* Signal motion detection */
1200         if (solo_is_motion_on(solo_enc)) {
1201                 buf->flags |= V4L2_BUF_FLAG_MOTION_ON;
1202                 if (solo_enc->motion_detected) {
1203                         buf->flags |= V4L2_BUF_FLAG_MOTION_DETECTED;
1204                         solo_reg_write(solo_enc->solo_dev, SOLO_VI_MOT_CLEAR,
1205                                        1 << solo_enc->ch);
1206                         solo_enc->motion_detected = 0;
1207                 }
1208         }
1209
1210         /* Check for key frame on mpeg data */
1211         if (fh->fmt == V4L2_PIX_FMT_MPEG) {
1212                 struct videobuf_dmabuf *vbuf =
1213                                 videobuf_to_dma(fh->vidq.bufs[buf->index]);
1214
1215                 if (vbuf) {
1216                         u8 *p = sg_virt(vbuf->sglist);
1217                         if (p[3] == 0x00)
1218                                 buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
1219                         else
1220                                 buf->flags |= V4L2_BUF_FLAG_PFRAME;
1221                 }
1222         }
1223
1224         return 0;
1225 }
1226
1227 static int solo_enc_streamon(struct file *file, void *priv,
1228                              enum v4l2_buf_type i)
1229 {
1230         struct solo_enc_fh *fh = priv;
1231
1232         if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1233                 return -EINVAL;
1234
1235         return videobuf_streamon(&fh->vidq);
1236 }
1237
1238 static int solo_enc_streamoff(struct file *file, void *priv,
1239                               enum v4l2_buf_type i)
1240 {
1241         struct solo_enc_fh *fh = priv;
1242
1243         if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1244                 return -EINVAL;
1245
1246         return videobuf_streamoff(&fh->vidq);
1247 }
1248
1249 static int solo_enc_s_std(struct file *file, void *priv, v4l2_std_id *i)
1250 {
1251         return 0;
1252 }
1253
1254 static int solo_enum_framesizes(struct file *file, void *priv,
1255                                 struct v4l2_frmsizeenum *fsize)
1256 {
1257         struct solo_enc_fh *fh = priv;
1258         struct solo6010_dev *solo_dev = fh->enc->solo_dev;
1259
1260         if (fsize->pixel_format != V4L2_PIX_FMT_MPEG)
1261                 return -EINVAL;
1262
1263         switch (fsize->index) {
1264         case 0:
1265                 fsize->discrete.width = solo_dev->video_hsize >> 1;
1266                 fsize->discrete.height = solo_dev->video_vsize;
1267                 break;
1268         case 1:
1269                 fsize->discrete.width = solo_dev->video_hsize;
1270                 fsize->discrete.height = solo_dev->video_vsize << 1;
1271                 break;
1272         default:
1273                 return -EINVAL;
1274         }
1275
1276         fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1277
1278         return 0;
1279 }
1280
1281 static int solo_enum_frameintervals(struct file *file, void *priv,
1282                                     struct v4l2_frmivalenum *fintv)
1283 {
1284         struct solo_enc_fh *fh = priv;
1285         struct solo6010_dev *solo_dev = fh->enc->solo_dev;
1286
1287         if (fintv->pixel_format != V4L2_PIX_FMT_MPEG || fintv->index)
1288                 return -EINVAL;
1289
1290         fintv->type = V4L2_FRMIVAL_TYPE_STEPWISE;
1291
1292         fintv->stepwise.min.numerator = solo_dev->fps;
1293         fintv->stepwise.min.denominator = 1;
1294
1295         fintv->stepwise.max.numerator = solo_dev->fps;
1296         fintv->stepwise.max.denominator = 15;
1297
1298         fintv->stepwise.step.numerator = 1;
1299         fintv->stepwise.step.denominator = 1;
1300
1301         return 0;
1302 }
1303
1304 static int solo_g_parm(struct file *file, void *priv,
1305                        struct v4l2_streamparm *sp)
1306 {
1307         struct solo_enc_fh *fh = priv;
1308         struct solo_enc_dev *solo_enc = fh->enc;
1309         struct solo6010_dev *solo_dev = solo_enc->solo_dev;
1310         struct v4l2_captureparm *cp = &sp->parm.capture;
1311
1312         cp->capability = V4L2_CAP_TIMEPERFRAME;
1313         cp->timeperframe.numerator = solo_enc->interval;
1314         cp->timeperframe.denominator = solo_dev->fps;
1315         cp->capturemode = 0;
1316         /* XXX: Shouldn't we be able to get/set this from videobuf? */
1317         cp->readbuffers = 2;
1318
1319         return 0;
1320 }
1321
1322 static int solo_s_parm(struct file *file, void *priv,
1323                        struct v4l2_streamparm *sp)
1324 {
1325         struct solo_enc_fh *fh = priv;
1326         struct solo_enc_dev *solo_enc = fh->enc;
1327         struct solo6010_dev *solo_dev = solo_enc->solo_dev;
1328         struct v4l2_captureparm *cp = &sp->parm.capture;
1329
1330         spin_lock(&solo_enc->lock);
1331
1332         if (atomic_read(&solo_enc->readers) > 0) {
1333                 spin_unlock(&solo_enc->lock);
1334                 return -EBUSY;
1335         }
1336
1337         if ((cp->timeperframe.numerator == 0) ||
1338             (cp->timeperframe.denominator == 0)) {
1339                 /* reset framerate */
1340                 cp->timeperframe.numerator = 1;
1341                 cp->timeperframe.denominator = solo_dev->fps;
1342         }
1343
1344         if (cp->timeperframe.denominator != solo_dev->fps)
1345                 cp->timeperframe.denominator = solo_dev->fps;
1346
1347         if (cp->timeperframe.numerator > 15)
1348                 cp->timeperframe.numerator = 15;
1349
1350         solo_enc->interval = cp->timeperframe.numerator;
1351
1352         cp->capability = V4L2_CAP_TIMEPERFRAME;
1353
1354         solo_enc->gop = max(solo_dev->fps / solo_enc->interval, 1);
1355         solo_update_mode(solo_enc);
1356
1357         spin_unlock(&solo_enc->lock);
1358
1359         return 0;
1360 }
1361
1362 static int solo_queryctrl(struct file *file, void *priv,
1363                           struct v4l2_queryctrl *qc)
1364 {
1365         struct solo_enc_fh *fh = priv;
1366         struct solo_enc_dev *solo_enc = fh->enc;
1367         struct solo6010_dev *solo_dev = solo_enc->solo_dev;
1368
1369         qc->id = v4l2_ctrl_next(solo_ctrl_classes, qc->id);
1370         if (!qc->id)
1371                 return -EINVAL;
1372
1373         switch (qc->id) {
1374         case V4L2_CID_BRIGHTNESS:
1375         case V4L2_CID_CONTRAST:
1376         case V4L2_CID_SATURATION:
1377         case V4L2_CID_HUE:
1378                 return v4l2_ctrl_query_fill(qc, 0x00, 0xff, 1, 0x80);
1379         case V4L2_CID_SHARPNESS:
1380                 return v4l2_ctrl_query_fill(qc, 0x00, 0x0f, 1, 0x00);
1381         case V4L2_CID_MPEG_VIDEO_ENCODING:
1382                 return v4l2_ctrl_query_fill(
1383                         qc, V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
1384                         V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 1,
1385                         V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC);
1386         case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
1387                 return v4l2_ctrl_query_fill(qc, 1, 255, 1, solo_dev->fps);
1388 #ifdef PRIVATE_CIDS
1389         case V4L2_CID_MOTION_THRESHOLD:
1390                 qc->flags |= V4L2_CTRL_FLAG_SLIDER;
1391                 qc->type = V4L2_CTRL_TYPE_INTEGER;
1392                 qc->minimum = 0;
1393                 qc->maximum = 0xffff;
1394                 qc->step = 1;
1395                 qc->default_value = SOLO_DEF_MOT_THRESH;
1396                 strlcpy(qc->name, "Motion Detection Threshold",
1397                         sizeof(qc->name));
1398                 return 0;
1399         case V4L2_CID_MOTION_ENABLE:
1400                 qc->type = V4L2_CTRL_TYPE_BOOLEAN;
1401                 qc->minimum = 0;
1402                 qc->maximum = qc->step = 1;
1403                 qc->default_value = 0;
1404                 strlcpy(qc->name, "Motion Detection Enable", sizeof(qc->name));
1405                 return 0;
1406 #else
1407         case V4L2_CID_MOTION_THRESHOLD:
1408                 return v4l2_ctrl_query_fill(qc, 0, 0xffff, 1,
1409                                             SOLO_DEF_MOT_THRESH);
1410         case V4L2_CID_MOTION_ENABLE:
1411                 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
1412 #endif
1413         case V4L2_CID_RDS_TX_RADIO_TEXT:
1414                 qc->type = V4L2_CTRL_TYPE_STRING;
1415                 qc->minimum = 0;
1416                 qc->maximum = OSD_TEXT_MAX;
1417                 qc->step = 1;
1418                 qc->default_value = 0;
1419                 strlcpy(qc->name, "OSD Text", sizeof(qc->name));
1420                 return 0;
1421         }
1422
1423         return -EINVAL;
1424 }
1425
1426 static int solo_querymenu(struct file *file, void *priv,
1427                           struct v4l2_querymenu *qmenu)
1428 {
1429         struct v4l2_queryctrl qctrl;
1430         int err;
1431
1432         qctrl.id = qmenu->id;
1433         err = solo_queryctrl(file, priv, &qctrl);
1434         if (err)
1435                 return err;
1436
1437         return v4l2_ctrl_query_menu(qmenu, &qctrl, NULL);
1438 }
1439
1440 static int solo_g_ctrl(struct file *file, void *priv,
1441                        struct v4l2_control *ctrl)
1442 {
1443         struct solo_enc_fh *fh = priv;
1444         struct solo_enc_dev *solo_enc = fh->enc;
1445         struct solo6010_dev *solo_dev = solo_enc->solo_dev;
1446
1447         switch (ctrl->id) {
1448         case V4L2_CID_BRIGHTNESS:
1449         case V4L2_CID_CONTRAST:
1450         case V4L2_CID_SATURATION:
1451         case V4L2_CID_HUE:
1452         case V4L2_CID_SHARPNESS:
1453                 return tw28_get_ctrl_val(solo_dev, ctrl->id, solo_enc->ch,
1454                                          &ctrl->value);
1455         case V4L2_CID_MPEG_VIDEO_ENCODING:
1456                 ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC;
1457                 break;
1458         case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
1459                 ctrl->value = solo_enc->gop;
1460                 break;
1461         case V4L2_CID_MOTION_THRESHOLD:
1462                 ctrl->value = solo_enc->motion_thresh;
1463                 break;
1464         case V4L2_CID_MOTION_ENABLE:
1465                 ctrl->value = solo_is_motion_on(solo_enc);
1466                 break;
1467         default:
1468                 return -EINVAL;
1469         }
1470
1471         return 0;
1472 }
1473
1474 static int solo_s_ctrl(struct file *file, void *priv,
1475                        struct v4l2_control *ctrl)
1476 {
1477         struct solo_enc_fh *fh = priv;
1478         struct solo_enc_dev *solo_enc = fh->enc;
1479         struct solo6010_dev *solo_dev = solo_enc->solo_dev;
1480
1481         switch (ctrl->id) {
1482         case V4L2_CID_BRIGHTNESS:
1483         case V4L2_CID_CONTRAST:
1484         case V4L2_CID_SATURATION:
1485         case V4L2_CID_HUE:
1486         case V4L2_CID_SHARPNESS:
1487                 return tw28_set_ctrl_val(solo_dev, ctrl->id, solo_enc->ch,
1488                                          ctrl->value);
1489         case V4L2_CID_MPEG_VIDEO_ENCODING:
1490                 if (ctrl->value != V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC)
1491                         return -ERANGE;
1492                 break;
1493         case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
1494                 if (ctrl->value < 1 || ctrl->value > 255)
1495                         return -ERANGE;
1496                 solo_enc->gop = ctrl->value;
1497                 solo_reg_write(solo_dev, SOLO_VE_CH_GOP(solo_enc->ch),
1498                                solo_enc->gop);
1499                 solo_reg_write(solo_dev, SOLO_VE_CH_GOP_E(solo_enc->ch),
1500                                solo_enc->gop);
1501                 break;
1502         case V4L2_CID_MOTION_THRESHOLD:
1503                 /* TODO accept value on lower 16-bits and use high
1504                  * 16-bits to assign the value to a specific block */
1505                 if (ctrl->value < 0 || ctrl->value > 0xffff)
1506                         return -ERANGE;
1507                 solo_enc->motion_thresh = ctrl->value;
1508                 solo_set_motion_threshold(solo_dev, solo_enc->ch, ctrl->value);
1509                 break;
1510         case V4L2_CID_MOTION_ENABLE:
1511                 solo_motion_toggle(solo_enc, ctrl->value);
1512                 break;
1513         default:
1514                 return -EINVAL;
1515         }
1516
1517         return 0;
1518 }
1519
1520 static int solo_s_ext_ctrls(struct file *file, void *priv,
1521                             struct v4l2_ext_controls *ctrls)
1522 {
1523         struct solo_enc_fh *fh = priv;
1524         struct solo_enc_dev *solo_enc = fh->enc;
1525         int i;
1526
1527         for (i = 0; i < ctrls->count; i++) {
1528                 struct v4l2_ext_control *ctrl = (ctrls->controls + i);
1529                 int err;
1530
1531                 switch (ctrl->id) {
1532                 case V4L2_CID_RDS_TX_RADIO_TEXT:
1533                         if (ctrl->size - 1 > OSD_TEXT_MAX)
1534                                 err = -ERANGE;
1535                         else {
1536                                 err = copy_from_user(solo_enc->osd_text,
1537                                                      ctrl->string,
1538                                                      OSD_TEXT_MAX);
1539                                 solo_enc->osd_text[OSD_TEXT_MAX] = '\0';
1540                                 if (!err)
1541                                         err = solo_osd_print(solo_enc);
1542                         }
1543                         break;
1544                 default:
1545                         err = -EINVAL;
1546                 }
1547
1548                 if (err < 0) {
1549                         ctrls->error_idx = i;
1550                         return err;
1551                 }
1552         }
1553
1554         return 0;
1555 }
1556
1557 static int solo_g_ext_ctrls(struct file *file, void *priv,
1558                             struct v4l2_ext_controls *ctrls)
1559 {
1560         struct solo_enc_fh *fh = priv;
1561         struct solo_enc_dev *solo_enc = fh->enc;
1562         int i;
1563
1564         for (i = 0; i < ctrls->count; i++) {
1565                 struct v4l2_ext_control *ctrl = (ctrls->controls + i);
1566                 int err;
1567
1568                 switch (ctrl->id) {
1569                 case V4L2_CID_RDS_TX_RADIO_TEXT:
1570                         if (ctrl->size < OSD_TEXT_MAX) {
1571                                 ctrl->size = OSD_TEXT_MAX;
1572                                 err = -ENOSPC;
1573                         } else {
1574                                 err = copy_to_user(ctrl->string,
1575                                                    solo_enc->osd_text,
1576                                                    OSD_TEXT_MAX);
1577                         }
1578                         break;
1579                 default:
1580                         err = -EINVAL;
1581                 }
1582
1583                 if (err < 0) {
1584                         ctrls->error_idx = i;
1585                         return err;
1586                 }
1587         }
1588
1589         return 0;
1590 }
1591
1592 static const struct v4l2_file_operations solo_enc_fops = {
1593         .owner                  = THIS_MODULE,
1594         .open                   = solo_enc_open,
1595         .release                = solo_enc_release,
1596         .read                   = solo_enc_read,
1597         .poll                   = solo_enc_poll,
1598         .mmap                   = solo_enc_mmap,
1599         .ioctl                  = video_ioctl2,
1600 };
1601
1602 static const struct v4l2_ioctl_ops solo_enc_ioctl_ops = {
1603         .vidioc_querycap                = solo_enc_querycap,
1604         .vidioc_s_std                   = solo_enc_s_std,
1605         /* Input callbacks */
1606         .vidioc_enum_input              = solo_enc_enum_input,
1607         .vidioc_s_input                 = solo_enc_set_input,
1608         .vidioc_g_input                 = solo_enc_get_input,
1609         /* Video capture format callbacks */
1610         .vidioc_enum_fmt_vid_cap        = solo_enc_enum_fmt_cap,
1611         .vidioc_try_fmt_vid_cap         = solo_enc_try_fmt_cap,
1612         .vidioc_s_fmt_vid_cap           = solo_enc_set_fmt_cap,
1613         .vidioc_g_fmt_vid_cap           = solo_enc_get_fmt_cap,
1614         /* Streaming I/O */
1615         .vidioc_reqbufs                 = solo_enc_reqbufs,
1616         .vidioc_querybuf                = solo_enc_querybuf,
1617         .vidioc_qbuf                    = solo_enc_qbuf,
1618         .vidioc_dqbuf                   = solo_enc_dqbuf,
1619         .vidioc_streamon                = solo_enc_streamon,
1620         .vidioc_streamoff               = solo_enc_streamoff,
1621         /* Frame size and interval */
1622         .vidioc_enum_framesizes         = solo_enum_framesizes,
1623         .vidioc_enum_frameintervals     = solo_enum_frameintervals,
1624         /* Video capture parameters */
1625         .vidioc_s_parm                  = solo_s_parm,
1626         .vidioc_g_parm                  = solo_g_parm,
1627         /* Controls */
1628         .vidioc_queryctrl               = solo_queryctrl,
1629         .vidioc_querymenu               = solo_querymenu,
1630         .vidioc_g_ctrl                  = solo_g_ctrl,
1631         .vidioc_s_ctrl                  = solo_s_ctrl,
1632         .vidioc_g_ext_ctrls             = solo_g_ext_ctrls,
1633         .vidioc_s_ext_ctrls             = solo_s_ext_ctrls,
1634 };
1635
1636 static struct video_device solo_enc_template = {
1637         .name                   = SOLO6010_NAME,
1638         .fops                   = &solo_enc_fops,
1639         .ioctl_ops              = &solo_enc_ioctl_ops,
1640         .minor                  = -1,
1641         .release                = video_device_release,
1642
1643         .tvnorms                = V4L2_STD_NTSC_M | V4L2_STD_PAL_B,
1644         .current_norm           = V4L2_STD_NTSC_M,
1645 };
1646
1647 static struct solo_enc_dev *solo_enc_alloc(struct solo6010_dev *solo_dev, u8 ch)
1648 {
1649         struct solo_enc_dev *solo_enc;
1650         int ret;
1651
1652         solo_enc = kzalloc(sizeof(*solo_enc), GFP_KERNEL);
1653         if (!solo_enc)
1654                 return ERR_PTR(-ENOMEM);
1655
1656         solo_enc->vfd = video_device_alloc();
1657         if (!solo_enc->vfd) {
1658                 kfree(solo_enc);
1659                 return ERR_PTR(-ENOMEM);
1660         }
1661
1662         solo_enc->solo_dev = solo_dev;
1663         solo_enc->ch = ch;
1664
1665         *solo_enc->vfd = solo_enc_template;
1666         solo_enc->vfd->parent = &solo_dev->pdev->dev;
1667         ret = video_register_device(solo_enc->vfd, VFL_TYPE_GRABBER,
1668                                     video_nr);
1669         if (ret < 0) {
1670                 video_device_release(solo_enc->vfd);
1671                 kfree(solo_enc);
1672                 return ERR_PTR(ret);
1673         }
1674
1675         video_set_drvdata(solo_enc->vfd, solo_enc);
1676
1677         snprintf(solo_enc->vfd->name, sizeof(solo_enc->vfd->name),
1678                  "%s-enc (%i/%i)", SOLO6010_NAME, solo_dev->vfd->num,
1679                  solo_enc->vfd->num);
1680
1681         if (video_nr != -1)
1682                 video_nr++;
1683
1684         spin_lock_init(&solo_enc->lock);
1685         init_waitqueue_head(&solo_enc->thread_wait);
1686         atomic_set(&solo_enc->readers, 0);
1687
1688         solo_enc->qp = SOLO_DEFAULT_QP;
1689         solo_enc->gop = solo_dev->fps;
1690         solo_enc->interval = 1;
1691         solo_enc->mode = SOLO_ENC_MODE_CIF;
1692         solo_enc->motion_thresh = SOLO_DEF_MOT_THRESH;
1693
1694         spin_lock(&solo_enc->lock);
1695         solo_update_mode(solo_enc);
1696         spin_unlock(&solo_enc->lock);
1697
1698         return solo_enc;
1699 }
1700
1701 static void solo_enc_free(struct solo_enc_dev *solo_enc)
1702 {
1703         if (solo_enc == NULL)
1704                 return;
1705
1706         video_unregister_device(solo_enc->vfd);
1707         kfree(solo_enc);
1708 }
1709
1710 int solo_enc_v4l2_init(struct solo6010_dev *solo_dev)
1711 {
1712         int i;
1713
1714         for (i = 0; i < solo_dev->nr_chans; i++) {
1715                 solo_dev->v4l2_enc[i] = solo_enc_alloc(solo_dev, i);
1716                 if (IS_ERR(solo_dev->v4l2_enc[i]))
1717                         break;
1718         }
1719
1720         if (i != solo_dev->nr_chans) {
1721                 int ret = PTR_ERR(solo_dev->v4l2_enc[i]);
1722                 while (i--)
1723                         solo_enc_free(solo_dev->v4l2_enc[i]);
1724                 return ret;
1725         }
1726
1727         /* D1@MAX-FPS * 4 */
1728         solo_dev->enc_bw_remain = solo_dev->fps * 4 * 4;
1729
1730         dev_info(&solo_dev->pdev->dev, "Encoders as /dev/video%d-%d\n",
1731                  solo_dev->v4l2_enc[0]->vfd->num,
1732                  solo_dev->v4l2_enc[solo_dev->nr_chans - 1]->vfd->num);
1733
1734         return 0;
1735 }
1736
1737 void solo_enc_v4l2_exit(struct solo6010_dev *solo_dev)
1738 {
1739         int i;
1740
1741         solo6010_irq_off(solo_dev, SOLO_IRQ_MOTION);
1742
1743         for (i = 0; i < solo_dev->nr_chans; i++)
1744                 solo_enc_free(solo_dev->v4l2_enc[i]);
1745 }