aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_dp_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_dp_helper.c')
-rw-r--r--drivers/gpu/drm/drm_dp_helper.c55
1 files changed, 35 insertions, 20 deletions
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 27671489477d..4b6e6f3ba0a1 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -577,7 +577,9 @@ static u32 drm_dp_i2c_functionality(struct i2c_adapter *adapter)
577 577
578/* 578/*
579 * Transfer a single I2C-over-AUX message and handle various error conditions, 579 * Transfer a single I2C-over-AUX message and handle various error conditions,
580 * retrying the transaction as appropriate. 580 * retrying the transaction as appropriate. It is assumed that the
581 * aux->transfer function does not modify anything in the msg other than the
582 * reply field.
581 */ 583 */
582static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) 584static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
583{ 585{
@@ -665,11 +667,26 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
665{ 667{
666 struct drm_dp_aux *aux = adapter->algo_data; 668 struct drm_dp_aux *aux = adapter->algo_data;
667 unsigned int i, j; 669 unsigned int i, j;
670 struct drm_dp_aux_msg msg;
671 int err = 0;
668 672
669 for (i = 0; i < num; i++) { 673 memset(&msg, 0, sizeof(msg));
670 struct drm_dp_aux_msg msg;
671 int err;
672 674
675 for (i = 0; i < num; i++) {
676 msg.address = msgs[i].addr;
677 msg.request = (msgs[i].flags & I2C_M_RD) ?
678 DP_AUX_I2C_READ :
679 DP_AUX_I2C_WRITE;
680 msg.request |= DP_AUX_I2C_MOT;
681 /* Send a bare address packet to start the transaction.
682 * Zero sized messages specify an address only (bare
683 * address) transaction.
684 */
685 msg.buffer = NULL;
686 msg.size = 0;
687 err = drm_dp_i2c_do_msg(aux, &msg);
688 if (err < 0)
689 break;
673 /* 690 /*
674 * Many hardware implementations support FIFOs larger than a 691 * Many hardware implementations support FIFOs larger than a
675 * single byte, but it has been empirically determined that 692 * single byte, but it has been empirically determined that
@@ -678,30 +695,28 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
678 * transferred byte-by-byte. 695 * transferred byte-by-byte.
679 */ 696 */
680 for (j = 0; j < msgs[i].len; j++) { 697 for (j = 0; j < msgs[i].len; j++) {
681 memset(&msg, 0, sizeof(msg));
682 msg.address = msgs[i].addr;
683
684 msg.request = (msgs[i].flags & I2C_M_RD) ?
685 DP_AUX_I2C_READ :
686 DP_AUX_I2C_WRITE;
687
688 /*
689 * All messages except the last one are middle-of-
690 * transfer messages.
691 */
692 if ((i < num - 1) || (j < msgs[i].len - 1))
693 msg.request |= DP_AUX_I2C_MOT;
694
695 msg.buffer = msgs[i].buf + j; 698 msg.buffer = msgs[i].buf + j;
696 msg.size = 1; 699 msg.size = 1;
697 700
698 err = drm_dp_i2c_do_msg(aux, &msg); 701 err = drm_dp_i2c_do_msg(aux, &msg);
699 if (err < 0) 702 if (err < 0)
700 return err; 703 break;
701 } 704 }
705 if (err < 0)
706 break;
702 } 707 }
708 if (err >= 0)
709 err = num;
710 /* Send a bare address packet to close out the transaction.
711 * Zero sized messages specify an address only (bare
712 * address) transaction.
713 */
714 msg.request &= ~DP_AUX_I2C_MOT;
715 msg.buffer = NULL;
716 msg.size = 0;
717 (void)drm_dp_i2c_do_msg(aux, &msg);
703 718
704 return num; 719 return err;
705} 720}
706 721
707static const struct i2c_algorithm drm_dp_i2c_algo = { 722static const struct i2c_algorithm drm_dp_i2c_algo = {