.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* cx25840 - Conexant CX25840 audio/video decoder driver |
---|
2 | 3 | * |
---|
3 | 4 | * Copyright (C) 2004 Ulf Eklund |
---|
.. | .. |
---|
21 | 22 | * CX23888 DIF support for the HVR1850 |
---|
22 | 23 | * Copyright (C) 2011 Steven Toth <stoth@kernellabs.com> |
---|
23 | 24 | * |
---|
24 | | - * This program is free software; you can redistribute it and/or |
---|
25 | | - * modify it under the terms of the GNU General Public License |
---|
26 | | - * as published by the Free Software Foundation; either version 2 |
---|
27 | | - * of the License, or (at your option) any later version. |
---|
28 | | - * |
---|
29 | | - * This program is distributed in the hope that it will be useful, |
---|
30 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
31 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
32 | | - * GNU General Public License for more details. |
---|
| 25 | + * CX2584x pin to pad mapping and output format configuration support are |
---|
| 26 | + * Copyright (C) 2011 Maciej S. Szmigiero <mail@maciej.szmigiero.name> |
---|
33 | 27 | */ |
---|
34 | | - |
---|
35 | 28 | |
---|
36 | 29 | #include <linux/kernel.h> |
---|
37 | 30 | #include <linux/module.h> |
---|
.. | .. |
---|
73 | 66 | |
---|
74 | 67 | static int cx25840_debug; |
---|
75 | 68 | |
---|
76 | | -module_param_named(debug,cx25840_debug, int, 0644); |
---|
| 69 | +module_param_named(debug, cx25840_debug, int, 0644); |
---|
77 | 70 | |
---|
78 | 71 | MODULE_PARM_DESC(debug, "Debugging messages [0=Off (default) 1=On]"); |
---|
79 | | - |
---|
80 | 72 | |
---|
81 | 73 | /* ----------------------------------------------------------------------- */ |
---|
82 | 74 | static void cx23888_std_setup(struct i2c_client *client); |
---|
.. | .. |
---|
84 | 76 | int cx25840_write(struct i2c_client *client, u16 addr, u8 value) |
---|
85 | 77 | { |
---|
86 | 78 | u8 buffer[3]; |
---|
| 79 | + |
---|
87 | 80 | buffer[0] = addr >> 8; |
---|
88 | 81 | buffer[1] = addr & 0xff; |
---|
89 | 82 | buffer[2] = value; |
---|
.. | .. |
---|
93 | 86 | int cx25840_write4(struct i2c_client *client, u16 addr, u32 value) |
---|
94 | 87 | { |
---|
95 | 88 | u8 buffer[6]; |
---|
| 89 | + |
---|
96 | 90 | buffer[0] = addr >> 8; |
---|
97 | 91 | buffer[1] = addr & 0xff; |
---|
98 | 92 | buffer[2] = value & 0xff; |
---|
.. | .. |
---|
102 | 96 | return i2c_master_send(client, buffer, 6); |
---|
103 | 97 | } |
---|
104 | 98 | |
---|
105 | | -u8 cx25840_read(struct i2c_client * client, u16 addr) |
---|
| 99 | +u8 cx25840_read(struct i2c_client *client, u16 addr) |
---|
106 | 100 | { |
---|
107 | 101 | struct i2c_msg msgs[2]; |
---|
108 | 102 | u8 tx_buf[2], rx_buf[1]; |
---|
.. | .. |
---|
113 | 107 | msgs[0].addr = client->addr; |
---|
114 | 108 | msgs[0].flags = 0; |
---|
115 | 109 | msgs[0].len = 2; |
---|
116 | | - msgs[0].buf = (char *) tx_buf; |
---|
| 110 | + msgs[0].buf = (char *)tx_buf; |
---|
117 | 111 | |
---|
118 | 112 | /* Read data from register */ |
---|
119 | 113 | msgs[1].addr = client->addr; |
---|
120 | 114 | msgs[1].flags = I2C_M_RD; |
---|
121 | 115 | msgs[1].len = 1; |
---|
122 | | - msgs[1].buf = (char *) rx_buf; |
---|
| 116 | + msgs[1].buf = (char *)rx_buf; |
---|
123 | 117 | |
---|
124 | 118 | if (i2c_transfer(client->adapter, msgs, 2) < 2) |
---|
125 | 119 | return 0; |
---|
.. | .. |
---|
127 | 121 | return rx_buf[0]; |
---|
128 | 122 | } |
---|
129 | 123 | |
---|
130 | | -u32 cx25840_read4(struct i2c_client * client, u16 addr) |
---|
| 124 | +u32 cx25840_read4(struct i2c_client *client, u16 addr) |
---|
131 | 125 | { |
---|
132 | 126 | struct i2c_msg msgs[2]; |
---|
133 | 127 | u8 tx_buf[2], rx_buf[4]; |
---|
.. | .. |
---|
138 | 132 | msgs[0].addr = client->addr; |
---|
139 | 133 | msgs[0].flags = 0; |
---|
140 | 134 | msgs[0].len = 2; |
---|
141 | | - msgs[0].buf = (char *) tx_buf; |
---|
| 135 | + msgs[0].buf = (char *)tx_buf; |
---|
142 | 136 | |
---|
143 | 137 | /* Read data from registers */ |
---|
144 | 138 | msgs[1].addr = client->addr; |
---|
145 | 139 | msgs[1].flags = I2C_M_RD; |
---|
146 | 140 | msgs[1].len = 4; |
---|
147 | | - msgs[1].buf = (char *) rx_buf; |
---|
| 141 | + msgs[1].buf = (char *)rx_buf; |
---|
148 | 142 | |
---|
149 | 143 | if (i2c_transfer(client->adapter, msgs, 2) < 2) |
---|
150 | 144 | return 0; |
---|
.. | .. |
---|
153 | 147 | rx_buf[0]; |
---|
154 | 148 | } |
---|
155 | 149 | |
---|
156 | | -int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned and_mask, |
---|
| 150 | +int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned int and_mask, |
---|
157 | 151 | u8 or_value) |
---|
158 | 152 | { |
---|
159 | 153 | return cx25840_write(client, addr, |
---|
.. | .. |
---|
171 | 165 | |
---|
172 | 166 | /* ----------------------------------------------------------------------- */ |
---|
173 | 167 | |
---|
174 | | -static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input, |
---|
175 | | - enum cx25840_audio_input aud_input); |
---|
| 168 | +static int set_input(struct i2c_client *client, |
---|
| 169 | + enum cx25840_video_input vid_input, |
---|
| 170 | + enum cx25840_audio_input aud_input); |
---|
176 | 171 | |
---|
177 | 172 | /* ----------------------------------------------------------------------- */ |
---|
178 | 173 | |
---|
179 | 174 | static int cx23885_s_io_pin_config(struct v4l2_subdev *sd, size_t n, |
---|
180 | | - struct v4l2_subdev_io_pin_config *p) |
---|
| 175 | + struct v4l2_subdev_io_pin_config *p) |
---|
181 | 176 | { |
---|
182 | 177 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
---|
183 | 178 | int i; |
---|
.. | .. |
---|
316 | 311 | return 0; |
---|
317 | 312 | } |
---|
318 | 313 | |
---|
| 314 | +static u8 cx25840_function_to_pad(struct i2c_client *client, u8 function) |
---|
| 315 | +{ |
---|
| 316 | + if (function > CX25840_PAD_VRESET) { |
---|
| 317 | + v4l_err(client, "invalid function %u, assuming default\n", |
---|
| 318 | + (unsigned int)function); |
---|
| 319 | + return 0; |
---|
| 320 | + } |
---|
| 321 | + |
---|
| 322 | + return function; |
---|
| 323 | +} |
---|
| 324 | + |
---|
| 325 | +static void cx25840_set_invert(u8 *pinctrl3, u8 *voutctrl4, u8 function, |
---|
| 326 | + u8 pin, bool invert) |
---|
| 327 | +{ |
---|
| 328 | + switch (function) { |
---|
| 329 | + case CX25840_PAD_IRQ_N: |
---|
| 330 | + if (invert) |
---|
| 331 | + *pinctrl3 &= ~2; |
---|
| 332 | + else |
---|
| 333 | + *pinctrl3 |= 2; |
---|
| 334 | + break; |
---|
| 335 | + |
---|
| 336 | + case CX25840_PAD_ACTIVE: |
---|
| 337 | + if (invert) |
---|
| 338 | + *voutctrl4 |= BIT(2); |
---|
| 339 | + else |
---|
| 340 | + *voutctrl4 &= ~BIT(2); |
---|
| 341 | + break; |
---|
| 342 | + |
---|
| 343 | + case CX25840_PAD_VACTIVE: |
---|
| 344 | + if (invert) |
---|
| 345 | + *voutctrl4 |= BIT(5); |
---|
| 346 | + else |
---|
| 347 | + *voutctrl4 &= ~BIT(5); |
---|
| 348 | + break; |
---|
| 349 | + |
---|
| 350 | + case CX25840_PAD_CBFLAG: |
---|
| 351 | + if (invert) |
---|
| 352 | + *voutctrl4 |= BIT(4); |
---|
| 353 | + else |
---|
| 354 | + *voutctrl4 &= ~BIT(4); |
---|
| 355 | + break; |
---|
| 356 | + |
---|
| 357 | + case CX25840_PAD_VRESET: |
---|
| 358 | + if (invert) |
---|
| 359 | + *voutctrl4 |= BIT(0); |
---|
| 360 | + else |
---|
| 361 | + *voutctrl4 &= ~BIT(0); |
---|
| 362 | + break; |
---|
| 363 | + } |
---|
| 364 | + |
---|
| 365 | + if (function != CX25840_PAD_DEFAULT) |
---|
| 366 | + return; |
---|
| 367 | + |
---|
| 368 | + switch (pin) { |
---|
| 369 | + case CX25840_PIN_DVALID_PRGM0: |
---|
| 370 | + if (invert) |
---|
| 371 | + *voutctrl4 |= BIT(6); |
---|
| 372 | + else |
---|
| 373 | + *voutctrl4 &= ~BIT(6); |
---|
| 374 | + break; |
---|
| 375 | + |
---|
| 376 | + case CX25840_PIN_HRESET_PRGM2: |
---|
| 377 | + if (invert) |
---|
| 378 | + *voutctrl4 |= BIT(1); |
---|
| 379 | + else |
---|
| 380 | + *voutctrl4 &= ~BIT(1); |
---|
| 381 | + break; |
---|
| 382 | + } |
---|
| 383 | +} |
---|
| 384 | + |
---|
| 385 | +static int cx25840_s_io_pin_config(struct v4l2_subdev *sd, size_t n, |
---|
| 386 | + struct v4l2_subdev_io_pin_config *p) |
---|
| 387 | +{ |
---|
| 388 | + struct i2c_client *client = v4l2_get_subdevdata(sd); |
---|
| 389 | + unsigned int i; |
---|
| 390 | + u8 pinctrl[6], pinconf[10], voutctrl4; |
---|
| 391 | + |
---|
| 392 | + for (i = 0; i < 6; i++) |
---|
| 393 | + pinctrl[i] = cx25840_read(client, 0x114 + i); |
---|
| 394 | + |
---|
| 395 | + for (i = 0; i < 10; i++) |
---|
| 396 | + pinconf[i] = cx25840_read(client, 0x11c + i); |
---|
| 397 | + |
---|
| 398 | + voutctrl4 = cx25840_read(client, 0x407); |
---|
| 399 | + |
---|
| 400 | + for (i = 0; i < n; i++) { |
---|
| 401 | + u8 strength = p[i].strength; |
---|
| 402 | + |
---|
| 403 | + if (strength != CX25840_PIN_DRIVE_SLOW && |
---|
| 404 | + strength != CX25840_PIN_DRIVE_MEDIUM && |
---|
| 405 | + strength != CX25840_PIN_DRIVE_FAST) { |
---|
| 406 | + v4l_err(client, |
---|
| 407 | + "invalid drive speed for pin %u (%u), assuming fast\n", |
---|
| 408 | + (unsigned int)p[i].pin, |
---|
| 409 | + (unsigned int)strength); |
---|
| 410 | + |
---|
| 411 | + strength = CX25840_PIN_DRIVE_FAST; |
---|
| 412 | + } |
---|
| 413 | + |
---|
| 414 | + switch (p[i].pin) { |
---|
| 415 | + case CX25840_PIN_DVALID_PRGM0: |
---|
| 416 | + if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_DISABLE)) |
---|
| 417 | + pinctrl[0] &= ~BIT(6); |
---|
| 418 | + else |
---|
| 419 | + pinctrl[0] |= BIT(6); |
---|
| 420 | + |
---|
| 421 | + pinconf[3] &= 0xf0; |
---|
| 422 | + pinconf[3] |= cx25840_function_to_pad(client, |
---|
| 423 | + p[i].function); |
---|
| 424 | + |
---|
| 425 | + cx25840_set_invert(&pinctrl[3], &voutctrl4, |
---|
| 426 | + p[i].function, |
---|
| 427 | + CX25840_PIN_DVALID_PRGM0, |
---|
| 428 | + p[i].flags & |
---|
| 429 | + BIT(V4L2_SUBDEV_IO_PIN_ACTIVE_LOW)); |
---|
| 430 | + |
---|
| 431 | + pinctrl[4] &= ~(3 << 2); /* CX25840_PIN_DRIVE_MEDIUM */ |
---|
| 432 | + switch (strength) { |
---|
| 433 | + case CX25840_PIN_DRIVE_SLOW: |
---|
| 434 | + pinctrl[4] |= 1 << 2; |
---|
| 435 | + break; |
---|
| 436 | + |
---|
| 437 | + case CX25840_PIN_DRIVE_FAST: |
---|
| 438 | + pinctrl[4] |= 2 << 2; |
---|
| 439 | + break; |
---|
| 440 | + } |
---|
| 441 | + |
---|
| 442 | + break; |
---|
| 443 | + |
---|
| 444 | + case CX25840_PIN_HRESET_PRGM2: |
---|
| 445 | + if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_DISABLE)) |
---|
| 446 | + pinctrl[1] &= ~BIT(0); |
---|
| 447 | + else |
---|
| 448 | + pinctrl[1] |= BIT(0); |
---|
| 449 | + |
---|
| 450 | + pinconf[4] &= 0xf0; |
---|
| 451 | + pinconf[4] |= cx25840_function_to_pad(client, |
---|
| 452 | + p[i].function); |
---|
| 453 | + |
---|
| 454 | + cx25840_set_invert(&pinctrl[3], &voutctrl4, |
---|
| 455 | + p[i].function, |
---|
| 456 | + CX25840_PIN_HRESET_PRGM2, |
---|
| 457 | + p[i].flags & |
---|
| 458 | + BIT(V4L2_SUBDEV_IO_PIN_ACTIVE_LOW)); |
---|
| 459 | + |
---|
| 460 | + pinctrl[4] &= ~(3 << 2); /* CX25840_PIN_DRIVE_MEDIUM */ |
---|
| 461 | + switch (strength) { |
---|
| 462 | + case CX25840_PIN_DRIVE_SLOW: |
---|
| 463 | + pinctrl[4] |= 1 << 2; |
---|
| 464 | + break; |
---|
| 465 | + |
---|
| 466 | + case CX25840_PIN_DRIVE_FAST: |
---|
| 467 | + pinctrl[4] |= 2 << 2; |
---|
| 468 | + break; |
---|
| 469 | + } |
---|
| 470 | + |
---|
| 471 | + break; |
---|
| 472 | + |
---|
| 473 | + case CX25840_PIN_PLL_CLK_PRGM7: |
---|
| 474 | + if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_DISABLE)) |
---|
| 475 | + pinctrl[2] &= ~BIT(2); |
---|
| 476 | + else |
---|
| 477 | + pinctrl[2] |= BIT(2); |
---|
| 478 | + |
---|
| 479 | + switch (p[i].function) { |
---|
| 480 | + case CX25840_PAD_XTI_X5_DLL: |
---|
| 481 | + pinconf[6] = 0; |
---|
| 482 | + break; |
---|
| 483 | + |
---|
| 484 | + case CX25840_PAD_AUX_PLL: |
---|
| 485 | + pinconf[6] = 1; |
---|
| 486 | + break; |
---|
| 487 | + |
---|
| 488 | + case CX25840_PAD_VID_PLL: |
---|
| 489 | + pinconf[6] = 5; |
---|
| 490 | + break; |
---|
| 491 | + |
---|
| 492 | + case CX25840_PAD_XTI: |
---|
| 493 | + pinconf[6] = 2; |
---|
| 494 | + break; |
---|
| 495 | + |
---|
| 496 | + default: |
---|
| 497 | + pinconf[6] = 3; |
---|
| 498 | + pinconf[6] |= |
---|
| 499 | + cx25840_function_to_pad(client, |
---|
| 500 | + p[i].function) |
---|
| 501 | + << 4; |
---|
| 502 | + } |
---|
| 503 | + |
---|
| 504 | + break; |
---|
| 505 | + |
---|
| 506 | + default: |
---|
| 507 | + v4l_err(client, "invalid or unsupported pin %u\n", |
---|
| 508 | + (unsigned int)p[i].pin); |
---|
| 509 | + break; |
---|
| 510 | + } |
---|
| 511 | + } |
---|
| 512 | + |
---|
| 513 | + cx25840_write(client, 0x407, voutctrl4); |
---|
| 514 | + |
---|
| 515 | + for (i = 0; i < 6; i++) |
---|
| 516 | + cx25840_write(client, 0x114 + i, pinctrl[i]); |
---|
| 517 | + |
---|
| 518 | + for (i = 0; i < 10; i++) |
---|
| 519 | + cx25840_write(client, 0x11c + i, pinconf[i]); |
---|
| 520 | + |
---|
| 521 | + return 0; |
---|
| 522 | +} |
---|
| 523 | + |
---|
319 | 524 | static int common_s_io_pin_config(struct v4l2_subdev *sd, size_t n, |
---|
320 | | - struct v4l2_subdev_io_pin_config *pincfg) |
---|
| 525 | + struct v4l2_subdev_io_pin_config *pincfg) |
---|
321 | 526 | { |
---|
322 | 527 | struct cx25840_state *state = to_state(sd); |
---|
323 | 528 | |
---|
324 | 529 | if (is_cx2388x(state)) |
---|
325 | 530 | return cx23885_s_io_pin_config(sd, n, pincfg); |
---|
| 531 | + else if (is_cx2584x(state)) |
---|
| 532 | + return cx25840_s_io_pin_config(sd, n, pincfg); |
---|
326 | 533 | return 0; |
---|
327 | 534 | } |
---|
328 | 535 | |
---|
.. | .. |
---|
330 | 537 | |
---|
331 | 538 | static void init_dll1(struct i2c_client *client) |
---|
332 | 539 | { |
---|
333 | | - /* This is the Hauppauge sequence used to |
---|
334 | | - * initialize the Delay Lock Loop 1 (ADC DLL). */ |
---|
| 540 | + /* |
---|
| 541 | + * This is the Hauppauge sequence used to |
---|
| 542 | + * initialize the Delay Lock Loop 1 (ADC DLL). |
---|
| 543 | + */ |
---|
335 | 544 | cx25840_write(client, 0x159, 0x23); |
---|
336 | 545 | cx25840_write(client, 0x15a, 0x87); |
---|
337 | 546 | cx25840_write(client, 0x15b, 0x06); |
---|
.. | .. |
---|
346 | 555 | |
---|
347 | 556 | static void init_dll2(struct i2c_client *client) |
---|
348 | 557 | { |
---|
349 | | - /* This is the Hauppauge sequence used to |
---|
350 | | - * initialize the Delay Lock Loop 2 (ADC DLL). */ |
---|
| 558 | + /* |
---|
| 559 | + * This is the Hauppauge sequence used to |
---|
| 560 | + * initialize the Delay Lock Loop 2 (ADC DLL). |
---|
| 561 | + */ |
---|
351 | 562 | cx25840_write(client, 0x15d, 0xe3); |
---|
352 | 563 | cx25840_write(client, 0x15e, 0x86); |
---|
353 | 564 | cx25840_write(client, 0x15f, 0x06); |
---|
.. | .. |
---|
359 | 570 | |
---|
360 | 571 | static void cx25836_initialize(struct i2c_client *client) |
---|
361 | 572 | { |
---|
362 | | - /* reset configuration is described on page 3-77 of the CX25836 datasheet */ |
---|
| 573 | + /* |
---|
| 574 | + *reset configuration is described on page 3-77 |
---|
| 575 | + * of the CX25836 datasheet |
---|
| 576 | + */ |
---|
| 577 | + |
---|
363 | 578 | /* 2. */ |
---|
364 | 579 | cx25840_and_or(client, 0x000, ~0x01, 0x01); |
---|
365 | 580 | cx25840_and_or(client, 0x000, ~0x01, 0x00); |
---|
.. | .. |
---|
385 | 600 | static void cx25840_work_handler(struct work_struct *work) |
---|
386 | 601 | { |
---|
387 | 602 | struct cx25840_state *state = container_of(work, struct cx25840_state, fw_work); |
---|
| 603 | + |
---|
388 | 604 | cx25840_loadfw(state->c); |
---|
389 | 605 | wake_up(&state->fw_wait); |
---|
| 606 | +} |
---|
| 607 | + |
---|
| 608 | +#define CX25840_VCONFIG_SET_BIT(state, opt_msk, voc, idx, bit, oneval) \ |
---|
| 609 | + do { \ |
---|
| 610 | + if ((state)->vid_config & (opt_msk)) { \ |
---|
| 611 | + if (((state)->vid_config & (opt_msk)) == \ |
---|
| 612 | + (oneval)) \ |
---|
| 613 | + (voc)[idx] |= BIT(bit); \ |
---|
| 614 | + else \ |
---|
| 615 | + (voc)[idx] &= ~BIT(bit); \ |
---|
| 616 | + } \ |
---|
| 617 | + } while (0) |
---|
| 618 | + |
---|
| 619 | +/* apply current vconfig to hardware regs */ |
---|
| 620 | +static void cx25840_vconfig_apply(struct i2c_client *client) |
---|
| 621 | +{ |
---|
| 622 | + struct cx25840_state *state = to_state(i2c_get_clientdata(client)); |
---|
| 623 | + u8 voutctrl[3]; |
---|
| 624 | + unsigned int i; |
---|
| 625 | + |
---|
| 626 | + for (i = 0; i < 3; i++) |
---|
| 627 | + voutctrl[i] = cx25840_read(client, 0x404 + i); |
---|
| 628 | + |
---|
| 629 | + if (state->vid_config & CX25840_VCONFIG_FMT_MASK) |
---|
| 630 | + voutctrl[0] &= ~3; |
---|
| 631 | + switch (state->vid_config & CX25840_VCONFIG_FMT_MASK) { |
---|
| 632 | + case CX25840_VCONFIG_FMT_BT656: |
---|
| 633 | + voutctrl[0] |= 1; |
---|
| 634 | + break; |
---|
| 635 | + |
---|
| 636 | + case CX25840_VCONFIG_FMT_VIP11: |
---|
| 637 | + voutctrl[0] |= 2; |
---|
| 638 | + break; |
---|
| 639 | + |
---|
| 640 | + case CX25840_VCONFIG_FMT_VIP2: |
---|
| 641 | + voutctrl[0] |= 3; |
---|
| 642 | + break; |
---|
| 643 | + |
---|
| 644 | + case CX25840_VCONFIG_FMT_BT601: |
---|
| 645 | + /* zero */ |
---|
| 646 | + default: |
---|
| 647 | + break; |
---|
| 648 | + } |
---|
| 649 | + |
---|
| 650 | + CX25840_VCONFIG_SET_BIT(state, CX25840_VCONFIG_RES_MASK, voutctrl, |
---|
| 651 | + 0, 2, CX25840_VCONFIG_RES_10BIT); |
---|
| 652 | + CX25840_VCONFIG_SET_BIT(state, CX25840_VCONFIG_VBIRAW_MASK, voutctrl, |
---|
| 653 | + 0, 3, CX25840_VCONFIG_VBIRAW_ENABLED); |
---|
| 654 | + CX25840_VCONFIG_SET_BIT(state, CX25840_VCONFIG_ANCDATA_MASK, voutctrl, |
---|
| 655 | + 0, 4, CX25840_VCONFIG_ANCDATA_ENABLED); |
---|
| 656 | + CX25840_VCONFIG_SET_BIT(state, CX25840_VCONFIG_TASKBIT_MASK, voutctrl, |
---|
| 657 | + 0, 5, CX25840_VCONFIG_TASKBIT_ONE); |
---|
| 658 | + CX25840_VCONFIG_SET_BIT(state, CX25840_VCONFIG_ACTIVE_MASK, voutctrl, |
---|
| 659 | + 1, 2, CX25840_VCONFIG_ACTIVE_HORIZONTAL); |
---|
| 660 | + CX25840_VCONFIG_SET_BIT(state, CX25840_VCONFIG_VALID_MASK, voutctrl, |
---|
| 661 | + 1, 3, CX25840_VCONFIG_VALID_ANDACTIVE); |
---|
| 662 | + CX25840_VCONFIG_SET_BIT(state, CX25840_VCONFIG_HRESETW_MASK, voutctrl, |
---|
| 663 | + 1, 4, CX25840_VCONFIG_HRESETW_PIXCLK); |
---|
| 664 | + |
---|
| 665 | + if (state->vid_config & CX25840_VCONFIG_CLKGATE_MASK) |
---|
| 666 | + voutctrl[1] &= ~(3 << 6); |
---|
| 667 | + switch (state->vid_config & CX25840_VCONFIG_CLKGATE_MASK) { |
---|
| 668 | + case CX25840_VCONFIG_CLKGATE_VALID: |
---|
| 669 | + voutctrl[1] |= 2; |
---|
| 670 | + break; |
---|
| 671 | + |
---|
| 672 | + case CX25840_VCONFIG_CLKGATE_VALIDACTIVE: |
---|
| 673 | + voutctrl[1] |= 3; |
---|
| 674 | + break; |
---|
| 675 | + |
---|
| 676 | + case CX25840_VCONFIG_CLKGATE_NONE: |
---|
| 677 | + /* zero */ |
---|
| 678 | + default: |
---|
| 679 | + break; |
---|
| 680 | + } |
---|
| 681 | + |
---|
| 682 | + CX25840_VCONFIG_SET_BIT(state, CX25840_VCONFIG_DCMODE_MASK, voutctrl, |
---|
| 683 | + 2, 0, CX25840_VCONFIG_DCMODE_BYTES); |
---|
| 684 | + CX25840_VCONFIG_SET_BIT(state, CX25840_VCONFIG_IDID0S_MASK, voutctrl, |
---|
| 685 | + 2, 1, CX25840_VCONFIG_IDID0S_LINECNT); |
---|
| 686 | + CX25840_VCONFIG_SET_BIT(state, CX25840_VCONFIG_VIPCLAMP_MASK, voutctrl, |
---|
| 687 | + 2, 4, CX25840_VCONFIG_VIPCLAMP_ENABLED); |
---|
| 688 | + |
---|
| 689 | + for (i = 0; i < 3; i++) |
---|
| 690 | + cx25840_write(client, 0x404 + i, voutctrl[i]); |
---|
390 | 691 | } |
---|
391 | 692 | |
---|
392 | 693 | static void cx25840_initialize(struct i2c_client *client) |
---|
.. | .. |
---|
398 | 699 | /* datasheet startup in numbered steps, refer to page 3-77 */ |
---|
399 | 700 | /* 2. */ |
---|
400 | 701 | cx25840_and_or(client, 0x803, ~0x10, 0x00); |
---|
401 | | - /* The default of this register should be 4, but I get 0 instead. |
---|
402 | | - * Set this register to 4 manually. */ |
---|
| 702 | + /* |
---|
| 703 | + * The default of this register should be 4, but I get 0 instead. |
---|
| 704 | + * Set this register to 4 manually. |
---|
| 705 | + */ |
---|
403 | 706 | cx25840_write(client, 0x000, 0x04); |
---|
404 | 707 | /* 3. */ |
---|
405 | 708 | init_dll1(client); |
---|
.. | .. |
---|
409 | 712 | cx25840_write(client, 0x13c, 0x01); |
---|
410 | 713 | cx25840_write(client, 0x13c, 0x00); |
---|
411 | 714 | /* 5. */ |
---|
412 | | - /* Do the firmware load in a work handler to prevent. |
---|
413 | | - Otherwise the kernel is blocked waiting for the |
---|
414 | | - bit-banging i2c interface to finish uploading the |
---|
415 | | - firmware. */ |
---|
| 715 | + /* |
---|
| 716 | + * Do the firmware load in a work handler to prevent. |
---|
| 717 | + * Otherwise the kernel is blocked waiting for the |
---|
| 718 | + * bit-banging i2c interface to finish uploading the |
---|
| 719 | + * firmware. |
---|
| 720 | + */ |
---|
416 | 721 | INIT_WORK(&state->fw_work, cx25840_work_handler); |
---|
417 | 722 | init_waitqueue_head(&state->fw_wait); |
---|
418 | 723 | q = create_singlethread_workqueue("cx25840_fw"); |
---|
.. | .. |
---|
454 | 759 | |
---|
455 | 760 | /* (re)set input */ |
---|
456 | 761 | set_input(client, state->vid_input, state->aud_input); |
---|
| 762 | + |
---|
| 763 | + if (state->generic_mode) |
---|
| 764 | + cx25840_vconfig_apply(client); |
---|
457 | 765 | |
---|
458 | 766 | /* start microcontroller */ |
---|
459 | 767 | cx25840_and_or(client, 0x803, ~0x10, 0x10); |
---|
.. | .. |
---|
641 | 949 | cx25840_write(client, 0x160, 0x1d); |
---|
642 | 950 | cx25840_write(client, 0x164, 0x00); |
---|
643 | 951 | |
---|
644 | | - /* Do the firmware load in a work handler to prevent. |
---|
645 | | - Otherwise the kernel is blocked waiting for the |
---|
646 | | - bit-banging i2c interface to finish uploading the |
---|
647 | | - firmware. */ |
---|
| 952 | + /* |
---|
| 953 | + * Do the firmware load in a work handler to prevent. |
---|
| 954 | + * Otherwise the kernel is blocked waiting for the |
---|
| 955 | + * bit-banging i2c interface to finish uploading the |
---|
| 956 | + * firmware. |
---|
| 957 | + */ |
---|
648 | 958 | INIT_WORK(&state->fw_work, cx25840_work_handler); |
---|
649 | 959 | init_waitqueue_head(&state->fw_wait); |
---|
650 | 960 | q = create_singlethread_workqueue("cx25840_fw"); |
---|
.. | .. |
---|
656 | 966 | destroy_workqueue(q); |
---|
657 | 967 | } |
---|
658 | 968 | |
---|
659 | | - /* Call the cx23888 specific std setup func, we no longer rely on |
---|
| 969 | + /* |
---|
| 970 | + * Call the cx23888 specific std setup func, we no longer rely on |
---|
660 | 971 | * the generic cx24840 func. |
---|
661 | 972 | */ |
---|
662 | 973 | if (is_cx23888(state)) |
---|
.. | .. |
---|
678 | 989 | cx25840_write(client, CX25840_AUD_INT_STAT_REG, 0xff); |
---|
679 | 990 | |
---|
680 | 991 | /* CC raw enable */ |
---|
681 | | - /* - VIP 1.1 control codes - 10bit, blue field enable. |
---|
| 992 | + |
---|
| 993 | + /* |
---|
| 994 | + * - VIP 1.1 control codes - 10bit, blue field enable. |
---|
682 | 995 | * - enable raw data during vertical blanking. |
---|
683 | 996 | * - enable ancillary Data insertion for 656 or VIP. |
---|
684 | 997 | */ |
---|
685 | 998 | cx25840_write4(client, 0x404, 0x0010253e); |
---|
686 | 999 | |
---|
687 | | - /* CC on - Undocumented Register */ |
---|
| 1000 | + /* CC on - VBI_LINE_CTRL3, FLD_VBI_MD_LINE12 */ |
---|
688 | 1001 | cx25840_write(client, state->vbi_regs_offset + 0x42f, 0x66); |
---|
689 | 1002 | |
---|
690 | 1003 | /* HVR-1250 / HVR1850 DIF related */ |
---|
691 | 1004 | /* Power everything up */ |
---|
692 | 1005 | cx25840_write4(client, 0x130, 0x0); |
---|
693 | 1006 | |
---|
694 | | - /* Undocumented */ |
---|
| 1007 | + /* SRC_COMB_CFG */ |
---|
695 | 1008 | if (is_cx23888(state)) |
---|
696 | 1009 | cx25840_write4(client, 0x454, 0x6628021F); |
---|
697 | 1010 | else |
---|
.. | .. |
---|
761 | 1074 | /* White crush, Chroma AGC & Chroma Killer enabled */ |
---|
762 | 1075 | cx25840_write(client, 0x401, 0xe8); |
---|
763 | 1076 | |
---|
764 | | - /* Do the firmware load in a work handler to prevent. |
---|
765 | | - Otherwise the kernel is blocked waiting for the |
---|
766 | | - bit-banging i2c interface to finish uploading the |
---|
767 | | - firmware. */ |
---|
| 1077 | + /* |
---|
| 1078 | + * Do the firmware load in a work handler to prevent. |
---|
| 1079 | + * Otherwise the kernel is blocked waiting for the |
---|
| 1080 | + * bit-banging i2c interface to finish uploading the |
---|
| 1081 | + * firmware. |
---|
| 1082 | + */ |
---|
768 | 1083 | INIT_WORK(&state->fw_work, cx25840_work_handler); |
---|
769 | 1084 | init_waitqueue_head(&state->fw_wait); |
---|
770 | 1085 | q = create_singlethread_workqueue("cx25840_fw"); |
---|
.. | .. |
---|
809 | 1124 | else |
---|
810 | 1125 | cx25840_write(client, 0x49f, 0x14); |
---|
811 | 1126 | |
---|
| 1127 | + /* generic mode uses the values that the chip autoconfig would set */ |
---|
812 | 1128 | if (std & V4L2_STD_625_50) { |
---|
813 | 1129 | hblank = 132; |
---|
814 | 1130 | hactive = 720; |
---|
815 | 1131 | burst = 93; |
---|
816 | | - vblank = 36; |
---|
817 | | - vactive = 580; |
---|
818 | | - vblank656 = 40; |
---|
| 1132 | + if (state->generic_mode) { |
---|
| 1133 | + vblank = 34; |
---|
| 1134 | + vactive = 576; |
---|
| 1135 | + vblank656 = 38; |
---|
| 1136 | + } else { |
---|
| 1137 | + vblank = 36; |
---|
| 1138 | + vactive = 580; |
---|
| 1139 | + vblank656 = 40; |
---|
| 1140 | + } |
---|
819 | 1141 | src_decimation = 0x21f; |
---|
820 | 1142 | luma_lpf = 2; |
---|
821 | 1143 | |
---|
.. | .. |
---|
824 | 1146 | comb = 0; |
---|
825 | 1147 | sc = 0x0a425f; |
---|
826 | 1148 | } else if (std == V4L2_STD_PAL_Nc) { |
---|
| 1149 | + if (state->generic_mode) { |
---|
| 1150 | + burst = 95; |
---|
| 1151 | + luma_lpf = 1; |
---|
| 1152 | + } |
---|
827 | 1153 | uv_lpf = 1; |
---|
828 | 1154 | comb = 0x20; |
---|
829 | 1155 | sc = 556453; |
---|
.. | .. |
---|
838 | 1164 | vactive = 487; |
---|
839 | 1165 | luma_lpf = 1; |
---|
840 | 1166 | uv_lpf = 1; |
---|
| 1167 | + if (state->generic_mode) { |
---|
| 1168 | + vblank = 20; |
---|
| 1169 | + vblank656 = 24; |
---|
| 1170 | + } |
---|
841 | 1171 | |
---|
842 | 1172 | src_decimation = 0x21f; |
---|
843 | 1173 | if (std == V4L2_STD_PAL_60) { |
---|
844 | | - vblank = 26; |
---|
845 | | - vblank656 = 26; |
---|
846 | | - burst = 0x5b; |
---|
| 1174 | + if (!state->generic_mode) { |
---|
| 1175 | + vblank = 26; |
---|
| 1176 | + vblank656 = 26; |
---|
| 1177 | + burst = 0x5b; |
---|
| 1178 | + } else { |
---|
| 1179 | + burst = 0x59; |
---|
| 1180 | + } |
---|
847 | 1181 | luma_lpf = 2; |
---|
848 | 1182 | comb = 0x20; |
---|
849 | 1183 | sc = 688739; |
---|
.. | .. |
---|
854 | 1188 | comb = 0x20; |
---|
855 | 1189 | sc = 555452; |
---|
856 | 1190 | } else { |
---|
857 | | - vblank = 26; |
---|
858 | | - vblank656 = 26; |
---|
| 1191 | + if (!state->generic_mode) { |
---|
| 1192 | + vblank = 26; |
---|
| 1193 | + vblank656 = 26; |
---|
| 1194 | + } |
---|
859 | 1195 | burst = 0x5b; |
---|
860 | 1196 | comb = 0x66; |
---|
861 | 1197 | sc = 556063; |
---|
.. | .. |
---|
876 | 1212 | int pll = (28636363L * ((((u64)pll_int) << 25L) + pll_frac)) >> 25L; |
---|
877 | 1213 | |
---|
878 | 1214 | pll /= pll_post; |
---|
879 | | - v4l_dbg(1, cx25840_debug, client, "PLL = %d.%06d MHz\n", |
---|
880 | | - pll / 1000000, pll % 1000000); |
---|
881 | | - v4l_dbg(1, cx25840_debug, client, "PLL/8 = %d.%06d MHz\n", |
---|
882 | | - pll / 8000000, (pll / 8) % 1000000); |
---|
| 1215 | + v4l_dbg(1, cx25840_debug, client, |
---|
| 1216 | + "PLL = %d.%06d MHz\n", |
---|
| 1217 | + pll / 1000000, pll % 1000000); |
---|
| 1218 | + v4l_dbg(1, cx25840_debug, client, |
---|
| 1219 | + "PLL/8 = %d.%06d MHz\n", |
---|
| 1220 | + pll / 8000000, (pll / 8) % 1000000); |
---|
883 | 1221 | |
---|
884 | 1222 | fin = ((u64)src_decimation * pll) >> 12; |
---|
885 | 1223 | v4l_dbg(1, cx25840_debug, client, |
---|
886 | | - "ADC Sampling freq = %d.%06d MHz\n", |
---|
887 | | - fin / 1000000, fin % 1000000); |
---|
| 1224 | + "ADC Sampling freq = %d.%06d MHz\n", |
---|
| 1225 | + fin / 1000000, fin % 1000000); |
---|
888 | 1226 | |
---|
889 | 1227 | fsc = (((u64)sc) * pll) >> 24L; |
---|
890 | 1228 | v4l_dbg(1, cx25840_debug, client, |
---|
891 | | - "Chroma sub-carrier freq = %d.%06d MHz\n", |
---|
892 | | - fsc / 1000000, fsc % 1000000); |
---|
| 1229 | + "Chroma sub-carrier freq = %d.%06d MHz\n", |
---|
| 1230 | + fsc / 1000000, fsc % 1000000); |
---|
893 | 1231 | |
---|
894 | | - v4l_dbg(1, cx25840_debug, client, "hblank %i, hactive %i, vblank %i, vactive %i, vblank656 %i, src_dec %i, burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x, sc 0x%06x\n", |
---|
| 1232 | + v4l_dbg(1, cx25840_debug, client, |
---|
| 1233 | + "hblank %i, hactive %i, vblank %i, vactive %i, vblank656 %i, src_dec %i, burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x, sc 0x%06x\n", |
---|
895 | 1234 | hblank, hactive, vblank, vactive, vblank656, |
---|
896 | | - src_decimation, burst, luma_lpf, uv_lpf, comb, sc); |
---|
| 1235 | + src_decimation, burst, luma_lpf, uv_lpf, |
---|
| 1236 | + comb, sc); |
---|
897 | 1237 | } |
---|
898 | 1238 | } |
---|
899 | 1239 | |
---|
.. | .. |
---|
948 | 1288 | /* Follow step 8c and 8d of section 3.16 in the cx25840 datasheet */ |
---|
949 | 1289 | if (std & V4L2_STD_SECAM) { |
---|
950 | 1290 | cx25840_write(client, 0x402, 0); |
---|
951 | | - } |
---|
952 | | - else { |
---|
| 1291 | + } else { |
---|
953 | 1292 | cx25840_write(client, 0x402, 0x04); |
---|
954 | | - cx25840_write(client, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11); |
---|
| 1293 | + cx25840_write(client, 0x49f, |
---|
| 1294 | + (std & V4L2_STD_NTSC) ? 0x14 : 0x11); |
---|
955 | 1295 | } |
---|
956 | 1296 | cx25840_and_or(client, 0x401, ~0x60, 0); |
---|
957 | 1297 | cx25840_and_or(client, 0x401, ~0x60, 0x60); |
---|
.. | .. |
---|
965 | 1305 | if (state->radio) { |
---|
966 | 1306 | cx25840_write(client, 0x808, 0xf9); |
---|
967 | 1307 | cx25840_write(client, 0x80b, 0x00); |
---|
968 | | - } |
---|
969 | | - else if (std & V4L2_STD_525_60) { |
---|
970 | | - /* Certain Hauppauge PVR150 models have a hardware bug |
---|
971 | | - that causes audio to drop out. For these models the |
---|
972 | | - audio standard must be set explicitly. |
---|
973 | | - To be precise: it affects cards with tuner models |
---|
974 | | - 85, 99 and 112 (model numbers from tveeprom). */ |
---|
| 1308 | + } else if (std & V4L2_STD_525_60) { |
---|
| 1309 | + /* |
---|
| 1310 | + * Certain Hauppauge PVR150 models have a hardware bug |
---|
| 1311 | + * that causes audio to drop out. For these models the |
---|
| 1312 | + * audio standard must be set explicitly. |
---|
| 1313 | + * To be precise: it affects cards with tuner models |
---|
| 1314 | + * 85, 99 and 112 (model numbers from tveeprom). |
---|
| 1315 | + */ |
---|
975 | 1316 | int hw_fix = state->pvr150_workaround; |
---|
976 | 1317 | |
---|
977 | 1318 | if (std == V4L2_STD_NTSC_M_JP) { |
---|
.. | .. |
---|
988 | 1329 | } else if (std & V4L2_STD_PAL) { |
---|
989 | 1330 | /* Autodetect audio standard and audio system */ |
---|
990 | 1331 | cx25840_write(client, 0x808, 0xff); |
---|
991 | | - /* Since system PAL-L is pretty much non-existent and |
---|
992 | | - not used by any public broadcast network, force |
---|
993 | | - 6.5 MHz carrier to be interpreted as System DK, |
---|
994 | | - this avoids DK audio detection instability */ |
---|
| 1332 | + /* |
---|
| 1333 | + * Since system PAL-L is pretty much non-existent and |
---|
| 1334 | + * not used by any public broadcast network, force |
---|
| 1335 | + * 6.5 MHz carrier to be interpreted as System DK, |
---|
| 1336 | + * this avoids DK audio detection instability |
---|
| 1337 | + */ |
---|
995 | 1338 | cx25840_write(client, 0x80b, 0x00); |
---|
996 | 1339 | } else if (std & V4L2_STD_SECAM) { |
---|
997 | 1340 | /* Autodetect audio standard and audio system */ |
---|
998 | 1341 | cx25840_write(client, 0x808, 0xff); |
---|
999 | | - /* If only one of SECAM-DK / SECAM-L is required, then force |
---|
1000 | | - 6.5MHz carrier, else autodetect it */ |
---|
| 1342 | + /* |
---|
| 1343 | + * If only one of SECAM-DK / SECAM-L is required, then force |
---|
| 1344 | + * 6.5MHz carrier, else autodetect it |
---|
| 1345 | + */ |
---|
1001 | 1346 | if ((std & V4L2_STD_SECAM_DK) && |
---|
1002 | 1347 | !(std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))) { |
---|
1003 | 1348 | /* 6.5 MHz carrier to be interpreted as System DK */ |
---|
1004 | 1349 | cx25840_write(client, 0x80b, 0x00); |
---|
1005 | | - } else if (!(std & V4L2_STD_SECAM_DK) && |
---|
1006 | | - (std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))) { |
---|
| 1350 | + } else if (!(std & V4L2_STD_SECAM_DK) && |
---|
| 1351 | + (std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))) { |
---|
1007 | 1352 | /* 6.5 MHz carrier to be interpreted as System L */ |
---|
1008 | 1353 | cx25840_write(client, 0x80b, 0x08); |
---|
1009 | | - } else { |
---|
| 1354 | + } else { |
---|
1010 | 1355 | /* 6.5 MHz carrier to be autodetected */ |
---|
1011 | 1356 | cx25840_write(client, 0x80b, 0x10); |
---|
1012 | | - } |
---|
| 1357 | + } |
---|
1013 | 1358 | } |
---|
1014 | 1359 | |
---|
1015 | 1360 | cx25840_and_or(client, 0x810, ~0x01, 0); |
---|
1016 | 1361 | } |
---|
1017 | 1362 | |
---|
1018 | | -static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input, |
---|
1019 | | - enum cx25840_audio_input aud_input) |
---|
| 1363 | +static int set_input(struct i2c_client *client, |
---|
| 1364 | + enum cx25840_video_input vid_input, |
---|
| 1365 | + enum cx25840_audio_input aud_input) |
---|
1020 | 1366 | { |
---|
1021 | 1367 | struct cx25840_state *state = to_state(i2c_get_clientdata(client)); |
---|
1022 | 1368 | u8 is_composite = (vid_input >= CX25840_COMPOSITE1 && |
---|
.. | .. |
---|
1041 | 1387 | vid_input); |
---|
1042 | 1388 | reg = vid_input & 0xff; |
---|
1043 | 1389 | is_composite = !is_component && |
---|
1044 | | - ((vid_input & CX25840_SVIDEO_ON) != CX25840_SVIDEO_ON); |
---|
| 1390 | + ((vid_input & CX25840_SVIDEO_ON) != CX25840_SVIDEO_ON); |
---|
1045 | 1391 | |
---|
1046 | 1392 | v4l_dbg(1, cx25840_debug, client, "mux cfg 0x%x comp=%d\n", |
---|
1047 | 1393 | reg, is_composite); |
---|
.. | .. |
---|
1049 | 1395 | reg = 0xf0 + (vid_input - CX25840_COMPOSITE1); |
---|
1050 | 1396 | } else { |
---|
1051 | 1397 | if ((vid_input & ~0xff0) || |
---|
1052 | | - luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA8 || |
---|
1053 | | - chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) { |
---|
| 1398 | + luma < CX25840_SVIDEO_LUMA1 || |
---|
| 1399 | + luma > CX25840_SVIDEO_LUMA8 || |
---|
| 1400 | + chroma < CX25840_SVIDEO_CHROMA4 || |
---|
| 1401 | + chroma > CX25840_SVIDEO_CHROMA8) { |
---|
1054 | 1402 | v4l_err(client, "0x%04x is not a valid video input!\n", |
---|
1055 | 1403 | vid_input); |
---|
1056 | 1404 | return -EINVAL; |
---|
.. | .. |
---|
1074 | 1422 | case CX25840_AUDIO_SERIAL: |
---|
1075 | 1423 | /* do nothing, use serial audio input */ |
---|
1076 | 1424 | break; |
---|
1077 | | - case CX25840_AUDIO4: reg &= ~0x30; break; |
---|
1078 | | - case CX25840_AUDIO5: reg &= ~0x30; reg |= 0x10; break; |
---|
1079 | | - case CX25840_AUDIO6: reg &= ~0x30; reg |= 0x20; break; |
---|
1080 | | - case CX25840_AUDIO7: reg &= ~0xc0; break; |
---|
1081 | | - case CX25840_AUDIO8: reg &= ~0xc0; reg |= 0x40; break; |
---|
1082 | | - |
---|
| 1425 | + case CX25840_AUDIO4: |
---|
| 1426 | + reg &= ~0x30; |
---|
| 1427 | + break; |
---|
| 1428 | + case CX25840_AUDIO5: |
---|
| 1429 | + reg &= ~0x30; |
---|
| 1430 | + reg |= 0x10; |
---|
| 1431 | + break; |
---|
| 1432 | + case CX25840_AUDIO6: |
---|
| 1433 | + reg &= ~0x30; |
---|
| 1434 | + reg |= 0x20; |
---|
| 1435 | + break; |
---|
| 1436 | + case CX25840_AUDIO7: |
---|
| 1437 | + reg &= ~0xc0; |
---|
| 1438 | + break; |
---|
| 1439 | + case CX25840_AUDIO8: |
---|
| 1440 | + reg &= ~0xc0; |
---|
| 1441 | + reg |= 0x40; |
---|
| 1442 | + break; |
---|
1083 | 1443 | default: |
---|
1084 | 1444 | v4l_err(client, "0x%04x is not a valid audio input!\n", |
---|
1085 | 1445 | aud_input); |
---|
.. | .. |
---|
1096 | 1456 | cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02); |
---|
1097 | 1457 | |
---|
1098 | 1458 | if (is_cx2388x(state)) { |
---|
1099 | | - |
---|
1100 | 1459 | /* Enable or disable the DIF for tuner use */ |
---|
1101 | 1460 | if (is_dif) { |
---|
1102 | 1461 | cx25840_and_or(client, 0x102, ~0x80, 0x80); |
---|
.. | .. |
---|
1127 | 1486 | cx25840_write4(client, 0x410, 0xffff0dbf); |
---|
1128 | 1487 | cx25840_write4(client, 0x414, 0x00137d03); |
---|
1129 | 1488 | |
---|
1130 | | - cx25840_write4(client, state->vbi_regs_offset + 0x42c, 0x42600000); |
---|
1131 | | - cx25840_write4(client, state->vbi_regs_offset + 0x430, 0x0000039b); |
---|
1132 | | - cx25840_write4(client, state->vbi_regs_offset + 0x438, 0x00000000); |
---|
1133 | | - |
---|
1134 | | - cx25840_write4(client, state->vbi_regs_offset + 0x440, 0xF8E3E824); |
---|
1135 | | - cx25840_write4(client, state->vbi_regs_offset + 0x444, 0x401040dc); |
---|
1136 | | - cx25840_write4(client, state->vbi_regs_offset + 0x448, 0xcd3f02a0); |
---|
1137 | | - cx25840_write4(client, state->vbi_regs_offset + 0x44c, 0x161f1000); |
---|
1138 | | - cx25840_write4(client, state->vbi_regs_offset + 0x450, 0x00000802); |
---|
1139 | | - |
---|
| 1489 | + if (is_cx23888(state)) { |
---|
| 1490 | + /* 888 MISC_TIM_CTRL */ |
---|
| 1491 | + cx25840_write4(client, 0x42c, 0x42600000); |
---|
| 1492 | + /* 888 FIELD_COUNT */ |
---|
| 1493 | + cx25840_write4(client, 0x430, 0x0000039b); |
---|
| 1494 | + /* 888 VSCALE_CTRL */ |
---|
| 1495 | + cx25840_write4(client, 0x438, 0x00000000); |
---|
| 1496 | + /* 888 DFE_CTRL1 */ |
---|
| 1497 | + cx25840_write4(client, 0x440, 0xF8E3E824); |
---|
| 1498 | + /* 888 DFE_CTRL2 */ |
---|
| 1499 | + cx25840_write4(client, 0x444, 0x401040dc); |
---|
| 1500 | + /* 888 DFE_CTRL3 */ |
---|
| 1501 | + cx25840_write4(client, 0x448, 0xcd3f02a0); |
---|
| 1502 | + /* 888 PLL_CTRL */ |
---|
| 1503 | + cx25840_write4(client, 0x44c, 0x161f1000); |
---|
| 1504 | + /* 888 HTL_CTRL */ |
---|
| 1505 | + cx25840_write4(client, 0x450, 0x00000802); |
---|
| 1506 | + } |
---|
1140 | 1507 | cx25840_write4(client, 0x91c, 0x01000000); |
---|
1141 | 1508 | cx25840_write4(client, 0x8e0, 0x03063870); |
---|
1142 | 1509 | cx25840_write4(client, 0x8d4, 0x7FFF0024); |
---|
.. | .. |
---|
1202 | 1569 | * Only one of the two will be in use. |
---|
1203 | 1570 | */ |
---|
1204 | 1571 | cx25840_write4(client, AFE_CTRL, val); |
---|
1205 | | - } else |
---|
| 1572 | + } else { |
---|
1206 | 1573 | cx25840_and_or(client, 0x102, ~0x2, 0); |
---|
| 1574 | + } |
---|
1207 | 1575 | } |
---|
1208 | 1576 | |
---|
1209 | 1577 | state->vid_input = vid_input; |
---|
.. | .. |
---|
1242 | 1610 | cx25840_write(client, 0x919, 0x01); |
---|
1243 | 1611 | } |
---|
1244 | 1612 | |
---|
1245 | | - if (is_cx2388x(state) && ((aud_input == CX25840_AUDIO7) || |
---|
1246 | | - (aud_input == CX25840_AUDIO6))) { |
---|
| 1613 | + if (is_cx2388x(state) && |
---|
| 1614 | + ((aud_input == CX25840_AUDIO7) || (aud_input == CX25840_AUDIO6))) { |
---|
1247 | 1615 | /* Configure audio from LR1 or LR2 input */ |
---|
1248 | 1616 | cx25840_write4(client, 0x910, 0); |
---|
1249 | 1617 | cx25840_write4(client, 0x8d0, 0x63073); |
---|
1250 | | - } else |
---|
1251 | | - if (is_cx2388x(state) && (aud_input == CX25840_AUDIO8)) { |
---|
| 1618 | + } else if (is_cx2388x(state) && (aud_input == CX25840_AUDIO8)) { |
---|
1252 | 1619 | /* Configure audio from tuner/sif input */ |
---|
1253 | 1620 | cx25840_write4(client, 0x910, 0x12b000c9); |
---|
1254 | 1621 | cx25840_write4(client, 0x8d0, 0x1f063870); |
---|
1255 | 1622 | } |
---|
1256 | 1623 | |
---|
1257 | 1624 | if (is_cx23888(state)) { |
---|
1258 | | - /* HVR1850 */ |
---|
1259 | | - /* AUD_IO_CTRL - I2S Input, Parallel1*/ |
---|
1260 | | - /* - Channel 1 src - Parallel1 (Merlin out) */ |
---|
1261 | | - /* - Channel 2 src - Parallel2 (Merlin out) */ |
---|
1262 | | - /* - Channel 3 src - Parallel3 (Merlin AC97 out) */ |
---|
1263 | | - /* - I2S source and dir - Merlin, output */ |
---|
| 1625 | + /* |
---|
| 1626 | + * HVR1850 |
---|
| 1627 | + * |
---|
| 1628 | + * AUD_IO_CTRL - I2S Input, Parallel1 |
---|
| 1629 | + * - Channel 1 src - Parallel1 (Merlin out) |
---|
| 1630 | + * - Channel 2 src - Parallel2 (Merlin out) |
---|
| 1631 | + * - Channel 3 src - Parallel3 (Merlin AC97 out) |
---|
| 1632 | + * - I2S source and dir - Merlin, output |
---|
| 1633 | + */ |
---|
1264 | 1634 | cx25840_write4(client, 0x124, 0x100); |
---|
1265 | 1635 | |
---|
1266 | 1636 | if (!is_dif) { |
---|
1267 | | - /* Stop microcontroller if we don't need it |
---|
| 1637 | + /* |
---|
| 1638 | + * Stop microcontroller if we don't need it |
---|
1268 | 1639 | * to avoid audio popping on svideo/composite use. |
---|
1269 | 1640 | */ |
---|
1270 | 1641 | cx25840_and_or(client, 0x803, ~0x10, 0x00); |
---|
.. | .. |
---|
1306 | 1677 | fmt = 0xc; |
---|
1307 | 1678 | } |
---|
1308 | 1679 | |
---|
1309 | | - v4l_dbg(1, cx25840_debug, client, "changing video std to fmt %i\n",fmt); |
---|
| 1680 | + v4l_dbg(1, cx25840_debug, client, |
---|
| 1681 | + "changing video std to fmt %i\n", fmt); |
---|
1310 | 1682 | |
---|
1311 | | - /* Follow step 9 of section 3.16 in the cx25840 datasheet. |
---|
1312 | | - Without this PAL may display a vertical ghosting effect. |
---|
1313 | | - This happens for example with the Yuan MPC622. */ |
---|
| 1683 | + /* |
---|
| 1684 | + * Follow step 9 of section 3.16 in the cx25840 datasheet. |
---|
| 1685 | + * Without this PAL may display a vertical ghosting effect. |
---|
| 1686 | + * This happens for example with the Yuan MPC622. |
---|
| 1687 | + */ |
---|
1314 | 1688 | if (fmt >= 4 && fmt < 8) { |
---|
1315 | 1689 | /* Set format to NTSC-M */ |
---|
1316 | 1690 | cx25840_and_or(client, 0x400, ~0xf, 1); |
---|
.. | .. |
---|
1372 | 1746 | /* ----------------------------------------------------------------------- */ |
---|
1373 | 1747 | |
---|
1374 | 1748 | static int cx25840_set_fmt(struct v4l2_subdev *sd, |
---|
1375 | | - struct v4l2_subdev_pad_config *cfg, |
---|
1376 | | - struct v4l2_subdev_format *format) |
---|
| 1749 | + struct v4l2_subdev_pad_config *cfg, |
---|
| 1750 | + struct v4l2_subdev_format *format) |
---|
1377 | 1751 | { |
---|
1378 | 1752 | struct v4l2_mbus_framefmt *fmt = &format->format; |
---|
1379 | 1753 | struct cx25840_state *state = to_state(sd); |
---|
1380 | 1754 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
---|
1381 | | - int HSC, VSC, Vsrc, Hsrc, filter, Vlines; |
---|
1382 | | - int is_50Hz = !(state->std & V4L2_STD_525_60); |
---|
| 1755 | + u32 hsc, vsc, v_src, h_src, v_add; |
---|
| 1756 | + int filter; |
---|
| 1757 | + int is_50hz = !(state->std & V4L2_STD_525_60); |
---|
1383 | 1758 | |
---|
1384 | 1759 | if (format->pad || fmt->code != MEDIA_BUS_FMT_FIXED) |
---|
1385 | 1760 | return -EINVAL; |
---|
.. | .. |
---|
1388 | 1763 | fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; |
---|
1389 | 1764 | |
---|
1390 | 1765 | if (is_cx23888(state)) { |
---|
1391 | | - Vsrc = (cx25840_read(client, 0x42a) & 0x3f) << 4; |
---|
1392 | | - Vsrc |= (cx25840_read(client, 0x429) & 0xf0) >> 4; |
---|
| 1766 | + v_src = (cx25840_read(client, 0x42a) & 0x3f) << 4; |
---|
| 1767 | + v_src |= (cx25840_read(client, 0x429) & 0xf0) >> 4; |
---|
1393 | 1768 | } else { |
---|
1394 | | - Vsrc = (cx25840_read(client, 0x476) & 0x3f) << 4; |
---|
1395 | | - Vsrc |= (cx25840_read(client, 0x475) & 0xf0) >> 4; |
---|
| 1769 | + v_src = (cx25840_read(client, 0x476) & 0x3f) << 4; |
---|
| 1770 | + v_src |= (cx25840_read(client, 0x475) & 0xf0) >> 4; |
---|
1396 | 1771 | } |
---|
1397 | 1772 | |
---|
1398 | 1773 | if (is_cx23888(state)) { |
---|
1399 | | - Hsrc = (cx25840_read(client, 0x426) & 0x3f) << 4; |
---|
1400 | | - Hsrc |= (cx25840_read(client, 0x425) & 0xf0) >> 4; |
---|
| 1774 | + h_src = (cx25840_read(client, 0x426) & 0x3f) << 4; |
---|
| 1775 | + h_src |= (cx25840_read(client, 0x425) & 0xf0) >> 4; |
---|
1401 | 1776 | } else { |
---|
1402 | | - Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4; |
---|
1403 | | - Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4; |
---|
| 1777 | + h_src = (cx25840_read(client, 0x472) & 0x3f) << 4; |
---|
| 1778 | + h_src |= (cx25840_read(client, 0x471) & 0xf0) >> 4; |
---|
1404 | 1779 | } |
---|
1405 | 1780 | |
---|
1406 | | - Vlines = fmt->height + (is_50Hz ? 4 : 7); |
---|
| 1781 | + if (!state->generic_mode) { |
---|
| 1782 | + v_add = is_50hz ? 4 : 7; |
---|
1407 | 1783 | |
---|
1408 | | - /* |
---|
1409 | | - * We keep 1 margin for the Vsrc < Vlines check since the |
---|
1410 | | - * cx23888 reports a Vsrc of 486 instead of 487 for the NTSC |
---|
1411 | | - * height. Without that margin the cx23885 fails in this |
---|
1412 | | - * check. |
---|
1413 | | - */ |
---|
1414 | | - if ((fmt->width == 0) || (Vlines == 0) || |
---|
1415 | | - (fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) || |
---|
1416 | | - (Vlines * 8 < Vsrc) || (Vsrc + 1 < Vlines)) { |
---|
1417 | | - v4l_err(client, "%dx%d is not a valid size!\n", |
---|
1418 | | - fmt->width, fmt->height); |
---|
1419 | | - return -ERANGE; |
---|
| 1784 | + /* |
---|
| 1785 | + * cx23888 in 525-line mode is programmed for 486 active lines |
---|
| 1786 | + * while other chips use 487 active lines. |
---|
| 1787 | + * |
---|
| 1788 | + * See reg 0x428 bits [21:12] in cx23888_std_setup() vs |
---|
| 1789 | + * vactive in cx25840_std_setup(). |
---|
| 1790 | + */ |
---|
| 1791 | + if (is_cx23888(state) && !is_50hz) |
---|
| 1792 | + v_add--; |
---|
| 1793 | + } else { |
---|
| 1794 | + v_add = 0; |
---|
1420 | 1795 | } |
---|
| 1796 | + |
---|
| 1797 | + if (h_src == 0 || |
---|
| 1798 | + v_src <= v_add) { |
---|
| 1799 | + v4l_err(client, |
---|
| 1800 | + "chip reported picture size (%u x %u) is far too small\n", |
---|
| 1801 | + (unsigned int)h_src, (unsigned int)v_src); |
---|
| 1802 | + /* |
---|
| 1803 | + * that's the best we can do since the output picture |
---|
| 1804 | + * size is completely unknown in this case |
---|
| 1805 | + */ |
---|
| 1806 | + return -EINVAL; |
---|
| 1807 | + } |
---|
| 1808 | + |
---|
| 1809 | + fmt->width = clamp(fmt->width, (h_src + 15) / 16, h_src); |
---|
| 1810 | + |
---|
| 1811 | + if (v_add * 8 >= v_src) |
---|
| 1812 | + fmt->height = clamp(fmt->height, (u32)1, v_src - v_add); |
---|
| 1813 | + else |
---|
| 1814 | + fmt->height = clamp(fmt->height, (v_src - v_add * 8 + 7) / 8, |
---|
| 1815 | + v_src - v_add); |
---|
| 1816 | + |
---|
1421 | 1817 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) |
---|
1422 | 1818 | return 0; |
---|
1423 | 1819 | |
---|
1424 | | - HSC = (Hsrc * (1 << 20)) / fmt->width - (1 << 20); |
---|
1425 | | - VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9)); |
---|
1426 | | - VSC &= 0x1fff; |
---|
| 1820 | + hsc = (h_src * (1 << 20)) / fmt->width - (1 << 20); |
---|
| 1821 | + vsc = (1 << 16) - (v_src * (1 << 9) / (fmt->height + v_add) - (1 << 9)); |
---|
| 1822 | + vsc &= 0x1fff; |
---|
1427 | 1823 | |
---|
1428 | 1824 | if (fmt->width >= 385) |
---|
1429 | 1825 | filter = 0; |
---|
.. | .. |
---|
1434 | 1830 | else |
---|
1435 | 1831 | filter = 3; |
---|
1436 | 1832 | |
---|
1437 | | - v4l_dbg(1, cx25840_debug, client, "decoder set size %dx%d -> scale %ux%u\n", |
---|
1438 | | - fmt->width, fmt->height, HSC, VSC); |
---|
| 1833 | + v4l_dbg(1, cx25840_debug, client, |
---|
| 1834 | + "decoder set size %u x %u with scale %x x %x\n", |
---|
| 1835 | + (unsigned int)fmt->width, (unsigned int)fmt->height, |
---|
| 1836 | + (unsigned int)hsc, (unsigned int)vsc); |
---|
1439 | 1837 | |
---|
1440 | | - /* HSCALE=HSC */ |
---|
| 1838 | + /* HSCALE=hsc */ |
---|
1441 | 1839 | if (is_cx23888(state)) { |
---|
1442 | | - cx25840_write4(client, 0x434, HSC | (1 << 24)); |
---|
1443 | | - /* VSCALE=VSC VS_INTRLACE=1 VFILT=filter */ |
---|
1444 | | - cx25840_write4(client, 0x438, VSC | (1 << 19) | (filter << 16)); |
---|
| 1840 | + cx25840_write4(client, 0x434, hsc | (1 << 24)); |
---|
| 1841 | + /* VSCALE=vsc VS_INTRLACE=1 VFILT=filter */ |
---|
| 1842 | + cx25840_write4(client, 0x438, vsc | (1 << 19) | (filter << 16)); |
---|
1445 | 1843 | } else { |
---|
1446 | | - cx25840_write(client, 0x418, HSC & 0xff); |
---|
1447 | | - cx25840_write(client, 0x419, (HSC >> 8) & 0xff); |
---|
1448 | | - cx25840_write(client, 0x41a, HSC >> 16); |
---|
1449 | | - /* VSCALE=VSC */ |
---|
1450 | | - cx25840_write(client, 0x41c, VSC & 0xff); |
---|
1451 | | - cx25840_write(client, 0x41d, VSC >> 8); |
---|
| 1844 | + cx25840_write(client, 0x418, hsc & 0xff); |
---|
| 1845 | + cx25840_write(client, 0x419, (hsc >> 8) & 0xff); |
---|
| 1846 | + cx25840_write(client, 0x41a, hsc >> 16); |
---|
| 1847 | + /* VSCALE=vsc */ |
---|
| 1848 | + cx25840_write(client, 0x41c, vsc & 0xff); |
---|
| 1849 | + cx25840_write(client, 0x41d, vsc >> 8); |
---|
1452 | 1850 | /* VS_INTRLACE=1 VFILT=filter */ |
---|
1453 | 1851 | cx25840_write(client, 0x41e, 0x8 | filter); |
---|
1454 | 1852 | } |
---|
.. | .. |
---|
1475 | 1873 | int vid_input = state->vid_input; |
---|
1476 | 1874 | |
---|
1477 | 1875 | v4l_info(client, "Video signal: %spresent\n", |
---|
1478 | | - (gen_stat2 & 0x20) ? "" : "not "); |
---|
| 1876 | + (gen_stat2 & 0x20) ? "" : "not "); |
---|
1479 | 1877 | v4l_info(client, "Detected format: %s\n", |
---|
1480 | | - fmt_strs[gen_stat1 & 0xf]); |
---|
| 1878 | + fmt_strs[gen_stat1 & 0xf]); |
---|
1481 | 1879 | |
---|
1482 | 1880 | v4l_info(client, "Specified standard: %s\n", |
---|
1483 | | - vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection"); |
---|
| 1881 | + vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection"); |
---|
1484 | 1882 | |
---|
1485 | 1883 | if (vid_input >= CX25840_COMPOSITE1 && |
---|
1486 | 1884 | vid_input <= CX25840_COMPOSITE8) { |
---|
1487 | 1885 | v4l_info(client, "Specified video input: Composite %d\n", |
---|
1488 | | - vid_input - CX25840_COMPOSITE1 + 1); |
---|
| 1886 | + vid_input - CX25840_COMPOSITE1 + 1); |
---|
1489 | 1887 | } else { |
---|
1490 | | - v4l_info(client, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n", |
---|
1491 | | - (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8); |
---|
| 1888 | + v4l_info(client, |
---|
| 1889 | + "Specified video input: S-Video (Luma In%d, Chroma In%d)\n", |
---|
| 1890 | + (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8); |
---|
1492 | 1891 | } |
---|
1493 | 1892 | |
---|
1494 | | - v4l_info(client, "Specified audioclock freq: %d Hz\n", state->audclk_freq); |
---|
| 1893 | + v4l_info(client, "Specified audioclock freq: %d Hz\n", |
---|
| 1894 | + state->audclk_freq); |
---|
1495 | 1895 | } |
---|
1496 | 1896 | |
---|
1497 | 1897 | /* ----------------------------------------------------------------------- */ |
---|
.. | .. |
---|
1510 | 1910 | char *p; |
---|
1511 | 1911 | |
---|
1512 | 1912 | switch (mod_det_stat0) { |
---|
1513 | | - case 0x00: p = "mono"; break; |
---|
1514 | | - case 0x01: p = "stereo"; break; |
---|
1515 | | - case 0x02: p = "dual"; break; |
---|
1516 | | - case 0x04: p = "tri"; break; |
---|
1517 | | - case 0x10: p = "mono with SAP"; break; |
---|
1518 | | - case 0x11: p = "stereo with SAP"; break; |
---|
1519 | | - case 0x12: p = "dual with SAP"; break; |
---|
1520 | | - case 0x14: p = "tri with SAP"; break; |
---|
1521 | | - case 0xfe: p = "forced mode"; break; |
---|
1522 | | - default: p = "not defined"; |
---|
| 1913 | + case 0x00: |
---|
| 1914 | + p = "mono"; |
---|
| 1915 | + break; |
---|
| 1916 | + case 0x01: |
---|
| 1917 | + p = "stereo"; |
---|
| 1918 | + break; |
---|
| 1919 | + case 0x02: |
---|
| 1920 | + p = "dual"; |
---|
| 1921 | + break; |
---|
| 1922 | + case 0x04: |
---|
| 1923 | + p = "tri"; |
---|
| 1924 | + break; |
---|
| 1925 | + case 0x10: |
---|
| 1926 | + p = "mono with SAP"; |
---|
| 1927 | + break; |
---|
| 1928 | + case 0x11: |
---|
| 1929 | + p = "stereo with SAP"; |
---|
| 1930 | + break; |
---|
| 1931 | + case 0x12: |
---|
| 1932 | + p = "dual with SAP"; |
---|
| 1933 | + break; |
---|
| 1934 | + case 0x14: |
---|
| 1935 | + p = "tri with SAP"; |
---|
| 1936 | + break; |
---|
| 1937 | + case 0xfe: |
---|
| 1938 | + p = "forced mode"; |
---|
| 1939 | + break; |
---|
| 1940 | + default: |
---|
| 1941 | + p = "not defined"; |
---|
1523 | 1942 | } |
---|
1524 | 1943 | v4l_info(client, "Detected audio mode: %s\n", p); |
---|
1525 | 1944 | |
---|
1526 | 1945 | switch (mod_det_stat1) { |
---|
1527 | | - case 0x00: p = "not defined"; break; |
---|
1528 | | - case 0x01: p = "EIAJ"; break; |
---|
1529 | | - case 0x02: p = "A2-M"; break; |
---|
1530 | | - case 0x03: p = "A2-BG"; break; |
---|
1531 | | - case 0x04: p = "A2-DK1"; break; |
---|
1532 | | - case 0x05: p = "A2-DK2"; break; |
---|
1533 | | - case 0x06: p = "A2-DK3"; break; |
---|
1534 | | - case 0x07: p = "A1 (6.0 MHz FM Mono)"; break; |
---|
1535 | | - case 0x08: p = "AM-L"; break; |
---|
1536 | | - case 0x09: p = "NICAM-BG"; break; |
---|
1537 | | - case 0x0a: p = "NICAM-DK"; break; |
---|
1538 | | - case 0x0b: p = "NICAM-I"; break; |
---|
1539 | | - case 0x0c: p = "NICAM-L"; break; |
---|
1540 | | - case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break; |
---|
1541 | | - case 0x0e: p = "IF FM Radio"; break; |
---|
1542 | | - case 0x0f: p = "BTSC"; break; |
---|
1543 | | - case 0x10: p = "high-deviation FM"; break; |
---|
1544 | | - case 0x11: p = "very high-deviation FM"; break; |
---|
1545 | | - case 0xfd: p = "unknown audio standard"; break; |
---|
1546 | | - case 0xfe: p = "forced audio standard"; break; |
---|
1547 | | - case 0xff: p = "no detected audio standard"; break; |
---|
1548 | | - default: p = "not defined"; |
---|
| 1946 | + case 0x00: |
---|
| 1947 | + p = "not defined"; |
---|
| 1948 | + break; |
---|
| 1949 | + case 0x01: |
---|
| 1950 | + p = "EIAJ"; |
---|
| 1951 | + break; |
---|
| 1952 | + case 0x02: |
---|
| 1953 | + p = "A2-M"; |
---|
| 1954 | + break; |
---|
| 1955 | + case 0x03: |
---|
| 1956 | + p = "A2-BG"; |
---|
| 1957 | + break; |
---|
| 1958 | + case 0x04: |
---|
| 1959 | + p = "A2-DK1"; |
---|
| 1960 | + break; |
---|
| 1961 | + case 0x05: |
---|
| 1962 | + p = "A2-DK2"; |
---|
| 1963 | + break; |
---|
| 1964 | + case 0x06: |
---|
| 1965 | + p = "A2-DK3"; |
---|
| 1966 | + break; |
---|
| 1967 | + case 0x07: |
---|
| 1968 | + p = "A1 (6.0 MHz FM Mono)"; |
---|
| 1969 | + break; |
---|
| 1970 | + case 0x08: |
---|
| 1971 | + p = "AM-L"; |
---|
| 1972 | + break; |
---|
| 1973 | + case 0x09: |
---|
| 1974 | + p = "NICAM-BG"; |
---|
| 1975 | + break; |
---|
| 1976 | + case 0x0a: |
---|
| 1977 | + p = "NICAM-DK"; |
---|
| 1978 | + break; |
---|
| 1979 | + case 0x0b: |
---|
| 1980 | + p = "NICAM-I"; |
---|
| 1981 | + break; |
---|
| 1982 | + case 0x0c: |
---|
| 1983 | + p = "NICAM-L"; |
---|
| 1984 | + break; |
---|
| 1985 | + case 0x0d: |
---|
| 1986 | + p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; |
---|
| 1987 | + break; |
---|
| 1988 | + case 0x0e: |
---|
| 1989 | + p = "IF FM Radio"; |
---|
| 1990 | + break; |
---|
| 1991 | + case 0x0f: |
---|
| 1992 | + p = "BTSC"; |
---|
| 1993 | + break; |
---|
| 1994 | + case 0x10: |
---|
| 1995 | + p = "high-deviation FM"; |
---|
| 1996 | + break; |
---|
| 1997 | + case 0x11: |
---|
| 1998 | + p = "very high-deviation FM"; |
---|
| 1999 | + break; |
---|
| 2000 | + case 0xfd: |
---|
| 2001 | + p = "unknown audio standard"; |
---|
| 2002 | + break; |
---|
| 2003 | + case 0xfe: |
---|
| 2004 | + p = "forced audio standard"; |
---|
| 2005 | + break; |
---|
| 2006 | + case 0xff: |
---|
| 2007 | + p = "no detected audio standard"; |
---|
| 2008 | + break; |
---|
| 2009 | + default: |
---|
| 2010 | + p = "not defined"; |
---|
1549 | 2011 | } |
---|
1550 | 2012 | v4l_info(client, "Detected audio standard: %s\n", p); |
---|
1551 | 2013 | v4l_info(client, "Audio microcontroller: %s\n", |
---|
1552 | | - (download_ctl & 0x10) ? |
---|
1553 | | - ((mute_ctl & 0x2) ? "detecting" : "running") : "stopped"); |
---|
| 2014 | + (download_ctl & 0x10) ? |
---|
| 2015 | + ((mute_ctl & 0x2) ? "detecting" : "running") : "stopped"); |
---|
1554 | 2016 | |
---|
1555 | 2017 | switch (audio_config >> 4) { |
---|
1556 | | - case 0x00: p = "undefined"; break; |
---|
1557 | | - case 0x01: p = "BTSC"; break; |
---|
1558 | | - case 0x02: p = "EIAJ"; break; |
---|
1559 | | - case 0x03: p = "A2-M"; break; |
---|
1560 | | - case 0x04: p = "A2-BG"; break; |
---|
1561 | | - case 0x05: p = "A2-DK1"; break; |
---|
1562 | | - case 0x06: p = "A2-DK2"; break; |
---|
1563 | | - case 0x07: p = "A2-DK3"; break; |
---|
1564 | | - case 0x08: p = "A1 (6.0 MHz FM Mono)"; break; |
---|
1565 | | - case 0x09: p = "AM-L"; break; |
---|
1566 | | - case 0x0a: p = "NICAM-BG"; break; |
---|
1567 | | - case 0x0b: p = "NICAM-DK"; break; |
---|
1568 | | - case 0x0c: p = "NICAM-I"; break; |
---|
1569 | | - case 0x0d: p = "NICAM-L"; break; |
---|
1570 | | - case 0x0e: p = "FM radio"; break; |
---|
1571 | | - case 0x0f: p = "automatic detection"; break; |
---|
1572 | | - default: p = "undefined"; |
---|
| 2018 | + case 0x00: |
---|
| 2019 | + p = "undefined"; |
---|
| 2020 | + break; |
---|
| 2021 | + case 0x01: |
---|
| 2022 | + p = "BTSC"; |
---|
| 2023 | + break; |
---|
| 2024 | + case 0x02: |
---|
| 2025 | + p = "EIAJ"; |
---|
| 2026 | + break; |
---|
| 2027 | + case 0x03: |
---|
| 2028 | + p = "A2-M"; |
---|
| 2029 | + break; |
---|
| 2030 | + case 0x04: |
---|
| 2031 | + p = "A2-BG"; |
---|
| 2032 | + break; |
---|
| 2033 | + case 0x05: |
---|
| 2034 | + p = "A2-DK1"; |
---|
| 2035 | + break; |
---|
| 2036 | + case 0x06: |
---|
| 2037 | + p = "A2-DK2"; |
---|
| 2038 | + break; |
---|
| 2039 | + case 0x07: |
---|
| 2040 | + p = "A2-DK3"; |
---|
| 2041 | + break; |
---|
| 2042 | + case 0x08: |
---|
| 2043 | + p = "A1 (6.0 MHz FM Mono)"; |
---|
| 2044 | + break; |
---|
| 2045 | + case 0x09: |
---|
| 2046 | + p = "AM-L"; |
---|
| 2047 | + break; |
---|
| 2048 | + case 0x0a: |
---|
| 2049 | + p = "NICAM-BG"; |
---|
| 2050 | + break; |
---|
| 2051 | + case 0x0b: |
---|
| 2052 | + p = "NICAM-DK"; |
---|
| 2053 | + break; |
---|
| 2054 | + case 0x0c: |
---|
| 2055 | + p = "NICAM-I"; |
---|
| 2056 | + break; |
---|
| 2057 | + case 0x0d: |
---|
| 2058 | + p = "NICAM-L"; |
---|
| 2059 | + break; |
---|
| 2060 | + case 0x0e: |
---|
| 2061 | + p = "FM radio"; |
---|
| 2062 | + break; |
---|
| 2063 | + case 0x0f: |
---|
| 2064 | + p = "automatic detection"; |
---|
| 2065 | + break; |
---|
| 2066 | + default: |
---|
| 2067 | + p = "undefined"; |
---|
1573 | 2068 | } |
---|
1574 | 2069 | v4l_info(client, "Configured audio standard: %s\n", p); |
---|
1575 | 2070 | |
---|
1576 | 2071 | if ((audio_config >> 4) < 0xF) { |
---|
1577 | 2072 | switch (audio_config & 0xF) { |
---|
1578 | | - case 0x00: p = "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; break; |
---|
1579 | | - case 0x01: p = "MONO2 (LANGUAGE B)"; break; |
---|
1580 | | - case 0x02: p = "MONO3 (STEREO forced MONO)"; break; |
---|
1581 | | - case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break; |
---|
1582 | | - case 0x04: p = "STEREO"; break; |
---|
1583 | | - case 0x05: p = "DUAL1 (AB)"; break; |
---|
1584 | | - case 0x06: p = "DUAL2 (AC) (FM)"; break; |
---|
1585 | | - case 0x07: p = "DUAL3 (BC) (FM)"; break; |
---|
1586 | | - case 0x08: p = "DUAL4 (AC) (AM)"; break; |
---|
1587 | | - case 0x09: p = "DUAL5 (BC) (AM)"; break; |
---|
1588 | | - case 0x0a: p = "SAP"; break; |
---|
1589 | | - default: p = "undefined"; |
---|
| 2073 | + case 0x00: |
---|
| 2074 | + p = "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; |
---|
| 2075 | + break; |
---|
| 2076 | + case 0x01: |
---|
| 2077 | + p = "MONO2 (LANGUAGE B)"; |
---|
| 2078 | + break; |
---|
| 2079 | + case 0x02: |
---|
| 2080 | + p = "MONO3 (STEREO forced MONO)"; |
---|
| 2081 | + break; |
---|
| 2082 | + case 0x03: |
---|
| 2083 | + p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; |
---|
| 2084 | + break; |
---|
| 2085 | + case 0x04: |
---|
| 2086 | + p = "STEREO"; |
---|
| 2087 | + break; |
---|
| 2088 | + case 0x05: |
---|
| 2089 | + p = "DUAL1 (AB)"; |
---|
| 2090 | + break; |
---|
| 2091 | + case 0x06: |
---|
| 2092 | + p = "DUAL2 (AC) (FM)"; |
---|
| 2093 | + break; |
---|
| 2094 | + case 0x07: |
---|
| 2095 | + p = "DUAL3 (BC) (FM)"; |
---|
| 2096 | + break; |
---|
| 2097 | + case 0x08: |
---|
| 2098 | + p = "DUAL4 (AC) (AM)"; |
---|
| 2099 | + break; |
---|
| 2100 | + case 0x09: |
---|
| 2101 | + p = "DUAL5 (BC) (AM)"; |
---|
| 2102 | + break; |
---|
| 2103 | + case 0x0a: |
---|
| 2104 | + p = "SAP"; |
---|
| 2105 | + break; |
---|
| 2106 | + default: |
---|
| 2107 | + p = "undefined"; |
---|
1590 | 2108 | } |
---|
1591 | 2109 | v4l_info(client, "Configured audio mode: %s\n", p); |
---|
1592 | 2110 | } else { |
---|
1593 | 2111 | switch (audio_config & 0xF) { |
---|
1594 | | - case 0x00: p = "BG"; break; |
---|
1595 | | - case 0x01: p = "DK1"; break; |
---|
1596 | | - case 0x02: p = "DK2"; break; |
---|
1597 | | - case 0x03: p = "DK3"; break; |
---|
1598 | | - case 0x04: p = "I"; break; |
---|
1599 | | - case 0x05: p = "L"; break; |
---|
1600 | | - case 0x06: p = "BTSC"; break; |
---|
1601 | | - case 0x07: p = "EIAJ"; break; |
---|
1602 | | - case 0x08: p = "A2-M"; break; |
---|
1603 | | - case 0x09: p = "FM Radio"; break; |
---|
1604 | | - case 0x0f: p = "automatic standard and mode detection"; break; |
---|
1605 | | - default: p = "undefined"; |
---|
| 2112 | + case 0x00: |
---|
| 2113 | + p = "BG"; |
---|
| 2114 | + break; |
---|
| 2115 | + case 0x01: |
---|
| 2116 | + p = "DK1"; |
---|
| 2117 | + break; |
---|
| 2118 | + case 0x02: |
---|
| 2119 | + p = "DK2"; |
---|
| 2120 | + break; |
---|
| 2121 | + case 0x03: |
---|
| 2122 | + p = "DK3"; |
---|
| 2123 | + break; |
---|
| 2124 | + case 0x04: |
---|
| 2125 | + p = "I"; |
---|
| 2126 | + break; |
---|
| 2127 | + case 0x05: |
---|
| 2128 | + p = "L"; |
---|
| 2129 | + break; |
---|
| 2130 | + case 0x06: |
---|
| 2131 | + p = "BTSC"; |
---|
| 2132 | + break; |
---|
| 2133 | + case 0x07: |
---|
| 2134 | + p = "EIAJ"; |
---|
| 2135 | + break; |
---|
| 2136 | + case 0x08: |
---|
| 2137 | + p = "A2-M"; |
---|
| 2138 | + break; |
---|
| 2139 | + case 0x09: |
---|
| 2140 | + p = "FM Radio"; |
---|
| 2141 | + break; |
---|
| 2142 | + case 0x0f: |
---|
| 2143 | + p = "automatic standard and mode detection"; |
---|
| 2144 | + break; |
---|
| 2145 | + default: |
---|
| 2146 | + p = "undefined"; |
---|
1606 | 2147 | } |
---|
1607 | 2148 | v4l_info(client, "Configured audio system: %s\n", p); |
---|
1608 | 2149 | } |
---|
1609 | 2150 | |
---|
1610 | 2151 | if (aud_input) { |
---|
1611 | | - v4l_info(client, "Specified audio input: Tuner (In%d)\n", aud_input); |
---|
| 2152 | + v4l_info(client, "Specified audio input: Tuner (In%d)\n", |
---|
| 2153 | + aud_input); |
---|
1612 | 2154 | } else { |
---|
1613 | 2155 | v4l_info(client, "Specified audio input: External\n"); |
---|
1614 | 2156 | } |
---|
1615 | 2157 | |
---|
1616 | 2158 | switch (pref_mode & 0xf) { |
---|
1617 | | - case 0: p = "mono/language A"; break; |
---|
1618 | | - case 1: p = "language B"; break; |
---|
1619 | | - case 2: p = "language C"; break; |
---|
1620 | | - case 3: p = "analog fallback"; break; |
---|
1621 | | - case 4: p = "stereo"; break; |
---|
1622 | | - case 5: p = "language AC"; break; |
---|
1623 | | - case 6: p = "language BC"; break; |
---|
1624 | | - case 7: p = "language AB"; break; |
---|
1625 | | - default: p = "undefined"; |
---|
| 2159 | + case 0: |
---|
| 2160 | + p = "mono/language A"; |
---|
| 2161 | + break; |
---|
| 2162 | + case 1: |
---|
| 2163 | + p = "language B"; |
---|
| 2164 | + break; |
---|
| 2165 | + case 2: |
---|
| 2166 | + p = "language C"; |
---|
| 2167 | + break; |
---|
| 2168 | + case 3: |
---|
| 2169 | + p = "analog fallback"; |
---|
| 2170 | + break; |
---|
| 2171 | + case 4: |
---|
| 2172 | + p = "stereo"; |
---|
| 2173 | + break; |
---|
| 2174 | + case 5: |
---|
| 2175 | + p = "language AC"; |
---|
| 2176 | + break; |
---|
| 2177 | + case 6: |
---|
| 2178 | + p = "language BC"; |
---|
| 2179 | + break; |
---|
| 2180 | + case 7: |
---|
| 2181 | + p = "language AB"; |
---|
| 2182 | + break; |
---|
| 2183 | + default: |
---|
| 2184 | + p = "undefined"; |
---|
1626 | 2185 | } |
---|
1627 | 2186 | v4l_info(client, "Preferred audio mode: %s\n", p); |
---|
1628 | 2187 | |
---|
1629 | 2188 | if ((audio_config & 0xf) == 0xf) { |
---|
1630 | 2189 | switch ((afc0 >> 3) & 0x3) { |
---|
1631 | | - case 0: p = "system DK"; break; |
---|
1632 | | - case 1: p = "system L"; break; |
---|
1633 | | - case 2: p = "autodetect"; break; |
---|
1634 | | - default: p = "undefined"; |
---|
| 2190 | + case 0: |
---|
| 2191 | + p = "system DK"; |
---|
| 2192 | + break; |
---|
| 2193 | + case 1: |
---|
| 2194 | + p = "system L"; |
---|
| 2195 | + break; |
---|
| 2196 | + case 2: |
---|
| 2197 | + p = "autodetect"; |
---|
| 2198 | + break; |
---|
| 2199 | + default: |
---|
| 2200 | + p = "undefined"; |
---|
1635 | 2201 | } |
---|
1636 | 2202 | v4l_info(client, "Selected 65 MHz format: %s\n", p); |
---|
1637 | 2203 | |
---|
1638 | 2204 | switch (afc0 & 0x7) { |
---|
1639 | | - case 0: p = "chroma"; break; |
---|
1640 | | - case 1: p = "BTSC"; break; |
---|
1641 | | - case 2: p = "EIAJ"; break; |
---|
1642 | | - case 3: p = "A2-M"; break; |
---|
1643 | | - case 4: p = "autodetect"; break; |
---|
1644 | | - default: p = "undefined"; |
---|
| 2205 | + case 0: |
---|
| 2206 | + p = "chroma"; |
---|
| 2207 | + break; |
---|
| 2208 | + case 1: |
---|
| 2209 | + p = "BTSC"; |
---|
| 2210 | + break; |
---|
| 2211 | + case 2: |
---|
| 2212 | + p = "EIAJ"; |
---|
| 2213 | + break; |
---|
| 2214 | + case 3: |
---|
| 2215 | + p = "A2-M"; |
---|
| 2216 | + break; |
---|
| 2217 | + case 4: |
---|
| 2218 | + p = "autodetect"; |
---|
| 2219 | + break; |
---|
| 2220 | + default: |
---|
| 2221 | + p = "undefined"; |
---|
1645 | 2222 | } |
---|
1646 | 2223 | v4l_info(client, "Selected 45 MHz format: %s\n", p); |
---|
1647 | 2224 | } |
---|
1648 | 2225 | } |
---|
1649 | 2226 | |
---|
| 2227 | +#define CX25840_VCONFIG_OPTION(state, cfg_in, opt_msk) \ |
---|
| 2228 | + do { \ |
---|
| 2229 | + if ((cfg_in) & (opt_msk)) { \ |
---|
| 2230 | + (state)->vid_config &= ~(opt_msk); \ |
---|
| 2231 | + (state)->vid_config |= (cfg_in) & (opt_msk); \ |
---|
| 2232 | + } \ |
---|
| 2233 | + } while (0) |
---|
| 2234 | + |
---|
| 2235 | +/* apply incoming options to the current vconfig */ |
---|
| 2236 | +static void cx25840_vconfig_add(struct cx25840_state *state, u32 cfg_in) |
---|
| 2237 | +{ |
---|
| 2238 | + CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_FMT_MASK); |
---|
| 2239 | + CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_RES_MASK); |
---|
| 2240 | + CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_VBIRAW_MASK); |
---|
| 2241 | + CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_ANCDATA_MASK); |
---|
| 2242 | + CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_TASKBIT_MASK); |
---|
| 2243 | + CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_ACTIVE_MASK); |
---|
| 2244 | + CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_VALID_MASK); |
---|
| 2245 | + CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_HRESETW_MASK); |
---|
| 2246 | + CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_CLKGATE_MASK); |
---|
| 2247 | + CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_DCMODE_MASK); |
---|
| 2248 | + CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_IDID0S_MASK); |
---|
| 2249 | + CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_VIPCLAMP_MASK); |
---|
| 2250 | +} |
---|
| 2251 | + |
---|
1650 | 2252 | /* ----------------------------------------------------------------------- */ |
---|
1651 | 2253 | |
---|
1652 | | -/* This load_fw operation must be called to load the driver's firmware. |
---|
1653 | | - Without this the audio standard detection will fail and you will |
---|
1654 | | - only get mono. |
---|
| 2254 | +/* |
---|
| 2255 | + * Initializes the device in the generic mode. |
---|
| 2256 | + * For cx2584x chips also adds additional video output settings provided |
---|
| 2257 | + * in @val parameter (CX25840_VCONFIG_*). |
---|
| 2258 | + * |
---|
| 2259 | + * The generic mode disables some of the ivtv-related hacks in this driver. |
---|
| 2260 | + * For cx2584x chips it also enables setting video output configuration while |
---|
| 2261 | + * setting it according to datasheet defaults by default. |
---|
| 2262 | + */ |
---|
| 2263 | +static int cx25840_init(struct v4l2_subdev *sd, u32 val) |
---|
| 2264 | +{ |
---|
| 2265 | + struct cx25840_state *state = to_state(sd); |
---|
1655 | 2266 | |
---|
1656 | | - Since loading the firmware is often problematic when the driver is |
---|
1657 | | - compiled into the kernel I recommend postponing calling this function |
---|
1658 | | - until the first open of the video device. Another reason for |
---|
1659 | | - postponing it is that loading this firmware takes a long time (seconds) |
---|
1660 | | - due to the slow i2c bus speed. So it will speed up the boot process if |
---|
1661 | | - you can avoid loading the fw as long as the video device isn't used. */ |
---|
1662 | | -static int cx25840_load_fw(struct v4l2_subdev *sd) |
---|
| 2267 | + state->generic_mode = true; |
---|
| 2268 | + |
---|
| 2269 | + if (is_cx2584x(state)) { |
---|
| 2270 | + /* set datasheet video output defaults */ |
---|
| 2271 | + state->vid_config = CX25840_VCONFIG_FMT_BT656 | |
---|
| 2272 | + CX25840_VCONFIG_RES_8BIT | |
---|
| 2273 | + CX25840_VCONFIG_VBIRAW_DISABLED | |
---|
| 2274 | + CX25840_VCONFIG_ANCDATA_ENABLED | |
---|
| 2275 | + CX25840_VCONFIG_TASKBIT_ONE | |
---|
| 2276 | + CX25840_VCONFIG_ACTIVE_HORIZONTAL | |
---|
| 2277 | + CX25840_VCONFIG_VALID_NORMAL | |
---|
| 2278 | + CX25840_VCONFIG_HRESETW_NORMAL | |
---|
| 2279 | + CX25840_VCONFIG_CLKGATE_NONE | |
---|
| 2280 | + CX25840_VCONFIG_DCMODE_DWORDS | |
---|
| 2281 | + CX25840_VCONFIG_IDID0S_NORMAL | |
---|
| 2282 | + CX25840_VCONFIG_VIPCLAMP_DISABLED; |
---|
| 2283 | + |
---|
| 2284 | + /* add additional settings */ |
---|
| 2285 | + cx25840_vconfig_add(state, val); |
---|
| 2286 | + } else { |
---|
| 2287 | + /* TODO: generic mode needs to be developed for other chips */ |
---|
| 2288 | + WARN_ON(1); |
---|
| 2289 | + } |
---|
| 2290 | + |
---|
| 2291 | + return 0; |
---|
| 2292 | +} |
---|
| 2293 | + |
---|
| 2294 | +static int cx25840_reset(struct v4l2_subdev *sd, u32 val) |
---|
1663 | 2295 | { |
---|
1664 | 2296 | struct cx25840_state *state = to_state(sd); |
---|
1665 | 2297 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
---|
1666 | 2298 | |
---|
| 2299 | + if (is_cx2583x(state)) |
---|
| 2300 | + cx25836_initialize(client); |
---|
| 2301 | + else if (is_cx2388x(state)) |
---|
| 2302 | + cx23885_initialize(client); |
---|
| 2303 | + else if (is_cx231xx(state)) |
---|
| 2304 | + cx231xx_initialize(client); |
---|
| 2305 | + else |
---|
| 2306 | + cx25840_initialize(client); |
---|
| 2307 | + |
---|
| 2308 | + state->is_initialized = 1; |
---|
| 2309 | + |
---|
| 2310 | + return 0; |
---|
| 2311 | +} |
---|
| 2312 | + |
---|
| 2313 | +/* |
---|
| 2314 | + * This load_fw operation must be called to load the driver's firmware. |
---|
| 2315 | + * This will load the firmware on the first invocation (further ones are NOP). |
---|
| 2316 | + * Without this the audio standard detection will fail and you will |
---|
| 2317 | + * only get mono. |
---|
| 2318 | + * Alternatively, you can call the reset operation instead of this one. |
---|
| 2319 | + * |
---|
| 2320 | + * Since loading the firmware is often problematic when the driver is |
---|
| 2321 | + * compiled into the kernel I recommend postponing calling this function |
---|
| 2322 | + * until the first open of the video device. Another reason for |
---|
| 2323 | + * postponing it is that loading this firmware takes a long time (seconds) |
---|
| 2324 | + * due to the slow i2c bus speed. So it will speed up the boot process if |
---|
| 2325 | + * you can avoid loading the fw as long as the video device isn't used. |
---|
| 2326 | + */ |
---|
| 2327 | +static int cx25840_load_fw(struct v4l2_subdev *sd) |
---|
| 2328 | +{ |
---|
| 2329 | + struct cx25840_state *state = to_state(sd); |
---|
| 2330 | + |
---|
1667 | 2331 | if (!state->is_initialized) { |
---|
1668 | 2332 | /* initialize and load firmware */ |
---|
1669 | | - state->is_initialized = 1; |
---|
1670 | | - if (is_cx2583x(state)) |
---|
1671 | | - cx25836_initialize(client); |
---|
1672 | | - else if (is_cx2388x(state)) |
---|
1673 | | - cx23885_initialize(client); |
---|
1674 | | - else if (is_cx231xx(state)) |
---|
1675 | | - cx231xx_initialize(client); |
---|
1676 | | - else |
---|
1677 | | - cx25840_initialize(client); |
---|
| 2333 | + cx25840_reset(sd, 0); |
---|
1678 | 2334 | } |
---|
1679 | 2335 | return 0; |
---|
1680 | 2336 | } |
---|
1681 | 2337 | |
---|
1682 | 2338 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
---|
1683 | | -static int cx25840_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) |
---|
| 2339 | +static int cx25840_g_register(struct v4l2_subdev *sd, |
---|
| 2340 | + struct v4l2_dbg_register *reg) |
---|
1684 | 2341 | { |
---|
1685 | 2342 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
---|
1686 | 2343 | |
---|
.. | .. |
---|
1689 | 2346 | return 0; |
---|
1690 | 2347 | } |
---|
1691 | 2348 | |
---|
1692 | | -static int cx25840_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg) |
---|
| 2349 | +static int cx25840_s_register(struct v4l2_subdev *sd, |
---|
| 2350 | + const struct v4l2_dbg_register *reg) |
---|
1693 | 2351 | { |
---|
1694 | 2352 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
---|
1695 | 2353 | |
---|
.. | .. |
---|
1708 | 2366 | return 0; |
---|
1709 | 2367 | |
---|
1710 | 2368 | v4l_dbg(1, cx25840_debug, client, "%s audio output\n", |
---|
1711 | | - enable ? "enable" : "disable"); |
---|
| 2369 | + enable ? "enable" : "disable"); |
---|
1712 | 2370 | |
---|
1713 | 2371 | if (enable) { |
---|
1714 | 2372 | v = cx25840_read(client, 0x115) | 0x80; |
---|
.. | .. |
---|
1731 | 2389 | u8 v; |
---|
1732 | 2390 | |
---|
1733 | 2391 | v4l_dbg(1, cx25840_debug, client, "%s video output\n", |
---|
1734 | | - enable ? "enable" : "disable"); |
---|
| 2392 | + enable ? "enable" : "disable"); |
---|
1735 | 2393 | |
---|
1736 | 2394 | /* |
---|
1737 | 2395 | * It's not clear what should be done for these devices. |
---|
.. | .. |
---|
1758 | 2416 | } |
---|
1759 | 2417 | |
---|
1760 | 2418 | /* Query the current detected video format */ |
---|
1761 | | -static int cx25840_g_std(struct v4l2_subdev *sd, v4l2_std_id *std) |
---|
| 2419 | +static int cx25840_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) |
---|
1762 | 2420 | { |
---|
1763 | 2421 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
---|
1764 | 2422 | |
---|
.. | .. |
---|
1784 | 2442 | }; |
---|
1785 | 2443 | |
---|
1786 | 2444 | u32 fmt = (cx25840_read4(client, 0x40c) >> 8) & 0xf; |
---|
1787 | | - *std = stds[ fmt ]; |
---|
| 2445 | + *std = stds[fmt]; |
---|
1788 | 2446 | |
---|
1789 | | - v4l_dbg(1, cx25840_debug, client, "g_std fmt = %x, v4l2_std_id = 0x%x\n", |
---|
1790 | | - fmt, (unsigned int)stds[ fmt ]); |
---|
| 2447 | + v4l_dbg(1, cx25840_debug, client, |
---|
| 2448 | + "querystd fmt = %x, v4l2_std_id = 0x%x\n", |
---|
| 2449 | + fmt, (unsigned int)stds[fmt]); |
---|
1791 | 2450 | |
---|
1792 | 2451 | return 0; |
---|
1793 | 2452 | } |
---|
.. | .. |
---|
1796 | 2455 | { |
---|
1797 | 2456 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
---|
1798 | 2457 | |
---|
1799 | | - /* A limited function that checks for signal status and returns |
---|
| 2458 | + /* |
---|
| 2459 | + * A limited function that checks for signal status and returns |
---|
1800 | 2460 | * the state. |
---|
1801 | 2461 | */ |
---|
1802 | 2462 | |
---|
1803 | 2463 | /* Check for status of Horizontal lock (SRC lock isn't reliable) */ |
---|
1804 | 2464 | if ((cx25840_read4(client, 0x40c) & 0x00010000) == 0) |
---|
1805 | 2465 | *status |= V4L2_IN_ST_NO_SIGNAL; |
---|
| 2466 | + |
---|
| 2467 | + return 0; |
---|
| 2468 | +} |
---|
| 2469 | + |
---|
| 2470 | +static int cx25840_g_std(struct v4l2_subdev *sd, v4l2_std_id *std) |
---|
| 2471 | +{ |
---|
| 2472 | + struct cx25840_state *state = to_state(sd); |
---|
| 2473 | + |
---|
| 2474 | + *std = state->std; |
---|
1806 | 2475 | |
---|
1807 | 2476 | return 0; |
---|
1808 | 2477 | } |
---|
.. | .. |
---|
1836 | 2505 | if (is_cx23888(state)) |
---|
1837 | 2506 | cx23888_std_setup(client); |
---|
1838 | 2507 | |
---|
| 2508 | + if (is_cx2584x(state) && state->generic_mode && config) { |
---|
| 2509 | + cx25840_vconfig_add(state, config); |
---|
| 2510 | + cx25840_vconfig_apply(client); |
---|
| 2511 | + } |
---|
| 2512 | + |
---|
1839 | 2513 | return set_input(client, input, state->aud_input); |
---|
1840 | 2514 | } |
---|
1841 | 2515 | |
---|
.. | .. |
---|
1850 | 2524 | return set_input(client, state->vid_input, input); |
---|
1851 | 2525 | } |
---|
1852 | 2526 | |
---|
1853 | | -static int cx25840_s_frequency(struct v4l2_subdev *sd, const struct v4l2_frequency *freq) |
---|
| 2527 | +static int cx25840_s_frequency(struct v4l2_subdev *sd, |
---|
| 2528 | + const struct v4l2_frequency *freq) |
---|
1854 | 2529 | { |
---|
1855 | 2530 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
---|
1856 | 2531 | |
---|
.. | .. |
---|
1873 | 2548 | if (is_cx2583x(state)) |
---|
1874 | 2549 | return 0; |
---|
1875 | 2550 | |
---|
1876 | | - vt->capability |= |
---|
1877 | | - V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | |
---|
1878 | | - V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; |
---|
| 2551 | + vt->capability |= V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | |
---|
| 2552 | + V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; |
---|
1879 | 2553 | |
---|
1880 | 2554 | mode = cx25840_read(client, 0x804); |
---|
1881 | 2555 | |
---|
.. | .. |
---|
1905 | 2579 | return 0; |
---|
1906 | 2580 | |
---|
1907 | 2581 | switch (vt->audmode) { |
---|
1908 | | - case V4L2_TUNER_MODE_MONO: |
---|
1909 | | - /* mono -> mono |
---|
1910 | | - stereo -> mono |
---|
1911 | | - bilingual -> lang1 */ |
---|
1912 | | - cx25840_and_or(client, 0x809, ~0xf, 0x00); |
---|
1913 | | - break; |
---|
1914 | | - case V4L2_TUNER_MODE_STEREO: |
---|
1915 | | - case V4L2_TUNER_MODE_LANG1: |
---|
1916 | | - /* mono -> mono |
---|
1917 | | - stereo -> stereo |
---|
1918 | | - bilingual -> lang1 */ |
---|
1919 | | - cx25840_and_or(client, 0x809, ~0xf, 0x04); |
---|
1920 | | - break; |
---|
1921 | | - case V4L2_TUNER_MODE_LANG1_LANG2: |
---|
1922 | | - /* mono -> mono |
---|
1923 | | - stereo -> stereo |
---|
1924 | | - bilingual -> lang1/lang2 */ |
---|
1925 | | - cx25840_and_or(client, 0x809, ~0xf, 0x07); |
---|
1926 | | - break; |
---|
1927 | | - case V4L2_TUNER_MODE_LANG2: |
---|
1928 | | - /* mono -> mono |
---|
1929 | | - stereo -> stereo |
---|
1930 | | - bilingual -> lang2 */ |
---|
1931 | | - cx25840_and_or(client, 0x809, ~0xf, 0x01); |
---|
1932 | | - break; |
---|
1933 | | - default: |
---|
1934 | | - return -EINVAL; |
---|
| 2582 | + case V4L2_TUNER_MODE_MONO: |
---|
| 2583 | + /* |
---|
| 2584 | + * mono -> mono |
---|
| 2585 | + * stereo -> mono |
---|
| 2586 | + * bilingual -> lang1 |
---|
| 2587 | + */ |
---|
| 2588 | + cx25840_and_or(client, 0x809, ~0xf, 0x00); |
---|
| 2589 | + break; |
---|
| 2590 | + case V4L2_TUNER_MODE_STEREO: |
---|
| 2591 | + case V4L2_TUNER_MODE_LANG1: |
---|
| 2592 | + /* |
---|
| 2593 | + * mono -> mono |
---|
| 2594 | + * stereo -> stereo |
---|
| 2595 | + * bilingual -> lang1 |
---|
| 2596 | + */ |
---|
| 2597 | + cx25840_and_or(client, 0x809, ~0xf, 0x04); |
---|
| 2598 | + break; |
---|
| 2599 | + case V4L2_TUNER_MODE_LANG1_LANG2: |
---|
| 2600 | + /* |
---|
| 2601 | + * mono -> mono |
---|
| 2602 | + * stereo -> stereo |
---|
| 2603 | + * bilingual -> lang1/lang2 |
---|
| 2604 | + */ |
---|
| 2605 | + cx25840_and_or(client, 0x809, ~0xf, 0x07); |
---|
| 2606 | + break; |
---|
| 2607 | + case V4L2_TUNER_MODE_LANG2: |
---|
| 2608 | + /* |
---|
| 2609 | + * mono -> mono |
---|
| 2610 | + * stereo -> stereo |
---|
| 2611 | + * bilingual -> lang2 |
---|
| 2612 | + */ |
---|
| 2613 | + cx25840_and_or(client, 0x809, ~0xf, 0x01); |
---|
| 2614 | + break; |
---|
| 2615 | + default: |
---|
| 2616 | + return -EINVAL; |
---|
1935 | 2617 | } |
---|
1936 | 2618 | state->audmode = vt->audmode; |
---|
1937 | | - return 0; |
---|
1938 | | -} |
---|
1939 | | - |
---|
1940 | | -static int cx25840_reset(struct v4l2_subdev *sd, u32 val) |
---|
1941 | | -{ |
---|
1942 | | - struct cx25840_state *state = to_state(sd); |
---|
1943 | | - struct i2c_client *client = v4l2_get_subdevdata(sd); |
---|
1944 | | - |
---|
1945 | | - if (is_cx2583x(state)) |
---|
1946 | | - cx25836_initialize(client); |
---|
1947 | | - else if (is_cx2388x(state)) |
---|
1948 | | - cx23885_initialize(client); |
---|
1949 | | - else if (is_cx231xx(state)) |
---|
1950 | | - cx231xx_initialize(client); |
---|
1951 | | - else |
---|
1952 | | - cx25840_initialize(client); |
---|
1953 | 2619 | return 0; |
---|
1954 | 2620 | } |
---|
1955 | 2621 | |
---|
.. | .. |
---|
5059 | 5725 | static const struct v4l2_subdev_core_ops cx25840_core_ops = { |
---|
5060 | 5726 | .log_status = cx25840_log_status, |
---|
5061 | 5727 | .reset = cx25840_reset, |
---|
| 5728 | + /* calling the (optional) init op will turn on the generic mode */ |
---|
| 5729 | + .init = cx25840_init, |
---|
5062 | 5730 | .load_fw = cx25840_load_fw, |
---|
5063 | 5731 | .s_io_pin_config = common_s_io_pin_config, |
---|
5064 | 5732 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
---|
.. | .. |
---|
5082 | 5750 | }; |
---|
5083 | 5751 | |
---|
5084 | 5752 | static const struct v4l2_subdev_video_ops cx25840_video_ops = { |
---|
5085 | | - .s_std = cx25840_s_std, |
---|
5086 | 5753 | .g_std = cx25840_g_std, |
---|
| 5754 | + .s_std = cx25840_s_std, |
---|
| 5755 | + .querystd = cx25840_querystd, |
---|
5087 | 5756 | .s_routing = cx25840_s_video_routing, |
---|
5088 | 5757 | .s_stream = cx25840_s_stream, |
---|
5089 | 5758 | .g_input_status = cx25840_g_input_status, |
---|
.. | .. |
---|
5119 | 5788 | /* Come out of digital power down */ |
---|
5120 | 5789 | cx25840_write(client, 0x000, 0); |
---|
5121 | 5790 | |
---|
5122 | | - /* Detecting whether the part is cx23885/7/8 is more |
---|
| 5791 | + /* |
---|
| 5792 | + * Detecting whether the part is cx23885/7/8 is more |
---|
5123 | 5793 | * difficult than it needs to be. No ID register. Instead we |
---|
5124 | 5794 | * probe certain registers indicated in the datasheets to look |
---|
5125 | | - * for specific defaults that differ between the silicon designs. */ |
---|
| 5795 | + * for specific defaults that differ between the silicon designs. |
---|
| 5796 | + */ |
---|
5126 | 5797 | |
---|
5127 | 5798 | /* It's either 885/7 if the IR Tx Clk Divider register exists */ |
---|
5128 | 5799 | if (cx25840_read4(client, 0x204) & 0xffff) { |
---|
5129 | | - /* CX23885 returns bogus repetitive byte values for the DIF, |
---|
5130 | | - * which doesn't exist for it. (Ex. 8a8a8a8a or 31313131) */ |
---|
| 5800 | + /* |
---|
| 5801 | + * CX23885 returns bogus repetitive byte values for the DIF, |
---|
| 5802 | + * which doesn't exist for it. (Ex. 8a8a8a8a or 31313131) |
---|
| 5803 | + */ |
---|
5131 | 5804 | ret = cx25840_read4(client, 0x300); |
---|
5132 | 5805 | if (((ret & 0xffff0000) >> 16) == (ret & 0xffff)) { |
---|
5133 | 5806 | /* No DIF */ |
---|
5134 | 5807 | ret = CX23885_AV; |
---|
5135 | 5808 | } else { |
---|
5136 | | - /* CX23887 has a broken DIF, but the registers |
---|
5137 | | - * appear valid (but unused), good enough to detect. */ |
---|
| 5809 | + /* |
---|
| 5810 | + * CX23887 has a broken DIF, but the registers |
---|
| 5811 | + * appear valid (but unused), good enough to detect. |
---|
| 5812 | + */ |
---|
5138 | 5813 | ret = CX23887_AV; |
---|
5139 | 5814 | } |
---|
5140 | 5815 | } else if (cx25840_read4(client, 0x300) & 0x0fffffff) { |
---|
.. | .. |
---|
5166 | 5841 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
---|
5167 | 5842 | return -EIO; |
---|
5168 | 5843 | |
---|
5169 | | - v4l_dbg(1, cx25840_debug, client, "detecting cx25840 client on address 0x%x\n", client->addr << 1); |
---|
| 5844 | + v4l_dbg(1, cx25840_debug, client, |
---|
| 5845 | + "detecting cx25840 client on address 0x%x\n", |
---|
| 5846 | + client->addr << 1); |
---|
5170 | 5847 | |
---|
5171 | 5848 | device_id = cx25840_read(client, 0x101) << 8; |
---|
5172 | 5849 | device_id |= cx25840_read(client, 0x100); |
---|
5173 | 5850 | v4l_dbg(1, cx25840_debug, client, "device_id = 0x%04x\n", device_id); |
---|
5174 | 5851 | |
---|
5175 | | - /* The high byte of the device ID should be |
---|
5176 | | - * 0x83 for the cx2583x and 0x84 for the cx2584x */ |
---|
| 5852 | + /* |
---|
| 5853 | + * The high byte of the device ID should be |
---|
| 5854 | + * 0x83 for the cx2583x and 0x84 for the cx2584x |
---|
| 5855 | + */ |
---|
5177 | 5856 | if ((device_id & 0xff00) == 0x8300) { |
---|
5178 | 5857 | id = CX25836 + ((device_id >> 4) & 0xf) - 6; |
---|
5179 | 5858 | } else if ((device_id & 0xff00) == 0x8400) { |
---|
.. | .. |
---|
5187 | 5866 | v4l_err(client, |
---|
5188 | 5867 | "likely a confused/unresponsive cx2388[578] A/V decoder found @ 0x%x (%s)\n", |
---|
5189 | 5868 | client->addr << 1, client->adapter->name); |
---|
5190 | | - v4l_err(client, "A method to reset it from the cx25840 driver software is not known at this time\n"); |
---|
| 5869 | + v4l_err(client, |
---|
| 5870 | + "A method to reset it from the cx25840 driver software is not known at this time\n"); |
---|
5191 | 5871 | return -ENODEV; |
---|
5192 | 5872 | } else { |
---|
5193 | 5873 | v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n"); |
---|
.. | .. |
---|
5195 | 5875 | } |
---|
5196 | 5876 | |
---|
5197 | 5877 | state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL); |
---|
5198 | | - if (state == NULL) |
---|
| 5878 | + if (!state) |
---|
5199 | 5879 | return -ENOMEM; |
---|
5200 | 5880 | |
---|
5201 | 5881 | sd = &state->sd; |
---|
.. | .. |
---|
5216 | 5896 | * those extra inputs. So, let's add it only when needed. |
---|
5217 | 5897 | */ |
---|
5218 | 5898 | state->pads[CX25840_PAD_INPUT].flags = MEDIA_PAD_FL_SINK; |
---|
| 5899 | + state->pads[CX25840_PAD_INPUT].sig_type = PAD_SIGNAL_ANALOG; |
---|
5219 | 5900 | state->pads[CX25840_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; |
---|
5220 | | - state->pads[CX25840_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE; |
---|
| 5901 | + state->pads[CX25840_PAD_VID_OUT].sig_type = PAD_SIGNAL_DV; |
---|
5221 | 5902 | sd->entity.function = MEDIA_ENT_F_ATV_DECODER; |
---|
5222 | 5903 | |
---|
5223 | 5904 | ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(state->pads), |
---|
5224 | | - state->pads); |
---|
| 5905 | + state->pads); |
---|
5225 | 5906 | if (ret < 0) { |
---|
5226 | 5907 | v4l_info(client, "failed to initialize media entity!\n"); |
---|
5227 | 5908 | return ret; |
---|
.. | .. |
---|
5249 | 5930 | case CX25841: |
---|
5250 | 5931 | case CX25842: |
---|
5251 | 5932 | case CX25843: |
---|
5252 | | - /* Note: revision '(device_id & 0x0f) == 2' was never built. The |
---|
5253 | | - marking skips from 0x1 == 22 to 0x3 == 23. */ |
---|
| 5933 | + /* |
---|
| 5934 | + * Note: revision '(device_id & 0x0f) == 2' was never built. |
---|
| 5935 | + * The marking skips from 0x1 == 22 to 0x3 == 23. |
---|
| 5936 | + */ |
---|
5254 | 5937 | v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n", |
---|
5255 | 5938 | (device_id & 0xfff0) >> 4, |
---|
5256 | 5939 | (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 |
---|
.. | .. |
---|
5278 | 5961 | state->std = V4L2_STD_NTSC_M; |
---|
5279 | 5962 | v4l2_ctrl_handler_init(&state->hdl, 9); |
---|
5280 | 5963 | v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops, |
---|
5281 | | - V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); |
---|
| 5964 | + V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); |
---|
5282 | 5965 | v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops, |
---|
5283 | | - V4L2_CID_CONTRAST, 0, 127, 1, 64); |
---|
| 5966 | + V4L2_CID_CONTRAST, 0, 127, 1, 64); |
---|
5284 | 5967 | v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops, |
---|
5285 | | - V4L2_CID_SATURATION, 0, 127, 1, 64); |
---|
| 5968 | + V4L2_CID_SATURATION, 0, 127, 1, 64); |
---|
5286 | 5969 | v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops, |
---|
5287 | | - V4L2_CID_HUE, -128, 127, 1, 0); |
---|
| 5970 | + V4L2_CID_HUE, -128, 127, 1, 0); |
---|
5288 | 5971 | if (!is_cx2583x(state)) { |
---|
5289 | 5972 | default_volume = cx25840_read(client, 0x8d4); |
---|
5290 | 5973 | /* |
---|
.. | .. |
---|
5296 | 5979 | /* Bottom out at -96 dB, v4l2 vol range 0x2e00-0x2fff */ |
---|
5297 | 5980 | default_volume = 228; |
---|
5298 | 5981 | cx25840_write(client, 0x8d4, 228); |
---|
5299 | | - } |
---|
5300 | | - else if (default_volume < 20) { |
---|
| 5982 | + } else if (default_volume < 20) { |
---|
5301 | 5983 | /* Top out at + 8 dB, v4l2 vol range 0xfe00-0xffff */ |
---|
5302 | 5984 | default_volume = 20; |
---|
5303 | 5985 | cx25840_write(client, 0x8d4, 20); |
---|
.. | .. |
---|
5305 | 5987 | default_volume = (((228 - default_volume) >> 1) + 23) << 9; |
---|
5306 | 5988 | |
---|
5307 | 5989 | state->volume = v4l2_ctrl_new_std(&state->hdl, |
---|
5308 | | - &cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME, |
---|
5309 | | - 0, 65535, 65535 / 100, default_volume); |
---|
| 5990 | + &cx25840_audio_ctrl_ops, |
---|
| 5991 | + V4L2_CID_AUDIO_VOLUME, |
---|
| 5992 | + 0, 65535, 65535 / 100, |
---|
| 5993 | + default_volume); |
---|
5310 | 5994 | state->mute = v4l2_ctrl_new_std(&state->hdl, |
---|
5311 | | - &cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_MUTE, |
---|
5312 | | - 0, 1, 1, 0); |
---|
| 5995 | + &cx25840_audio_ctrl_ops, |
---|
| 5996 | + V4L2_CID_AUDIO_MUTE, |
---|
| 5997 | + 0, 1, 1, 0); |
---|
5313 | 5998 | v4l2_ctrl_new_std(&state->hdl, &cx25840_audio_ctrl_ops, |
---|
5314 | | - V4L2_CID_AUDIO_BALANCE, |
---|
5315 | | - 0, 65535, 65535 / 100, 32768); |
---|
| 5999 | + V4L2_CID_AUDIO_BALANCE, |
---|
| 6000 | + 0, 65535, 65535 / 100, 32768); |
---|
5316 | 6001 | v4l2_ctrl_new_std(&state->hdl, &cx25840_audio_ctrl_ops, |
---|
5317 | | - V4L2_CID_AUDIO_BASS, |
---|
5318 | | - 0, 65535, 65535 / 100, 32768); |
---|
| 6002 | + V4L2_CID_AUDIO_BASS, |
---|
| 6003 | + 0, 65535, 65535 / 100, 32768); |
---|
5319 | 6004 | v4l2_ctrl_new_std(&state->hdl, &cx25840_audio_ctrl_ops, |
---|
5320 | | - V4L2_CID_AUDIO_TREBLE, |
---|
5321 | | - 0, 65535, 65535 / 100, 32768); |
---|
| 6005 | + V4L2_CID_AUDIO_TREBLE, |
---|
| 6006 | + 0, 65535, 65535 / 100, 32768); |
---|
5322 | 6007 | } |
---|
5323 | 6008 | sd->ctrl_handler = &state->hdl; |
---|
5324 | 6009 | if (state->hdl.error) { |
---|