default n
help
If this menu is enabled, you can detect ESD of panel.
+config EXYNOS_PANEL_CABC
+ bool "Support CABC using DDI command"
+ depends on EXYNOS_DPU20
+ default n
+ help
+ If this menu is enabled, you can control CABC mode of panle.
config EXYNOS_LOW_PERSISTENCE
bool "Support Low Persistence Mode"
int (*doze_suspend)(struct dsim_device *dsim);
#if defined(CONFIG_EXYNOS_READ_ESD_SOLUTION)
int (*read_state)(struct dsim_device *dsim);
+#if defined(CONFIG_EXYNOS_PANEL_CABC)
+ int (*cabc)(struct dsim_device *dsim, int mode);
#endif
};
return ret;
}
+#if defined(CONFIG_EXYNOS_PANEL_CABC)
+static ssize_t dsim_cabc_sysfs_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int count = 0;
+ struct dsim_device *dsim = dev_get_drvdata(dev);
+
+ count = dsim->panel_ops->cabc(dsim, 0x80);
+ dsim_info("[CABC] read byte: %d\n", count);
+ sprintf(buf, "%d", count);
+
+ /* return: read byte(s) count */
+ return count;
+}
+
+static ssize_t dsim_cabc_sysfs_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int ret;
+ unsigned long mode;
+ struct dsim_device *dsim = dev_get_drvdata(dev);
+
+ /* when success, return 0 */
+ ret = kstrtoul(buf, 0, &mode);
+ if (ret)
+ return 0;
+
+ ret = dsim->panel_ops->cabc(dsim, mode);
+
+ /* return: write byte(s) count */
+ return ret;
+}
+
+static DEVICE_ATTR(cabc, 0644, dsim_cabc_sysfs_show, dsim_cabc_sysfs_store);
+
+int dsim_create_cabc_sysfs(struct dsim_device *dsim)
+{
+ int ret = 0;
+
+ ret = device_create_file(dsim->dev, &dev_attr_cabc);
+ if (ret)
+ dsim_err("failed to create cabc control sysfs\n");
+
+ return ret;
+}
+#endif
+
static void dsim_parse_lcd_info(struct dsim_device *dsim)
{
struct device_node *node = NULL;
#if defined(READ_ESD_SOLUTION_TEST)
dsim_create_esd_test_sysfs(dsim);
#endif
+#if defined(CONFIG_EXYNOS_PANEL_CABC)
+ dsim_create_cabc_sysfs(dsim);
#endif
#ifdef DPHY_LOOP
return 0;
}
+#if defined (CONFIG_EXYNOS_PANEL_CABC)
+static int nt36672a_cabc_mode(struct dsim_device *dsim, int mode)
+{
+ int ret = 0;
+ int count;
+ unsigned char buf[] = {0x0, 0x0};
+ unsigned char SEQ_CABC_CMD[] = {0x55, 0x00, 0x00};
+ unsigned char cmd = MIPI_DCS_WRITE_POWER_SAVE; /* 0x55 */
+
+ dsim_info("%s: CABC mode[%d] write/read\n", __func__, mode);
+
+ switch (mode) {
+ /* read */
+ case CABC_READ_MODE:
+ cmd = MIPI_DCS_GET_POWER_SAVE; /* 0x56 */
+ ret = dsim_read_data(dsim, MIPI_DSI_DCS_READ, cmd, 0x1, buf);
+ if (ret < 0) {
+ dsim_err("CABC REG(0x%02x) read failure!\n", cmd);
+ count = 0;
+ } else {
+ dsim_info("CABC REG(0x%02x) read success: 0x%02x\n",
+ cmd, *(unsigned int *)buf & 0xFF);
+ count = 1;
+ }
+ return count;
+
+ /*write */
+ case POWER_SAVE_OFF:
+ SEQ_CABC_CMD[1] = CABC_OFF;
+ break;
+ case POWER_SAVE_LOW:
+ SEQ_CABC_CMD[1] = CABC_USER_IMAGE;
+ break;
+ case POWER_SAVE_MEDIUM:
+ SEQ_CABC_CMD[1] = CABC_STILL_PICTURE;
+ break;
+ case POWER_SAVE_HIGH:
+ SEQ_CABC_CMD[1] = CABC_MOVING_IMAGE;
+ break;
+ default:
+ dsim_err("Unavailable CABC mode(%d)!\n", mode);
+ return -EINVAL;
+ }
+ ret = dsim_write_data(dsim, MIPI_DSI_DCS_LONG_WRITE,
+ (unsigned long)SEQ_CABC_CMD /* cmd */,
+ ARRAY_SIZE(SEQ_CABC_CMD));
+ if (ret < 0) {
+ dsim_err("CABC write command failure!\n");
+ count = 0;
+ } else {
+ dsim_dbg("CABC write command success!\n");
+ count = ARRAY_SIZE(SEQ_CABC_CMD);
+ }
+
+ return count;
+}
+#endif
+
struct dsim_lcd_driver nt36672a_mipi_lcd_driver = {
.probe = nt36672a_probe,
.displayon = nt36672a_displayon,
.suspend = nt36672a_suspend,
.resume = nt36672a_resume,
+#if defined (CONFIG_EXYNOS_PANEL_CABC)
+ .cabc = nt36672a_cabc_mode,
+#endif
};
#ifndef __NT36672A_PARAM_H__
#define __NT36672A_PARAM_H__
+#if defined(CONFIG_EXYNOS_PANEL_CABC)
+enum cabc_mode {
+ CABC_OFF = 0,
+ CABC_USER_IMAGE,
+ CABC_STILL_PICTURE,
+ CABC_MOVING_IMAGE,
+ CABC_READ_MODE = 0x80,
+};
+
+enum power_mode {
+ POWER_SAVE_OFF = 0,
+ POWER_SAVE_LOW = 1,
+ POWER_SAVE_MEDIUM = 2,
+ POWER_SAVE_HIGH = 3,
+ POWER_SAVE_MAX = 4,
+};
+#endif
+
/* MIPI commands list */
static const unsigned char SEQ_SLEEP_OUT[] = {
0x11,