Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: cxusb: add analog mode support for Medion MD95700

This patch adds support for analog part of Medion 95700 in the cxusb
driver.

What works:
* Video capture at various sizes with sequential fields,
* Input switching (TV Tuner, Composite, S-Video),
* TV and radio tuning,
* Video standard switching and auto detection,
* Radio mode switching (stereo / mono),
* Unplugging while capturing,
* DVB / analog coexistence.

What does not work yet:
* Audio,
* VBI,
* Picture controls.

Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
[hverkuil-cisco@xs4all.nl: remove left-over commented-out debug message]
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>

authored by

Maciej S. Szmigiero and committed by
Mauro Carvalho Chehab
e478d405 d525e5c2

+1968 -4
+14 -2
drivers/media/usb/dvb-usb/Kconfig
··· 139 139 select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT 140 140 help 141 141 Say Y here to support the Conexant USB2.0 hybrid reference design. 142 - Currently, only DVB and ATSC modes are supported, analog mode 143 - shall be added in the future. Devices that require this module: 142 + DVB and ATSC modes are supported, for a basic analog mode support 143 + see the next option ("Analog support for the Conexant USB2.0 hybrid 144 + reference design"). 145 + Devices that require this module: 144 146 145 147 Medion MD95700 hybrid USB2.0 device. 146 148 DViCO FusionHDTV (Bluebird) USB2.0 devices 149 + 150 + config DVB_USB_CXUSB_ANALOG 151 + bool "Analog support for the Conexant USB2.0 hybrid reference design" 152 + depends on DVB_USB_CXUSB && VIDEO_V4L2 153 + select VIDEO_CX25840 154 + select VIDEOBUF2_VMALLOC 155 + help 156 + Say Y here to enable basic analog mode support for the Conexant 157 + USB2.0 hybrid reference design. 158 + Currently this mode is supported only on a Medion MD95700 device. 147 159 148 160 config DVB_USB_M920X 149 161 tristate "Uli m920x DVB-T USB2.0 support"
+3
drivers/media/usb/dvb-usb/Makefile
··· 42 42 obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o 43 43 44 44 dvb-usb-cxusb-objs := cxusb.o 45 + ifeq ($(CONFIG_DVB_USB_CXUSB_ANALOG),y) 46 + dvb-usb-cxusb-objs += cxusb-analog.o 47 + endif 45 48 obj-$(CONFIG_DVB_USB_CXUSB) += dvb-usb-cxusb.o 46 49 47 50 dvb-usb-ttusb2-objs := ttusb2.o
+1845
drivers/media/usb/dvb-usb/cxusb-analog.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + // 3 + // DVB USB compliant linux driver for Conexant USB reference design - 4 + // (analog part). 5 + // 6 + // Copyright (C) 2011, 2017, 2018 7 + // Maciej S. Szmigiero (mail@maciej.szmigiero.name) 8 + // 9 + // In case there are new analog / DVB-T hybrid devices released in the market 10 + // using the same general design as Medion MD95700: a CX25840 video decoder 11 + // outputting a BT.656 stream to a USB bridge chip which then forwards it to 12 + // the host in isochronous USB packets this code should be made generic, with 13 + // board specific bits implemented via separate card structures. 14 + // 15 + // This is, however, unlikely as the Medion model was released 16 + // years ago (in 2005). 17 + // 18 + // TODO: 19 + // * audio support, 20 + // * finish radio support (requires audio of course), 21 + // * VBI support, 22 + // * controls support 23 + 24 + #include <linux/bitops.h> 25 + #include <linux/device.h> 26 + #include <linux/slab.h> 27 + #include <linux/string.h> 28 + #include <linux/timekeeping.h> 29 + #include <linux/vmalloc.h> 30 + #include <media/drv-intf/cx25840.h> 31 + #include <media/tuner.h> 32 + #include <media/v4l2-fh.h> 33 + #include <media/v4l2-ioctl.h> 34 + #include <media/v4l2-subdev.h> 35 + #include <media/videobuf2-vmalloc.h> 36 + 37 + #include "cxusb.h" 38 + 39 + static int cxusb_medion_v_queue_setup(struct vb2_queue *q, 40 + unsigned int *num_buffers, 41 + unsigned int *num_planes, 42 + unsigned int sizes[], 43 + struct device *alloc_devs[]) 44 + { 45 + struct dvb_usb_device *dvbdev = vb2_get_drv_priv(q); 46 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 47 + unsigned int size = cxdev->width * cxdev->height * 2; 48 + 49 + if (*num_planes > 0) { 50 + if (*num_planes != 1) 51 + return -EINVAL; 52 + 53 + if (sizes[0] < size) 54 + return -EINVAL; 55 + } else { 56 + *num_planes = 1; 57 + sizes[0] = size; 58 + } 59 + 60 + return 0; 61 + } 62 + 63 + static int cxusb_medion_v_buf_init(struct vb2_buffer *vb) 64 + { 65 + struct dvb_usb_device *dvbdev = vb2_get_drv_priv(vb->vb2_queue); 66 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 67 + 68 + cxusb_vprintk(dvbdev, OPS, "buffer init\n"); 69 + 70 + if (vb2_plane_size(vb, 0) < cxdev->width * cxdev->height * 2) 71 + return -ENOMEM; 72 + 73 + cxusb_vprintk(dvbdev, OPS, "buffer OK\n"); 74 + 75 + return 0; 76 + } 77 + 78 + static void cxusb_auxbuf_init(struct dvb_usb_device *dvbdev, 79 + struct cxusb_medion_auxbuf *auxbuf, 80 + u8 *buf, unsigned int len) 81 + { 82 + cxusb_vprintk(dvbdev, AUXB, "initializing auxbuf of len %u\n", len); 83 + 84 + auxbuf->buf = buf; 85 + auxbuf->len = len; 86 + auxbuf->paylen = 0; 87 + } 88 + 89 + static void cxusb_auxbuf_head_trim(struct dvb_usb_device *dvbdev, 90 + struct cxusb_medion_auxbuf *auxbuf, 91 + unsigned int pos) 92 + { 93 + if (pos == 0) 94 + return; 95 + 96 + if (WARN_ON(pos > auxbuf->paylen)) 97 + return; 98 + 99 + cxusb_vprintk(dvbdev, AUXB, 100 + "trimming auxbuf len by %u to %u\n", 101 + pos, auxbuf->paylen - pos); 102 + 103 + memmove(auxbuf->buf, auxbuf->buf + pos, auxbuf->paylen - pos); 104 + auxbuf->paylen -= pos; 105 + } 106 + 107 + static unsigned int cxusb_auxbuf_paylen(struct cxusb_medion_auxbuf *auxbuf) 108 + { 109 + return auxbuf->paylen; 110 + } 111 + 112 + static bool cxusb_auxbuf_make_space(struct dvb_usb_device *dvbdev, 113 + struct cxusb_medion_auxbuf *auxbuf, 114 + unsigned int howmuch) 115 + { 116 + unsigned int freespace; 117 + 118 + if (WARN_ON(howmuch >= auxbuf->len)) 119 + howmuch = auxbuf->len - 1; 120 + 121 + freespace = auxbuf->len - cxusb_auxbuf_paylen(auxbuf); 122 + 123 + cxusb_vprintk(dvbdev, AUXB, "freespace is %u\n", freespace); 124 + 125 + if (freespace >= howmuch) 126 + return true; 127 + 128 + howmuch -= freespace; 129 + 130 + cxusb_vprintk(dvbdev, AUXB, "will overwrite %u bytes of buffer\n", 131 + howmuch); 132 + 133 + cxusb_auxbuf_head_trim(dvbdev, auxbuf, howmuch); 134 + 135 + return false; 136 + } 137 + 138 + /* returns false if some data was overwritten */ 139 + static bool cxusb_auxbuf_append_urb(struct dvb_usb_device *dvbdev, 140 + struct cxusb_medion_auxbuf *auxbuf, 141 + struct urb *urb) 142 + { 143 + unsigned long len; 144 + int i; 145 + bool ret; 146 + 147 + for (i = 0, len = 0; i < urb->number_of_packets; i++) 148 + len += urb->iso_frame_desc[i].actual_length; 149 + 150 + ret = cxusb_auxbuf_make_space(dvbdev, auxbuf, len); 151 + 152 + for (i = 0; i < urb->number_of_packets; i++) { 153 + unsigned int to_copy; 154 + 155 + to_copy = urb->iso_frame_desc[i].actual_length; 156 + 157 + memcpy(auxbuf->buf + auxbuf->paylen, urb->transfer_buffer + 158 + urb->iso_frame_desc[i].offset, to_copy); 159 + 160 + auxbuf->paylen += to_copy; 161 + } 162 + 163 + return ret; 164 + } 165 + 166 + static bool cxusb_auxbuf_copy(struct cxusb_medion_auxbuf *auxbuf, 167 + unsigned int pos, unsigned char *dest, 168 + unsigned int len) 169 + { 170 + if (pos + len > auxbuf->paylen) 171 + return false; 172 + 173 + memcpy(dest, auxbuf->buf + pos, len); 174 + 175 + return true; 176 + } 177 + 178 + static bool cxusb_medion_cf_refc_fld_chg(struct dvb_usb_device *dvbdev, 179 + struct cxusb_bt656_params *bt656, 180 + bool firstfield, 181 + unsigned int maxlines, 182 + unsigned int maxlinesamples, 183 + unsigned char buf[4]) 184 + { 185 + bool firstfield_code = (buf[3] & CXUSB_BT656_FIELD_MASK) == 186 + CXUSB_BT656_FIELD_1; 187 + unsigned int remlines; 188 + 189 + if (bt656->line == 0 || firstfield == firstfield_code) 190 + return false; 191 + 192 + if (bt656->fmode == LINE_SAMPLES) { 193 + unsigned int remsamples = maxlinesamples - 194 + bt656->linesamples; 195 + 196 + cxusb_vprintk(dvbdev, BT656, 197 + "field %c after line %u field change\n", 198 + firstfield ? '1' : '2', bt656->line); 199 + 200 + if (bt656->buf != NULL && remsamples > 0) { 201 + memset(bt656->buf, 0, remsamples); 202 + bt656->buf += remsamples; 203 + 204 + cxusb_vprintk(dvbdev, BT656, 205 + "field %c line %u %u samples still remaining (of %u)\n", 206 + firstfield ? '1' : '2', 207 + bt656->line, remsamples, 208 + maxlinesamples); 209 + } 210 + 211 + bt656->line++; 212 + } 213 + 214 + remlines = maxlines - bt656->line; 215 + if (bt656->buf != NULL && remlines > 0) { 216 + memset(bt656->buf, 0, remlines * maxlinesamples); 217 + bt656->buf += remlines * maxlinesamples; 218 + 219 + cxusb_vprintk(dvbdev, BT656, 220 + "field %c %u lines still remaining (of %u)\n", 221 + firstfield ? '1' : '2', remlines, 222 + maxlines); 223 + } 224 + 225 + return true; 226 + } 227 + 228 + static void cxusb_medion_cf_refc_start_sch(struct dvb_usb_device *dvbdev, 229 + struct cxusb_bt656_params *bt656, 230 + bool firstfield, 231 + unsigned char buf[4]) 232 + { 233 + bool firstfield_code = (buf[3] & CXUSB_BT656_FIELD_MASK) == 234 + CXUSB_BT656_FIELD_1; 235 + bool sav_code = (buf[3] & CXUSB_BT656_SEAV_MASK) == 236 + CXUSB_BT656_SEAV_SAV; 237 + bool vbi_code = (buf[3] & CXUSB_BT656_VBI_MASK) == 238 + CXUSB_BT656_VBI_ON; 239 + 240 + if (!sav_code || firstfield != firstfield_code) 241 + return; 242 + 243 + if (!vbi_code) { 244 + cxusb_vprintk(dvbdev, BT656, "line start @ pos %u\n", 245 + bt656->pos); 246 + 247 + bt656->linesamples = 0; 248 + bt656->fmode = LINE_SAMPLES; 249 + } else { 250 + cxusb_vprintk(dvbdev, BT656, "VBI start @ pos %u\n", 251 + bt656->pos); 252 + 253 + bt656->fmode = VBI_SAMPLES; 254 + } 255 + } 256 + 257 + static void cxusb_medion_cf_refc_line_smpl(struct dvb_usb_device *dvbdev, 258 + struct cxusb_bt656_params *bt656, 259 + bool firstfield, 260 + unsigned int maxlinesamples, 261 + unsigned char buf[4]) 262 + { 263 + bool sav_code = (buf[3] & CXUSB_BT656_SEAV_MASK) == 264 + CXUSB_BT656_SEAV_SAV; 265 + unsigned int remsamples; 266 + 267 + if (sav_code) 268 + cxusb_vprintk(dvbdev, BT656, 269 + "SAV in line samples @ line %u, pos %u\n", 270 + bt656->line, bt656->pos); 271 + 272 + remsamples = maxlinesamples - bt656->linesamples; 273 + if (bt656->buf != NULL && remsamples > 0) { 274 + memset(bt656->buf, 0, remsamples); 275 + bt656->buf += remsamples; 276 + 277 + cxusb_vprintk(dvbdev, BT656, 278 + "field %c line %u %u samples still remaining (of %u)\n", 279 + firstfield ? '1' : '2', bt656->line, remsamples, 280 + maxlinesamples); 281 + } 282 + 283 + bt656->fmode = START_SEARCH; 284 + bt656->line++; 285 + } 286 + 287 + static void cxusb_medion_cf_refc_vbi_smpl(struct dvb_usb_device *dvbdev, 288 + struct cxusb_bt656_params *bt656, 289 + unsigned char buf[4]) 290 + { 291 + bool sav_code = (buf[3] & CXUSB_BT656_SEAV_MASK) == 292 + CXUSB_BT656_SEAV_SAV; 293 + 294 + if (sav_code) 295 + cxusb_vprintk(dvbdev, BT656, "SAV in VBI samples @ pos %u\n", 296 + bt656->pos); 297 + 298 + bt656->fmode = START_SEARCH; 299 + } 300 + 301 + /* returns whether the whole 4-byte code should be skipped in the buffer */ 302 + static bool cxusb_medion_cf_ref_code(struct dvb_usb_device *dvbdev, 303 + struct cxusb_bt656_params *bt656, 304 + bool firstfield, 305 + unsigned int maxlines, 306 + unsigned int maxlinesamples, 307 + unsigned char buf[4]) 308 + { 309 + if (bt656->fmode == START_SEARCH) 310 + cxusb_medion_cf_refc_start_sch(dvbdev, bt656, firstfield, buf); 311 + else if (bt656->fmode == LINE_SAMPLES) { 312 + cxusb_medion_cf_refc_line_smpl(dvbdev, bt656, firstfield, 313 + maxlinesamples, buf); 314 + return false; 315 + } else if (bt656->fmode == VBI_SAMPLES) { 316 + cxusb_medion_cf_refc_vbi_smpl(dvbdev, bt656, buf); 317 + return false; 318 + } 319 + 320 + return true; 321 + } 322 + 323 + static bool cxusb_medion_cs_start_sch(struct dvb_usb_device *dvbdev, 324 + struct cxusb_medion_auxbuf *auxbuf, 325 + struct cxusb_bt656_params *bt656, 326 + unsigned int maxlinesamples) 327 + { 328 + unsigned char buf[64]; 329 + unsigned int idx; 330 + unsigned int tocheck = clamp_t(size_t, maxlinesamples / 4, 3, 331 + sizeof(buf)); 332 + 333 + if (!cxusb_auxbuf_copy(auxbuf, bt656->pos + 1, buf, tocheck)) 334 + return false; 335 + 336 + for (idx = 0; idx <= tocheck - 3; idx++) 337 + if (memcmp(buf + idx, CXUSB_BT656_PREAMBLE, 3) == 0) { 338 + bt656->pos += (1 + idx); 339 + return true; 340 + } 341 + 342 + cxusb_vprintk(dvbdev, BT656, "line %u early start, pos %u\n", 343 + bt656->line, bt656->pos); 344 + 345 + bt656->linesamples = 0; 346 + bt656->fmode = LINE_SAMPLES; 347 + 348 + return true; 349 + } 350 + 351 + static void cxusb_medion_cs_line_smpl(struct cxusb_bt656_params *bt656, 352 + unsigned int maxlinesamples, 353 + unsigned char val) 354 + { 355 + if (bt656->buf != NULL) 356 + *(bt656->buf++) = val; 357 + 358 + bt656->linesamples++; 359 + bt656->pos++; 360 + 361 + if (bt656->linesamples >= maxlinesamples) { 362 + bt656->fmode = START_SEARCH; 363 + bt656->line++; 364 + } 365 + } 366 + 367 + static bool cxusb_medion_copy_samples(struct dvb_usb_device *dvbdev, 368 + struct cxusb_medion_auxbuf *auxbuf, 369 + struct cxusb_bt656_params *bt656, 370 + unsigned int maxlinesamples, 371 + unsigned char val) 372 + { 373 + if (bt656->fmode == START_SEARCH && bt656->line > 0) 374 + return cxusb_medion_cs_start_sch(dvbdev, auxbuf, bt656, 375 + maxlinesamples); 376 + else if (bt656->fmode == LINE_SAMPLES) 377 + cxusb_medion_cs_line_smpl(bt656, maxlinesamples, val); 378 + else /* TODO: copy VBI samples */ 379 + bt656->pos++; 380 + 381 + return true; 382 + } 383 + 384 + static bool cxusb_medion_copy_field(struct dvb_usb_device *dvbdev, 385 + struct cxusb_medion_auxbuf *auxbuf, 386 + struct cxusb_bt656_params *bt656, 387 + bool firstfield, 388 + unsigned int maxlines, 389 + unsigned int maxlinesmpls) 390 + { 391 + while (bt656->line < maxlines) { 392 + unsigned char val; 393 + 394 + if (!cxusb_auxbuf_copy(auxbuf, bt656->pos, &val, 1)) 395 + break; 396 + 397 + if (val == CXUSB_BT656_PREAMBLE[0]) { 398 + unsigned char buf[4]; 399 + 400 + buf[0] = val; 401 + if (!cxusb_auxbuf_copy(auxbuf, bt656->pos + 1, 402 + buf + 1, 3)) 403 + break; 404 + 405 + if (buf[1] == CXUSB_BT656_PREAMBLE[1] && 406 + buf[2] == CXUSB_BT656_PREAMBLE[2]) { 407 + /* 408 + * is this a field change? 409 + * if so, terminate copying the current field 410 + */ 411 + if (cxusb_medion_cf_refc_fld_chg(dvbdev, 412 + bt656, 413 + firstfield, 414 + maxlines, 415 + maxlinesmpls, 416 + buf)) 417 + return true; 418 + 419 + if (cxusb_medion_cf_ref_code(dvbdev, bt656, 420 + firstfield, 421 + maxlines, 422 + maxlinesmpls, 423 + buf)) 424 + bt656->pos += 4; 425 + 426 + continue; 427 + } 428 + } 429 + 430 + if (!cxusb_medion_copy_samples(dvbdev, auxbuf, bt656, 431 + maxlinesmpls, val)) 432 + break; 433 + } 434 + 435 + if (bt656->line < maxlines) { 436 + cxusb_vprintk(dvbdev, BT656, 437 + "end of buffer pos = %u, line = %u\n", 438 + bt656->pos, bt656->line); 439 + return false; 440 + } 441 + 442 + return true; 443 + } 444 + 445 + static bool cxusb_medion_v_process_auxbuf(struct cxusb_medion_dev *cxdev, 446 + bool reset) 447 + { 448 + struct dvb_usb_device *dvbdev = cxdev->dvbdev; 449 + struct cxusb_bt656_params *bt656 = &cxdev->bt656; 450 + 451 + /* 452 + * if this is a new frame 453 + * fetch a buffer from list 454 + */ 455 + if (bt656->mode == NEW_FRAME) { 456 + if (!list_empty(&cxdev->buflist)) { 457 + cxdev->vbuf = 458 + list_first_entry(&cxdev->buflist, 459 + struct cxusb_medion_vbuffer, 460 + list); 461 + list_del(&cxdev->vbuf->list); 462 + } else 463 + dev_warn(&dvbdev->udev->dev, "no free buffers\n"); 464 + } 465 + 466 + if (bt656->mode == NEW_FRAME || reset) { 467 + cxusb_vprintk(dvbdev, URB, "will copy field 1\n"); 468 + bt656->pos = 0; 469 + bt656->mode = FIRST_FIELD; 470 + bt656->fmode = START_SEARCH; 471 + bt656->line = 0; 472 + 473 + if (cxdev->vbuf != NULL) { 474 + cxdev->vbuf->vb2.vb2_buf.timestamp = ktime_get_ns(); 475 + bt656->buf = vb2_plane_vaddr(&cxdev->vbuf->vb2.vb2_buf, 476 + 0); 477 + } 478 + } 479 + 480 + if (bt656->mode == FIRST_FIELD) { 481 + if (!cxusb_medion_copy_field(dvbdev, &cxdev->auxbuf, bt656, 482 + true, cxdev->height / 2, 483 + cxdev->width * 2)) 484 + return false; 485 + 486 + /* 487 + * do not trim buffer there in case 488 + * we need to reset the search later 489 + */ 490 + 491 + cxusb_vprintk(dvbdev, URB, "will copy field 2\n"); 492 + bt656->mode = SECOND_FIELD; 493 + bt656->fmode = START_SEARCH; 494 + bt656->line = 0; 495 + } 496 + 497 + if (bt656->mode == SECOND_FIELD) { 498 + if (!cxusb_medion_copy_field(dvbdev, &cxdev->auxbuf, bt656, 499 + false, cxdev->height / 2, 500 + cxdev->width * 2)) 501 + return false; 502 + 503 + cxusb_auxbuf_head_trim(dvbdev, &cxdev->auxbuf, bt656->pos); 504 + 505 + bt656->mode = NEW_FRAME; 506 + 507 + if (cxdev->vbuf != NULL) { 508 + vb2_set_plane_payload(&cxdev->vbuf->vb2.vb2_buf, 0, 509 + cxdev->width * cxdev->height * 2); 510 + 511 + cxdev->vbuf->vb2.field = cxdev->field_order; 512 + cxdev->vbuf->vb2.sequence = cxdev->vbuf_sequence++; 513 + 514 + vb2_buffer_done(&cxdev->vbuf->vb2.vb2_buf, 515 + VB2_BUF_STATE_DONE); 516 + 517 + cxdev->vbuf = NULL; 518 + cxdev->bt656.buf = NULL; 519 + 520 + cxusb_vprintk(dvbdev, URB, "frame done\n"); 521 + } else { 522 + cxusb_vprintk(dvbdev, URB, "frame skipped\n"); 523 + cxdev->vbuf_sequence++; 524 + } 525 + } 526 + 527 + return true; 528 + } 529 + 530 + static bool cxusb_medion_v_complete_handle_urb(struct cxusb_medion_dev *cxdev, 531 + bool *auxbuf_reset) 532 + { 533 + struct dvb_usb_device *dvbdev = cxdev->dvbdev; 534 + unsigned int urbn; 535 + struct urb *urb; 536 + int ret; 537 + 538 + *auxbuf_reset = false; 539 + 540 + urbn = cxdev->nexturb; 541 + if (!test_bit(urbn, &cxdev->urbcomplete)) 542 + return false; 543 + 544 + clear_bit(urbn, &cxdev->urbcomplete); 545 + 546 + do { 547 + cxdev->nexturb++; 548 + cxdev->nexturb %= CXUSB_VIDEO_URBS; 549 + urb = cxdev->streamurbs[cxdev->nexturb]; 550 + } while (urb == NULL); 551 + 552 + urb = cxdev->streamurbs[urbn]; 553 + cxusb_vprintk(dvbdev, URB, "URB %u status = %d\n", urbn, urb->status); 554 + 555 + if (urb->status == 0 || urb->status == -EXDEV) { 556 + int i; 557 + unsigned long len; 558 + 559 + for (i = 0, len = 0; i < urb->number_of_packets; i++) 560 + len += urb->iso_frame_desc[i].actual_length; 561 + 562 + cxusb_vprintk(dvbdev, URB, "URB %u data len = %lu\n", urbn, 563 + len); 564 + 565 + if (len > 0) { 566 + cxusb_vprintk(dvbdev, URB, "appending URB\n"); 567 + 568 + /* 569 + * append new data to auxbuf while 570 + * overwriting old data if necessary 571 + * 572 + * if any overwrite happens then we can no 573 + * longer rely on consistency of the whole 574 + * data so let's start again the current 575 + * auxbuf frame assembling process from 576 + * the beginning 577 + */ 578 + *auxbuf_reset = 579 + !cxusb_auxbuf_append_urb(dvbdev, 580 + &cxdev->auxbuf, 581 + urb); 582 + } 583 + } 584 + 585 + cxusb_vprintk(dvbdev, URB, "URB %u resubmit\n", urbn); 586 + 587 + ret = usb_submit_urb(urb, GFP_KERNEL); 588 + if (ret != 0) 589 + dev_err(&dvbdev->udev->dev, 590 + "unable to resubmit URB %u (%d), you'll have to restart streaming\n", 591 + urbn, ret); 592 + 593 + /* next URB is complete already? reschedule us then to handle it */ 594 + return test_bit(cxdev->nexturb, &cxdev->urbcomplete); 595 + } 596 + 597 + static void cxusb_medion_v_complete_work(struct work_struct *work) 598 + { 599 + struct cxusb_medion_dev *cxdev = container_of(work, 600 + struct cxusb_medion_dev, 601 + urbwork); 602 + struct dvb_usb_device *dvbdev = cxdev->dvbdev; 603 + bool auxbuf_reset; 604 + bool reschedule; 605 + 606 + mutex_lock(cxdev->videodev->lock); 607 + 608 + cxusb_vprintk(dvbdev, URB, "worker called, stop_streaming = %d\n", 609 + (int)cxdev->stop_streaming); 610 + 611 + if (cxdev->stop_streaming) 612 + goto unlock; 613 + 614 + reschedule = cxusb_medion_v_complete_handle_urb(cxdev, &auxbuf_reset); 615 + 616 + if (cxusb_medion_v_process_auxbuf(cxdev, auxbuf_reset)) 617 + /* reschedule us until auxbuf no longer can produce any frame */ 618 + reschedule = true; 619 + 620 + if (reschedule) { 621 + cxusb_vprintk(dvbdev, URB, "rescheduling worker\n"); 622 + schedule_work(&cxdev->urbwork); 623 + } 624 + 625 + unlock: 626 + mutex_unlock(cxdev->videodev->lock); 627 + } 628 + 629 + static void cxusb_medion_v_complete(struct urb *u) 630 + { 631 + struct dvb_usb_device *dvbdev = u->context; 632 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 633 + unsigned int i; 634 + 635 + for (i = 0; i < CXUSB_VIDEO_URBS; i++) 636 + if (cxdev->streamurbs[i] == u) 637 + break; 638 + 639 + if (i >= CXUSB_VIDEO_URBS) { 640 + dev_err(&dvbdev->udev->dev, 641 + "complete on unknown URB\n"); 642 + return; 643 + } 644 + 645 + cxusb_vprintk(dvbdev, URB, "URB %u complete\n", i); 646 + 647 + set_bit(i, &cxdev->urbcomplete); 648 + schedule_work(&cxdev->urbwork); 649 + } 650 + 651 + static void cxusb_medion_urbs_free(struct cxusb_medion_dev *cxdev) 652 + { 653 + unsigned int i; 654 + 655 + for (i = 0; i < CXUSB_VIDEO_URBS; i++) 656 + if (cxdev->streamurbs[i] != NULL) { 657 + kfree(cxdev->streamurbs[i]->transfer_buffer); 658 + usb_free_urb(cxdev->streamurbs[i]); 659 + cxdev->streamurbs[i] = NULL; 660 + } 661 + } 662 + 663 + static void cxusb_medion_return_buffers(struct cxusb_medion_dev *cxdev, 664 + bool requeue) 665 + { 666 + struct cxusb_medion_vbuffer *vbuf, *vbuf_tmp; 667 + 668 + list_for_each_entry_safe(vbuf, vbuf_tmp, &cxdev->buflist, 669 + list) { 670 + list_del(&vbuf->list); 671 + vb2_buffer_done(&vbuf->vb2.vb2_buf, 672 + requeue ? VB2_BUF_STATE_QUEUED : 673 + VB2_BUF_STATE_ERROR); 674 + } 675 + 676 + if (cxdev->vbuf != NULL) { 677 + vb2_buffer_done(&cxdev->vbuf->vb2.vb2_buf, 678 + requeue ? VB2_BUF_STATE_QUEUED : 679 + VB2_BUF_STATE_ERROR); 680 + 681 + cxdev->vbuf = NULL; 682 + cxdev->bt656.buf = NULL; 683 + } 684 + } 685 + 686 + static int cxusb_medion_v_ss_auxbuf_alloc(struct cxusb_medion_dev *cxdev, 687 + int *npackets) 688 + { 689 + struct dvb_usb_device *dvbdev = cxdev->dvbdev; 690 + u8 *buf; 691 + unsigned int framelen, urblen, auxbuflen; 692 + 693 + framelen = (cxdev->width * 2 + 4 + 4) * 694 + (cxdev->height + 50 /* VBI lines */); 695 + 696 + /* 697 + * try to fit a whole frame into each URB, as long as doing so 698 + * does not require very high order memory allocations 699 + */ 700 + BUILD_BUG_ON(CXUSB_VIDEO_URB_MAX_SIZE / CXUSB_VIDEO_PKT_SIZE > 701 + CXUSB_VIDEO_MAX_FRAME_PKTS); 702 + *npackets = min_t(int, (framelen + CXUSB_VIDEO_PKT_SIZE - 1) / 703 + CXUSB_VIDEO_PKT_SIZE, 704 + CXUSB_VIDEO_URB_MAX_SIZE / CXUSB_VIDEO_PKT_SIZE); 705 + urblen = *npackets * CXUSB_VIDEO_PKT_SIZE; 706 + 707 + cxusb_vprintk(dvbdev, URB, 708 + "each URB will have %d packets for total of %u bytes (%u x %u @ %u)\n", 709 + *npackets, urblen, (unsigned int)cxdev->width, 710 + (unsigned int)cxdev->height, framelen); 711 + 712 + auxbuflen = framelen + urblen; 713 + 714 + buf = vmalloc(auxbuflen); 715 + if (buf == NULL) 716 + return -ENOMEM; 717 + 718 + cxusb_auxbuf_init(dvbdev, &cxdev->auxbuf, buf, auxbuflen); 719 + 720 + return 0; 721 + } 722 + 723 + static u32 cxusb_medion_norm2field_order(v4l2_std_id norm) 724 + { 725 + bool is625 = norm & V4L2_STD_625_50; 726 + bool is525 = norm & V4L2_STD_525_60; 727 + 728 + if (!is625 && !is525) 729 + return V4L2_FIELD_NONE; 730 + 731 + if (is625 && is525) 732 + return V4L2_FIELD_NONE; 733 + 734 + if (is625) 735 + return V4L2_FIELD_SEQ_TB; 736 + else /* is525 */ 737 + return V4L2_FIELD_SEQ_BT; 738 + } 739 + 740 + static u32 cxusb_medion_field_order(struct cxusb_medion_dev *cxdev) 741 + { 742 + struct dvb_usb_device *dvbdev = cxdev->dvbdev; 743 + u32 field; 744 + int ret; 745 + v4l2_std_id norm; 746 + 747 + /* TV tuner is PAL-only so it is always TB */ 748 + if (cxdev->input == 0) 749 + return V4L2_FIELD_SEQ_TB; 750 + 751 + field = cxusb_medion_norm2field_order(cxdev->norm); 752 + if (field != V4L2_FIELD_NONE) 753 + return field; 754 + 755 + ret = v4l2_subdev_call(cxdev->cx25840, video, g_std, &norm); 756 + if (ret != 0) 757 + cxusb_vprintk(dvbdev, OPS, 758 + "cannot get current standard for input %u\n", 759 + (unsigned int)cxdev->input); 760 + else { 761 + field = cxusb_medion_norm2field_order(norm); 762 + if (field != V4L2_FIELD_NONE) 763 + return field; 764 + } 765 + 766 + dev_warn(&dvbdev->udev->dev, 767 + "cannot determine field order for the current standard setup and received signal, using TB\n"); 768 + return V4L2_FIELD_SEQ_TB; 769 + } 770 + 771 + static int cxusb_medion_v_start_streaming(struct vb2_queue *q, 772 + unsigned int count) 773 + { 774 + struct dvb_usb_device *dvbdev = vb2_get_drv_priv(q); 775 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 776 + u8 streamon_params[2] = { 0x03, 0x00 }; 777 + int npackets, i; 778 + int ret; 779 + 780 + cxusb_vprintk(dvbdev, OPS, "should start streaming\n"); 781 + 782 + if (cxdev->stop_streaming) { 783 + /* stream is being stopped */ 784 + ret = -EBUSY; 785 + goto ret_retbufs; 786 + } 787 + 788 + cxdev->field_order = cxusb_medion_field_order(cxdev); 789 + 790 + ret = v4l2_subdev_call(cxdev->cx25840, video, s_stream, 1); 791 + if (ret != 0) { 792 + dev_err(&dvbdev->udev->dev, 793 + "unable to start stream (%d)\n", ret); 794 + goto ret_retbufs; 795 + } 796 + 797 + ret = cxusb_ctrl_msg(dvbdev, CMD_STREAMING_ON, streamon_params, 2, 798 + NULL, 0); 799 + if (ret != 0) { 800 + dev_err(&dvbdev->udev->dev, 801 + "unable to start streaming (%d)\n", ret); 802 + goto ret_unstream_cx; 803 + } 804 + 805 + ret = cxusb_medion_v_ss_auxbuf_alloc(cxdev, &npackets); 806 + if (ret != 0) 807 + goto ret_unstream_md; 808 + 809 + for (i = 0; i < CXUSB_VIDEO_URBS; i++) { 810 + int framen; 811 + u8 *streambuf; 812 + struct urb *surb; 813 + 814 + /* 815 + * TODO: change this to an array of single pages to avoid 816 + * doing a large continuous allocation when (if) 817 + * s-g isochronous USB transfers are supported 818 + */ 819 + streambuf = kmalloc(npackets * CXUSB_VIDEO_PKT_SIZE, 820 + GFP_KERNEL); 821 + if (streambuf == NULL) { 822 + if (i < 2) { 823 + ret = -ENOMEM; 824 + goto ret_freeab; 825 + } else 826 + break; 827 + } 828 + 829 + surb = usb_alloc_urb(npackets, GFP_KERNEL); 830 + if (surb == NULL) { 831 + kfree(streambuf); 832 + ret = -ENOMEM; 833 + goto ret_freeu; 834 + } 835 + 836 + cxdev->streamurbs[i] = surb; 837 + surb->dev = dvbdev->udev; 838 + surb->context = dvbdev; 839 + surb->pipe = usb_rcvisocpipe(dvbdev->udev, 2); 840 + 841 + surb->interval = 1; 842 + surb->transfer_flags = URB_ISO_ASAP; 843 + 844 + surb->transfer_buffer = streambuf; 845 + 846 + surb->complete = cxusb_medion_v_complete; 847 + surb->number_of_packets = npackets; 848 + surb->transfer_buffer_length = npackets * CXUSB_VIDEO_PKT_SIZE; 849 + 850 + for (framen = 0; framen < npackets; framen++) { 851 + surb->iso_frame_desc[framen].offset = 852 + CXUSB_VIDEO_PKT_SIZE * framen; 853 + 854 + surb->iso_frame_desc[framen].length = 855 + CXUSB_VIDEO_PKT_SIZE; 856 + } 857 + } 858 + 859 + cxdev->urbcomplete = 0; 860 + cxdev->nexturb = 0; 861 + cxdev->vbuf_sequence = 0; 862 + 863 + cxdev->vbuf = NULL; 864 + cxdev->bt656.mode = NEW_FRAME; 865 + cxdev->bt656.buf = NULL; 866 + 867 + for (i = 0; i < CXUSB_VIDEO_URBS; i++) 868 + if (cxdev->streamurbs[i] != NULL) { 869 + ret = usb_submit_urb(cxdev->streamurbs[i], 870 + GFP_KERNEL); 871 + if (ret != 0) 872 + dev_err(&dvbdev->udev->dev, 873 + "URB %d submission failed (%d)\n", i, 874 + ret); 875 + } 876 + 877 + return 0; 878 + 879 + ret_freeu: 880 + cxusb_medion_urbs_free(cxdev); 881 + 882 + ret_freeab: 883 + vfree(cxdev->auxbuf.buf); 884 + 885 + ret_unstream_md: 886 + cxusb_ctrl_msg(dvbdev, CMD_STREAMING_OFF, NULL, 0, NULL, 0); 887 + 888 + ret_unstream_cx: 889 + v4l2_subdev_call(cxdev->cx25840, video, s_stream, 0); 890 + 891 + ret_retbufs: 892 + cxusb_medion_return_buffers(cxdev, true); 893 + 894 + return ret; 895 + } 896 + 897 + static void cxusb_medion_v_stop_streaming(struct vb2_queue *q) 898 + { 899 + struct dvb_usb_device *dvbdev = vb2_get_drv_priv(q); 900 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 901 + int ret; 902 + unsigned int i; 903 + 904 + cxusb_vprintk(dvbdev, OPS, "should stop streaming\n"); 905 + 906 + if (WARN_ON(cxdev->stop_streaming)) 907 + return; 908 + 909 + cxdev->stop_streaming = true; 910 + 911 + cxusb_ctrl_msg(dvbdev, CMD_STREAMING_OFF, NULL, 0, NULL, 0); 912 + 913 + ret = v4l2_subdev_call(cxdev->cx25840, video, s_stream, 0); 914 + if (ret != 0) 915 + dev_err(&dvbdev->udev->dev, "unable to stop stream (%d)\n", 916 + ret); 917 + 918 + /* let URB completion run */ 919 + mutex_unlock(cxdev->videodev->lock); 920 + 921 + for (i = 0; i < CXUSB_VIDEO_URBS; i++) 922 + if (cxdev->streamurbs[i] != NULL) 923 + usb_kill_urb(cxdev->streamurbs[i]); 924 + 925 + flush_work(&cxdev->urbwork); 926 + 927 + mutex_lock(cxdev->videodev->lock); 928 + 929 + /* free transfer buffer and URB */ 930 + vfree(cxdev->auxbuf.buf); 931 + 932 + cxusb_medion_urbs_free(cxdev); 933 + 934 + cxusb_medion_return_buffers(cxdev, false); 935 + 936 + cxdev->stop_streaming = false; 937 + } 938 + 939 + static void cxusub_medion_v_buf_queue(struct vb2_buffer *vb) 940 + { 941 + struct vb2_v4l2_buffer *v4l2buf = to_vb2_v4l2_buffer(vb); 942 + struct cxusb_medion_vbuffer *vbuf = 943 + container_of(v4l2buf, struct cxusb_medion_vbuffer, vb2); 944 + struct dvb_usb_device *dvbdev = vb2_get_drv_priv(vb->vb2_queue); 945 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 946 + 947 + /* cxusb_vprintk(dvbdev, OPS, "mmmm.. a fresh buffer...\n"); */ 948 + 949 + list_add_tail(&vbuf->list, &cxdev->buflist); 950 + } 951 + 952 + static const struct vb2_ops cxdev_video_qops = { 953 + .queue_setup = cxusb_medion_v_queue_setup, 954 + .buf_init = cxusb_medion_v_buf_init, 955 + .start_streaming = cxusb_medion_v_start_streaming, 956 + .stop_streaming = cxusb_medion_v_stop_streaming, 957 + .buf_queue = cxusub_medion_v_buf_queue, 958 + .wait_prepare = vb2_ops_wait_prepare, 959 + .wait_finish = vb2_ops_wait_finish 960 + }; 961 + 962 + static const __u32 videocaps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | 963 + V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; 964 + static const __u32 radiocaps = V4L2_CAP_TUNER | V4L2_CAP_RADIO; 965 + 966 + static int cxusb_medion_v_querycap(struct file *file, void *fh, 967 + struct v4l2_capability *cap) 968 + { 969 + struct dvb_usb_device *dvbdev = video_drvdata(file); 970 + 971 + strscpy(cap->driver, dvbdev->udev->dev.driver->name, 972 + sizeof(cap->driver)); 973 + strscpy(cap->card, "Medion 95700", sizeof(cap->card)); 974 + usb_make_path(dvbdev->udev, cap->bus_info, sizeof(cap->bus_info)); 975 + 976 + cap->capabilities = videocaps | radiocaps | V4L2_CAP_DEVICE_CAPS; 977 + 978 + return 0; 979 + } 980 + 981 + static int cxusb_medion_v_enum_fmt_vid_cap(struct file *file, void *fh, 982 + struct v4l2_fmtdesc *f) 983 + { 984 + if (f->index != 0) 985 + return -EINVAL; 986 + 987 + f->pixelformat = V4L2_PIX_FMT_UYVY; 988 + 989 + return 0; 990 + } 991 + 992 + static int cxusb_medion_g_fmt_vid_cap(struct file *file, void *fh, 993 + struct v4l2_format *f) 994 + { 995 + struct dvb_usb_device *dvbdev = video_drvdata(file); 996 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 997 + 998 + f->fmt.pix.width = cxdev->width; 999 + f->fmt.pix.height = cxdev->height; 1000 + f->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY; 1001 + f->fmt.pix.field = vb2_start_streaming_called(&cxdev->videoqueue) ? 1002 + cxdev->field_order : cxusb_medion_field_order(cxdev); 1003 + f->fmt.pix.bytesperline = cxdev->width * 2; 1004 + f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 1005 + f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height; 1006 + 1007 + return 0; 1008 + } 1009 + 1010 + static int cxusb_medion_try_s_fmt_vid_cap(struct file *file, 1011 + struct v4l2_format *f, 1012 + bool isset) 1013 + { 1014 + struct dvb_usb_device *dvbdev = video_drvdata(file); 1015 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 1016 + struct v4l2_subdev_format subfmt; 1017 + u32 field; 1018 + int ret; 1019 + 1020 + if (isset && vb2_is_busy(&cxdev->videoqueue)) 1021 + return -EBUSY; 1022 + 1023 + field = vb2_start_streaming_called(&cxdev->videoqueue) ? 1024 + cxdev->field_order : cxusb_medion_field_order(cxdev); 1025 + 1026 + memset(&subfmt, 0, sizeof(subfmt)); 1027 + subfmt.which = isset ? V4L2_SUBDEV_FORMAT_ACTIVE : 1028 + V4L2_SUBDEV_FORMAT_TRY; 1029 + subfmt.format.width = f->fmt.pix.width & ~1; 1030 + subfmt.format.height = f->fmt.pix.height & ~1; 1031 + subfmt.format.code = MEDIA_BUS_FMT_FIXED; 1032 + subfmt.format.field = field; 1033 + subfmt.format.colorspace = V4L2_COLORSPACE_SMPTE170M; 1034 + 1035 + ret = v4l2_subdev_call(cxdev->cx25840, pad, set_fmt, NULL, &subfmt); 1036 + if (ret != 0) 1037 + return ret; 1038 + 1039 + f->fmt.pix.width = subfmt.format.width; 1040 + f->fmt.pix.height = subfmt.format.height; 1041 + f->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY; 1042 + f->fmt.pix.field = field; 1043 + f->fmt.pix.bytesperline = f->fmt.pix.width * 2; 1044 + f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height; 1045 + f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 1046 + 1047 + if (isset) { 1048 + cxdev->width = f->fmt.pix.width; 1049 + cxdev->height = f->fmt.pix.height; 1050 + } 1051 + 1052 + return 0; 1053 + } 1054 + 1055 + static int cxusb_medion_try_fmt_vid_cap(struct file *file, void *fh, 1056 + struct v4l2_format *f) 1057 + { 1058 + return cxusb_medion_try_s_fmt_vid_cap(file, f, false); 1059 + } 1060 + 1061 + static int cxusb_medion_s_fmt_vid_cap(struct file *file, void *fh, 1062 + struct v4l2_format *f) 1063 + { 1064 + return cxusb_medion_try_s_fmt_vid_cap(file, f, true); 1065 + } 1066 + 1067 + static const struct { 1068 + struct v4l2_input input; 1069 + u32 inputcfg; 1070 + } cxusb_medion_inputs[] = { 1071 + { .input = { .name = "TV tuner", .type = V4L2_INPUT_TYPE_TUNER, 1072 + .tuner = 0, .std = V4L2_STD_PAL }, 1073 + .inputcfg = CX25840_COMPOSITE2, }, 1074 + 1075 + { .input = { .name = "Composite", .type = V4L2_INPUT_TYPE_CAMERA, 1076 + .std = V4L2_STD_ALL }, 1077 + .inputcfg = CX25840_COMPOSITE1, }, 1078 + 1079 + { .input = { .name = "S-Video", .type = V4L2_INPUT_TYPE_CAMERA, 1080 + .std = V4L2_STD_ALL }, 1081 + .inputcfg = CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 } 1082 + }; 1083 + 1084 + #define CXUSB_INPUT_CNT ARRAY_SIZE(cxusb_medion_inputs) 1085 + 1086 + static int cxusb_medion_enum_input(struct file *file, void *fh, 1087 + struct v4l2_input *inp) 1088 + { 1089 + struct dvb_usb_device *dvbdev = video_drvdata(file); 1090 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 1091 + u32 index = inp->index; 1092 + 1093 + if (index >= CXUSB_INPUT_CNT) 1094 + return -EINVAL; 1095 + 1096 + *inp = cxusb_medion_inputs[index].input; 1097 + inp->index = index; 1098 + inp->capabilities |= V4L2_IN_CAP_STD; 1099 + 1100 + if (index == cxdev->input) { 1101 + int ret; 1102 + u32 status = 0; 1103 + 1104 + ret = v4l2_subdev_call(cxdev->cx25840, video, g_input_status, 1105 + &status); 1106 + if (ret != 0) 1107 + dev_warn(&dvbdev->udev->dev, 1108 + "cx25840 input status query failed (%d)\n", 1109 + ret); 1110 + else 1111 + inp->status = status; 1112 + } 1113 + 1114 + return 0; 1115 + } 1116 + 1117 + static int cxusb_medion_g_input(struct file *file, void *fh, 1118 + unsigned int *i) 1119 + { 1120 + struct dvb_usb_device *dvbdev = video_drvdata(file); 1121 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 1122 + 1123 + *i = cxdev->input; 1124 + 1125 + return 0; 1126 + } 1127 + 1128 + static int cxusb_medion_set_norm(struct cxusb_medion_dev *cxdev, 1129 + v4l2_std_id norm) 1130 + { 1131 + struct dvb_usb_device *dvbdev = cxdev->dvbdev; 1132 + int ret; 1133 + 1134 + cxusb_vprintk(dvbdev, OPS, 1135 + "trying to set standard for input %u to %lx\n", 1136 + (unsigned int)cxdev->input, 1137 + (unsigned long)norm); 1138 + 1139 + /* no autodetection support */ 1140 + if (norm == V4L2_STD_UNKNOWN) 1141 + return -EINVAL; 1142 + 1143 + /* on composite or S-Video any std is acceptable */ 1144 + if (cxdev->input != 0) { 1145 + ret = v4l2_subdev_call(cxdev->cx25840, video, s_std, norm); 1146 + if (ret) 1147 + return ret; 1148 + 1149 + goto ret_savenorm; 1150 + } 1151 + 1152 + /* TV tuner is only able to demodulate PAL */ 1153 + if ((norm & ~V4L2_STD_PAL) != 0) 1154 + return -EINVAL; 1155 + 1156 + ret = v4l2_subdev_call(cxdev->tda9887, video, s_std, norm); 1157 + if (ret != 0) { 1158 + dev_err(&dvbdev->udev->dev, 1159 + "tda9887 norm setup failed (%d)\n", 1160 + ret); 1161 + return ret; 1162 + } 1163 + 1164 + ret = v4l2_subdev_call(cxdev->tuner, video, s_std, norm); 1165 + if (ret != 0) { 1166 + dev_err(&dvbdev->udev->dev, 1167 + "tuner norm setup failed (%d)\n", 1168 + ret); 1169 + return ret; 1170 + } 1171 + 1172 + ret = v4l2_subdev_call(cxdev->cx25840, video, s_std, norm); 1173 + if (ret != 0) { 1174 + dev_err(&dvbdev->udev->dev, 1175 + "cx25840 norm setup failed (%d)\n", 1176 + ret); 1177 + return ret; 1178 + } 1179 + 1180 + ret_savenorm: 1181 + cxdev->norm = norm; 1182 + 1183 + return 0; 1184 + } 1185 + 1186 + static int cxusb_medion_s_input(struct file *file, void *fh, 1187 + unsigned int i) 1188 + { 1189 + struct dvb_usb_device *dvbdev = video_drvdata(file); 1190 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 1191 + int ret; 1192 + v4l2_std_id norm; 1193 + 1194 + if (i >= CXUSB_INPUT_CNT) 1195 + return -EINVAL; 1196 + 1197 + ret = v4l2_subdev_call(cxdev->cx25840, video, s_routing, 1198 + cxusb_medion_inputs[i].inputcfg, 0, 0); 1199 + if (ret != 0) 1200 + return ret; 1201 + 1202 + cxdev->input = i; 1203 + cxdev->videodev->tvnorms = cxusb_medion_inputs[i].input.std; 1204 + 1205 + norm = cxdev->norm & cxusb_medion_inputs[i].input.std; 1206 + if (norm == 0) 1207 + norm = cxusb_medion_inputs[i].input.std; 1208 + 1209 + cxusb_medion_set_norm(cxdev, norm); 1210 + 1211 + return 0; 1212 + } 1213 + 1214 + static int cxusb_medion_g_tuner(struct file *file, void *fh, 1215 + struct v4l2_tuner *tuner) 1216 + { 1217 + struct dvb_usb_device *dvbdev = video_drvdata(file); 1218 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 1219 + struct video_device *vdev = video_devdata(file); 1220 + int ret; 1221 + 1222 + if (tuner->index != 0) 1223 + return -EINVAL; 1224 + 1225 + if (vdev->vfl_type == VFL_TYPE_GRABBER) 1226 + tuner->type = V4L2_TUNER_ANALOG_TV; 1227 + else 1228 + tuner->type = V4L2_TUNER_RADIO; 1229 + 1230 + tuner->capability = 0; 1231 + tuner->afc = 0; 1232 + 1233 + /* 1234 + * fills: 1235 + * always: capability (static), rangelow (static), rangehigh (static) 1236 + * radio mode: afc (may fail silently), rxsubchans (static), audmode 1237 + */ 1238 + ret = v4l2_subdev_call(cxdev->tda9887, tuner, g_tuner, tuner); 1239 + if (ret != 0) 1240 + return ret; 1241 + 1242 + /* 1243 + * fills: 1244 + * always: capability (static), rangelow (static), rangehigh (static) 1245 + * radio mode: rxsubchans (always stereo), audmode, 1246 + * signal (might be wrong) 1247 + */ 1248 + ret = v4l2_subdev_call(cxdev->tuner, tuner, g_tuner, tuner); 1249 + if (ret != 0) 1250 + return ret; 1251 + 1252 + tuner->signal = 0; 1253 + 1254 + /* 1255 + * fills: TV mode: capability, rxsubchans, audmode, signal 1256 + */ 1257 + ret = v4l2_subdev_call(cxdev->cx25840, tuner, g_tuner, tuner); 1258 + if (ret != 0) 1259 + return ret; 1260 + 1261 + if (vdev->vfl_type == VFL_TYPE_GRABBER) 1262 + strscpy(tuner->name, "TV tuner", sizeof(tuner->name)); 1263 + else 1264 + strscpy(tuner->name, "Radio tuner", sizeof(tuner->name)); 1265 + 1266 + memset(tuner->reserved, 0, sizeof(tuner->reserved)); 1267 + 1268 + return 0; 1269 + } 1270 + 1271 + static int cxusb_medion_s_tuner(struct file *file, void *fh, 1272 + const struct v4l2_tuner *tuner) 1273 + { 1274 + struct dvb_usb_device *dvbdev = video_drvdata(file); 1275 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 1276 + struct video_device *vdev = video_devdata(file); 1277 + int ret; 1278 + 1279 + if (tuner->index != 0) 1280 + return -EINVAL; 1281 + 1282 + ret = v4l2_subdev_call(cxdev->tda9887, tuner, s_tuner, tuner); 1283 + if (ret != 0) 1284 + return ret; 1285 + 1286 + ret = v4l2_subdev_call(cxdev->tuner, tuner, s_tuner, tuner); 1287 + if (ret != 0) 1288 + return ret; 1289 + 1290 + /* 1291 + * make sure that cx25840 is in a correct TV / radio mode, 1292 + * since calls above may have changed it for tuner / IF demod 1293 + */ 1294 + if (vdev->vfl_type == VFL_TYPE_GRABBER) 1295 + v4l2_subdev_call(cxdev->cx25840, video, s_std, cxdev->norm); 1296 + else 1297 + v4l2_subdev_call(cxdev->cx25840, tuner, s_radio); 1298 + 1299 + return v4l2_subdev_call(cxdev->cx25840, tuner, s_tuner, tuner); 1300 + } 1301 + 1302 + static int cxusb_medion_g_frequency(struct file *file, void *fh, 1303 + struct v4l2_frequency *freq) 1304 + { 1305 + struct dvb_usb_device *dvbdev = video_drvdata(file); 1306 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 1307 + 1308 + if (freq->tuner != 0) 1309 + return -EINVAL; 1310 + 1311 + return v4l2_subdev_call(cxdev->tuner, tuner, g_frequency, freq); 1312 + } 1313 + 1314 + static int cxusb_medion_s_frequency(struct file *file, void *fh, 1315 + const struct v4l2_frequency *freq) 1316 + { 1317 + struct dvb_usb_device *dvbdev = video_drvdata(file); 1318 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 1319 + struct video_device *vdev = video_devdata(file); 1320 + int ret; 1321 + 1322 + if (freq->tuner != 0) 1323 + return -EINVAL; 1324 + 1325 + ret = v4l2_subdev_call(cxdev->tda9887, tuner, s_frequency, freq); 1326 + if (ret != 0) 1327 + return ret; 1328 + 1329 + ret = v4l2_subdev_call(cxdev->tuner, tuner, s_frequency, freq); 1330 + if (ret != 0) 1331 + return ret; 1332 + 1333 + /* 1334 + * make sure that cx25840 is in a correct TV / radio mode, 1335 + * since calls above may have changed it for tuner / IF demod 1336 + */ 1337 + if (vdev->vfl_type == VFL_TYPE_GRABBER) 1338 + v4l2_subdev_call(cxdev->cx25840, video, s_std, cxdev->norm); 1339 + else 1340 + v4l2_subdev_call(cxdev->cx25840, tuner, s_radio); 1341 + 1342 + return v4l2_subdev_call(cxdev->cx25840, tuner, s_frequency, freq); 1343 + } 1344 + 1345 + static int cxusb_medion_g_std(struct file *file, void *fh, 1346 + v4l2_std_id *norm) 1347 + { 1348 + struct dvb_usb_device *dvbdev = video_drvdata(file); 1349 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 1350 + 1351 + *norm = cxdev->norm; 1352 + 1353 + if (*norm == V4L2_STD_UNKNOWN) 1354 + return -ENODATA; 1355 + 1356 + return 0; 1357 + } 1358 + 1359 + static int cxusb_medion_s_std(struct file *file, void *fh, 1360 + v4l2_std_id norm) 1361 + { 1362 + struct dvb_usb_device *dvbdev = video_drvdata(file); 1363 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 1364 + 1365 + return cxusb_medion_set_norm(cxdev, norm); 1366 + } 1367 + 1368 + static int cxusb_medion_querystd(struct file *file, void *fh, 1369 + v4l2_std_id *norm) 1370 + { 1371 + struct dvb_usb_device *dvbdev = video_drvdata(file); 1372 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 1373 + v4l2_std_id norm_mask; 1374 + int ret; 1375 + 1376 + /* 1377 + * make sure we don't have improper std bits set for the TV tuner 1378 + * (could happen when no signal was present yet after reset) 1379 + */ 1380 + if (cxdev->input == 0) 1381 + norm_mask = V4L2_STD_PAL; 1382 + else 1383 + norm_mask = V4L2_STD_ALL; 1384 + 1385 + ret = v4l2_subdev_call(cxdev->cx25840, video, querystd, norm); 1386 + if (ret != 0) { 1387 + cxusb_vprintk(dvbdev, OPS, 1388 + "cannot get detected standard for input %u\n", 1389 + (unsigned int)cxdev->input); 1390 + return ret; 1391 + } 1392 + 1393 + cxusb_vprintk(dvbdev, OPS, "input %u detected standard is %lx\n", 1394 + (unsigned int)cxdev->input, (unsigned long)*norm); 1395 + *norm &= norm_mask; 1396 + 1397 + return 0; 1398 + } 1399 + 1400 + static int cxusb_medion_log_status(struct file *file, void *fh) 1401 + { 1402 + struct dvb_usb_device *dvbdev = video_drvdata(file); 1403 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 1404 + 1405 + v4l2_device_call_all(&cxdev->v4l2dev, 0, core, log_status); 1406 + 1407 + return 0; 1408 + } 1409 + 1410 + static const struct v4l2_ioctl_ops cxusb_video_ioctl = { 1411 + .vidioc_querycap = cxusb_medion_v_querycap, 1412 + .vidioc_enum_fmt_vid_cap = cxusb_medion_v_enum_fmt_vid_cap, 1413 + .vidioc_g_fmt_vid_cap = cxusb_medion_g_fmt_vid_cap, 1414 + .vidioc_s_fmt_vid_cap = cxusb_medion_s_fmt_vid_cap, 1415 + .vidioc_try_fmt_vid_cap = cxusb_medion_try_fmt_vid_cap, 1416 + .vidioc_enum_input = cxusb_medion_enum_input, 1417 + .vidioc_g_input = cxusb_medion_g_input, 1418 + .vidioc_s_input = cxusb_medion_s_input, 1419 + .vidioc_g_tuner = cxusb_medion_g_tuner, 1420 + .vidioc_s_tuner = cxusb_medion_s_tuner, 1421 + .vidioc_g_frequency = cxusb_medion_g_frequency, 1422 + .vidioc_s_frequency = cxusb_medion_s_frequency, 1423 + .vidioc_g_std = cxusb_medion_g_std, 1424 + .vidioc_s_std = cxusb_medion_s_std, 1425 + .vidioc_querystd = cxusb_medion_querystd, 1426 + .vidioc_log_status = cxusb_medion_log_status, 1427 + .vidioc_reqbufs = vb2_ioctl_reqbufs, 1428 + .vidioc_querybuf = vb2_ioctl_querybuf, 1429 + .vidioc_qbuf = vb2_ioctl_qbuf, 1430 + .vidioc_dqbuf = vb2_ioctl_dqbuf, 1431 + .vidioc_create_bufs = vb2_ioctl_create_bufs, 1432 + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, 1433 + .vidioc_streamon = vb2_ioctl_streamon, 1434 + .vidioc_streamoff = vb2_ioctl_streamoff 1435 + }; 1436 + 1437 + static const struct v4l2_ioctl_ops cxusb_radio_ioctl = { 1438 + .vidioc_querycap = cxusb_medion_v_querycap, 1439 + .vidioc_g_tuner = cxusb_medion_g_tuner, 1440 + .vidioc_s_tuner = cxusb_medion_s_tuner, 1441 + .vidioc_g_frequency = cxusb_medion_g_frequency, 1442 + .vidioc_s_frequency = cxusb_medion_s_frequency, 1443 + .vidioc_log_status = cxusb_medion_log_status 1444 + }; 1445 + 1446 + /* 1447 + * in principle, this should be const, but s_io_pin_config is declared 1448 + * to take non-const, and gcc complains 1449 + */ 1450 + static struct v4l2_subdev_io_pin_config cxusub_medion_pin_config[] = { 1451 + { .pin = CX25840_PIN_DVALID_PRGM0, .function = CX25840_PAD_DEFAULT, 1452 + .strength = CX25840_PIN_DRIVE_MEDIUM }, 1453 + { .pin = CX25840_PIN_PLL_CLK_PRGM7, .function = CX25840_PAD_AUX_PLL }, 1454 + { .pin = CX25840_PIN_HRESET_PRGM2, .function = CX25840_PAD_ACTIVE, 1455 + .strength = CX25840_PIN_DRIVE_MEDIUM } 1456 + }; 1457 + 1458 + int cxusb_medion_analog_init(struct dvb_usb_device *dvbdev) 1459 + { 1460 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 1461 + u8 tuner_analog_msg_data[] = { 0x9c, 0x60, 0x85, 0x54 }; 1462 + struct i2c_msg tuner_analog_msg = { .addr = 0x61, .flags = 0, 1463 + .buf = tuner_analog_msg_data, 1464 + .len = 1465 + sizeof(tuner_analog_msg_data) }; 1466 + struct v4l2_subdev_format subfmt; 1467 + int ret; 1468 + 1469 + /* switch tuner to analog mode so IF demod will become accessible */ 1470 + ret = i2c_transfer(&dvbdev->i2c_adap, &tuner_analog_msg, 1); 1471 + if (ret != 1) 1472 + dev_warn(&dvbdev->udev->dev, 1473 + "tuner analog switch failed (%d)\n", ret); 1474 + 1475 + /* 1476 + * cx25840 might have lost power during mode switching so we need 1477 + * to set it again 1478 + */ 1479 + ret = v4l2_subdev_call(cxdev->cx25840, core, reset, 0); 1480 + if (ret != 0) 1481 + dev_warn(&dvbdev->udev->dev, 1482 + "cx25840 reset failed (%d)\n", ret); 1483 + 1484 + ret = v4l2_subdev_call(cxdev->cx25840, video, s_routing, 1485 + CX25840_COMPOSITE1, 0, 0); 1486 + if (ret != 0) 1487 + dev_warn(&dvbdev->udev->dev, 1488 + "cx25840 initial input setting failed (%d)\n", ret); 1489 + 1490 + /* composite */ 1491 + cxdev->input = 1; 1492 + cxdev->videodev->tvnorms = V4L2_STD_ALL; 1493 + cxdev->norm = V4L2_STD_PAL; 1494 + 1495 + /* TODO: setup audio samples insertion */ 1496 + 1497 + ret = v4l2_subdev_call(cxdev->cx25840, core, s_io_pin_config, 1498 + sizeof(cxusub_medion_pin_config) / 1499 + sizeof(cxusub_medion_pin_config[0]), 1500 + cxusub_medion_pin_config); 1501 + if (ret != 0) 1502 + dev_warn(&dvbdev->udev->dev, 1503 + "cx25840 pin config failed (%d)\n", ret); 1504 + 1505 + /* make sure that we aren't in radio mode */ 1506 + v4l2_subdev_call(cxdev->tda9887, video, s_std, cxdev->norm); 1507 + v4l2_subdev_call(cxdev->tuner, video, s_std, cxdev->norm); 1508 + v4l2_subdev_call(cxdev->cx25840, video, s_std, cxdev->norm); 1509 + 1510 + memset(&subfmt, 0, sizeof(subfmt)); 1511 + subfmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; 1512 + subfmt.format.width = cxdev->width; 1513 + subfmt.format.height = cxdev->height; 1514 + subfmt.format.code = MEDIA_BUS_FMT_FIXED; 1515 + subfmt.format.field = V4L2_FIELD_SEQ_TB; 1516 + subfmt.format.colorspace = V4L2_COLORSPACE_SMPTE170M; 1517 + 1518 + ret = v4l2_subdev_call(cxdev->cx25840, pad, set_fmt, NULL, &subfmt); 1519 + if (ret != 0) 1520 + dev_warn(&dvbdev->udev->dev, 1521 + "cx25840 format set failed (%d)\n", ret); 1522 + 1523 + if (ret == 0) { 1524 + cxdev->width = subfmt.format.width; 1525 + cxdev->height = subfmt.format.height; 1526 + } 1527 + 1528 + return 0; 1529 + } 1530 + 1531 + static int cxusb_videoradio_open(struct file *f) 1532 + { 1533 + struct dvb_usb_device *dvbdev = video_drvdata(f); 1534 + int ret; 1535 + 1536 + /* 1537 + * no locking needed since this call only modifies analog 1538 + * state if there are no other analog handles currenly 1539 + * opened so ops done via them cannot create a conflict 1540 + */ 1541 + ret = cxusb_medion_get(dvbdev, CXUSB_OPEN_ANALOG); 1542 + if (ret != 0) 1543 + return ret; 1544 + 1545 + ret = v4l2_fh_open(f); 1546 + if (ret != 0) 1547 + goto ret_release; 1548 + 1549 + cxusb_vprintk(dvbdev, OPS, "got open\n"); 1550 + 1551 + return 0; 1552 + 1553 + ret_release: 1554 + cxusb_medion_put(dvbdev); 1555 + 1556 + return ret; 1557 + } 1558 + 1559 + static int cxusb_videoradio_release(struct file *f) 1560 + { 1561 + struct video_device *vdev = video_devdata(f); 1562 + struct dvb_usb_device *dvbdev = video_drvdata(f); 1563 + int ret; 1564 + 1565 + cxusb_vprintk(dvbdev, OPS, "got release\n"); 1566 + 1567 + if (vdev->vfl_type == VFL_TYPE_GRABBER) 1568 + ret = vb2_fop_release(f); 1569 + else 1570 + ret = v4l2_fh_release(f); 1571 + 1572 + cxusb_medion_put(dvbdev); 1573 + 1574 + return ret; 1575 + } 1576 + 1577 + static const struct v4l2_file_operations cxusb_video_fops = { 1578 + .owner = THIS_MODULE, 1579 + .read = vb2_fop_read, 1580 + .poll = vb2_fop_poll, 1581 + .unlocked_ioctl = video_ioctl2, 1582 + .mmap = vb2_fop_mmap, 1583 + .open = cxusb_videoradio_open, 1584 + .release = cxusb_videoradio_release 1585 + }; 1586 + 1587 + static const struct v4l2_file_operations cxusb_radio_fops = { 1588 + .owner = THIS_MODULE, 1589 + .unlocked_ioctl = video_ioctl2, 1590 + .open = cxusb_videoradio_open, 1591 + .release = cxusb_videoradio_release 1592 + }; 1593 + 1594 + static void cxusb_medion_v4l2_release(struct v4l2_device *v4l2_dev) 1595 + { 1596 + struct cxusb_medion_dev *cxdev = 1597 + container_of(v4l2_dev, struct cxusb_medion_dev, v4l2dev); 1598 + struct dvb_usb_device *dvbdev = cxdev->dvbdev; 1599 + 1600 + cxusb_vprintk(dvbdev, OPS, "v4l2 device release\n"); 1601 + 1602 + v4l2_device_unregister(&cxdev->v4l2dev); 1603 + 1604 + mutex_destroy(&cxdev->dev_lock); 1605 + 1606 + while (completion_done(&cxdev->v4l2_release)) 1607 + schedule(); 1608 + 1609 + complete(&cxdev->v4l2_release); 1610 + } 1611 + 1612 + static void cxusb_medion_videodev_release(struct video_device *vdev) 1613 + { 1614 + struct dvb_usb_device *dvbdev = video_get_drvdata(vdev); 1615 + 1616 + cxusb_vprintk(dvbdev, OPS, "video device release\n"); 1617 + 1618 + vb2_queue_release(vdev->queue); 1619 + 1620 + video_device_release(vdev); 1621 + } 1622 + 1623 + static int cxusb_medion_register_analog_video(struct dvb_usb_device *dvbdev) 1624 + { 1625 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 1626 + int ret; 1627 + 1628 + cxdev->videoqueue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1629 + cxdev->videoqueue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ | 1630 + VB2_DMABUF; 1631 + cxdev->videoqueue.ops = &cxdev_video_qops; 1632 + cxdev->videoqueue.mem_ops = &vb2_vmalloc_memops; 1633 + cxdev->videoqueue.drv_priv = dvbdev; 1634 + cxdev->videoqueue.buf_struct_size = 1635 + sizeof(struct cxusb_medion_vbuffer); 1636 + cxdev->videoqueue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 1637 + cxdev->videoqueue.min_buffers_needed = 6; 1638 + cxdev->videoqueue.lock = &cxdev->dev_lock; 1639 + 1640 + ret = vb2_queue_init(&cxdev->videoqueue); 1641 + if (ret) { 1642 + dev_err(&dvbdev->udev->dev, 1643 + "video queue init failed, ret = %d\n", ret); 1644 + return ret; 1645 + } 1646 + 1647 + cxdev->videodev = video_device_alloc(); 1648 + if (cxdev->videodev == NULL) { 1649 + dev_err(&dvbdev->udev->dev, "video device alloc failed\n"); 1650 + ret = -ENOMEM; 1651 + goto ret_qrelease; 1652 + } 1653 + 1654 + cxdev->videodev->device_caps = videocaps; 1655 + cxdev->videodev->fops = &cxusb_video_fops; 1656 + cxdev->videodev->v4l2_dev = &cxdev->v4l2dev; 1657 + cxdev->videodev->queue = &cxdev->videoqueue; 1658 + strscpy(cxdev->videodev->name, "cxusb", sizeof(cxdev->videodev->name)); 1659 + cxdev->videodev->vfl_dir = VFL_DIR_RX; 1660 + cxdev->videodev->ioctl_ops = &cxusb_video_ioctl; 1661 + cxdev->videodev->tvnorms = V4L2_STD_ALL; 1662 + cxdev->videodev->release = cxusb_medion_videodev_release; 1663 + cxdev->videodev->lock = &cxdev->dev_lock; 1664 + video_set_drvdata(cxdev->videodev, dvbdev); 1665 + 1666 + ret = video_register_device(cxdev->videodev, VFL_TYPE_GRABBER, -1); 1667 + if (ret) { 1668 + dev_err(&dvbdev->udev->dev, 1669 + "video device register failed, ret = %d\n", ret); 1670 + goto ret_vrelease; 1671 + } 1672 + 1673 + return 0; 1674 + 1675 + ret_vrelease: 1676 + video_device_release(cxdev->videodev); 1677 + 1678 + ret_qrelease: 1679 + vb2_queue_release(&cxdev->videoqueue); 1680 + 1681 + return ret; 1682 + } 1683 + 1684 + static int cxusb_medion_register_analog_radio(struct dvb_usb_device *dvbdev) 1685 + { 1686 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 1687 + int ret; 1688 + 1689 + cxdev->radiodev = video_device_alloc(); 1690 + if (cxdev->radiodev == NULL) { 1691 + dev_err(&dvbdev->udev->dev, "radio device alloc failed\n"); 1692 + return -ENOMEM; 1693 + } 1694 + 1695 + cxdev->radiodev->device_caps = radiocaps; 1696 + cxdev->radiodev->fops = &cxusb_radio_fops; 1697 + cxdev->radiodev->v4l2_dev = &cxdev->v4l2dev; 1698 + strscpy(cxdev->radiodev->name, "cxusb", sizeof(cxdev->radiodev->name)); 1699 + cxdev->radiodev->vfl_dir = VFL_DIR_RX; 1700 + cxdev->radiodev->ioctl_ops = &cxusb_radio_ioctl; 1701 + cxdev->radiodev->release = video_device_release; 1702 + cxdev->radiodev->lock = &cxdev->dev_lock; 1703 + video_set_drvdata(cxdev->radiodev, dvbdev); 1704 + 1705 + ret = video_register_device(cxdev->radiodev, VFL_TYPE_RADIO, -1); 1706 + if (ret) { 1707 + dev_err(&dvbdev->udev->dev, 1708 + "radio device register failed, ret = %d\n", ret); 1709 + video_device_release(cxdev->radiodev); 1710 + return ret; 1711 + } 1712 + 1713 + return 0; 1714 + } 1715 + 1716 + static int cxusb_medion_register_analog_subdevs(struct dvb_usb_device *dvbdev) 1717 + { 1718 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 1719 + int ret; 1720 + struct tuner_setup tun_setup; 1721 + 1722 + /* attach cx25840 capture chip */ 1723 + cxdev->cx25840 = v4l2_i2c_new_subdev(&cxdev->v4l2dev, 1724 + &dvbdev->i2c_adap, 1725 + "cx25840", 0x44, NULL); 1726 + if (cxdev->cx25840 == NULL) { 1727 + dev_err(&dvbdev->udev->dev, "cx25840 not found\n"); 1728 + return -ENODEV; 1729 + } 1730 + 1731 + /* 1732 + * Initialize cx25840 chip by calling its subdevice init core op. 1733 + * 1734 + * This switches it into the generic mode that disables some of 1735 + * ivtv-related hacks in the cx25840 driver while allowing setting 1736 + * of the chip video output configuration (passed in the call below 1737 + * as the last argument). 1738 + */ 1739 + ret = v4l2_subdev_call(cxdev->cx25840, core, init, 1740 + CX25840_VCONFIG_FMT_BT656 | 1741 + CX25840_VCONFIG_RES_8BIT | 1742 + CX25840_VCONFIG_VBIRAW_DISABLED | 1743 + CX25840_VCONFIG_ANCDATA_DISABLED | 1744 + CX25840_VCONFIG_ACTIVE_COMPOSITE | 1745 + CX25840_VCONFIG_VALID_ANDACTIVE | 1746 + CX25840_VCONFIG_HRESETW_NORMAL | 1747 + CX25840_VCONFIG_CLKGATE_NONE | 1748 + CX25840_VCONFIG_DCMODE_DWORDS); 1749 + if (ret != 0) { 1750 + dev_err(&dvbdev->udev->dev, 1751 + "cx25840 init failed (%d)\n", ret); 1752 + return ret; 1753 + } 1754 + 1755 + /* attach analog tuner */ 1756 + cxdev->tuner = v4l2_i2c_new_subdev(&cxdev->v4l2dev, 1757 + &dvbdev->i2c_adap, 1758 + "tuner", 0x61, NULL); 1759 + if (cxdev->tuner == NULL) { 1760 + dev_err(&dvbdev->udev->dev, "tuner not found\n"); 1761 + return -ENODEV; 1762 + } 1763 + 1764 + /* configure it */ 1765 + memset(&tun_setup, 0, sizeof(tun_setup)); 1766 + tun_setup.addr = 0x61; 1767 + tun_setup.type = TUNER_PHILIPS_FMD1216ME_MK3; 1768 + tun_setup.mode_mask = T_RADIO | T_ANALOG_TV; 1769 + v4l2_subdev_call(cxdev->tuner, tuner, s_type_addr, &tun_setup); 1770 + 1771 + /* attach IF demod */ 1772 + cxdev->tda9887 = v4l2_i2c_new_subdev(&cxdev->v4l2dev, 1773 + &dvbdev->i2c_adap, 1774 + "tuner", 0x43, NULL); 1775 + if (cxdev->tda9887 == NULL) { 1776 + dev_err(&dvbdev->udev->dev, "tda9887 not found\n"); 1777 + return -ENODEV; 1778 + } 1779 + 1780 + return 0; 1781 + } 1782 + 1783 + int cxusb_medion_register_analog(struct dvb_usb_device *dvbdev) 1784 + { 1785 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 1786 + int ret; 1787 + 1788 + mutex_init(&cxdev->dev_lock); 1789 + 1790 + init_completion(&cxdev->v4l2_release); 1791 + 1792 + cxdev->v4l2dev.release = cxusb_medion_v4l2_release; 1793 + 1794 + ret = v4l2_device_register(&dvbdev->udev->dev, &cxdev->v4l2dev); 1795 + if (ret != 0) { 1796 + dev_err(&dvbdev->udev->dev, 1797 + "V4L2 device registration failed, ret = %d\n", ret); 1798 + mutex_destroy(&cxdev->dev_lock); 1799 + return ret; 1800 + } 1801 + 1802 + ret = cxusb_medion_register_analog_subdevs(dvbdev); 1803 + if (ret) 1804 + goto ret_unregister; 1805 + 1806 + INIT_WORK(&cxdev->urbwork, cxusb_medion_v_complete_work); 1807 + INIT_LIST_HEAD(&cxdev->buflist); 1808 + 1809 + cxdev->width = 320; 1810 + cxdev->height = 240; 1811 + 1812 + ret = cxusb_medion_register_analog_video(dvbdev); 1813 + if (ret) 1814 + goto ret_unregister; 1815 + 1816 + ret = cxusb_medion_register_analog_radio(dvbdev); 1817 + if (ret) 1818 + goto ret_vunreg; 1819 + 1820 + return 0; 1821 + 1822 + ret_vunreg: 1823 + video_unregister_device(cxdev->videodev); 1824 + 1825 + ret_unregister: 1826 + v4l2_device_put(&cxdev->v4l2dev); 1827 + wait_for_completion(&cxdev->v4l2_release); 1828 + 1829 + return ret; 1830 + } 1831 + 1832 + void cxusb_medion_unregister_analog(struct dvb_usb_device *dvbdev) 1833 + { 1834 + struct cxusb_medion_dev *cxdev = dvbdev->priv; 1835 + 1836 + cxusb_vprintk(dvbdev, OPS, "unregistering analog\n"); 1837 + 1838 + video_unregister_device(cxdev->radiodev); 1839 + video_unregister_device(cxdev->videodev); 1840 + 1841 + v4l2_device_put(&cxdev->v4l2dev); 1842 + wait_for_completion(&cxdev->v4l2_release); 1843 + 1844 + cxusb_vprintk(dvbdev, OPS, "analog unregistered\n"); 1845 + }
-2
drivers/media/usb/dvb-usb/cxusb.c
··· 11 11 * design, so it can be reused for the "analogue-only" device (if it will 12 12 * appear at all). 13 13 * 14 - * TODO: Use the cx25840-driver for the analogue part 15 14 * 16 15 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@posteo.de) 17 16 * Copyright (C) 2006 Michael Krufky (mkrufky@linuxtv.org) ··· 2547 2548 MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); 2548 2549 MODULE_AUTHOR("Maciej S. Szmigiero <mail@maciej.szmigiero.name>"); 2549 2550 MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design"); 2550 - MODULE_VERSION("1.0-alpha"); 2551 2551 MODULE_LICENSE("GPL");
+106
drivers/media/usb/dvb-usb/cxusb.h
··· 2 2 #ifndef _DVB_USB_CXUSB_H_ 3 3 #define _DVB_USB_CXUSB_H_ 4 4 5 + #include <linux/completion.h> 5 6 #include <linux/i2c.h> 7 + #include <linux/list.h> 6 8 #include <linux/mutex.h> 9 + #include <linux/usb.h> 10 + #include <linux/workqueue.h> 11 + #include <media/v4l2-common.h> 12 + #include <media/v4l2-dev.h> 13 + #include <media/v4l2-device.h> 14 + #include <media/videobuf2-core.h> 15 + #include <media/videobuf2-v4l2.h> 7 16 8 17 #define DVB_USB_LOG_PREFIX "cxusb" 9 18 #include "dvb-usb.h" 19 + 20 + #define CXUSB_VIDEO_URBS (5) 21 + #define CXUSB_VIDEO_URB_MAX_SIZE (512 * 1024) 22 + 23 + #define CXUSB_VIDEO_PKT_SIZE 3030 24 + #define CXUSB_VIDEO_MAX_FRAME_PKTS 346 25 + #define CXUSB_VIDEO_MAX_FRAME_SIZE (CXUSB_VIDEO_MAX_FRAME_PKTS * \ 26 + CXUSB_VIDEO_PKT_SIZE) 10 27 11 28 /* usb commands - some of it are guesses, don't have a reference yet */ 12 29 #define CMD_BLUEBIRD_GPIO_RW 0x05 ··· 49 32 #define CMD_ANALOG 0x50 50 33 #define CMD_DIGITAL 0x51 51 34 35 + #define CXUSB_BT656_PREAMBLE ((const u8 *)"\xff\x00\x00") 36 + 37 + #define CXUSB_BT656_FIELD_MASK BIT(6) 38 + #define CXUSB_BT656_FIELD_1 0 39 + #define CXUSB_BT656_FIELD_2 BIT(6) 40 + 41 + #define CXUSB_BT656_VBI_MASK BIT(5) 42 + #define CXUSB_BT656_VBI_ON BIT(5) 43 + #define CXUSB_BT656_VBI_OFF 0 44 + 45 + #define CXUSB_BT656_SEAV_MASK BIT(4) 46 + #define CXUSB_BT656_SEAV_EAV BIT(4) 47 + #define CXUSB_BT656_SEAV_SAV 0 48 + 52 49 /* Max transfer size done by I2C transfer functions */ 53 50 #define MAX_XFER_SIZE 80 54 51 ··· 85 54 CXUSB_OPEN_ANALOG, CXUSB_OPEN_DIGITAL 86 55 }; 87 56 57 + struct cxusb_medion_auxbuf { 58 + u8 *buf; 59 + unsigned int len; 60 + unsigned int paylen; 61 + }; 62 + 63 + enum cxusb_bt656_mode { 64 + NEW_FRAME, FIRST_FIELD, SECOND_FIELD 65 + }; 66 + 67 + enum cxusb_bt656_fmode { 68 + START_SEARCH, LINE_SAMPLES, VBI_SAMPLES 69 + }; 70 + 71 + struct cxusb_bt656_params { 72 + enum cxusb_bt656_mode mode; 73 + enum cxusb_bt656_fmode fmode; 74 + unsigned int pos; 75 + unsigned int line; 76 + unsigned int linesamples; 77 + u8 *buf; 78 + }; 79 + 88 80 struct cxusb_medion_dev { 89 81 /* has to be the first one */ 90 82 struct cxusb_state state; ··· 117 63 enum cxusb_open_type open_type; 118 64 unsigned int open_ctr; 119 65 struct mutex open_lock; 66 + 67 + #ifdef CONFIG_DVB_USB_CXUSB_ANALOG 68 + struct v4l2_device v4l2dev; 69 + struct v4l2_subdev *cx25840; 70 + struct v4l2_subdev *tuner; 71 + struct v4l2_subdev *tda9887; 72 + struct video_device *videodev, *radiodev; 73 + struct mutex dev_lock; 74 + 75 + struct vb2_queue videoqueue; 76 + u32 input; 77 + bool stop_streaming; 78 + u32 width, height; 79 + u32 field_order; 80 + struct cxusb_medion_auxbuf auxbuf; 81 + v4l2_std_id norm; 82 + 83 + struct urb *streamurbs[CXUSB_VIDEO_URBS]; 84 + unsigned long urbcomplete; 85 + struct work_struct urbwork; 86 + unsigned int nexturb; 87 + 88 + struct cxusb_bt656_params bt656; 89 + struct cxusb_medion_vbuffer *vbuf; 90 + __u32 vbuf_sequence; 91 + 92 + struct list_head buflist; 93 + 94 + struct completion v4l2_release; 95 + #endif 96 + }; 97 + 98 + struct cxusb_medion_vbuffer { 99 + struct vb2_v4l2_buffer vb2; 100 + struct list_head list; 120 101 }; 121 102 122 103 /* defines for "debug" module parameter */ 123 104 #define CXUSB_DBG_RC BIT(0) 124 105 #define CXUSB_DBG_I2C BIT(1) 125 106 #define CXUSB_DBG_MISC BIT(2) 107 + #define CXUSB_DBG_BT656 BIT(3) 108 + #define CXUSB_DBG_URB BIT(4) 109 + #define CXUSB_DBG_OPS BIT(5) 110 + #define CXUSB_DBG_AUXB BIT(6) 126 111 127 112 extern int dvb_usb_cxusb_debug; 113 + 114 + #define cxusb_vprintk(dvbdev, lvl, ...) do { \ 115 + struct cxusb_medion_dev *_cxdev = (dvbdev)->priv; \ 116 + if (dvb_usb_cxusb_debug & CXUSB_DBG_##lvl) \ 117 + v4l2_printk(KERN_DEBUG, \ 118 + &_cxdev->v4l2dev, __VA_ARGS__); \ 119 + } while (0) 128 120 129 121 int cxusb_ctrl_msg(struct dvb_usb_device *d, 130 122 u8 cmd, const u8 *wbuf, int wlen, u8 *rbuf, int rlen); 131 123 124 + #ifdef CONFIG_DVB_USB_CXUSB_ANALOG 125 + int cxusb_medion_analog_init(struct dvb_usb_device *dvbdev); 126 + int cxusb_medion_register_analog(struct dvb_usb_device *dvbdev); 127 + void cxusb_medion_unregister_analog(struct dvb_usb_device *dvbdev); 128 + #else 132 129 static inline int cxusb_medion_analog_init(struct dvb_usb_device *dvbdev) 133 130 { 134 131 return -EINVAL; ··· 193 88 static inline void cxusb_medion_unregister_analog(struct dvb_usb_device *dvbdev) 194 89 { 195 90 } 91 + #endif 196 92 197 93 int cxusb_medion_get(struct dvb_usb_device *dvbdev, 198 94 enum cxusb_open_type open_type);