2019-05-27 09:55:01 +03:00
/* SPDX-License-Identifier: GPL-2.0-or-later */
2017-01-22 02:30:47 +03:00
/*
* MIPI Display Bus Interface ( DBI ) LCD controller support
*
* Copyright 2016 Noralf Trønnes
*/
# ifndef __LINUX_MIPI_DBI_H
# define __LINUX_MIPI_DBI_H
2019-02-25 17:42:30 +03:00
# include <linux/mutex.h>
# include <drm/drm_device.h>
# include <drm/drm_simple_kms_helper.h>
2017-01-22 02:30:47 +03:00
2019-01-15 07:36:41 +03:00
struct drm_rect ;
2017-01-22 02:30:47 +03:00
struct gpio_desc ;
2022-12-02 15:56:41 +03:00
struct iosys_map ;
2017-01-22 02:30:47 +03:00
struct regulator ;
2022-12-02 15:56:41 +03:00
struct spi_device ;
2017-01-22 02:30:47 +03:00
/**
2019-07-22 13:43:07 +03:00
* struct mipi_dbi - MIPI DBI interface
2017-01-22 02:30:47 +03:00
*/
struct mipi_dbi {
2019-07-22 13:43:07 +03:00
/**
* @ cmdlock : Command lock
*/
struct mutex cmdlock ;
/**
* @ command : Bus specific callback executing commands .
*/
int ( * command ) ( struct mipi_dbi * dbi , u8 * cmd , u8 * param , size_t num ) ;
/**
* @ read_commands : Array of read commands terminated by a zero entry .
* Reading is disabled if this is NULL .
*/
const u8 * read_commands ;
/**
* @ swap_bytes : Swap bytes in buffer before transfer
*/
bool swap_bytes ;
/**
* @ reset : Optional reset gpio
*/
struct gpio_desc * reset ;
/* Type C specific */
/**
* @ spi : SPI device
*/
struct spi_device * spi ;
/**
* @ dc : Optional D / C gpio .
*/
struct gpio_desc * dc ;
/**
* @ tx_buf9 : Buffer used for Option 1 9 - bit conversion
*/
void * tx_buf9 ;
/**
* @ tx_buf9_len : Size of tx_buf9 .
*/
size_t tx_buf9_len ;
} ;
/**
* struct mipi_dbi_dev - MIPI DBI device
*/
struct mipi_dbi_dev {
2019-02-25 17:42:30 +03:00
/**
* @ drm : DRM device
*/
struct drm_device drm ;
/**
* @ pipe : Display pipe structure
*/
struct drm_simple_display_pipe pipe ;
2019-07-19 18:59:16 +03:00
/**
* @ connector : Connector
*/
struct drm_connector connector ;
/**
* @ mode : Fixed display mode
*/
struct drm_display_mode mode ;
2019-07-22 13:43:07 +03:00
/**
* @ tx_buf : Buffer used for transfer ( copy clip rect area )
*/
2017-01-22 02:30:47 +03:00
u16 * tx_buf ;
2019-07-22 13:43:07 +03:00
/**
* @ rotation : initial rotation in degrees Counter Clock Wise
*/
2017-01-22 02:30:47 +03:00
unsigned int rotation ;
2019-07-22 13:43:07 +03:00
2020-01-15 15:45:46 +03:00
/**
* @ left_offset : Horizontal offset of the display relative to the
* controller ' s driver array
*/
unsigned int left_offset ;
/**
* @ top_offset : Vertical offset of the display relative to the
* controller ' s driver array
*/
unsigned int top_offset ;
2019-07-22 13:43:07 +03:00
/**
* @ backlight : backlight device ( optional )
*/
2017-01-22 02:30:47 +03:00
struct backlight_device * backlight ;
2019-07-22 13:43:07 +03:00
/**
2022-12-01 19:02:43 +03:00
* @ regulator : power regulator ( Vdd ) ( optional )
2019-07-22 13:43:07 +03:00
*/
2017-01-22 02:30:47 +03:00
struct regulator * regulator ;
2019-07-22 13:43:07 +03:00
2022-12-01 19:02:43 +03:00
/**
* @ io_regulator : I / O power regulator ( Vddi ) ( optional )
*/
struct regulator * io_regulator ;
2019-07-22 13:43:07 +03:00
/**
* @ dbi : MIPI DBI interface
*/
struct mipi_dbi dbi ;
2022-02-27 15:47:12 +03:00
/**
* @ driver_private : Driver private data .
* Necessary for drivers with private data since devm_drm_dev_alloc ( )
* can ' t allocate structures that embed a structure which then again
* embeds drm_device .
*/
void * driver_private ;
2017-01-22 02:30:47 +03:00
} ;
2019-07-22 13:43:07 +03:00
static inline struct mipi_dbi_dev * drm_to_mipi_dbi_dev ( struct drm_device * drm )
2017-01-22 02:30:47 +03:00
{
2019-07-22 13:43:07 +03:00
return container_of ( drm , struct mipi_dbi_dev , drm ) ;
2017-01-22 02:30:47 +03:00
}
2019-07-22 13:43:05 +03:00
int mipi_dbi_spi_init ( struct spi_device * spi , struct mipi_dbi * dbi ,
2017-08-04 01:33:45 +03:00
struct gpio_desc * dc ) ;
2019-07-22 13:43:07 +03:00
int mipi_dbi_dev_init_with_formats ( struct mipi_dbi_dev * dbidev ,
const struct drm_simple_display_pipe_funcs * funcs ,
const uint32_t * formats , unsigned int format_count ,
const struct drm_display_mode * mode ,
unsigned int rotation , size_t tx_buf_size ) ;
int mipi_dbi_dev_init ( struct mipi_dbi_dev * dbidev ,
const struct drm_simple_display_pipe_funcs * funcs ,
const struct drm_display_mode * mode , unsigned int rotation ) ;
2022-09-05 17:16:46 +03:00
enum drm_mode_status mipi_dbi_pipe_mode_valid ( struct drm_simple_display_pipe * pipe ,
const struct drm_display_mode * mode ) ;
2019-01-15 07:36:42 +03:00
void mipi_dbi_pipe_update ( struct drm_simple_display_pipe * pipe ,
struct drm_plane_state * old_state ) ;
2019-07-22 13:43:07 +03:00
void mipi_dbi_enable_flush ( struct mipi_dbi_dev * dbidev ,
2018-03-23 18:35:09 +03:00
struct drm_crtc_state * crtc_state ,
struct drm_plane_state * plan_state ) ;
2017-01-22 02:30:47 +03:00
void mipi_dbi_pipe_disable ( struct drm_simple_display_pipe * pipe ) ;
2022-12-02 15:56:42 +03:00
int mipi_dbi_pipe_begin_fb_access ( struct drm_simple_display_pipe * pipe ,
struct drm_plane_state * plane_state ) ;
void mipi_dbi_pipe_end_fb_access ( struct drm_simple_display_pipe * pipe ,
struct drm_plane_state * plane_state ) ;
void mipi_dbi_pipe_reset_plane ( struct drm_simple_display_pipe * pipe ) ;
struct drm_plane_state * mipi_dbi_pipe_duplicate_plane_state ( struct drm_simple_display_pipe * pipe ) ;
void mipi_dbi_pipe_destroy_plane_state ( struct drm_simple_display_pipe * pipe ,
struct drm_plane_state * plane_state ) ;
2019-07-22 13:43:05 +03:00
void mipi_dbi_hw_reset ( struct mipi_dbi * dbi ) ;
bool mipi_dbi_display_is_on ( struct mipi_dbi * dbi ) ;
2019-07-22 13:43:07 +03:00
int mipi_dbi_poweron_reset ( struct mipi_dbi_dev * dbidev ) ;
int mipi_dbi_poweron_conditional_reset ( struct mipi_dbi_dev * dbidev ) ;
2019-07-19 18:59:12 +03:00
2017-11-19 23:12:07 +03:00
u32 mipi_dbi_spi_cmd_max_speed ( struct spi_device * spi , size_t len ) ;
2019-07-19 18:59:12 +03:00
int mipi_dbi_spi_transfer ( struct spi_device * spi , u32 speed_hz ,
u8 bpw , const void * buf , size_t len ) ;
2017-01-22 02:30:47 +03:00
2019-07-22 13:43:05 +03:00
int mipi_dbi_command_read ( struct mipi_dbi * dbi , u8 cmd , u8 * val ) ;
int mipi_dbi_command_buf ( struct mipi_dbi * dbi , u8 cmd , u8 * data , size_t len ) ;
2020-03-16 19:42:49 +03:00
int mipi_dbi_command_stackbuf ( struct mipi_dbi * dbi , u8 cmd , const u8 * data ,
size_t len ) ;
2022-12-02 15:56:41 +03:00
int mipi_dbi_buf_copy ( void * dst , struct iosys_map * src , struct drm_framebuffer * fb ,
2019-01-15 07:36:41 +03:00
struct drm_rect * clip , bool swap ) ;
2022-12-02 15:56:41 +03:00
2017-01-22 02:30:47 +03:00
/**
* mipi_dbi_command - MIPI DCS command with optional parameter ( s )
2019-07-22 13:43:05 +03:00
* @ dbi : MIPI DBI structure
2017-01-22 02:30:47 +03:00
* @ cmd : Command
2021-01-02 00:18:17 +03:00
* @ seq : Optional parameter ( s )
2017-01-22 02:30:47 +03:00
*
* Send MIPI DCS command to the controller . Use mipi_dbi_command_read ( ) for
* get / read .
*
* Returns :
* Zero on success , negative error code on failure .
*/
2019-07-22 13:43:05 +03:00
# define mipi_dbi_command(dbi, cmd, seq...) \
2017-01-22 02:30:47 +03:00
( { \
2020-03-16 19:42:49 +03:00
const u8 d [ ] = { seq } ; \
2021-07-02 16:56:01 +03:00
struct device * dev = & ( dbi ) - > spi - > dev ; \
int ret ; \
ret = mipi_dbi_command_stackbuf ( dbi , cmd , d , ARRAY_SIZE ( d ) ) ; \
if ( ret ) \
dev_err_ratelimited ( dev , " error %d when sending command %#02x \n " , ret , cmd ) ; \
ret ; \
2017-01-22 02:30:47 +03:00
} )
# ifdef CONFIG_DEBUG_FS
2020-03-10 16:31:21 +03:00
void mipi_dbi_debugfs_init ( struct drm_minor * minor ) ;
2017-01-22 02:30:47 +03:00
# else
2021-12-21 22:37:54 +03:00
static inline void mipi_dbi_debugfs_init ( struct drm_minor * minor ) { }
2017-01-22 02:30:47 +03:00
# endif
2022-12-02 15:56:40 +03:00
/**
* DRM_MIPI_DBI_SIMPLE_DISPLAY_PIPE_FUNCS - Initializes struct drm_simple_display_pipe_funcs
* for MIPI - DBI devices
* @ enable_ : Enable - callback implementation
*
* This macro initializes struct drm_simple_display_pipe_funcs with default
* values for MIPI - DBI - based devices . The only callback that depends on the
* hardware is @ enable , for which the driver has to provide an implementation .
* MIPI - based drivers are encouraged to use this macro for initialization .
*/
# define DRM_MIPI_DBI_SIMPLE_DISPLAY_PIPE_FUNCS(enable_) \
. mode_valid = mipi_dbi_pipe_mode_valid , \
. enable = ( enable_ ) , \
. disable = mipi_dbi_pipe_disable , \
2022-12-02 15:56:42 +03:00
. update = mipi_dbi_pipe_update , \
. begin_fb_access = mipi_dbi_pipe_begin_fb_access , \
. end_fb_access = mipi_dbi_pipe_end_fb_access , \
. reset_plane = mipi_dbi_pipe_reset_plane , \
. duplicate_plane_state = mipi_dbi_pipe_duplicate_plane_state , \
. destroy_plane_state = mipi_dbi_pipe_destroy_plane_state
2022-12-02 15:56:40 +03:00
2017-01-22 02:30:47 +03:00
# endif /* __LINUX_MIPI_DBI_H */