aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2014-01-30 14:32:21 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-05-25 12:00:21 -0400
commit05cacb176712cbbd3ae0331d92fe57741ef2d2ba (patch)
tree50c6ac8a152648175433e2acf3ea6e84a292f16d
parentc269887c2da49ad55ff59217255b0e95b0cec0e9 (diff)
[media] adv7604: Store I2C addresses and clients in arrays
This allows replacing duplicate code blocks by loops over the arrays. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r--drivers/media/i2c/adv7604.c248
-rw-r--r--include/media/adv7604.h30
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
380static s32 adv_smbus_read_byte_data(struct i2c_client *client, u8 command) 369static 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
385static s32 adv_smbus_write_byte_data(struct i2c_client *client, 376static 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
407static s32 adv_smbus_write_i2c_block_data(struct i2c_client *client, 400static 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
423static inline int io_read(struct v4l2_subdev *sd, u8 reg) 418static 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
430static inline int io_write(struct v4l2_subdev *sd, u8 reg, u8 val) 425static 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
437static inline int io_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) 432static 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
449static inline int avlink_write(struct v4l2_subdev *sd, u8 reg, u8 val) 444static 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
456static inline int cec_read(struct v4l2_subdev *sd, u8 reg) 451static 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
463static inline int cec_write(struct v4l2_subdev *sd, u8 reg, u8 val) 458static 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
470static inline int cec_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) 465static 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
482static inline int infoframe_write(struct v4l2_subdev *sd, u8 reg, u8 val) 477static 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
489static inline int esdp_read(struct v4l2_subdev *sd, u8 reg) 485static 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
496static inline int esdp_write(struct v4l2_subdev *sd, u8 reg, u8 val) 492static 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
503static inline int dpp_read(struct v4l2_subdev *sd, u8 reg) 499static 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
510static inline int dpp_write(struct v4l2_subdev *sd, u8 reg, u8 val) 506static 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
517static inline int afe_read(struct v4l2_subdev *sd, u8 reg) 513static 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
524static inline int afe_write(struct v4l2_subdev *sd, u8 reg, u8 val) 520static 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
531static inline int rep_read(struct v4l2_subdev *sd, u8 reg) 527static 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
538static inline int rep_write(struct v4l2_subdev *sd, u8 reg, u8 val) 534static 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
545static inline int rep_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) 541static 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
557static inline int edid_write(struct v4l2_subdev *sd, u8 reg, u8 val) 553static 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
564static inline int edid_read_block(struct v4l2_subdev *sd, unsigned len, u8 *val) 560static 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
624static u16 hdmi_read16(struct v4l2_subdev *sd, u8 reg, u16 mask) 620static 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
636static inline int hdmi_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) 632static 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
648static inline int test_write(struct v4l2_subdev *sd, u8 reg, u8 val) 644static 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
655static inline int cp_read(struct v4l2_subdev *sd, u8 reg) 651static 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
662static u16 cp_read16(struct v4l2_subdev *sd, u8 reg, u16 mask) 658static 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
674static inline int cp_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) 670static 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
686static inline int vdp_write(struct v4l2_subdev *sd, u8 reg, u8 val) 682static 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
693enum {
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
799static void adv7604_write_reg_seq(struct v4l2_subdev *sd, 720static 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
2572static void adv7604_unregister_clients(struct adv7604_state *state) 2495static 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
2600static struct i2c_client *adv7604_dummy_client(struct v4l2_subdev *sd, 2505static 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
82enum 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 */
83struct adv7604_platform_data { 100struct 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
142enum adv7604_pad { 148enum adv7604_pad {