diff options
Diffstat (limited to 'drivers/gpu/drm/i2c/adv7511.c')
| -rw-r--r-- | drivers/gpu/drm/i2c/adv7511.c | 48 | 
1 files changed, 29 insertions, 19 deletions
| diff --git a/drivers/gpu/drm/i2c/adv7511.c b/drivers/gpu/drm/i2c/adv7511.c index 533d1e3d4a99..a02112ba1c3d 100644 --- a/drivers/gpu/drm/i2c/adv7511.c +++ b/drivers/gpu/drm/i2c/adv7511.c @@ -136,6 +136,7 @@ static bool adv7511_register_volatile(struct device *dev, unsigned int reg)  	case ADV7511_REG_BKSV(3):  	case ADV7511_REG_BKSV(4):  	case ADV7511_REG_DDC_STATUS: +	case ADV7511_REG_EDID_READ_CTRL:  	case ADV7511_REG_BSTATUS(0):  	case ADV7511_REG_BSTATUS(1):  	case ADV7511_REG_CHIP_ID_HIGH: @@ -362,24 +363,31 @@ static void adv7511_power_on(struct adv7511 *adv7511)  {  	adv7511->current_edid_segment = -1; -	regmap_write(adv7511->regmap, ADV7511_REG_INT(0), -		     ADV7511_INT0_EDID_READY); -	regmap_write(adv7511->regmap, ADV7511_REG_INT(1), -		     ADV7511_INT1_DDC_ERROR);  	regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,  			   ADV7511_POWER_POWER_DOWN, 0); +	if (adv7511->i2c_main->irq) { +		/* +		 * Documentation says the INT_ENABLE registers are reset in +		 * POWER_DOWN mode. My 7511w preserved the bits, however. +		 * Still, let's be safe and stick to the documentation. +		 */ +		regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(0), +			     ADV7511_INT0_EDID_READY); +		regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(1), +			     ADV7511_INT1_DDC_ERROR); +	}  	/* -	 * Per spec it is allowed to pulse the HDP signal to indicate that the +	 * Per spec it is allowed to pulse the HPD signal to indicate that the  	 * EDID information has changed. Some monitors do this when they wakeup -	 * from standby or are enabled. When the HDP goes low the adv7511 is +	 * from standby or are enabled. When the HPD goes low the adv7511 is  	 * reset and the outputs are disabled which might cause the monitor to -	 * go to standby again. To avoid this we ignore the HDP pin for the +	 * go to standby again. To avoid this we ignore the HPD pin for the  	 * first few seconds after enabling the output.  	 */  	regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, -			   ADV7511_REG_POWER2_HDP_SRC_MASK, -			   ADV7511_REG_POWER2_HDP_SRC_NONE); +			   ADV7511_REG_POWER2_HPD_SRC_MASK, +			   ADV7511_REG_POWER2_HPD_SRC_NONE);  	/*  	 * Most of the registers are reset during power down or when HPD is low. @@ -413,9 +421,9 @@ static bool adv7511_hpd(struct adv7511 *adv7511)  	if (ret < 0)  		return false; -	if (irq0 & ADV7511_INT0_HDP) { +	if (irq0 & ADV7511_INT0_HPD) {  		regmap_write(adv7511->regmap, ADV7511_REG_INT(0), -			     ADV7511_INT0_HDP); +			     ADV7511_INT0_HPD);  		return true;  	} @@ -438,7 +446,7 @@ static int adv7511_irq_process(struct adv7511 *adv7511)  	regmap_write(adv7511->regmap, ADV7511_REG_INT(0), irq0);  	regmap_write(adv7511->regmap, ADV7511_REG_INT(1), irq1); -	if (irq0 & ADV7511_INT0_HDP && adv7511->encoder) +	if (irq0 & ADV7511_INT0_HPD && adv7511->encoder)  		drm_helper_hpd_irq_event(adv7511->encoder->dev);  	if (irq0 & ADV7511_INT0_EDID_READY || irq1 & ADV7511_INT1_DDC_ERROR) { @@ -567,12 +575,14 @@ static int adv7511_get_modes(struct drm_encoder *encoder,  	/* Reading the EDID only works if the device is powered */  	if (!adv7511->powered) { -		regmap_write(adv7511->regmap, ADV7511_REG_INT(0), -			     ADV7511_INT0_EDID_READY); -		regmap_write(adv7511->regmap, ADV7511_REG_INT(1), -			     ADV7511_INT1_DDC_ERROR);  		regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,  				   ADV7511_POWER_POWER_DOWN, 0); +		if (adv7511->i2c_main->irq) { +			regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(0), +				     ADV7511_INT0_EDID_READY); +			regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(1), +				     ADV7511_INT1_DDC_ERROR); +		}  		adv7511->current_edid_segment = -1;  	} @@ -638,10 +648,10 @@ adv7511_encoder_detect(struct drm_encoder *encoder,  		if (adv7511->status == connector_status_connected)  			status = connector_status_disconnected;  	} else { -		/* Renable HDP sensing */ +		/* Renable HPD sensing */  		regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, -				   ADV7511_REG_POWER2_HDP_SRC_MASK, -				   ADV7511_REG_POWER2_HDP_SRC_BOTH); +				   ADV7511_REG_POWER2_HPD_SRC_MASK, +				   ADV7511_REG_POWER2_HPD_SRC_BOTH);  	}  	adv7511->status = status; | 
