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