linux/drivers/gpu/drm/panel/panel-ilitek-ili9322.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Ilitek ILI9322 TFT LCD drm_panel driver.
 *
 * This panel can be configured to support:
 * - 8-bit serial RGB interface
 * - 24-bit parallel RGB interface
 * - 8-bit ITU-R BT.601 interface
 * - 8-bit ITU-R BT.656 interface
 * - Up to 320RGBx240 dots resolution TFT LCD displays
 * - Scaling, brightness and contrast
 *
 * The scaling means that the display accepts a 640x480 or 720x480
 * input and rescales it to fit to the 320x240 display. So what we
 * present to the system is something else than what comes out on the
 * actual display.
 *
 * Copyright (C) 2017 Linus Walleij <[email protected]>
 * Derived from drivers/drm/gpu/panel/panel-samsung-ld9040.c
 */

#include <linux/bitops.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>

#include <video/mipi_display.h>
#include <video/of_videomode.h>
#include <video/videomode.h>

#include <drm/drm_modes.h>
#include <drm/drm_panel.h>

#define ILI9322_CHIP_ID
#define ILI9322_CHIP_ID_MAGIC

/*
 * Voltage on the communication interface, from 0.7 (0x00)
 * to 1.32 (0x1f) times the VREG1OUT voltage in 2% increments.
 * 1.00 (0x0f) is the default.
 */
#define ILI9322_VCOM_AMP

/*
 * High voltage on the communication signals, from 0.37 (0x00) to
 * 1.0 (0x3f) times the VREGOUT1 voltage in 1% increments.
 * 0.83 (0x2e) is the default.
 */
#define ILI9322_VCOM_HIGH

/*
 * VREG1 voltage regulator from 3.6V (0x00) to 6.0V (0x18) in 0.1V
 * increments. 5.4V (0x12) is the default. This is the reference
 * voltage for the VCOM levels and the greyscale level.
 */
#define ILI9322_VREG1_VOLTAGE

/* Describes the incoming signal */
#define ILI9322_ENTRY
/* 0 = right-to-left, 1 = left-to-right (default), horizontal flip */
#define ILI9322_ENTRY_HDIR
/* 0 = down-to-up, 1 = up-to-down (default), vertical flip  */
#define ILI9322_ENTRY_VDIR
/* NTSC, PAL or autodetect */
#define ILI9322_ENTRY_NTSC
#define ILI9322_ENTRY_PAL
#define ILI9322_ENTRY_AUTODETECT
/* Input format */
#define ILI9322_ENTRY_SERIAL_RGB_THROUGH
#define ILI9322_ENTRY_SERIAL_RGB_ALIGNED
#define ILI9322_ENTRY_SERIAL_RGB_DUMMY_320X240
#define ILI9322_ENTRY_SERIAL_RGB_DUMMY_360X240
#define ILI9322_ENTRY_DISABLE_1
#define ILI9322_ENTRY_PARALLEL_RGB_THROUGH
#define ILI9322_ENTRY_PARALLEL_RGB_ALIGNED
#define ILI9322_ENTRY_YUV_640Y_320CBCR_25_54_MHZ
#define ILI9322_ENTRY_YUV_720Y_360CBCR_27_MHZ
#define ILI9322_ENTRY_DISABLE_2
#define ILI9322_ENTRY_ITU_R_BT_656_720X360
#define ILI9322_ENTRY_ITU_R_BT_656_640X320

/* Power control */
#define ILI9322_POW_CTRL
#define ILI9322_POW_CTRL_STB
#define ILI9322_POW_CTRL_VGL
#define ILI9322_POW_CTRL_VGH
#define ILI9322_POW_CTRL_DDVDH
#define ILI9322_POW_CTRL_VCOM
#define ILI9322_POW_CTRL_VCL
#define ILI9322_POW_CTRL_AUTO
#define ILI9322_POW_CTRL_STANDBY
#define ILI9322_POW_CTRL_DEFAULT

/* Vertical back porch bits 0..5 */
#define ILI9322_VBP

/* Horizontal back porch, 8 bits */
#define ILI9322_HBP

/*
 * Polarity settings:
 * 1 = positive polarity
 * 0 = negative polarity
 */
#define ILI9322_POL
#define ILI9322_POL_DCLK
#define ILI9322_POL_HSYNC
#define ILI9322_POL_VSYNC
#define ILI9322_POL_DE
/*
 * 0 means YCBCR are ordered Cb0,Y0,Cr0,Y1,Cb2,Y2,Cr2,Y3 (default)
 *   in RGB mode this means RGB comes in RGBRGB
 * 1 means YCBCR are ordered Cr0,Y0,Cb0,Y1,Cr2,Y2,Cb2,Y3
 *   in RGB mode this means RGB comes in BGRBGR
 */
#define ILI9322_POL_YCBCR_MODE
/* Formula A for YCbCR->RGB = 0, Formula B = 1 */
#define ILI9322_POL_FORMULA
/* Reverse polarity: 0 = 0..255, 1 = 255..0 */
#define ILI9322_POL_REV

#define ILI9322_IF_CTRL
#define ILI9322_IF_CTRL_HSYNC_VSYNC
#define ILI9322_IF_CTRL_HSYNC_VSYNC_DE
#define ILI9322_IF_CTRL_DE_ONLY
#define ILI9322_IF_CTRL_SYNC_DISABLED
#define ILI9322_IF_CTRL_LINE_INVERSION

#define ILI9322_GLOBAL_RESET
#define ILI9322_GLOBAL_RESET_ASSERT

/*
 * 4+4 bits of negative and positive gamma correction
 * Upper nybble, bits 4-7 are negative gamma
 * Lower nybble, bits 0-3 are positive gamma
 */
#define ILI9322_GAMMA_1
#define ILI9322_GAMMA_2
#define ILI9322_GAMMA_3
#define ILI9322_GAMMA_4
#define ILI9322_GAMMA_5
#define ILI9322_GAMMA_6
#define ILI9322_GAMMA_7
#define ILI9322_GAMMA_8

/*
 * enum ili9322_input - the format of the incoming signal to the panel
 *
 * The panel can be connected to various input streams and four of them can
 * be selected by electronic straps on the display. However it is possible
 * to select another mode or override the electronic default with this
 * setting.
 */
enum ili9322_input {};

static const char * const ili9322_inputs[] =;

/**
 * struct ili9322_config - the system specific ILI9322 configuration
 * @width_mm: physical panel width [mm]
 * @height_mm: physical panel height [mm]
 * @flip_horizontal: flip the image horizontally (right-to-left scan)
 * (only in RGB and YUV modes)
 * @flip_vertical: flip the image vertically (down-to-up scan)
 * (only in RGB and YUV modes)
 * @input: the input/entry type used in this system, if this is set to
 * ILI9322_INPUT_UNKNOWN the driver will try to figure it out by probing
 * the hardware
 * @vreg1out_mv: the output in microvolts for the VREGOUT1 regulator used
 * to drive the physical display. Valid ranges are 3600 thru 6000 in 100
 * microvolt increments. If not specified, hardware defaults will be
 * used (4.5V).
 * @vcom_high_percent: the percentage of VREGOUT1 used for the peak
 * voltage on the communications link. Valid ranges are 37 thru 100
 * percent. If not specified, hardware defaults will be used (91%).
 * @vcom_amplitude_percent: the percentage of VREGOUT1 used for the
 * peak-to-peak amplitude of the communcation signals to the physical
 * display. Valid ranges are 70 thru 132 percent in increments if two
 * percent. Odd percentages will be truncated. If not specified, hardware
 * defaults will be used (114%).
 * @dclk_active_high: data/pixel clock active high, data will be clocked
 * in on the rising edge of the DCLK (this is usually the case).
 * @syncmode: The synchronization mode, what sync signals are emitted.
 * See the enum for details.
 * @de_active_high: DE (data entry) is active high
 * @hsync_active_high: HSYNC is active high
 * @vsync_active_high: VSYNC is active high
 * @gamma_corr_pos: a set of 8 nybbles describing positive
 * gamma correction for voltages V1 thru V8. Valid range 0..15
 * @gamma_corr_neg: a set of 8 nybbles describing negative
 * gamma correction for voltages V1 thru V8. Valid range 0..15
 *
 * These adjust what grayscale voltage will be output for input data V1 = 0,
 * V2 = 16, V3 = 48, V4 = 96, V5 = 160, V6 = 208, V7 = 240 and V8 = 255.
 * The curve is shaped like this:
 *
 *  ^
 *  |                                                        V8
 *  |                                                   V7
 *  |                                          V6
 *  |                               V5
 *  |                    V4
 *  |            V3
 *  |     V2
 *  | V1
 *  +----------------------------------------------------------->
 *    0   16     48      96         160        208      240  255
 *
 * The negative and postive gamma values adjust the V1 thru V8 up/down
 * according to the datasheet specifications. This is a property of the
 * physical display connected to the display controller and may vary.
 * If defined, both arrays must be supplied in full. If the properties
 * are not supplied, hardware defaults will be used.
 */
struct ili9322_config {};

struct ili9322 {};

static inline struct ili9322 *panel_to_ili9322(struct drm_panel *panel)
{}

static int ili9322_regmap_spi_write(void *context, const void *data,
				    size_t count)
{}

static int ili9322_regmap_spi_read(void *context, const void *reg,
				   size_t reg_size, void *val, size_t val_size)
{}

static struct regmap_bus ili9322_regmap_bus =;

static bool ili9322_writeable_reg(struct device *dev, unsigned int reg)
{}

static const struct regmap_config ili9322_regmap_config =;

static int ili9322_init(struct drm_panel *panel, struct ili9322 *ili)
{}

/*
 * This power-on sequence if from the datasheet, page 57.
 */
static int ili9322_power_on(struct ili9322 *ili)
{}

static int ili9322_power_off(struct ili9322 *ili)
{}

static int ili9322_disable(struct drm_panel *panel)
{}

static int ili9322_unprepare(struct drm_panel *panel)
{}

static int ili9322_prepare(struct drm_panel *panel)
{}

static int ili9322_enable(struct drm_panel *panel)
{}

/* Serial RGB modes */
static const struct drm_display_mode srgb_320x240_mode =;

static const struct drm_display_mode srgb_360x240_mode =;

/* This is the only mode listed for parallel RGB in the datasheet */
static const struct drm_display_mode prgb_320x240_mode =;

/* YUV modes */
static const struct drm_display_mode yuv_640x320_mode =;

static const struct drm_display_mode yuv_720x360_mode =;

/* BT.656 VGA mode, 640x480 */
static const struct drm_display_mode itu_r_bt_656_640_mode =;

/* BT.656 D1 mode 720x480 */
static const struct drm_display_mode itu_r_bt_656_720_mode =;

static int ili9322_get_modes(struct drm_panel *panel,
			     struct drm_connector *connector)
{}

static const struct drm_panel_funcs ili9322_drm_funcs =;

static int ili9322_probe(struct spi_device *spi)
{}

static void ili9322_remove(struct spi_device *spi)
{}

/*
 * The D-Link DIR-685 panel is marked LM918A01-1A SY-B4-091116-E0199
 */
static const struct ili9322_config ili9322_dir_685 =;

static const struct of_device_id ili9322_of_match[] =;
MODULE_DEVICE_TABLE(of, ili9322_of_match);

static struct spi_driver ili9322_driver =;
module_spi_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();