/* * Panel power down status
*/ #define VR30 0x30 /* Read only bit indicating that the panel is not in a safe poweroff state. */ # define VR30_PANEL_ON (1 << 15)
/* Some Bios implementations do not restore the DVO state upon * resume from standby. Thus, this driver has to handle it * instead. The following list contains all registers that * require saving.
*/ staticconst u16 backup_addresses[] = { 0x11, 0x12, 0x18, 0x19, 0x1a, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x8e, 0x8f, 0x10 /* this must come last */
};
struct ivch_priv { bool quiet;
u16 width, height;
/* Register backup */
u16 reg_backup[ARRAY_SIZE(backup_addresses)];
};
staticvoid ivch_dump_regs(struct intel_dvo_device *dvo); /* * Reads a register on the ivch. * * Each of the 256 registers are 16 bits long.
*/ staticbool ivch_read(struct intel_dvo_device *dvo, int addr, u16 *data)
{ struct ivch_priv *priv = dvo->dev_priv; struct i2c_adapter *adapter = dvo->i2c_bus;
u8 out_buf[1];
u8 in_buf[2];
out_buf[0] = addr;
out_buf[1] = data & 0xff;
out_buf[2] = data >> 8;
if (i2c_transfer(adapter, &msg, 1) == 1) returntrue;
if (!priv->quiet) {
DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
addr, adapter->name, dvo->target_addr);
}
returnfalse;
}
/* Probes the given bus and target address for an ivch */ staticbool ivch_init(struct intel_dvo_device *dvo, struct i2c_adapter *adapter)
{ struct ivch_priv *priv;
u16 temp; int i;
priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (priv == NULL) returnfalse;
if (!ivch_read(dvo, VR00, &temp)) goto out;
priv->quiet = false;
/* Since the identification bits are probably zeroes, which doesn't seem * very unique, check that the value in the base address field matches * the address it's responding on.
*/ if ((temp & VR00_BASE_ADDRESS_MASK) != dvo->target_addr) {
DRM_DEBUG_KMS("ivch detect failed due to address mismatch " "(%d vs %d)\n",
(temp & VR00_BASE_ADDRESS_MASK), dvo->target_addr); goto out;
}
/* Make a backup of the registers to be able to restore them * upon suspend.
*/ for (i = 0; i < ARRAY_SIZE(backup_addresses); i++)
ivch_read(dvo, backup_addresses[i], priv->reg_backup + i);
/* Restore the DVO registers after a resume * from RAM. Registers have been saved during * the initialization.
*/ staticvoid ivch_reset(struct intel_dvo_device *dvo)
{ struct ivch_priv *priv = dvo->dev_priv; int i;
DRM_DEBUG_KMS("Resetting the IVCH registers\n");
ivch_write(dvo, VR10, 0x0000);
for (i = 0; i < ARRAY_SIZE(backup_addresses); i++)
ivch_write(dvo, backup_addresses[i], priv->reg_backup[i]);
}
/* Sets the power state of the panel connected to the ivch */ staticvoid ivch_dpms(struct intel_dvo_device *dvo, bool enable)
{ int i;
u16 vr01, vr30, backlight;
ivch_reset(dvo);
/* Set the new power state of the panel. */ if (!ivch_read(dvo, VR01, &vr01)) return;
/* Wait for the panel to make its state transition */ for (i = 0; i < 100; i++) { if (!ivch_read(dvo, VR30, &vr30)) break;
if (((vr30 & VR30_PANEL_ON) != 0) == enable) break;
udelay(1000);
} /* wait some more; vch may fail to resync sometimes without this */
udelay(16 * 1000);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Angebot
Hier finden Sie eine Liste der Produkte des Unternehmens