diff options
| -rw-r--r-- | drivers/media/i2c/adv7604.c | 248 | ||||
| -rw-r--r-- | include/media/adv7604.h | 30 |
2 files changed, 88 insertions, 190 deletions
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 154790923668..fc71c171ea18 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c | |||
| @@ -159,18 +159,7 @@ struct adv7604_state { | |||
| 159 | bool restart_stdi_once; | 159 | bool restart_stdi_once; |
| 160 | 160 | ||
| 161 | /* i2c clients */ | 161 | /* i2c clients */ |
| 162 | struct i2c_client *i2c_avlink; | 162 | struct i2c_client *i2c_clients[ADV7604_PAGE_MAX]; |
| 163 | struct i2c_client *i2c_cec; | ||
| 164 | struct i2c_client *i2c_infoframe; | ||
| 165 | struct i2c_client *i2c_esdp; | ||
| 166 | struct i2c_client *i2c_dpp; | ||
| 167 | struct i2c_client *i2c_afe; | ||
| 168 | struct i2c_client *i2c_repeater; | ||
| 169 | struct i2c_client *i2c_edid; | ||
| 170 | struct i2c_client *i2c_hdmi; | ||
| 171 | struct i2c_client *i2c_test; | ||
| 172 | struct i2c_client *i2c_cp; | ||
| 173 | struct i2c_client *i2c_vdp; | ||
| 174 | 163 | ||
| 175 | /* controls */ | 164 | /* controls */ |
| 176 | struct v4l2_ctrl *detect_tx_5v_ctrl; | 165 | struct v4l2_ctrl *detect_tx_5v_ctrl; |
| @@ -377,14 +366,18 @@ static s32 adv_smbus_read_byte_data_check(struct i2c_client *client, | |||
| 377 | return -EIO; | 366 | return -EIO; |
| 378 | } | 367 | } |
| 379 | 368 | ||
| 380 | static s32 adv_smbus_read_byte_data(struct i2c_client *client, u8 command) | 369 | static s32 adv_smbus_read_byte_data(struct adv7604_state *state, |
| 370 | enum adv7604_page page, u8 command) | ||
| 381 | { | 371 | { |
| 382 | return adv_smbus_read_byte_data_check(client, command, true); | 372 | return adv_smbus_read_byte_data_check(state->i2c_clients[page], |
| 373 | command, true); | ||
| 383 | } | 374 | } |
| 384 | 375 | ||
| 385 | static s32 adv_smbus_write_byte_data(struct i2c_client *client, | 376 | static s32 adv_smbus_write_byte_data(struct adv7604_state *state, |
| 386 | u8 command, u8 value) | 377 | enum adv7604_page page, u8 command, |
| 378 | u8 value) | ||
| 387 | { | 379 | { |
| 380 | struct i2c_client *client = state->i2c_clients[page]; | ||
| 388 | union i2c_smbus_data data; | 381 | union i2c_smbus_data data; |
| 389 | int err; | 382 | int err; |
| 390 | int i; | 383 | int i; |
| @@ -404,9 +397,11 @@ static s32 adv_smbus_write_byte_data(struct i2c_client *client, | |||
| 404 | return err; | 397 | return err; |
| 405 | } | 398 | } |
| 406 | 399 | ||
| 407 | static s32 adv_smbus_write_i2c_block_data(struct i2c_client *client, | 400 | static s32 adv_smbus_write_i2c_block_data(struct adv7604_state *state, |
| 408 | u8 command, unsigned length, const u8 *values) | 401 | enum adv7604_page page, u8 command, |
| 402 | unsigned length, const u8 *values) | ||
| 409 | { | 403 | { |
| 404 | struct i2c_client *client = state->i2c_clients[page]; | ||
| 410 | union i2c_smbus_data data; | 405 | union i2c_smbus_data data; |
| 411 | 406 | ||
| 412 | if (length > I2C_SMBUS_BLOCK_MAX) | 407 | if (length > I2C_SMBUS_BLOCK_MAX) |
| @@ -422,16 +417,16 @@ static s32 adv_smbus_write_i2c_block_data(struct i2c_client *client, | |||
| 422 | 417 | ||
| 423 | static inline int io_read(struct v4l2_subdev *sd, u8 reg) | 418 | static inline int io_read(struct v4l2_subdev *sd, u8 reg) |
| 424 | { | 419 | { |
| 425 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 420 | struct adv7604_state *state = to_state(sd); |
| 426 | 421 | ||
| 427 | return adv_smbus_read_byte_data(client, reg); | 422 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_IO, reg); |
| 428 | } | 423 | } |
| 429 | 424 | ||
| 430 | static inline int io_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 425 | static inline int io_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
| 431 | { | 426 | { |
| 432 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 427 | struct adv7604_state *state = to_state(sd); |
| 433 | 428 | ||
| 434 | return adv_smbus_write_byte_data(client, reg, val); | 429 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_IO, reg, val); |
| 435 | } | 430 | } |
| 436 | 431 | ||
| 437 | static inline int io_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) | 432 | static inline int io_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) |
| @@ -443,28 +438,28 @@ static inline int avlink_read(struct v4l2_subdev *sd, u8 reg) | |||
| 443 | { | 438 | { |
| 444 | struct adv7604_state *state = to_state(sd); | 439 | struct adv7604_state *state = to_state(sd); |
| 445 | 440 | ||
| 446 | return adv_smbus_read_byte_data(state->i2c_avlink, reg); | 441 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_AVLINK, reg); |
| 447 | } | 442 | } |
| 448 | 443 | ||
| 449 | static inline int avlink_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 444 | static inline int avlink_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
| 450 | { | 445 | { |
| 451 | struct adv7604_state *state = to_state(sd); | 446 | struct adv7604_state *state = to_state(sd); |
| 452 | 447 | ||
| 453 | return adv_smbus_write_byte_data(state->i2c_avlink, reg, val); | 448 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_AVLINK, reg, val); |
| 454 | } | 449 | } |
| 455 | 450 | ||
| 456 | static inline int cec_read(struct v4l2_subdev *sd, u8 reg) | 451 | static inline int cec_read(struct v4l2_subdev *sd, u8 reg) |
| 457 | { | 452 | { |
| 458 | struct adv7604_state *state = to_state(sd); | 453 | struct adv7604_state *state = to_state(sd); |
| 459 | 454 | ||
| 460 | return adv_smbus_read_byte_data(state->i2c_cec, reg); | 455 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_CEC, reg); |
| 461 | } | 456 | } |
| 462 | 457 | ||
| 463 | static inline int cec_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 458 | static inline int cec_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
| 464 | { | 459 | { |
| 465 | struct adv7604_state *state = to_state(sd); | 460 | struct adv7604_state *state = to_state(sd); |
| 466 | 461 | ||
| 467 | return adv_smbus_write_byte_data(state->i2c_cec, reg, val); | 462 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_CEC, reg, val); |
| 468 | } | 463 | } |
| 469 | 464 | ||
| 470 | static inline int cec_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) | 465 | static inline int cec_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) |
| @@ -476,70 +471,71 @@ static inline int infoframe_read(struct v4l2_subdev *sd, u8 reg) | |||
| 476 | { | 471 | { |
| 477 | struct adv7604_state *state = to_state(sd); | 472 | struct adv7604_state *state = to_state(sd); |
| 478 | 473 | ||
| 479 | return adv_smbus_read_byte_data(state->i2c_infoframe, reg); | 474 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_INFOFRAME, reg); |
| 480 | } | 475 | } |
| 481 | 476 | ||
| 482 | static inline int infoframe_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 477 | static inline int infoframe_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
| 483 | { | 478 | { |
| 484 | struct adv7604_state *state = to_state(sd); | 479 | struct adv7604_state *state = to_state(sd); |
| 485 | 480 | ||
| 486 | return adv_smbus_write_byte_data(state->i2c_infoframe, reg, val); | 481 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_INFOFRAME, |
| 482 | reg, val); | ||
| 487 | } | 483 | } |
| 488 | 484 | ||
| 489 | static inline int esdp_read(struct v4l2_subdev *sd, u8 reg) | 485 | static inline int esdp_read(struct v4l2_subdev *sd, u8 reg) |
| 490 | { | 486 | { |
| 491 | struct adv7604_state *state = to_state(sd); | 487 | struct adv7604_state *state = to_state(sd); |
| 492 | 488 | ||
| 493 | return adv_smbus_read_byte_data(state->i2c_esdp, reg); | 489 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_ESDP, reg); |
| 494 | } | 490 | } |
| 495 | 491 | ||
| 496 | static inline int esdp_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 492 | static inline int esdp_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
| 497 | { | 493 | { |
| 498 | struct adv7604_state *state = to_state(sd); | 494 | struct adv7604_state *state = to_state(sd); |
| 499 | 495 | ||
| 500 | return adv_smbus_write_byte_data(state->i2c_esdp, reg, val); | 496 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_ESDP, reg, val); |
| 501 | } | 497 | } |
| 502 | 498 | ||
| 503 | static inline int dpp_read(struct v4l2_subdev *sd, u8 reg) | 499 | static inline int dpp_read(struct v4l2_subdev *sd, u8 reg) |
| 504 | { | 500 | { |
| 505 | struct adv7604_state *state = to_state(sd); | 501 | struct adv7604_state *state = to_state(sd); |
| 506 | 502 | ||
| 507 | return adv_smbus_read_byte_data(state->i2c_dpp, reg); | 503 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_DPP, reg); |
| 508 | } | 504 | } |
| 509 | 505 | ||
| 510 | static inline int dpp_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 506 | static inline int dpp_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
| 511 | { | 507 | { |
| 512 | struct adv7604_state *state = to_state(sd); | 508 | struct adv7604_state *state = to_state(sd); |
| 513 | 509 | ||
| 514 | return adv_smbus_write_byte_data(state->i2c_dpp, reg, val); | 510 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_DPP, reg, val); |
| 515 | } | 511 | } |
| 516 | 512 | ||
| 517 | static inline int afe_read(struct v4l2_subdev *sd, u8 reg) | 513 | static inline int afe_read(struct v4l2_subdev *sd, u8 reg) |
| 518 | { | 514 | { |
| 519 | struct adv7604_state *state = to_state(sd); | 515 | struct adv7604_state *state = to_state(sd); |
| 520 | 516 | ||
| 521 | return adv_smbus_read_byte_data(state->i2c_afe, reg); | 517 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_AFE, reg); |
| 522 | } | 518 | } |
| 523 | 519 | ||
| 524 | static inline int afe_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 520 | static inline int afe_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
| 525 | { | 521 | { |
| 526 | struct adv7604_state *state = to_state(sd); | 522 | struct adv7604_state *state = to_state(sd); |
| 527 | 523 | ||
| 528 | return adv_smbus_write_byte_data(state->i2c_afe, reg, val); | 524 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_AFE, reg, val); |
| 529 | } | 525 | } |
| 530 | 526 | ||
| 531 | static inline int rep_read(struct v4l2_subdev *sd, u8 reg) | 527 | static inline int rep_read(struct v4l2_subdev *sd, u8 reg) |
| 532 | { | 528 | { |
| 533 | struct adv7604_state *state = to_state(sd); | 529 | struct adv7604_state *state = to_state(sd); |
| 534 | 530 | ||
| 535 | return adv_smbus_read_byte_data(state->i2c_repeater, reg); | 531 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_REP, reg); |
| 536 | } | 532 | } |
| 537 | 533 | ||
| 538 | static inline int rep_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 534 | static inline int rep_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
| 539 | { | 535 | { |
| 540 | struct adv7604_state *state = to_state(sd); | 536 | struct adv7604_state *state = to_state(sd); |
| 541 | 537 | ||
| 542 | return adv_smbus_write_byte_data(state->i2c_repeater, reg, val); | 538 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_REP, reg, val); |
| 543 | } | 539 | } |
| 544 | 540 | ||
| 545 | static inline int rep_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) | 541 | static inline int rep_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) |
| @@ -551,20 +547,20 @@ static inline int edid_read(struct v4l2_subdev *sd, u8 reg) | |||
| 551 | { | 547 | { |
| 552 | struct adv7604_state *state = to_state(sd); | 548 | struct adv7604_state *state = to_state(sd); |
| 553 | 549 | ||
| 554 | return adv_smbus_read_byte_data(state->i2c_edid, reg); | 550 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_EDID, reg); |
| 555 | } | 551 | } |
| 556 | 552 | ||
| 557 | static inline int edid_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 553 | static inline int edid_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
| 558 | { | 554 | { |
| 559 | struct adv7604_state *state = to_state(sd); | 555 | struct adv7604_state *state = to_state(sd); |
| 560 | 556 | ||
| 561 | return adv_smbus_write_byte_data(state->i2c_edid, reg, val); | 557 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_EDID, reg, val); |
| 562 | } | 558 | } |
| 563 | 559 | ||
| 564 | static inline int edid_read_block(struct v4l2_subdev *sd, unsigned len, u8 *val) | 560 | static inline int edid_read_block(struct v4l2_subdev *sd, unsigned len, u8 *val) |
| 565 | { | 561 | { |
| 566 | struct adv7604_state *state = to_state(sd); | 562 | struct adv7604_state *state = to_state(sd); |
| 567 | struct i2c_client *client = state->i2c_edid; | 563 | struct i2c_client *client = state->i2c_clients[ADV7604_PAGE_EDID]; |
| 568 | u8 msgbuf0[1] = { 0 }; | 564 | u8 msgbuf0[1] = { 0 }; |
| 569 | u8 msgbuf1[256]; | 565 | u8 msgbuf1[256]; |
| 570 | struct i2c_msg msg[2] = { | 566 | struct i2c_msg msg[2] = { |
| @@ -597,8 +593,8 @@ static inline int edid_write_block(struct v4l2_subdev *sd, | |||
| 597 | v4l2_dbg(2, debug, sd, "%s: write EDID block (%d byte)\n", __func__, len); | 593 | v4l2_dbg(2, debug, sd, "%s: write EDID block (%d byte)\n", __func__, len); |
| 598 | 594 | ||
| 599 | for (i = 0; !err && i < len; i += I2C_SMBUS_BLOCK_MAX) | 595 | for (i = 0; !err && i < len; i += I2C_SMBUS_BLOCK_MAX) |
| 600 | err = adv_smbus_write_i2c_block_data(state->i2c_edid, i, | 596 | err = adv_smbus_write_i2c_block_data(state, ADV7604_PAGE_EDID, |
| 601 | I2C_SMBUS_BLOCK_MAX, val + i); | 597 | i, I2C_SMBUS_BLOCK_MAX, val + i); |
| 602 | return err; | 598 | return err; |
| 603 | } | 599 | } |
| 604 | 600 | ||
| @@ -618,7 +614,7 @@ static inline int hdmi_read(struct v4l2_subdev *sd, u8 reg) | |||
| 618 | { | 614 | { |
| 619 | struct adv7604_state *state = to_state(sd); | 615 | struct adv7604_state *state = to_state(sd); |
| 620 | 616 | ||
| 621 | return adv_smbus_read_byte_data(state->i2c_hdmi, reg); | 617 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_HDMI, reg); |
| 622 | } | 618 | } |
| 623 | 619 | ||
| 624 | static u16 hdmi_read16(struct v4l2_subdev *sd, u8 reg, u16 mask) | 620 | static u16 hdmi_read16(struct v4l2_subdev *sd, u8 reg, u16 mask) |
| @@ -630,7 +626,7 @@ static inline int hdmi_write(struct v4l2_subdev *sd, u8 reg, u8 val) | |||
| 630 | { | 626 | { |
| 631 | struct adv7604_state *state = to_state(sd); | 627 | struct adv7604_state *state = to_state(sd); |
| 632 | 628 | ||
| 633 | return adv_smbus_write_byte_data(state->i2c_hdmi, reg, val); | 629 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_HDMI, reg, val); |
| 634 | } | 630 | } |
| 635 | 631 | ||
| 636 | static inline int hdmi_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) | 632 | static inline int hdmi_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) |
| @@ -642,21 +638,21 @@ static inline int test_read(struct v4l2_subdev *sd, u8 reg) | |||
| 642 | { | 638 | { |
| 643 | struct adv7604_state *state = to_state(sd); | 639 | struct adv7604_state *state = to_state(sd); |
| 644 | 640 | ||
| 645 | return adv_smbus_read_byte_data(state->i2c_test, reg); | 641 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_TEST, reg); |
| 646 | } | 642 | } |
| 647 | 643 | ||
| 648 | static inline int test_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 644 | static inline int test_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
| 649 | { | 645 | { |
| 650 | struct adv7604_state *state = to_state(sd); | 646 | struct adv7604_state *state = to_state(sd); |
| 651 | 647 | ||
| 652 | return adv_smbus_write_byte_data(state->i2c_test, reg, val); | 648 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_TEST, reg, val); |
| 653 | } | 649 | } |
| 654 | 650 | ||
| 655 | static inline int cp_read(struct v4l2_subdev *sd, u8 reg) | 651 | static inline int cp_read(struct v4l2_subdev *sd, u8 reg) |
| 656 | { | 652 | { |
| 657 | struct adv7604_state *state = to_state(sd); | 653 | struct adv7604_state *state = to_state(sd); |
| 658 | 654 | ||
| 659 | return adv_smbus_read_byte_data(state->i2c_cp, reg); | 655 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_CP, reg); |
| 660 | } | 656 | } |
| 661 | 657 | ||
| 662 | static u16 cp_read16(struct v4l2_subdev *sd, u8 reg, u16 mask) | 658 | static u16 cp_read16(struct v4l2_subdev *sd, u8 reg, u16 mask) |
| @@ -668,7 +664,7 @@ static inline int cp_write(struct v4l2_subdev *sd, u8 reg, u8 val) | |||
| 668 | { | 664 | { |
| 669 | struct adv7604_state *state = to_state(sd); | 665 | struct adv7604_state *state = to_state(sd); |
| 670 | 666 | ||
| 671 | return adv_smbus_write_byte_data(state->i2c_cp, reg, val); | 667 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_CP, reg, val); |
| 672 | } | 668 | } |
| 673 | 669 | ||
| 674 | static inline int cp_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) | 670 | static inline int cp_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) |
| @@ -680,32 +676,15 @@ static inline int vdp_read(struct v4l2_subdev *sd, u8 reg) | |||
| 680 | { | 676 | { |
| 681 | struct adv7604_state *state = to_state(sd); | 677 | struct adv7604_state *state = to_state(sd); |
| 682 | 678 | ||
| 683 | return adv_smbus_read_byte_data(state->i2c_vdp, reg); | 679 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_VDP, reg); |
| 684 | } | 680 | } |
| 685 | 681 | ||
| 686 | static inline int vdp_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 682 | static inline int vdp_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
| 687 | { | 683 | { |
| 688 | struct adv7604_state *state = to_state(sd); | 684 | struct adv7604_state *state = to_state(sd); |
| 689 | 685 | ||
| 690 | return adv_smbus_write_byte_data(state->i2c_vdp, reg, val); | 686 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_VDP, reg, val); |
| 691 | } | 687 | } |
| 692 | |||
| 693 | enum { | ||
| 694 | ADV7604_PAGE_IO, | ||
| 695 | ADV7604_PAGE_AVLINK, | ||
| 696 | ADV7604_PAGE_CEC, | ||
| 697 | ADV7604_PAGE_INFOFRAME, | ||
| 698 | ADV7604_PAGE_ESDP, | ||
| 699 | ADV7604_PAGE_DPP, | ||
| 700 | ADV7604_PAGE_AFE, | ||
| 701 | ADV7604_PAGE_REP, | ||
| 702 | ADV7604_PAGE_EDID, | ||
| 703 | ADV7604_PAGE_HDMI, | ||
| 704 | ADV7604_PAGE_TEST, | ||
| 705 | ADV7604_PAGE_CP, | ||
| 706 | ADV7604_PAGE_VDP, | ||
| 707 | ADV7604_PAGE_TERM, | ||
| 708 | }; | ||
| 709 | 688 | ||
| 710 | #define ADV7604_REG(page, offset) (((page) << 8) | (offset)) | 689 | #define ADV7604_REG(page, offset) (((page) << 8) | (offset)) |
| 711 | #define ADV7604_REG_SEQ_TERM 0xffff | 690 | #define ADV7604_REG_SEQ_TERM 0xffff |
| @@ -721,36 +700,7 @@ static int adv7604_read_reg(struct v4l2_subdev *sd, unsigned int reg) | |||
| 721 | 700 | ||
| 722 | reg &= 0xff; | 701 | reg &= 0xff; |
| 723 | 702 | ||
| 724 | switch (page) { | 703 | return adv_smbus_read_byte_data(state, page, reg); |
| 725 | case ADV7604_PAGE_IO: | ||
| 726 | return io_read(sd, reg); | ||
| 727 | case ADV7604_PAGE_AVLINK: | ||
| 728 | return avlink_read(sd, reg); | ||
| 729 | case ADV7604_PAGE_CEC: | ||
| 730 | return cec_read(sd, reg); | ||
| 731 | case ADV7604_PAGE_INFOFRAME: | ||
| 732 | return infoframe_read(sd, reg); | ||
| 733 | case ADV7604_PAGE_ESDP: | ||
| 734 | return esdp_read(sd, reg); | ||
| 735 | case ADV7604_PAGE_DPP: | ||
| 736 | return dpp_read(sd, reg); | ||
| 737 | case ADV7604_PAGE_AFE: | ||
| 738 | return afe_read(sd, reg); | ||
| 739 | case ADV7604_PAGE_REP: | ||
| 740 | return rep_read(sd, reg); | ||
| 741 | case ADV7604_PAGE_EDID: | ||
| 742 | return edid_read(sd, reg); | ||
| 743 | case ADV7604_PAGE_HDMI: | ||
| 744 | return hdmi_read(sd, reg); | ||
| 745 | case ADV7604_PAGE_TEST: | ||
| 746 | return test_read(sd, reg); | ||
| 747 | case ADV7604_PAGE_CP: | ||
| 748 | return cp_read(sd, reg); | ||
| 749 | case ADV7604_PAGE_VDP: | ||
| 750 | return vdp_read(sd, reg); | ||
| 751 | } | ||
| 752 | |||
| 753 | return -EINVAL; | ||
| 754 | } | 704 | } |
| 755 | #endif | 705 | #endif |
| 756 | 706 | ||
| @@ -764,36 +714,7 @@ static int adv7604_write_reg(struct v4l2_subdev *sd, unsigned int reg, u8 val) | |||
| 764 | 714 | ||
| 765 | reg &= 0xff; | 715 | reg &= 0xff; |
| 766 | 716 | ||
| 767 | switch (page) { | 717 | return adv_smbus_write_byte_data(state, page, reg, val); |
| 768 | case ADV7604_PAGE_IO: | ||
| 769 | return io_write(sd, reg, val); | ||
| 770 | case ADV7604_PAGE_AVLINK: | ||
| 771 | return avlink_write(sd, reg, val); | ||
| 772 | case ADV7604_PAGE_CEC: | ||
| 773 | return cec_write(sd, reg, val); | ||
| 774 | case ADV7604_PAGE_INFOFRAME: | ||
| 775 | return infoframe_write(sd, reg, val); | ||
| 776 | case ADV7604_PAGE_ESDP: | ||
| 777 | return esdp_write(sd, reg, val); | ||
| 778 | case ADV7604_PAGE_DPP: | ||
| 779 | return dpp_write(sd, reg, val); | ||
| 780 | case ADV7604_PAGE_AFE: | ||
| 781 | return afe_write(sd, reg, val); | ||
| 782 | case ADV7604_PAGE_REP: | ||
| 783 | return rep_write(sd, reg, val); | ||
| 784 | case ADV7604_PAGE_EDID: | ||
| 785 | return edid_write(sd, reg, val); | ||
| 786 | case ADV7604_PAGE_HDMI: | ||
| 787 | return hdmi_write(sd, reg, val); | ||
| 788 | case ADV7604_PAGE_TEST: | ||
| 789 | return test_write(sd, reg, val); | ||
| 790 | case ADV7604_PAGE_CP: | ||
| 791 | return cp_write(sd, reg, val); | ||
| 792 | case ADV7604_PAGE_VDP: | ||
| 793 | return vdp_write(sd, reg, val); | ||
| 794 | } | ||
| 795 | |||
| 796 | return -EINVAL; | ||
| 797 | } | 718 | } |
| 798 | 719 | ||
| 799 | static void adv7604_write_reg_seq(struct v4l2_subdev *sd, | 720 | static void adv7604_write_reg_seq(struct v4l2_subdev *sd, |
| @@ -1064,7 +985,6 @@ static void configure_custom_video_timings(struct v4l2_subdev *sd, | |||
| 1064 | const struct v4l2_bt_timings *bt) | 985 | const struct v4l2_bt_timings *bt) |
| 1065 | { | 986 | { |
| 1066 | struct adv7604_state *state = to_state(sd); | 987 | struct adv7604_state *state = to_state(sd); |
| 1067 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
| 1068 | u32 width = htotal(bt); | 988 | u32 width = htotal(bt); |
| 1069 | u32 height = vtotal(bt); | 989 | u32 height = vtotal(bt); |
| 1070 | u16 cp_start_sav = bt->hsync + bt->hbackporch - 4; | 990 | u16 cp_start_sav = bt->hsync + bt->hbackporch - 4; |
| @@ -1090,7 +1010,8 @@ static void configure_custom_video_timings(struct v4l2_subdev *sd, | |||
| 1090 | /* Should only be set in auto-graphics mode [REF_02, p. 91-92] */ | 1010 | /* Should only be set in auto-graphics mode [REF_02, p. 91-92] */ |
| 1091 | /* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */ | 1011 | /* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */ |
| 1092 | /* IO-map reg. 0x16 and 0x17 should be written in sequence */ | 1012 | /* IO-map reg. 0x16 and 0x17 should be written in sequence */ |
| 1093 | if (adv_smbus_write_i2c_block_data(client, 0x16, 2, pll)) | 1013 | if (adv_smbus_write_i2c_block_data(state, ADV7604_PAGE_IO, |
| 1014 | 0x16, 2, pll)) | ||
| 1094 | v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n"); | 1015 | v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n"); |
| 1095 | 1016 | ||
| 1096 | /* active video - horizontal timing */ | 1017 | /* active video - horizontal timing */ |
| @@ -1141,7 +1062,8 @@ static void adv7604_set_offset(struct v4l2_subdev *sd, bool auto_offset, u16 off | |||
| 1141 | offset_buf[3] = offset_c & 0x0ff; | 1062 | offset_buf[3] = offset_c & 0x0ff; |
| 1142 | 1063 | ||
| 1143 | /* Registers must be written in this order with no i2c access in between */ | 1064 | /* Registers must be written in this order with no i2c access in between */ |
| 1144 | if (adv_smbus_write_i2c_block_data(state->i2c_cp, 0x77, 4, offset_buf)) | 1065 | if (adv_smbus_write_i2c_block_data(state, ADV7604_PAGE_CP, |
| 1066 | 0x77, 4, offset_buf)) | ||
| 1145 | v4l2_err(sd, "%s: i2c error writing to CP reg 0x77, 0x78, 0x79, 0x7a\n", __func__); | 1067 | v4l2_err(sd, "%s: i2c error writing to CP reg 0x77, 0x78, 0x79, 0x7a\n", __func__); |
| 1146 | } | 1068 | } |
| 1147 | 1069 | ||
| @@ -1170,7 +1092,8 @@ static void adv7604_set_gain(struct v4l2_subdev *sd, bool auto_gain, u16 gain_a, | |||
| 1170 | gain_buf[3] = ((gain_c & 0x0ff)); | 1092 | gain_buf[3] = ((gain_c & 0x0ff)); |
| 1171 | 1093 | ||
| 1172 | /* Registers must be written in this order with no i2c access in between */ | 1094 | /* Registers must be written in this order with no i2c access in between */ |
| 1173 | if (adv_smbus_write_i2c_block_data(state->i2c_cp, 0x73, 4, gain_buf)) | 1095 | if (adv_smbus_write_i2c_block_data(state, ADV7604_PAGE_CP, |
| 1096 | 0x73, 4, gain_buf)) | ||
| 1174 | v4l2_err(sd, "%s: i2c error writing to CP reg 0x73, 0x74, 0x75, 0x76\n", __func__); | 1097 | v4l2_err(sd, "%s: i2c error writing to CP reg 0x73, 0x74, 0x75, 0x76\n", __func__); |
| 1175 | } | 1098 | } |
| 1176 | 1099 | ||
| @@ -2571,30 +2494,12 @@ static void adv7611_setup_irqs(struct v4l2_subdev *sd) | |||
| 2571 | 2494 | ||
| 2572 | static void adv7604_unregister_clients(struct adv7604_state *state) | 2495 | static void adv7604_unregister_clients(struct adv7604_state *state) |
| 2573 | { | 2496 | { |
| 2574 | if (state->i2c_avlink) | 2497 | unsigned int i; |
| 2575 | i2c_unregister_device(state->i2c_avlink); | 2498 | |
| 2576 | if (state->i2c_cec) | 2499 | for (i = 1; i < ARRAY_SIZE(state->i2c_clients); ++i) { |
| 2577 | i2c_unregister_device(state->i2c_cec); | 2500 | if (state->i2c_clients[i]) |
| 2578 | if (state->i2c_infoframe) | 2501 | i2c_unregister_device(state->i2c_clients[i]); |
| 2579 | i2c_unregister_device(state->i2c_infoframe); | 2502 | } |
| 2580 | if (state->i2c_esdp) | ||
| 2581 | i2c_unregister_device(state->i2c_esdp); | ||
| 2582 | if (state->i2c_dpp) | ||
| 2583 | i2c_unregister_device(state->i2c_dpp); | ||
| 2584 | if (state->i2c_afe) | ||
| 2585 | i2c_unregister_device(state->i2c_afe); | ||
| 2586 | if (state->i2c_repeater) | ||
| 2587 | i2c_unregister_device(state->i2c_repeater); | ||
| 2588 | if (state->i2c_edid) | ||
| 2589 | i2c_unregister_device(state->i2c_edid); | ||
| 2590 | if (state->i2c_hdmi) | ||
| 2591 | i2c_unregister_device(state->i2c_hdmi); | ||
| 2592 | if (state->i2c_test) | ||
| 2593 | i2c_unregister_device(state->i2c_test); | ||
| 2594 | if (state->i2c_cp) | ||
| 2595 | i2c_unregister_device(state->i2c_cp); | ||
| 2596 | if (state->i2c_vdp) | ||
| 2597 | i2c_unregister_device(state->i2c_vdp); | ||
| 2598 | } | 2503 | } |
| 2599 | 2504 | ||
| 2600 | static struct i2c_client *adv7604_dummy_client(struct v4l2_subdev *sd, | 2505 | static struct i2c_client *adv7604_dummy_client(struct v4l2_subdev *sd, |
| @@ -2761,6 +2666,7 @@ static int adv7604_probe(struct i2c_client *client, | |||
| 2761 | } | 2666 | } |
| 2762 | 2667 | ||
| 2763 | state->info = &adv7604_chip_info[id->driver_data]; | 2668 | state->info = &adv7604_chip_info[id->driver_data]; |
| 2669 | state->i2c_clients[ADV7604_PAGE_IO] = client; | ||
| 2764 | 2670 | ||
| 2765 | /* initialize variables */ | 2671 | /* initialize variables */ |
| 2766 | state->restart_stdi_once = true; | 2672 | state->restart_stdi_once = true; |
| @@ -2852,34 +2758,20 @@ static int adv7604_probe(struct i2c_client *client, | |||
| 2852 | goto err_hdl; | 2758 | goto err_hdl; |
| 2853 | } | 2759 | } |
| 2854 | 2760 | ||
| 2855 | state->i2c_cec = adv7604_dummy_client(sd, pdata->i2c_cec, 0xf4); | 2761 | for (i = 1; i < ADV7604_PAGE_MAX; ++i) { |
| 2856 | state->i2c_infoframe = adv7604_dummy_client(sd, pdata->i2c_infoframe, 0xf5); | 2762 | if (!(BIT(i) & state->info->page_mask)) |
| 2857 | state->i2c_afe = adv7604_dummy_client(sd, pdata->i2c_afe, 0xf8); | 2763 | continue; |
| 2858 | state->i2c_repeater = adv7604_dummy_client(sd, pdata->i2c_repeater, 0xf9); | ||
| 2859 | state->i2c_edid = adv7604_dummy_client(sd, pdata->i2c_edid, 0xfa); | ||
| 2860 | state->i2c_hdmi = adv7604_dummy_client(sd, pdata->i2c_hdmi, 0xfb); | ||
| 2861 | state->i2c_cp = adv7604_dummy_client(sd, pdata->i2c_cp, 0xfd); | ||
| 2862 | if (!state->i2c_cec || !state->i2c_infoframe || !state->i2c_afe || | ||
| 2863 | !state->i2c_repeater || !state->i2c_edid || !state->i2c_hdmi || | ||
| 2864 | !state->i2c_cp) { | ||
| 2865 | err = -ENOMEM; | ||
| 2866 | v4l2_err(sd, "failed to create digital i2c clients\n"); | ||
| 2867 | goto err_i2c; | ||
| 2868 | } | ||
| 2869 | 2764 | ||
| 2870 | if (adv7604_has_afe(state)) { | 2765 | state->i2c_clients[i] = |
| 2871 | state->i2c_avlink = adv7604_dummy_client(sd, pdata->i2c_avlink, 0xf3); | 2766 | adv7604_dummy_client(sd, pdata->i2c_addresses[i], |
| 2872 | state->i2c_esdp = adv7604_dummy_client(sd, pdata->i2c_esdp, 0xf6); | 2767 | 0xf2 + i); |
| 2873 | state->i2c_dpp = adv7604_dummy_client(sd, pdata->i2c_dpp, 0xf7); | 2768 | if (state->i2c_clients[i] == NULL) { |
| 2874 | state->i2c_test = adv7604_dummy_client(sd, pdata->i2c_test, 0xfc); | ||
| 2875 | state->i2c_vdp = adv7604_dummy_client(sd, pdata->i2c_vdp, 0xfe); | ||
| 2876 | if (!state->i2c_avlink || !state->i2c_esdp || !state->i2c_dpp || | ||
| 2877 | !state->i2c_test || !state->i2c_vdp) { | ||
| 2878 | err = -ENOMEM; | 2769 | err = -ENOMEM; |
| 2879 | v4l2_err(sd, "failed to create analog i2c clients\n"); | 2770 | v4l2_err(sd, "failed to create i2c client %u\n", i); |
| 2880 | goto err_i2c; | 2771 | goto err_i2c; |
| 2881 | } | 2772 | } |
| 2882 | } | 2773 | } |
| 2774 | |||
| 2883 | /* work queues */ | 2775 | /* work queues */ |
| 2884 | state->work_queues = create_singlethread_workqueue(client->name); | 2776 | state->work_queues = create_singlethread_workqueue(client->name); |
| 2885 | if (!state->work_queues) { | 2777 | if (!state->work_queues) { |
diff --git a/include/media/adv7604.h b/include/media/adv7604.h index d8b2cb8f5dce..276135b7faa3 100644 --- a/include/media/adv7604.h +++ b/include/media/adv7604.h | |||
| @@ -79,6 +79,23 @@ enum adv7604_int1_config { | |||
| 79 | ADV7604_INT1_CONFIG_DISABLED, | 79 | ADV7604_INT1_CONFIG_DISABLED, |
| 80 | }; | 80 | }; |
| 81 | 81 | ||
| 82 | enum adv7604_page { | ||
| 83 | ADV7604_PAGE_IO, | ||
| 84 | ADV7604_PAGE_AVLINK, | ||
| 85 | ADV7604_PAGE_CEC, | ||
| 86 | ADV7604_PAGE_INFOFRAME, | ||
| 87 | ADV7604_PAGE_ESDP, | ||
| 88 | ADV7604_PAGE_DPP, | ||
| 89 | ADV7604_PAGE_AFE, | ||
| 90 | ADV7604_PAGE_REP, | ||
| 91 | ADV7604_PAGE_EDID, | ||
| 92 | ADV7604_PAGE_HDMI, | ||
| 93 | ADV7604_PAGE_TEST, | ||
| 94 | ADV7604_PAGE_CP, | ||
| 95 | ADV7604_PAGE_VDP, | ||
| 96 | ADV7604_PAGE_MAX, | ||
| 97 | }; | ||
| 98 | |||
| 82 | /* Platform dependent definition */ | 99 | /* Platform dependent definition */ |
| 83 | struct adv7604_platform_data { | 100 | struct adv7604_platform_data { |
| 84 | /* DIS_PWRDNB: 1 if the PWRDNB pin is unused and unconnected */ | 101 | /* DIS_PWRDNB: 1 if the PWRDNB pin is unused and unconnected */ |
| @@ -125,18 +142,7 @@ struct adv7604_platform_data { | |||
| 125 | unsigned hdmi_free_run_mode; | 142 | unsigned hdmi_free_run_mode; |
| 126 | 143 | ||
| 127 | /* i2c addresses: 0 == use default */ | 144 | /* i2c addresses: 0 == use default */ |
| 128 | u8 i2c_avlink; | 145 | u8 i2c_addresses[ADV7604_PAGE_MAX]; |
| 129 | u8 i2c_cec; | ||
| 130 | u8 i2c_infoframe; | ||
| 131 | u8 i2c_esdp; | ||
| 132 | u8 i2c_dpp; | ||
| 133 | u8 i2c_afe; | ||
| 134 | u8 i2c_repeater; | ||
| 135 | u8 i2c_edid; | ||
| 136 | u8 i2c_hdmi; | ||
| 137 | u8 i2c_test; | ||
| 138 | u8 i2c_cp; | ||
| 139 | u8 i2c_vdp; | ||
| 140 | }; | 146 | }; |
| 141 | 147 | ||
| 142 | enum adv7604_pad { | 148 | enum adv7604_pad { |
