// SPDX-License-Identifier: GPL-2.0-only
/*
* Generic DSI Command Mode panel driver
*
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
* Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
*/
/* #define DEBUG */
#include <linux/backlight.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/sched/signal.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/of_device.h>
#include <linux/regulator/consumer.h>
#include <drm/drm_connector.h>
#include <video/mipi_display.h>
#include <video/of_display_timing.h>
#include "../dss/omapdss.h"
/* DSI Virtual channel. Hardcoded for now. */
#define TCH 0
#define DCS_READ_NUM_ERRORS 0x05
#define DCS_BRIGHTNESS 0x51
#define DCS_CTRL_DISPLAY 0x53
#define DCS_GET_ID1 0xda
#define DCS_GET_ID2 0xdb
#define DCS_GET_ID3 0xdc
struct panel_drv_data {
struct omap_dss_device dssdev;
struct omap_dss_device *src;
struct videomode vm;
struct platform_device *pdev;
struct mutex lock;
struct backlight_device *bldev;
struct backlight_device *extbldev;
unsigned long hw_guard_end; /* next value of jiffies when we can
* issue the next sleep in/out command
*/
unsigned long hw_guard_wait; /* max guard time in jiffies */
/* panel HW configuration from DT or platform data */
struct gpio_desc *reset_gpio;
struct gpio_desc *ext_te_gpio;
struct regulator *vpnl;
struct regulator *vddi;
bool use_dsi_backlight;
int width_mm;
int height_mm;
struct omap_dsi_pin_config pin_config;
/* runtime variables */
bool enabled;
bool te_enabled;
atomic_t do_update;
int channel;
struct delayed_work te_timeout_work;
bool intro_printed;
struct workqueue_struct *workqueue;
bool ulps_enabled;
unsigned int ulps_timeout;
struct delayed_work ulps_work;
};
#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
static irqreturn_t dsicm_te_isr(int irq, void *data);
static void dsicm_te_timeout_work_callback(struct work_struct *work);
static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable);
static int dsicm_panel_reset(struct panel_drv_data *ddata);
static void dsicm_ulps_work(struct work_struct *work);
static void dsicm_bl_power(struct panel_drv_data *ddata, bool enable)
{
struct back