2 * Copyright (C) 2010-2013 Bluecherry, LLC <http://www.bluecherrydvr.com>
5 * Ben Collins <bcollins@ubuntu.com>
8 * John Brooks <john.brooks@bluecherry.net>
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.
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.
21 #include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/kthread.h>
24 #include <linux/freezer.h>
26 #include <media/v4l2-ioctl.h>
27 #include <media/v4l2-common.h>
28 #include <media/v4l2-event.h>
29 #include <media/videobuf2-dma-sg.h>
32 #include "solo6x10-tw28.h"
33 #include "solo6x10-jpeg.h"
35 #define MIN_VID_BUFFERS 2
36 #define FRAME_BUF_SIZE (196 * 1024)
38 #define DMA_ALIGN 4096
41 static u8 vop_6010_ntsc_d1
[] = {
42 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20,
43 0x02, 0x48, 0x1d, 0xc0, 0x00, 0x40, 0x00, 0x40,
44 0x00, 0x40, 0x00, 0x80, 0x00, 0x97, 0x53, 0x04,
45 0x1f, 0x4c, 0x58, 0x10, 0xf0, 0x71, 0x18, 0x3f,
48 static u8 vop_6010_ntsc_cif
[] = {
49 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20,
50 0x02, 0x48, 0x1d, 0xc0, 0x00, 0x40, 0x00, 0x40,
51 0x00, 0x40, 0x00, 0x80, 0x00, 0x97, 0x53, 0x04,
52 0x1f, 0x4c, 0x2c, 0x10, 0x78, 0x51, 0x18, 0x3f,
55 static u8 vop_6010_pal_d1
[] = {
56 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20,
57 0x02, 0x48, 0x15, 0xc0, 0x00, 0x40, 0x00, 0x40,
58 0x00, 0x40, 0x00, 0x80, 0x00, 0x97, 0x53, 0x04,
59 0x1f, 0x4c, 0x58, 0x11, 0x20, 0x71, 0x18, 0x3f,
62 static u8 vop_6010_pal_cif
[] = {
63 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20,
64 0x02, 0x48, 0x15, 0xc0, 0x00, 0x40, 0x00, 0x40,
65 0x00, 0x40, 0x00, 0x80, 0x00, 0x97, 0x53, 0x04,
66 0x1f, 0x4c, 0x2c, 0x10, 0x90, 0x51, 0x18, 0x3f,
70 static u8 vop_6110_ntsc_d1
[] = {
71 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0x00, 0x1e,
72 0x9a, 0x74, 0x05, 0x81, 0xec, 0x80, 0x00, 0x00,
73 0x00, 0x01, 0x68, 0xce, 0x32, 0x28, 0x00, 0x00,
76 static u8 vop_6110_ntsc_cif
[] = {
77 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0x00, 0x1e,
78 0x9a, 0x74, 0x0b, 0x0f, 0xc8, 0x00, 0x00, 0x00,
79 0x01, 0x68, 0xce, 0x32, 0x28, 0x00, 0x00, 0x00,
82 static u8 vop_6110_pal_d1
[] = {
83 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0x00, 0x1e,
84 0x9a, 0x74, 0x05, 0x80, 0x93, 0x20, 0x00, 0x00,
85 0x00, 0x01, 0x68, 0xce, 0x32, 0x28, 0x00, 0x00,
88 static u8 vop_6110_pal_cif
[] = {
89 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0x00, 0x1e,
90 0x9a, 0x74, 0x0b, 0x04, 0xb2, 0x00, 0x00, 0x00,
91 0x01, 0x68, 0xce, 0x32, 0x28, 0x00, 0x00, 0x00,
94 typedef __le32 vop_header
[16];
97 enum solo_enc_types type
;
102 static int solo_is_motion_on(struct solo_enc_dev
*solo_enc
)
104 struct solo_dev
*solo_dev
= solo_enc
->solo_dev
;
106 return (solo_dev
->motion_mask
>> solo_enc
->ch
) & 1;
109 static int solo_motion_detected(struct solo_enc_dev
*solo_enc
)
111 struct solo_dev
*solo_dev
= solo_enc
->solo_dev
;
113 u32 ch_mask
= 1 << solo_enc
->ch
;
116 spin_lock_irqsave(&solo_enc
->motion_lock
, flags
);
117 if (solo_reg_read(solo_dev
, SOLO_VI_MOT_STATUS
) & ch_mask
) {
118 solo_reg_write(solo_dev
, SOLO_VI_MOT_CLEAR
, ch_mask
);
121 spin_unlock_irqrestore(&solo_enc
->motion_lock
, flags
);
126 static void solo_motion_toggle(struct solo_enc_dev
*solo_enc
, int on
)
128 struct solo_dev
*solo_dev
= solo_enc
->solo_dev
;
129 u32 mask
= 1 << solo_enc
->ch
;
132 spin_lock_irqsave(&solo_enc
->motion_lock
, flags
);
135 solo_dev
->motion_mask
|= mask
;
137 solo_dev
->motion_mask
&= ~mask
;
139 solo_reg_write(solo_dev
, SOLO_VI_MOT_CLEAR
, mask
);
141 solo_reg_write(solo_dev
, SOLO_VI_MOT_ADR
,
142 SOLO_VI_MOTION_EN(solo_dev
->motion_mask
) |
143 (SOLO_MOTION_EXT_ADDR(solo_dev
) >> 16));
145 spin_unlock_irqrestore(&solo_enc
->motion_lock
, flags
);
148 void solo_update_mode(struct solo_enc_dev
*solo_enc
)
150 struct solo_dev
*solo_dev
= solo_enc
->solo_dev
;
154 solo_enc
->interlaced
= (solo_enc
->mode
& 0x08) ? 1 : 0;
155 solo_enc
->bw_weight
= max(solo_dev
->fps
/ solo_enc
->interval
, 1);
157 if (solo_enc
->mode
== SOLO_ENC_MODE_CIF
) {
158 solo_enc
->width
= solo_dev
->video_hsize
>> 1;
159 solo_enc
->height
= solo_dev
->video_vsize
;
160 if (solo_dev
->type
== SOLO_DEV_6110
) {
161 if (solo_dev
->video_type
== SOLO_VO_FMT_TYPE_NTSC
) {
162 vop
= vop_6110_ntsc_cif
;
163 vop_len
= sizeof(vop_6110_ntsc_cif
);
165 vop
= vop_6110_pal_cif
;
166 vop_len
= sizeof(vop_6110_pal_cif
);
169 if (solo_dev
->video_type
== SOLO_VO_FMT_TYPE_NTSC
) {
170 vop
= vop_6010_ntsc_cif
;
171 vop_len
= sizeof(vop_6010_ntsc_cif
);
173 vop
= vop_6010_pal_cif
;
174 vop_len
= sizeof(vop_6010_pal_cif
);
178 solo_enc
->width
= solo_dev
->video_hsize
;
179 solo_enc
->height
= solo_dev
->video_vsize
<< 1;
180 solo_enc
->bw_weight
<<= 2;
181 if (solo_dev
->type
== SOLO_DEV_6110
) {
182 if (solo_dev
->video_type
== SOLO_VO_FMT_TYPE_NTSC
) {
183 vop
= vop_6110_ntsc_d1
;
184 vop_len
= sizeof(vop_6110_ntsc_d1
);
186 vop
= vop_6110_pal_d1
;
187 vop_len
= sizeof(vop_6110_pal_d1
);
190 if (solo_dev
->video_type
== SOLO_VO_FMT_TYPE_NTSC
) {
191 vop
= vop_6010_ntsc_d1
;
192 vop_len
= sizeof(vop_6010_ntsc_d1
);
194 vop
= vop_6010_pal_d1
;
195 vop_len
= sizeof(vop_6010_pal_d1
);
200 memcpy(solo_enc
->vop
, vop
, vop_len
);
202 /* Some fixups for 6010/M4V */
203 if (solo_dev
->type
== SOLO_DEV_6010
) {
204 u16 fps
= solo_dev
->fps
* 1000;
205 u16 interval
= solo_enc
->interval
* 1000;
209 /* Frame rate and interval */
211 vop
[23] = ((fps
<< 4) & 0xf0) | 0x0c
212 | ((interval
>> 13) & 0x3);
213 vop
[24] = (interval
>> 5) & 0xff;
214 vop
[25] = ((interval
<< 3) & 0xf8) | 0x04;
217 solo_enc
->vop_len
= vop_len
;
219 /* Now handle the jpeg header */
220 vop
= solo_enc
->jpeg_header
;
221 vop
[SOF0_START
+ 5] = 0xff & (solo_enc
->height
>> 8);
222 vop
[SOF0_START
+ 6] = 0xff & solo_enc
->height
;
223 vop
[SOF0_START
+ 7] = 0xff & (solo_enc
->width
>> 8);
224 vop
[SOF0_START
+ 8] = 0xff & solo_enc
->width
;
226 memcpy(vop
+ DQT_START
,
227 jpeg_dqt
[solo_g_jpeg_qp(solo_dev
, solo_enc
->ch
)], DQT_LEN
);
230 static int solo_enc_on(struct solo_enc_dev
*solo_enc
)
232 u8 ch
= solo_enc
->ch
;
233 struct solo_dev
*solo_dev
= solo_enc
->solo_dev
;
236 solo_update_mode(solo_enc
);
238 /* Make sure to do a bandwidth check */
239 if (solo_enc
->bw_weight
> solo_dev
->enc_bw_remain
)
241 solo_enc
->sequence
= 0;
242 solo_dev
->enc_bw_remain
-= solo_enc
->bw_weight
;
244 if (solo_enc
->type
== SOLO_ENC_TYPE_EXT
)
245 solo_reg_write(solo_dev
, SOLO_CAP_CH_COMP_ENA_E(ch
), 1);
247 /* Disable all encoding for this channel */
248 solo_reg_write(solo_dev
, SOLO_CAP_CH_SCALE(ch
), 0);
250 /* Common for both std and ext encoding */
251 solo_reg_write(solo_dev
, SOLO_VE_CH_INTL(ch
),
252 solo_enc
->interlaced
? 1 : 0);
254 if (solo_enc
->interlaced
)
255 interval
= solo_enc
->interval
- 1;
257 interval
= solo_enc
->interval
;
259 /* Standard encoding only */
260 solo_reg_write(solo_dev
, SOLO_VE_CH_GOP(ch
), solo_enc
->gop
);
261 solo_reg_write(solo_dev
, SOLO_VE_CH_QP(ch
), solo_enc
->qp
);
262 solo_reg_write(solo_dev
, SOLO_CAP_CH_INTV(ch
), interval
);
264 /* Extended encoding only */
265 solo_reg_write(solo_dev
, SOLO_VE_CH_GOP_E(ch
), solo_enc
->gop
);
266 solo_reg_write(solo_dev
, SOLO_VE_CH_QP_E(ch
), solo_enc
->qp
);
267 solo_reg_write(solo_dev
, SOLO_CAP_CH_INTV_E(ch
), interval
);
269 /* Enables the standard encoder */
270 solo_reg_write(solo_dev
, SOLO_CAP_CH_SCALE(ch
), solo_enc
->mode
);
275 static void solo_enc_off(struct solo_enc_dev
*solo_enc
)
277 struct solo_dev
*solo_dev
= solo_enc
->solo_dev
;
279 solo_dev
->enc_bw_remain
+= solo_enc
->bw_weight
;
281 solo_reg_write(solo_dev
, SOLO_CAP_CH_SCALE(solo_enc
->ch
), 0);
282 solo_reg_write(solo_dev
, SOLO_CAP_CH_COMP_ENA_E(solo_enc
->ch
), 0);
285 static int enc_get_mpeg_dma(struct solo_dev
*solo_dev
, dma_addr_t dma
,
286 unsigned int off
, unsigned int size
)
290 if (off
> SOLO_MP4E_EXT_SIZE(solo_dev
))
294 if (off
+ size
<= SOLO_MP4E_EXT_SIZE(solo_dev
)) {
295 return solo_p2m_dma_t(solo_dev
, 0, dma
,
296 SOLO_MP4E_EXT_ADDR(solo_dev
) + off
, size
,
301 ret
= solo_p2m_dma_t(solo_dev
, 0, dma
,
302 SOLO_MP4E_EXT_ADDR(solo_dev
) + off
,
303 SOLO_MP4E_EXT_SIZE(solo_dev
) - off
, 0, 0);
306 ret
= solo_p2m_dma_t(solo_dev
, 0,
307 dma
+ SOLO_MP4E_EXT_SIZE(solo_dev
) - off
,
308 SOLO_MP4E_EXT_ADDR(solo_dev
),
309 size
+ off
- SOLO_MP4E_EXT_SIZE(solo_dev
), 0, 0);
315 /* Build a descriptor queue out of an SG list and send it to the P2M for
317 static int solo_send_desc(struct solo_enc_dev
*solo_enc
, int skip
,
318 struct sg_table
*vbuf
, int off
, int size
,
319 unsigned int base
, unsigned int base_size
)
321 struct solo_dev
*solo_dev
= solo_enc
->solo_dev
;
322 struct scatterlist
*sg
;
326 if (WARN_ON_ONCE(size
> FRAME_BUF_SIZE
))
329 solo_enc
->desc_count
= 1;
331 for_each_sg(vbuf
->sgl
, sg
, vbuf
->nents
, i
) {
332 struct solo_p2m_desc
*desc
;
335 int left
= base_size
- off
;
337 desc
= &solo_enc
->desc_items
[solo_enc
->desc_count
++];
338 dma
= sg_dma_address(sg
);
339 len
= sg_dma_len(sg
);
341 /* We assume this is smaller than the scatter size */
350 len
= min(len
, size
);
353 /* Single descriptor */
354 solo_p2m_fill_desc(desc
, 0, dma
, base
+ off
,
358 /* XXX: Do these as separate DMA requests, to avoid
359 timeout errors triggered by awkwardly sized
361 <https://github.com/bluecherrydvr/solo6x10/issues/8>
363 ret
= solo_p2m_dma_t(solo_dev
, 0, dma
, base
+ off
,
368 ret
= solo_p2m_dma_t(solo_dev
, 0, dma
+ left
, base
,
373 solo_enc
->desc_count
--;
381 if (off
>= base_size
)
384 /* Because we may use two descriptors per loop */
385 if (solo_enc
->desc_count
>= (solo_enc
->desc_nelts
- 1)) {
386 ret
= solo_p2m_dma_desc(solo_dev
, solo_enc
->desc_items
,
388 solo_enc
->desc_count
- 1);
391 solo_enc
->desc_count
= 1;
395 if (solo_enc
->desc_count
<= 1)
398 return solo_p2m_dma_desc(solo_dev
, solo_enc
->desc_items
,
399 solo_enc
->desc_dma
, solo_enc
->desc_count
- 1);
402 /* Extract values from VOP header - VE_STATUSxx */
403 static inline int vop_interlaced(const vop_header
*vh
)
405 return (__le32_to_cpu((*vh
)[0]) >> 30) & 1;
408 static inline u8
vop_channel(const vop_header
*vh
)
410 return (__le32_to_cpu((*vh
)[0]) >> 24) & 0x1F;
413 static inline u8
vop_type(const vop_header
*vh
)
415 return (__le32_to_cpu((*vh
)[0]) >> 22) & 3;
418 static inline u32
vop_mpeg_size(const vop_header
*vh
)
420 return __le32_to_cpu((*vh
)[0]) & 0xFFFFF;
423 static inline u8
vop_hsize(const vop_header
*vh
)
425 return (__le32_to_cpu((*vh
)[1]) >> 8) & 0xFF;
428 static inline u8
vop_vsize(const vop_header
*vh
)
430 return __le32_to_cpu((*vh
)[1]) & 0xFF;
433 static inline u32
vop_mpeg_offset(const vop_header
*vh
)
435 return __le32_to_cpu((*vh
)[2]);
438 static inline u32
vop_jpeg_offset(const vop_header
*vh
)
440 return __le32_to_cpu((*vh
)[3]);
443 static inline u32
vop_jpeg_size(const vop_header
*vh
)
445 return __le32_to_cpu((*vh
)[4]) & 0xFFFFF;
448 static inline u32
vop_sec(const vop_header
*vh
)
450 return __le32_to_cpu((*vh
)[5]);
453 static inline u32
vop_usec(const vop_header
*vh
)
455 return __le32_to_cpu((*vh
)[6]);
458 static int solo_fill_jpeg(struct solo_enc_dev
*solo_enc
,
459 struct vb2_buffer
*vb
, const vop_header
*vh
)
461 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
462 struct solo_dev
*solo_dev
= solo_enc
->solo_dev
;
463 struct sg_table
*sgt
= vb2_dma_sg_plane_desc(vb
, 0);
466 vbuf
->flags
|= V4L2_BUF_FLAG_KEYFRAME
;
468 if (vb2_plane_size(vb
, 0) < vop_jpeg_size(vh
) + solo_enc
->jpeg_len
)
471 frame_size
= ALIGN(vop_jpeg_size(vh
) + solo_enc
->jpeg_len
, DMA_ALIGN
);
472 vb2_set_plane_payload(vb
, 0, vop_jpeg_size(vh
) + solo_enc
->jpeg_len
);
474 return solo_send_desc(solo_enc
, solo_enc
->jpeg_len
, sgt
,
475 vop_jpeg_offset(vh
) - SOLO_JPEG_EXT_ADDR(solo_dev
),
476 frame_size
, SOLO_JPEG_EXT_ADDR(solo_dev
),
477 SOLO_JPEG_EXT_SIZE(solo_dev
));
480 static int solo_fill_mpeg(struct solo_enc_dev
*solo_enc
,
481 struct vb2_buffer
*vb
, const vop_header
*vh
)
483 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
484 struct solo_dev
*solo_dev
= solo_enc
->solo_dev
;
485 struct sg_table
*sgt
= vb2_dma_sg_plane_desc(vb
, 0);
486 int frame_off
, frame_size
;
489 if (vb2_plane_size(vb
, 0) < vop_mpeg_size(vh
))
492 /* If this is a key frame, add extra header */
493 vbuf
->flags
&= ~(V4L2_BUF_FLAG_KEYFRAME
| V4L2_BUF_FLAG_PFRAME
|
494 V4L2_BUF_FLAG_BFRAME
);
496 skip
= solo_enc
->vop_len
;
497 vbuf
->flags
|= V4L2_BUF_FLAG_KEYFRAME
;
498 vb2_set_plane_payload(vb
, 0, vop_mpeg_size(vh
) +
501 vbuf
->flags
|= V4L2_BUF_FLAG_PFRAME
;
502 vb2_set_plane_payload(vb
, 0, vop_mpeg_size(vh
));
505 /* Now get the actual mpeg payload */
506 frame_off
= (vop_mpeg_offset(vh
) - SOLO_MP4E_EXT_ADDR(solo_dev
) +
507 sizeof(*vh
)) % SOLO_MP4E_EXT_SIZE(solo_dev
);
508 frame_size
= ALIGN(vop_mpeg_size(vh
) + skip
, DMA_ALIGN
);
510 return solo_send_desc(solo_enc
, skip
, sgt
, frame_off
, frame_size
,
511 SOLO_MP4E_EXT_ADDR(solo_dev
),
512 SOLO_MP4E_EXT_SIZE(solo_dev
));
515 static int solo_enc_fillbuf(struct solo_enc_dev
*solo_enc
,
516 struct vb2_buffer
*vb
, struct solo_enc_buf
*enc_buf
)
518 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
519 const vop_header
*vh
= enc_buf
->vh
;
522 switch (solo_enc
->fmt
) {
523 case V4L2_PIX_FMT_MPEG4
:
524 case V4L2_PIX_FMT_H264
:
525 ret
= solo_fill_mpeg(solo_enc
, vb
, vh
);
527 default: /* V4L2_PIX_FMT_MJPEG */
528 ret
= solo_fill_jpeg(solo_enc
, vb
, vh
);
533 vbuf
->sequence
= solo_enc
->sequence
++;
534 vbuf
->timestamp
.tv_sec
= vop_sec(vh
);
535 vbuf
->timestamp
.tv_usec
= vop_usec(vh
);
537 /* Check for motion flags */
538 if (solo_is_motion_on(solo_enc
) && enc_buf
->motion
) {
539 struct v4l2_event ev
= {
540 .type
= V4L2_EVENT_MOTION_DET
,
543 = V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ
,
544 .frame_sequence
= vbuf
->sequence
,
545 .region_mask
= enc_buf
->motion
? 1 : 0,
549 v4l2_event_queue(solo_enc
->vfd
, &ev
);
553 vb2_buffer_done(vb
, ret
? VB2_BUF_STATE_ERROR
: VB2_BUF_STATE_DONE
);
558 static void solo_enc_handle_one(struct solo_enc_dev
*solo_enc
,
559 struct solo_enc_buf
*enc_buf
)
561 struct solo_vb2_buf
*vb
;
564 mutex_lock(&solo_enc
->lock
);
565 if (solo_enc
->type
!= enc_buf
->type
)
568 spin_lock_irqsave(&solo_enc
->av_lock
, flags
);
569 if (list_empty(&solo_enc
->vidq_active
)) {
570 spin_unlock_irqrestore(&solo_enc
->av_lock
, flags
);
573 vb
= list_first_entry(&solo_enc
->vidq_active
, struct solo_vb2_buf
,
576 spin_unlock_irqrestore(&solo_enc
->av_lock
, flags
);
578 solo_enc_fillbuf(solo_enc
, &vb
->vb
.vb2_buf
, enc_buf
);
580 mutex_unlock(&solo_enc
->lock
);
583 void solo_enc_v4l2_isr(struct solo_dev
*solo_dev
)
585 wake_up_interruptible_all(&solo_dev
->ring_thread_wait
);
588 static void solo_handle_ring(struct solo_dev
*solo_dev
)
591 struct solo_enc_dev
*solo_enc
;
592 struct solo_enc_buf enc_buf
;
593 u32 mpeg_current
, off
;
597 /* Check if the hardware has any new ones in the queue */
598 cur_q
= solo_reg_read(solo_dev
, SOLO_VE_STATE(11)) & 0xff;
599 if (cur_q
== solo_dev
->enc_idx
)
602 mpeg_current
= solo_reg_read(solo_dev
,
603 SOLO_VE_MPEG4_QUE(solo_dev
->enc_idx
));
604 solo_dev
->enc_idx
= (solo_dev
->enc_idx
+ 1) % MP4_QS
;
606 ch
= (mpeg_current
>> 24) & 0x1f;
607 off
= mpeg_current
& 0x00ffffff;
609 if (ch
>= SOLO_MAX_CHANNELS
) {
610 ch
-= SOLO_MAX_CHANNELS
;
611 enc_buf
.type
= SOLO_ENC_TYPE_EXT
;
613 enc_buf
.type
= SOLO_ENC_TYPE_STD
;
615 solo_enc
= solo_dev
->v4l2_enc
[ch
];
616 if (solo_enc
== NULL
) {
617 dev_err(&solo_dev
->pdev
->dev
,
618 "Got spurious packet for channel %d\n", ch
);
623 if (enc_get_mpeg_dma(solo_dev
, solo_dev
->vh_dma
, off
,
627 enc_buf
.vh
= solo_dev
->vh_buf
;
630 if (vop_mpeg_offset(enc_buf
.vh
) !=
631 SOLO_MP4E_EXT_ADDR(solo_dev
) + off
)
634 if (solo_motion_detected(solo_enc
))
639 solo_enc_handle_one(solo_enc
, &enc_buf
);
643 static int solo_ring_thread(void *data
)
645 struct solo_dev
*solo_dev
= data
;
646 DECLARE_WAITQUEUE(wait
, current
);
649 add_wait_queue(&solo_dev
->ring_thread_wait
, &wait
);
652 long timeout
= schedule_timeout_interruptible(HZ
);
654 if (timeout
== -ERESTARTSYS
|| kthread_should_stop())
656 solo_handle_ring(solo_dev
);
660 remove_wait_queue(&solo_dev
->ring_thread_wait
, &wait
);
665 static int solo_enc_queue_setup(struct vb2_queue
*q
,
667 unsigned int *num_buffers
,
668 unsigned int *num_planes
, unsigned int sizes
[],
671 struct solo_enc_dev
*solo_enc
= vb2_get_drv_priv(q
);
673 sizes
[0] = FRAME_BUF_SIZE
;
674 alloc_ctxs
[0] = solo_enc
->alloc_ctx
;
677 if (*num_buffers
< MIN_VID_BUFFERS
)
678 *num_buffers
= MIN_VID_BUFFERS
;
683 static void solo_enc_buf_queue(struct vb2_buffer
*vb
)
685 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
686 struct vb2_queue
*vq
= vb
->vb2_queue
;
687 struct solo_enc_dev
*solo_enc
= vb2_get_drv_priv(vq
);
688 struct solo_vb2_buf
*solo_vb
=
689 container_of(vbuf
, struct solo_vb2_buf
, vb
);
691 spin_lock(&solo_enc
->av_lock
);
692 list_add_tail(&solo_vb
->list
, &solo_enc
->vidq_active
);
693 spin_unlock(&solo_enc
->av_lock
);
696 static int solo_ring_start(struct solo_dev
*solo_dev
)
698 solo_dev
->ring_thread
= kthread_run(solo_ring_thread
, solo_dev
,
699 SOLO6X10_NAME
"_ring");
700 if (IS_ERR(solo_dev
->ring_thread
)) {
701 int err
= PTR_ERR(solo_dev
->ring_thread
);
703 solo_dev
->ring_thread
= NULL
;
707 solo_irq_on(solo_dev
, SOLO_IRQ_ENCODER
);
712 static void solo_ring_stop(struct solo_dev
*solo_dev
)
714 if (solo_dev
->ring_thread
) {
715 kthread_stop(solo_dev
->ring_thread
);
716 solo_dev
->ring_thread
= NULL
;
719 solo_irq_off(solo_dev
, SOLO_IRQ_ENCODER
);
722 static int solo_enc_start_streaming(struct vb2_queue
*q
, unsigned int count
)
724 struct solo_enc_dev
*solo_enc
= vb2_get_drv_priv(q
);
726 return solo_enc_on(solo_enc
);
729 static void solo_enc_stop_streaming(struct vb2_queue
*q
)
731 struct solo_enc_dev
*solo_enc
= vb2_get_drv_priv(q
);
734 spin_lock_irqsave(&solo_enc
->av_lock
, flags
);
735 solo_enc_off(solo_enc
);
736 while (!list_empty(&solo_enc
->vidq_active
)) {
737 struct solo_vb2_buf
*buf
= list_entry(
738 solo_enc
->vidq_active
.next
,
739 struct solo_vb2_buf
, list
);
741 list_del(&buf
->list
);
742 vb2_buffer_done(&buf
->vb
.vb2_buf
, VB2_BUF_STATE_ERROR
);
744 spin_unlock_irqrestore(&solo_enc
->av_lock
, flags
);
747 static void solo_enc_buf_finish(struct vb2_buffer
*vb
)
749 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
750 struct solo_enc_dev
*solo_enc
= vb2_get_drv_priv(vb
->vb2_queue
);
751 struct sg_table
*sgt
= vb2_dma_sg_plane_desc(vb
, 0);
753 switch (solo_enc
->fmt
) {
754 case V4L2_PIX_FMT_MPEG4
:
755 case V4L2_PIX_FMT_H264
:
756 if (vbuf
->flags
& V4L2_BUF_FLAG_KEYFRAME
)
757 sg_copy_from_buffer(sgt
->sgl
, sgt
->nents
,
758 solo_enc
->vop
, solo_enc
->vop_len
);
760 default: /* V4L2_PIX_FMT_MJPEG */
761 sg_copy_from_buffer(sgt
->sgl
, sgt
->nents
,
762 solo_enc
->jpeg_header
, solo_enc
->jpeg_len
);
767 static struct vb2_ops solo_enc_video_qops
= {
768 .queue_setup
= solo_enc_queue_setup
,
769 .buf_queue
= solo_enc_buf_queue
,
770 .buf_finish
= solo_enc_buf_finish
,
771 .start_streaming
= solo_enc_start_streaming
,
772 .stop_streaming
= solo_enc_stop_streaming
,
773 .wait_prepare
= vb2_ops_wait_prepare
,
774 .wait_finish
= vb2_ops_wait_finish
,
777 static int solo_enc_querycap(struct file
*file
, void *priv
,
778 struct v4l2_capability
*cap
)
780 struct solo_enc_dev
*solo_enc
= video_drvdata(file
);
781 struct solo_dev
*solo_dev
= solo_enc
->solo_dev
;
783 strcpy(cap
->driver
, SOLO6X10_NAME
);
784 snprintf(cap
->card
, sizeof(cap
->card
), "Softlogic 6x10 Enc %d",
786 snprintf(cap
->bus_info
, sizeof(cap
->bus_info
), "PCI:%s",
787 pci_name(solo_dev
->pdev
));
788 cap
->device_caps
= V4L2_CAP_VIDEO_CAPTURE
|
789 V4L2_CAP_READWRITE
| V4L2_CAP_STREAMING
;
790 cap
->capabilities
= cap
->device_caps
| V4L2_CAP_DEVICE_CAPS
;
794 static int solo_enc_enum_input(struct file
*file
, void *priv
,
795 struct v4l2_input
*input
)
797 struct solo_enc_dev
*solo_enc
= video_drvdata(file
);
798 struct solo_dev
*solo_dev
= solo_enc
->solo_dev
;
803 snprintf(input
->name
, sizeof(input
->name
), "Encoder %d",
805 input
->type
= V4L2_INPUT_TYPE_CAMERA
;
806 input
->std
= solo_enc
->vfd
->tvnorms
;
808 if (!tw28_get_video_status(solo_dev
, solo_enc
->ch
))
809 input
->status
= V4L2_IN_ST_NO_SIGNAL
;
814 static int solo_enc_set_input(struct file
*file
, void *priv
,
823 static int solo_enc_get_input(struct file
*file
, void *priv
,
831 static int solo_enc_enum_fmt_cap(struct file
*file
, void *priv
,
832 struct v4l2_fmtdesc
*f
)
834 struct solo_enc_dev
*solo_enc
= video_drvdata(file
);
835 int dev_type
= solo_enc
->solo_dev
->type
;
841 f
->pixelformat
= V4L2_PIX_FMT_MPEG4
;
842 strcpy(f
->description
, "MPEG-4 part 2");
845 f
->pixelformat
= V4L2_PIX_FMT_H264
;
846 strcpy(f
->description
, "H.264");
851 f
->pixelformat
= V4L2_PIX_FMT_MJPEG
;
852 strcpy(f
->description
, "MJPEG");
858 f
->flags
= V4L2_FMT_FLAG_COMPRESSED
;
863 static inline int solo_valid_pixfmt(u32 pixfmt
, int dev_type
)
865 return (pixfmt
== V4L2_PIX_FMT_H264
&& dev_type
== SOLO_DEV_6110
)
866 || (pixfmt
== V4L2_PIX_FMT_MPEG4
&& dev_type
== SOLO_DEV_6010
)
867 || pixfmt
== V4L2_PIX_FMT_MJPEG
? 0 : -EINVAL
;
870 static int solo_enc_try_fmt_cap(struct file
*file
, void *priv
,
871 struct v4l2_format
*f
)
873 struct solo_enc_dev
*solo_enc
= video_drvdata(file
);
874 struct solo_dev
*solo_dev
= solo_enc
->solo_dev
;
875 struct v4l2_pix_format
*pix
= &f
->fmt
.pix
;
877 if (solo_valid_pixfmt(pix
->pixelformat
, solo_dev
->type
))
880 if (pix
->width
< solo_dev
->video_hsize
||
881 pix
->height
< solo_dev
->video_vsize
<< 1) {
882 /* Default to CIF 1/2 size */
883 pix
->width
= solo_dev
->video_hsize
>> 1;
884 pix
->height
= solo_dev
->video_vsize
;
887 pix
->width
= solo_dev
->video_hsize
;
888 pix
->height
= solo_dev
->video_vsize
<< 1;
891 switch (pix
->field
) {
892 case V4L2_FIELD_NONE
:
893 case V4L2_FIELD_INTERLACED
:
897 pix
->field
= V4L2_FIELD_INTERLACED
;
902 pix
->colorspace
= V4L2_COLORSPACE_SMPTE170M
;
903 pix
->sizeimage
= FRAME_BUF_SIZE
;
904 pix
->bytesperline
= 0;
910 static int solo_enc_set_fmt_cap(struct file
*file
, void *priv
,
911 struct v4l2_format
*f
)
913 struct solo_enc_dev
*solo_enc
= video_drvdata(file
);
914 struct solo_dev
*solo_dev
= solo_enc
->solo_dev
;
915 struct v4l2_pix_format
*pix
= &f
->fmt
.pix
;
918 if (vb2_is_busy(&solo_enc
->vidq
))
921 ret
= solo_enc_try_fmt_cap(file
, priv
, f
);
925 if (pix
->width
== solo_dev
->video_hsize
)
926 solo_enc
->mode
= SOLO_ENC_MODE_D1
;
928 solo_enc
->mode
= SOLO_ENC_MODE_CIF
;
930 /* This does not change the encoder at all */
931 solo_enc
->fmt
= pix
->pixelformat
;
934 * More information is needed about these 'extended' types. As far
935 * as I can tell these are basically additional video streams with
936 * different MPEG encoding attributes that can run in parallel with
937 * the main stream. If so, then this should be implemented as a
938 * second video node. Abusing priv like this is certainly not the
941 solo_enc->type = SOLO_ENC_TYPE_EXT;
943 solo_update_mode(solo_enc
);
947 static int solo_enc_get_fmt_cap(struct file
*file
, void *priv
,
948 struct v4l2_format
*f
)
950 struct solo_enc_dev
*solo_enc
= video_drvdata(file
);
951 struct v4l2_pix_format
*pix
= &f
->fmt
.pix
;
953 pix
->width
= solo_enc
->width
;
954 pix
->height
= solo_enc
->height
;
955 pix
->pixelformat
= solo_enc
->fmt
;
956 pix
->field
= solo_enc
->interlaced
? V4L2_FIELD_INTERLACED
:
958 pix
->sizeimage
= FRAME_BUF_SIZE
;
959 pix
->colorspace
= V4L2_COLORSPACE_SMPTE170M
;
965 static int solo_enc_g_std(struct file
*file
, void *priv
, v4l2_std_id
*i
)
967 struct solo_enc_dev
*solo_enc
= video_drvdata(file
);
968 struct solo_dev
*solo_dev
= solo_enc
->solo_dev
;
970 if (solo_dev
->video_type
== SOLO_VO_FMT_TYPE_NTSC
)
971 *i
= V4L2_STD_NTSC_M
;
977 static int solo_enc_s_std(struct file
*file
, void *priv
, v4l2_std_id std
)
979 struct solo_enc_dev
*solo_enc
= video_drvdata(file
);
981 return solo_set_video_type(solo_enc
->solo_dev
, std
& V4L2_STD_625_50
);
984 static int solo_enum_framesizes(struct file
*file
, void *priv
,
985 struct v4l2_frmsizeenum
*fsize
)
987 struct solo_enc_dev
*solo_enc
= video_drvdata(file
);
988 struct solo_dev
*solo_dev
= solo_enc
->solo_dev
;
990 if (solo_valid_pixfmt(fsize
->pixel_format
, solo_dev
->type
))
993 switch (fsize
->index
) {
995 fsize
->discrete
.width
= solo_dev
->video_hsize
>> 1;
996 fsize
->discrete
.height
= solo_dev
->video_vsize
;
999 fsize
->discrete
.width
= solo_dev
->video_hsize
;
1000 fsize
->discrete
.height
= solo_dev
->video_vsize
<< 1;
1006 fsize
->type
= V4L2_FRMSIZE_TYPE_DISCRETE
;
1011 static int solo_enum_frameintervals(struct file
*file
, void *priv
,
1012 struct v4l2_frmivalenum
*fintv
)
1014 struct solo_enc_dev
*solo_enc
= video_drvdata(file
);
1015 struct solo_dev
*solo_dev
= solo_enc
->solo_dev
;
1017 if (solo_valid_pixfmt(fintv
->pixel_format
, solo_dev
->type
))
1021 if ((fintv
->width
!= solo_dev
->video_hsize
>> 1 ||
1022 fintv
->height
!= solo_dev
->video_vsize
) &&
1023 (fintv
->width
!= solo_dev
->video_hsize
||
1024 fintv
->height
!= solo_dev
->video_vsize
<< 1))
1027 fintv
->type
= V4L2_FRMIVAL_TYPE_STEPWISE
;
1029 fintv
->stepwise
.min
.numerator
= 1;
1030 fintv
->stepwise
.min
.denominator
= solo_dev
->fps
;
1032 fintv
->stepwise
.max
.numerator
= 15;
1033 fintv
->stepwise
.max
.denominator
= solo_dev
->fps
;
1035 fintv
->stepwise
.step
.numerator
= 1;
1036 fintv
->stepwise
.step
.denominator
= solo_dev
->fps
;
1041 static int solo_g_parm(struct file
*file
, void *priv
,
1042 struct v4l2_streamparm
*sp
)
1044 struct solo_enc_dev
*solo_enc
= video_drvdata(file
);
1045 struct v4l2_captureparm
*cp
= &sp
->parm
.capture
;
1047 cp
->capability
= V4L2_CAP_TIMEPERFRAME
;
1048 cp
->timeperframe
.numerator
= solo_enc
->interval
;
1049 cp
->timeperframe
.denominator
= solo_enc
->solo_dev
->fps
;
1050 cp
->capturemode
= 0;
1051 /* XXX: Shouldn't we be able to get/set this from videobuf? */
1052 cp
->readbuffers
= 2;
1057 static inline int calc_interval(u8 fps
, u32 n
, u32 d
)
1064 return min(15U, n
/ d
+ (n
% d
>= (fps
>> 1)));
1067 static int solo_s_parm(struct file
*file
, void *priv
,
1068 struct v4l2_streamparm
*sp
)
1070 struct solo_enc_dev
*solo_enc
= video_drvdata(file
);
1071 struct v4l2_fract
*t
= &sp
->parm
.capture
.timeperframe
;
1072 u8 fps
= solo_enc
->solo_dev
->fps
;
1074 if (vb2_is_streaming(&solo_enc
->vidq
))
1077 solo_enc
->interval
= calc_interval(fps
, t
->numerator
, t
->denominator
);
1078 solo_update_mode(solo_enc
);
1079 return solo_g_parm(file
, priv
, sp
);
1082 static int solo_s_ctrl(struct v4l2_ctrl
*ctrl
)
1084 struct solo_enc_dev
*solo_enc
=
1085 container_of(ctrl
->handler
, struct solo_enc_dev
, hdl
);
1086 struct solo_dev
*solo_dev
= solo_enc
->solo_dev
;
1090 case V4L2_CID_BRIGHTNESS
:
1091 case V4L2_CID_CONTRAST
:
1092 case V4L2_CID_SATURATION
:
1094 case V4L2_CID_SHARPNESS
:
1095 return tw28_set_ctrl_val(solo_dev
, ctrl
->id
, solo_enc
->ch
,
1097 case V4L2_CID_MPEG_VIDEO_GOP_SIZE
:
1098 solo_enc
->gop
= ctrl
->val
;
1099 solo_reg_write(solo_dev
, SOLO_VE_CH_GOP(solo_enc
->ch
), solo_enc
->gop
);
1100 solo_reg_write(solo_dev
, SOLO_VE_CH_GOP_E(solo_enc
->ch
), solo_enc
->gop
);
1102 case V4L2_CID_MPEG_VIDEO_H264_MIN_QP
:
1103 solo_enc
->qp
= ctrl
->val
;
1104 solo_reg_write(solo_dev
, SOLO_VE_CH_QP(solo_enc
->ch
), solo_enc
->qp
);
1105 solo_reg_write(solo_dev
, SOLO_VE_CH_QP_E(solo_enc
->ch
), solo_enc
->qp
);
1107 case V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD
:
1108 solo_enc
->motion_thresh
= ctrl
->val
<< 8;
1109 if (!solo_enc
->motion_global
|| !solo_enc
->motion_enabled
)
1111 return solo_set_motion_threshold(solo_dev
, solo_enc
->ch
,
1112 solo_enc
->motion_thresh
);
1113 case V4L2_CID_DETECT_MD_MODE
:
1114 solo_enc
->motion_global
= ctrl
->val
== V4L2_DETECT_MD_MODE_GLOBAL
;
1115 solo_enc
->motion_enabled
= ctrl
->val
> V4L2_DETECT_MD_MODE_DISABLED
;
1117 if (solo_enc
->motion_global
)
1118 err
= solo_set_motion_threshold(solo_dev
, solo_enc
->ch
,
1119 solo_enc
->motion_thresh
);
1121 err
= solo_set_motion_block(solo_dev
, solo_enc
->ch
,
1122 solo_enc
->md_thresholds
->p_cur
.p_u16
);
1126 solo_motion_toggle(solo_enc
, ctrl
->val
);
1128 case V4L2_CID_DETECT_MD_THRESHOLD_GRID
:
1129 if (solo_enc
->motion_enabled
&& !solo_enc
->motion_global
)
1130 return solo_set_motion_block(solo_dev
, solo_enc
->ch
,
1131 solo_enc
->md_thresholds
->p_new
.p_u16
);
1133 case V4L2_CID_OSD_TEXT
:
1134 strcpy(solo_enc
->osd_text
, ctrl
->p_new
.p_char
);
1135 return solo_osd_print(solo_enc
);
1143 static int solo_subscribe_event(struct v4l2_fh
*fh
,
1144 const struct v4l2_event_subscription
*sub
)
1147 switch (sub
->type
) {
1148 case V4L2_EVENT_CTRL
:
1149 return v4l2_ctrl_subscribe_event(fh
, sub
);
1150 case V4L2_EVENT_MOTION_DET
:
1151 /* Allow for up to 30 events (1 second for NTSC) to be
1153 return v4l2_event_subscribe(fh
, sub
, 30, NULL
);
1158 static const struct v4l2_file_operations solo_enc_fops
= {
1159 .owner
= THIS_MODULE
,
1160 .open
= v4l2_fh_open
,
1161 .release
= vb2_fop_release
,
1162 .read
= vb2_fop_read
,
1163 .poll
= vb2_fop_poll
,
1164 .mmap
= vb2_fop_mmap
,
1165 .unlocked_ioctl
= video_ioctl2
,
1168 static const struct v4l2_ioctl_ops solo_enc_ioctl_ops
= {
1169 .vidioc_querycap
= solo_enc_querycap
,
1170 .vidioc_s_std
= solo_enc_s_std
,
1171 .vidioc_g_std
= solo_enc_g_std
,
1172 /* Input callbacks */
1173 .vidioc_enum_input
= solo_enc_enum_input
,
1174 .vidioc_s_input
= solo_enc_set_input
,
1175 .vidioc_g_input
= solo_enc_get_input
,
1176 /* Video capture format callbacks */
1177 .vidioc_enum_fmt_vid_cap
= solo_enc_enum_fmt_cap
,
1178 .vidioc_try_fmt_vid_cap
= solo_enc_try_fmt_cap
,
1179 .vidioc_s_fmt_vid_cap
= solo_enc_set_fmt_cap
,
1180 .vidioc_g_fmt_vid_cap
= solo_enc_get_fmt_cap
,
1182 .vidioc_reqbufs
= vb2_ioctl_reqbufs
,
1183 .vidioc_querybuf
= vb2_ioctl_querybuf
,
1184 .vidioc_qbuf
= vb2_ioctl_qbuf
,
1185 .vidioc_dqbuf
= vb2_ioctl_dqbuf
,
1186 .vidioc_streamon
= vb2_ioctl_streamon
,
1187 .vidioc_streamoff
= vb2_ioctl_streamoff
,
1188 /* Frame size and interval */
1189 .vidioc_enum_framesizes
= solo_enum_framesizes
,
1190 .vidioc_enum_frameintervals
= solo_enum_frameintervals
,
1191 /* Video capture parameters */
1192 .vidioc_s_parm
= solo_s_parm
,
1193 .vidioc_g_parm
= solo_g_parm
,
1194 /* Logging and events */
1195 .vidioc_log_status
= v4l2_ctrl_log_status
,
1196 .vidioc_subscribe_event
= solo_subscribe_event
,
1197 .vidioc_unsubscribe_event
= v4l2_event_unsubscribe
,
1200 static const struct video_device solo_enc_template
= {
1201 .name
= SOLO6X10_NAME
,
1202 .fops
= &solo_enc_fops
,
1203 .ioctl_ops
= &solo_enc_ioctl_ops
,
1205 .release
= video_device_release
,
1206 .tvnorms
= V4L2_STD_NTSC_M
| V4L2_STD_PAL
,
1209 static const struct v4l2_ctrl_ops solo_ctrl_ops
= {
1210 .s_ctrl
= solo_s_ctrl
,
1213 static const struct v4l2_ctrl_config solo_osd_text_ctrl
= {
1214 .ops
= &solo_ctrl_ops
,
1215 .id
= V4L2_CID_OSD_TEXT
,
1217 .type
= V4L2_CTRL_TYPE_STRING
,
1218 .max
= OSD_TEXT_MAX
,
1222 /* Motion Detection Threshold matrix */
1223 static const struct v4l2_ctrl_config solo_md_thresholds
= {
1224 .ops
= &solo_ctrl_ops
,
1225 .id
= V4L2_CID_DETECT_MD_THRESHOLD_GRID
,
1226 .dims
= { SOLO_MOTION_SZ
, SOLO_MOTION_SZ
},
1227 .def
= SOLO_DEF_MOT_THRESH
,
1232 static struct solo_enc_dev
*solo_enc_alloc(struct solo_dev
*solo_dev
,
1235 struct solo_enc_dev
*solo_enc
;
1236 struct v4l2_ctrl_handler
*hdl
;
1239 solo_enc
= kzalloc(sizeof(*solo_enc
), GFP_KERNEL
);
1241 return ERR_PTR(-ENOMEM
);
1243 hdl
= &solo_enc
->hdl
;
1244 solo_enc
->alloc_ctx
= vb2_dma_sg_init_ctx(&solo_dev
->pdev
->dev
);
1245 if (IS_ERR(solo_enc
->alloc_ctx
)) {
1246 ret
= PTR_ERR(solo_enc
->alloc_ctx
);
1249 v4l2_ctrl_handler_init(hdl
, 10);
1250 v4l2_ctrl_new_std(hdl
, &solo_ctrl_ops
,
1251 V4L2_CID_BRIGHTNESS
, 0, 255, 1, 128);
1252 v4l2_ctrl_new_std(hdl
, &solo_ctrl_ops
,
1253 V4L2_CID_CONTRAST
, 0, 255, 1, 128);
1254 v4l2_ctrl_new_std(hdl
, &solo_ctrl_ops
,
1255 V4L2_CID_SATURATION
, 0, 255, 1, 128);
1256 v4l2_ctrl_new_std(hdl
, &solo_ctrl_ops
,
1257 V4L2_CID_HUE
, 0, 255, 1, 128);
1258 if (tw28_has_sharpness(solo_dev
, ch
))
1259 v4l2_ctrl_new_std(hdl
, &solo_ctrl_ops
,
1260 V4L2_CID_SHARPNESS
, 0, 15, 1, 0);
1261 v4l2_ctrl_new_std(hdl
, &solo_ctrl_ops
,
1262 V4L2_CID_MPEG_VIDEO_GOP_SIZE
, 1, 255, 1, solo_dev
->fps
);
1263 v4l2_ctrl_new_std(hdl
, &solo_ctrl_ops
,
1264 V4L2_CID_MPEG_VIDEO_H264_MIN_QP
, 0, 31, 1, SOLO_DEFAULT_QP
);
1265 v4l2_ctrl_new_std_menu(hdl
, &solo_ctrl_ops
,
1266 V4L2_CID_DETECT_MD_MODE
,
1267 V4L2_DETECT_MD_MODE_THRESHOLD_GRID
, 0,
1268 V4L2_DETECT_MD_MODE_DISABLED
);
1269 v4l2_ctrl_new_std(hdl
, &solo_ctrl_ops
,
1270 V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD
, 0, 0xff, 1,
1271 SOLO_DEF_MOT_THRESH
>> 8);
1272 v4l2_ctrl_new_custom(hdl
, &solo_osd_text_ctrl
, NULL
);
1273 solo_enc
->md_thresholds
=
1274 v4l2_ctrl_new_custom(hdl
, &solo_md_thresholds
, NULL
);
1280 solo_enc
->solo_dev
= solo_dev
;
1282 mutex_init(&solo_enc
->lock
);
1283 spin_lock_init(&solo_enc
->av_lock
);
1284 INIT_LIST_HEAD(&solo_enc
->vidq_active
);
1285 solo_enc
->fmt
= (solo_dev
->type
== SOLO_DEV_6010
) ?
1286 V4L2_PIX_FMT_MPEG4
: V4L2_PIX_FMT_H264
;
1287 solo_enc
->type
= SOLO_ENC_TYPE_STD
;
1289 solo_enc
->qp
= SOLO_DEFAULT_QP
;
1290 solo_enc
->gop
= solo_dev
->fps
;
1291 solo_enc
->interval
= 1;
1292 solo_enc
->mode
= SOLO_ENC_MODE_CIF
;
1293 solo_enc
->motion_global
= true;
1294 solo_enc
->motion_thresh
= SOLO_DEF_MOT_THRESH
;
1295 solo_enc
->vidq
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1296 solo_enc
->vidq
.io_modes
= VB2_MMAP
| VB2_USERPTR
| VB2_READ
;
1297 solo_enc
->vidq
.ops
= &solo_enc_video_qops
;
1298 solo_enc
->vidq
.mem_ops
= &vb2_dma_sg_memops
;
1299 solo_enc
->vidq
.drv_priv
= solo_enc
;
1300 solo_enc
->vidq
.gfp_flags
= __GFP_DMA32
| __GFP_KSWAPD_RECLAIM
;
1301 solo_enc
->vidq
.timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
;
1302 solo_enc
->vidq
.buf_struct_size
= sizeof(struct solo_vb2_buf
);
1303 solo_enc
->vidq
.lock
= &solo_enc
->lock
;
1304 ret
= vb2_queue_init(&solo_enc
->vidq
);
1307 solo_update_mode(solo_enc
);
1309 spin_lock_init(&solo_enc
->motion_lock
);
1311 /* Initialize this per encoder */
1312 solo_enc
->jpeg_len
= sizeof(jpeg_header
);
1313 memcpy(solo_enc
->jpeg_header
, jpeg_header
, solo_enc
->jpeg_len
);
1315 solo_enc
->desc_nelts
= 32;
1316 solo_enc
->desc_items
= pci_alloc_consistent(solo_dev
->pdev
,
1317 sizeof(struct solo_p2m_desc
) *
1318 solo_enc
->desc_nelts
,
1319 &solo_enc
->desc_dma
);
1321 if (solo_enc
->desc_items
== NULL
)
1324 solo_enc
->vfd
= video_device_alloc();
1328 *solo_enc
->vfd
= solo_enc_template
;
1329 solo_enc
->vfd
->v4l2_dev
= &solo_dev
->v4l2_dev
;
1330 solo_enc
->vfd
->ctrl_handler
= hdl
;
1331 solo_enc
->vfd
->queue
= &solo_enc
->vidq
;
1332 solo_enc
->vfd
->lock
= &solo_enc
->lock
;
1333 video_set_drvdata(solo_enc
->vfd
, solo_enc
);
1334 ret
= video_register_device(solo_enc
->vfd
, VFL_TYPE_GRABBER
, nr
);
1338 snprintf(solo_enc
->vfd
->name
, sizeof(solo_enc
->vfd
->name
),
1339 "%s-enc (%i/%i)", SOLO6X10_NAME
, solo_dev
->vfd
->num
,
1340 solo_enc
->vfd
->num
);
1345 video_device_release(solo_enc
->vfd
);
1347 pci_free_consistent(solo_enc
->solo_dev
->pdev
,
1348 sizeof(struct solo_p2m_desc
) * solo_enc
->desc_nelts
,
1349 solo_enc
->desc_items
, solo_enc
->desc_dma
);
1351 v4l2_ctrl_handler_free(hdl
);
1352 vb2_dma_sg_cleanup_ctx(solo_enc
->alloc_ctx
);
1354 return ERR_PTR(ret
);
1357 static void solo_enc_free(struct solo_enc_dev
*solo_enc
)
1359 if (solo_enc
== NULL
)
1362 pci_free_consistent(solo_enc
->solo_dev
->pdev
,
1363 sizeof(struct solo_p2m_desc
) * solo_enc
->desc_nelts
,
1364 solo_enc
->desc_items
, solo_enc
->desc_dma
);
1365 video_unregister_device(solo_enc
->vfd
);
1366 v4l2_ctrl_handler_free(&solo_enc
->hdl
);
1367 vb2_dma_sg_cleanup_ctx(solo_enc
->alloc_ctx
);
1371 int solo_enc_v4l2_init(struct solo_dev
*solo_dev
, unsigned nr
)
1375 init_waitqueue_head(&solo_dev
->ring_thread_wait
);
1377 solo_dev
->vh_size
= sizeof(vop_header
);
1378 solo_dev
->vh_buf
= pci_alloc_consistent(solo_dev
->pdev
,
1381 if (solo_dev
->vh_buf
== NULL
)
1384 for (i
= 0; i
< solo_dev
->nr_chans
; i
++) {
1385 solo_dev
->v4l2_enc
[i
] = solo_enc_alloc(solo_dev
, i
, nr
);
1386 if (IS_ERR(solo_dev
->v4l2_enc
[i
]))
1390 if (i
!= solo_dev
->nr_chans
) {
1391 int ret
= PTR_ERR(solo_dev
->v4l2_enc
[i
]);
1394 solo_enc_free(solo_dev
->v4l2_enc
[i
]);
1395 pci_free_consistent(solo_dev
->pdev
, solo_dev
->vh_size
,
1396 solo_dev
->vh_buf
, solo_dev
->vh_dma
);
1397 solo_dev
->vh_buf
= NULL
;
1401 if (solo_dev
->type
== SOLO_DEV_6010
)
1402 solo_dev
->enc_bw_remain
= solo_dev
->fps
* 4 * 4;
1404 solo_dev
->enc_bw_remain
= solo_dev
->fps
* 4 * 5;
1406 dev_info(&solo_dev
->pdev
->dev
, "Encoders as /dev/video%d-%d\n",
1407 solo_dev
->v4l2_enc
[0]->vfd
->num
,
1408 solo_dev
->v4l2_enc
[solo_dev
->nr_chans
- 1]->vfd
->num
);
1410 return solo_ring_start(solo_dev
);
1413 void solo_enc_v4l2_exit(struct solo_dev
*solo_dev
)
1417 solo_ring_stop(solo_dev
);
1419 for (i
= 0; i
< solo_dev
->nr_chans
; i
++)
1420 solo_enc_free(solo_dev
->v4l2_enc
[i
]);
1422 if (solo_dev
->vh_buf
)
1423 pci_free_consistent(solo_dev
->pdev
, solo_dev
->vh_size
,
1424 solo_dev
->vh_buf
, solo_dev
->vh_dma
);