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