/* * The power-on and power-off sequences are taken from the * LTV350QV-F04 data sheet from Samsung. The register definitions are * taken from the S6F2002 command list also from Samsung. * * There's still some voodoo going on here, but it's a lot better than * in the first incarnation of the driver where all we had was the raw * numbers from the initialization sequence.
*/ staticint ltv350qv_write_reg(struct ltv350qv *lcd, u8 reg, u16 val)
{ struct spi_message msg; struct spi_transfer index_xfer = {
.len = 3,
.cs_change = 1,
}; struct spi_transfer value_xfer = {
.len = 3,
};
/* The comments are taken straight from the data sheet */ staticint ltv350qv_power_on(struct ltv350qv *lcd)
{ int ret;
/* Power On Reset Display off State */ if (ltv350qv_write_reg(lcd, LTV_PWRCTL1, 0x0000)) goto err;
usleep_range(15000, 16000);
/* Power Setting Function 1 */ if (ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE)) goto err; if (ltv350qv_write_reg(lcd, LTV_PWRCTL2, LTV_VCOML_ENABLE)) goto err_power1;
/* Power Setting Function 2 */ if (ltv350qv_write_reg(lcd, LTV_PWRCTL1,
LTV_VCOM_DISABLE | LTV_DRIVE_CURRENT(5)
| LTV_SUPPLY_CURRENT(5))) goto err_power2;
msleep(55);
/* Instruction Setting */
ret = ltv350qv_write_reg(lcd, LTV_IFCTL,
LTV_NMD | LTV_REV | LTV_NL(0x1d));
ret |= ltv350qv_write_reg(lcd, LTV_DATACTL,
LTV_DS_SAME | LTV_CHS_480
| LTV_DF_RGB | LTV_RGB_BGR);
ret |= ltv350qv_write_reg(lcd, LTV_ENTRY_MODE,
LTV_VSPL_ACTIVE_LOW
| LTV_HSPL_ACTIVE_LOW
| LTV_DPL_SAMPLE_RISING
| LTV_EPL_ACTIVE_LOW
| LTV_SS_RIGHT_TO_LEFT);
ret |= ltv350qv_write_reg(lcd, LTV_GATECTL1, LTV_CLW(3));
ret |= ltv350qv_write_reg(lcd, LTV_GATECTL2,
LTV_NW_INV_1LINE | LTV_FWI(3));
ret |= ltv350qv_write_reg(lcd, LTV_VBP, 0x000a);
ret |= ltv350qv_write_reg(lcd, LTV_HBP, 0x0021);
ret |= ltv350qv_write_reg(lcd, LTV_SOTCTL, LTV_SDT(3) | LTV_EQ(0));
ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(0), 0x0103);
ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(1), 0x0301);
ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(2), 0x1f0f);
ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(3), 0x1f0f);
ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(4), 0x0707);
ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(5), 0x0307);
ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(6), 0x0707);
ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(7), 0x0000);
ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(8), 0x0004);
ret |= ltv350qv_write_reg(lcd, LTV_GAMMA(9), 0x0000); if (ret) goto err_settings;
/* Wait more than 2 frames */
msleep(20);
/* Display On Sequence */
ret = ltv350qv_write_reg(lcd, LTV_PWRCTL1,
LTV_VCOM_DISABLE | LTV_VCOMOUT_ENABLE
| LTV_POWER_ON | LTV_DRIVE_CURRENT(5)
| LTV_SUPPLY_CURRENT(5));
ret |= ltv350qv_write_reg(lcd, LTV_GATECTL2,
LTV_NW_INV_1LINE | LTV_DSC | LTV_FWI(3)); if (ret) goto err_disp_on;
/* Display should now be ON. Phew. */ return 0;
err_disp_on: /* * Try to recover. Error handling probably isn't very useful * at this point, just make a best effort to switch the panel * off.
*/
ltv350qv_write_reg(lcd, LTV_PWRCTL1,
LTV_VCOM_DISABLE | LTV_DRIVE_CURRENT(5)
| LTV_SUPPLY_CURRENT(5));
ltv350qv_write_reg(lcd, LTV_GATECTL2,
LTV_NW_INV_1LINE | LTV_FWI(3));
err_settings:
err_power2:
err_power1:
ltv350qv_write_reg(lcd, LTV_PWRCTL2, 0x0000);
usleep_range(1000, 1100);
err:
ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE); return -EIO;
}
staticint ltv350qv_power_off(struct ltv350qv *lcd)
{ int ret;
/* Display Off Sequence */
ret = ltv350qv_write_reg(lcd, LTV_PWRCTL1,
LTV_VCOM_DISABLE
| LTV_DRIVE_CURRENT(5)
| LTV_SUPPLY_CURRENT(5));
ret |= ltv350qv_write_reg(lcd, LTV_GATECTL2,
LTV_NW_INV_1LINE | LTV_FWI(3));
/* Power down setting 1 */
ret |= ltv350qv_write_reg(lcd, LTV_PWRCTL2, 0x0000);
/* Wait at least 1 ms */
usleep_range(1000, 1100);
/* Power down setting 2 */
ret |= ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE);
/* * No point in trying to recover here. If we can't switch the * panel off, what are we supposed to do other than inform the * user about the failure?
*/ if (ret) return -EIO;
/* Display power should now be OFF */ return 0;
}
staticint ltv350qv_power(struct ltv350qv *lcd, int power)
{ int ret = 0;
if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
ret = ltv350qv_power_on(lcd); elseif (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
ret = ltv350qv_power_off(lcd);
/* Power down all displays on reboot, poweroff or halt */ staticvoid ltv350qv_shutdown(struct spi_device *spi)
{ struct ltv350qv *lcd = spi_get_drvdata(spi);
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.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.