mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
rk hdmi: coding style for upstream
This commit is contained in:
@@ -2,14 +2,14 @@ menuconfig RK_HDMI
|
||||
bool "Rockchip HDMI support"
|
||||
depends on FB_ROCKCHIP || DRM_ROCKCHIP
|
||||
select FB_MODE_HELPERS
|
||||
|
||||
|
||||
if RK_HDMI
|
||||
source "drivers/video/rockchip/hdmi/chips/Kconfig"
|
||||
endif
|
||||
|
||||
config RK_HDMI_DEBUG
|
||||
bool "Rockchip HDMI Debugging"
|
||||
bool "Rockchip HDMI Debugging"
|
||||
depends on RK_HDMI
|
||||
default n
|
||||
help
|
||||
Enableds verbose debugging the the HDMI drivers
|
||||
help
|
||||
Enableds verbose debugging the the HDMI drivers
|
||||
|
||||
@@ -14,21 +14,23 @@
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
#include <linux/earlysuspend.h>
|
||||
#endif
|
||||
#include <asm/atomic.h>
|
||||
#include <linux/atomic.h>
|
||||
#include<linux/rk_screen.h>
|
||||
#include <linux/rk_fb.h>
|
||||
|
||||
/* default HDMI output video mode */
|
||||
#define HDMI_VIDEO_DEFAULT_MODE HDMI_1280x720p_60Hz//HDMI_1920x1080p_60Hz
|
||||
#define HDMI_VIDEO_DEFAULT_MODE HDMI_1280x720p_60Hz
|
||||
|
||||
// HDMI video source
|
||||
/* HDMI video source */
|
||||
enum {
|
||||
HDMI_SOURCE_LCDC0 = 0,
|
||||
HDMI_SOURCE_LCDC1 = 1
|
||||
};
|
||||
|
||||
/* If HDMI_ENABLE, system will auto configure output mode according to EDID
|
||||
* If HDMI_DISABLE, system will output mode according to macro HDMI_VIDEO_DEFAULT_MODE
|
||||
/*
|
||||
* If HDMI_ENABLE, system will auto configure output mode according to EDID
|
||||
* If HDMI_DISABLE, system will output mode according to
|
||||
* macro HDMI_VIDEO_DEFAULT_MODE
|
||||
*/
|
||||
#define HDMI_AUTO_CONFIGURE HDMI_DISABLE
|
||||
|
||||
@@ -63,69 +65,68 @@ enum {
|
||||
/********************************************************************
|
||||
** <20>ṹ<EFBFBD><E1B9B9><EFBFBD><EFBFBD> *
|
||||
********************************************************************/
|
||||
/* HDMI video mode code according CEA-861-E*/
|
||||
enum hdmi_video_mode
|
||||
{
|
||||
/* HDMI video mode code according CEA-861-E */
|
||||
enum hdmi_video_mode {
|
||||
HDMI_640x480p_60Hz = 1,
|
||||
HDMI_720x480p_60Hz_4_3,
|
||||
HDMI_720x480p_60Hz_16_9,
|
||||
HDMI_1280x720p_60Hz,
|
||||
HDMI_1920x1080i_60Hz, //5
|
||||
HDMI_1920x1080i_60Hz, /* 5 */
|
||||
HDMI_720x480i_60Hz_4_3,
|
||||
HDMI_720x480i_60Hz_16_9,
|
||||
HDMI_720x240p_60Hz_4_3,
|
||||
HDMI_720x240p_60Hz_16_9,
|
||||
HDMI_2880x480i_60Hz_4_3, //10
|
||||
HDMI_2880x480i_60Hz_4_3, /* 10 */
|
||||
HDMI_2880x480i_60Hz_16_9,
|
||||
HDMI_2880x240p_60Hz_4_3,
|
||||
HDMI_2880x240p_60Hz_16_9,
|
||||
HDMI_1440x480p_60Hz_4_3,
|
||||
HDMI_1440x480p_60Hz_16_9, //15
|
||||
HDMI_1440x480p_60Hz_16_9, /* 15 */
|
||||
HDMI_1920x1080p_60Hz,
|
||||
HDMI_720x576p_50Hz_4_3,
|
||||
HDMI_720x576p_50Hz_16_9,
|
||||
HDMI_1280x720p_50Hz,
|
||||
HDMI_1920x1080i_50Hz, //20
|
||||
HDMI_1920x1080i_50Hz, /* 20 */
|
||||
HDMI_720x576i_50Hz_4_3,
|
||||
HDMI_720x576i_50Hz_16_9,
|
||||
HDMI_720x288p_50Hz_4_3,
|
||||
HDMI_720x288p_50Hz_16_9,
|
||||
HDMI_2880x576i_50Hz_4_3, //25
|
||||
HDMI_2880x576i_50Hz_4_3, /* 25 */
|
||||
HDMI_2880x576i_50Hz_16_9,
|
||||
HDMI_2880x288p_50Hz_4_3,
|
||||
HDMI_2880x288p_50Hz_16_9,
|
||||
HDMI_1440x576p_50Hz_4_3,
|
||||
HDMI_1440x576p_50Hz_16_9, //30
|
||||
HDMI_1440x576p_50Hz_16_9, /* 30 */
|
||||
HDMI_1920x1080p_50Hz,
|
||||
HDMI_1920x1080p_24Hz,
|
||||
HDMI_1920x1080p_25Hz,
|
||||
HDMI_1920x1080p_30Hz,
|
||||
HDMI_2880x480p_60Hz_4_3, //35
|
||||
HDMI_2880x480p_60Hz_4_3, /* 35 */
|
||||
HDMI_2880x480p_60Hz_16_9,
|
||||
HDMI_2880x576p_50Hz_4_3,
|
||||
HDMI_2880x576p_50Hz_16_9,
|
||||
HDMI_1920x1080i_50Hz_2, // V Line 1250 total
|
||||
HDMI_1920x1080i_100Hz, //40
|
||||
HDMI_1920x1080i_50Hz_2, /* V Line 1250 total */
|
||||
HDMI_1920x1080i_100Hz, /* 40 */
|
||||
HDMI_1280x720p_100Hz,
|
||||
HDMI_720x576p_100Hz_4_3,
|
||||
HDMI_720x576p_100Hz_16_9,
|
||||
HDMI_720x576i_100Hz_4_3,
|
||||
HDMI_720x576i_100Hz_16_9, //45
|
||||
HDMI_720x576i_100Hz_16_9, /* 45 */
|
||||
HDMI_1920x1080i_120Hz,
|
||||
HDMI_1280x720p_120Hz,
|
||||
HDMI_720x480p_120Hz_4_3,
|
||||
HDMI_720x480p_120Hz_16_9,
|
||||
HDMI_720x480i_120Hz_4_3, //50
|
||||
HDMI_720x480p_120Hz_16_9,
|
||||
HDMI_720x480i_120Hz_4_3, /* 50 */
|
||||
HDMI_720x480i_120Hz_16_9,
|
||||
HDMI_720x576p_200Hz_4_3,
|
||||
HDMI_720x576p_200Hz_16_9,
|
||||
HDMI_720x576i_200Hz_4_3,
|
||||
HDMI_720x576i_200Hz_16_9, //55
|
||||
HDMI_720x576i_200Hz_16_9, /* 55 */
|
||||
HDMI_720x480p_240Hz_4_3,
|
||||
HDMI_720x480p_240Hz_16_9,
|
||||
HDMI_720x480p_240Hz_16_9,
|
||||
HDMI_720x480i_240Hz_4_3,
|
||||
HDMI_720x480i_240Hz_16_9,
|
||||
HDMI_1280x720p_24Hz, //60
|
||||
HDMI_1280x720p_24Hz, /* 60 */
|
||||
HDMI_1280x720p_25Hz,
|
||||
HDMI_1280x720p_30Hz,
|
||||
HDMI_1920x1080p_120Hz,
|
||||
@@ -139,7 +140,7 @@ enum {
|
||||
HDMI_COLOR_YCbCr444
|
||||
};
|
||||
|
||||
/*HDMI Video Color Depth*/
|
||||
/* HDMI Video Color Depth */
|
||||
enum {
|
||||
HDMI_COLOR_DEPTH_8BIT = 0x1,
|
||||
HDMI_COLOR_DEPTH_10BIT = 0x2,
|
||||
@@ -148,17 +149,16 @@ enum {
|
||||
};
|
||||
|
||||
/* HDMI Audio type */
|
||||
enum hdmi_audio_type
|
||||
{
|
||||
enum hdmi_audio_type {
|
||||
HDMI_AUDIO_LPCM = 1,
|
||||
HDMI_AUDIO_AC3,
|
||||
HDMI_AUDIO_MPEG1,
|
||||
HDMI_AUDIO_MP3,
|
||||
HDMI_AUDIO_MPEG2,
|
||||
HDMI_AUDIO_AAC_LC, //AAC
|
||||
HDMI_AUDIO_AAC_LC, /* AAC */
|
||||
HDMI_AUDIO_DTS,
|
||||
HDMI_AUDIO_ATARC,
|
||||
HDMI_AUDIO_DSD, //One bit Audio
|
||||
HDMI_AUDIO_DSD, /* One bit Audio */
|
||||
HDMI_AUDIO_E_AC3,
|
||||
HDMI_AUDIO_DTS_HD,
|
||||
HDMI_AUDIO_MLP,
|
||||
@@ -168,11 +168,11 @@ enum hdmi_audio_type
|
||||
|
||||
/* I2S Fs */
|
||||
enum hdmi_audio_fs {
|
||||
HDMI_AUDIO_FS_32000 = 0x1,
|
||||
HDMI_AUDIO_FS_44100 = 0x2,
|
||||
HDMI_AUDIO_FS_48000 = 0x4,
|
||||
HDMI_AUDIO_FS_88200 = 0x8,
|
||||
HDMI_AUDIO_FS_96000 = 0x10,
|
||||
HDMI_AUDIO_FS_32000 = 0x1,
|
||||
HDMI_AUDIO_FS_44100 = 0x2,
|
||||
HDMI_AUDIO_FS_48000 = 0x4,
|
||||
HDMI_AUDIO_FS_88200 = 0x8,
|
||||
HDMI_AUDIO_FS_96000 = 0x10,
|
||||
HDMI_AUDIO_FS_176400 = 0x20,
|
||||
HDMI_AUDIO_FS_192000 = 0x40
|
||||
};
|
||||
@@ -187,8 +187,8 @@ enum hdmi_audio_word_length {
|
||||
/* EDID block size */
|
||||
#define HDMI_EDID_BLOCK_SIZE 128
|
||||
|
||||
// HDMI state machine
|
||||
enum hdmi_state{
|
||||
/* HDMI state machine */
|
||||
enum hdmi_state {
|
||||
HDMI_SLEEP = 0,
|
||||
HDMI_INITIAL,
|
||||
WAIT_HOTPLUG,
|
||||
@@ -200,7 +200,7 @@ enum hdmi_state{
|
||||
PLAY_BACK,
|
||||
};
|
||||
|
||||
// HDMI configuration command
|
||||
/* HDMI configuration command */
|
||||
enum hdmi_change {
|
||||
HDMI_CONFIG_NONE = 0,
|
||||
HDMI_CONFIG_VIDEO,
|
||||
@@ -212,7 +212,7 @@ enum hdmi_change {
|
||||
HDMI_CONFIG_DISPLAY
|
||||
};
|
||||
|
||||
// HDMI Hotplug status
|
||||
/* HDMI Hotplug status */
|
||||
enum {
|
||||
HDMI_HPD_REMOVED = 0,
|
||||
HDMI_HPD_INSERT,
|
||||
@@ -220,13 +220,12 @@ enum {
|
||||
};
|
||||
|
||||
/* HDMI STATUS */
|
||||
#define HDMI_DISABLE 0
|
||||
#define HDMI_DISABLE 0
|
||||
#define HDMI_ENABLE 1
|
||||
#define HDMI_UNKOWN 0xFF
|
||||
|
||||
/* HDMI Error Code */
|
||||
enum hdmi_errorcode
|
||||
{
|
||||
enum hdmi_errorcode {
|
||||
HDMI_ERROR_SUCESS = 0,
|
||||
HDMI_ERROR_FALSE,
|
||||
HDMI_ERROR_I2C,
|
||||
@@ -235,133 +234,150 @@ enum hdmi_errorcode
|
||||
|
||||
/* HDMI audio parameters */
|
||||
struct hdmi_audio {
|
||||
u32 type; //Audio type
|
||||
u32 channel; //Audio channel number
|
||||
u32 rate; //Audio sampling rate
|
||||
u32 word_length; //Audio data word length
|
||||
u32 type; /* Audio type */
|
||||
u32 channel; /* Audio channel number */
|
||||
u32 rate; /* Audio sampling rate */
|
||||
u32 word_length; /* Audio data word length */
|
||||
};
|
||||
|
||||
struct hdmi_edid {
|
||||
unsigned char sink_hdmi; //HDMI display device flag
|
||||
unsigned char ycbcr444; //Display device support YCbCr444
|
||||
unsigned char ycbcr422; //Display device support YCbCr422
|
||||
unsigned char deepcolor; //bit3:DC_48bit; bit2:DC_36bit; bit1:DC_30bit; bit0:DC_Y444;
|
||||
unsigned char sink_hdmi; /* HDMI display device flag */
|
||||
unsigned char ycbcr444; /* Display device support YCbCr444 */
|
||||
unsigned char ycbcr422; /* Display device support YCbCr422 */
|
||||
unsigned char deepcolor; /* bit3:DC_48bit; bit2:DC_36bit;
|
||||
* bit1:DC_30bit; bit0:DC_Y444;
|
||||
*/
|
||||
unsigned char latency_fields_present;
|
||||
unsigned char i_latency_fields_present;
|
||||
unsigned char video_latency;
|
||||
unsigned char audio_latency;
|
||||
unsigned char interlaced_video_latency;
|
||||
unsigned char interlaced_audio_latency;
|
||||
unsigned char video_present; //have additional video format abount 4k and/or 3d
|
||||
unsigned char support_3d; //3D format support
|
||||
unsigned int maxtmdsclock; //max tmds clock freq support
|
||||
struct fb_monspecs *specs; //Device spec
|
||||
struct list_head modelist; //Device supported display mode list
|
||||
struct hdmi_audio *audio; //Device supported audio info
|
||||
int audio_num; //Device supported audio type number
|
||||
int base_audio_support; //Device supported base audio
|
||||
unsigned char video_present; /* have additional video format
|
||||
* abount 4k and/or 3d
|
||||
*/
|
||||
unsigned char support_3d; /* 3D format support */
|
||||
unsigned int maxtmdsclock; /* max tmds clock freq support */
|
||||
struct fb_monspecs *specs; /* Device spec */
|
||||
struct list_head modelist; /* Device supported display mode list */
|
||||
struct hdmi_audio *audio; /* Device supported audio info */
|
||||
int audio_num; /* Device supported audio type number */
|
||||
int base_audio_support; /* Device supported base audio */
|
||||
};
|
||||
|
||||
/* RK HDMI Video Configure Parameters */
|
||||
struct hdmi_video_para {
|
||||
int vic;
|
||||
int input_mode; //input video data interface
|
||||
int input_color; //input video color mode
|
||||
int output_mode; //output hdmi or dvi
|
||||
int output_color; //output video color mode
|
||||
unsigned char format_3d; //output 3d format
|
||||
unsigned char color_depth; //color depth: 8bit; 10bit; 12bit; 16bit;
|
||||
unsigned char pixel_repet; //pixel repettion
|
||||
unsigned char pixel_pack_phase; //pixel packing default phase
|
||||
unsigned char color_limit_range;//quantization range 0: full range(0~255) 1:limit range(16~235)
|
||||
int input_mode; /* input video data interface */
|
||||
int input_color; /* input video color mode */
|
||||
int output_mode; /* output hdmi or dvi */
|
||||
int output_color; /* output video color mode */
|
||||
unsigned char format_3d; /* output 3d format */
|
||||
unsigned char color_depth; /* color depth: 8bit; 10bit;
|
||||
* 12bit; 16bit;
|
||||
*/
|
||||
unsigned char pixel_repet; /* pixel repettion */
|
||||
unsigned char pixel_pack_phase; /* pixel packing default phase */
|
||||
unsigned char color_limit_range; /* quantization range
|
||||
* 0: full range(0~255)
|
||||
* 1:limit range(16~235)
|
||||
*/
|
||||
};
|
||||
|
||||
struct hdmi {
|
||||
struct device *dev;
|
||||
int id;
|
||||
int irq;
|
||||
struct device *dev;
|
||||
int id;
|
||||
int irq;
|
||||
struct rk_lcdc_driver *lcdc;
|
||||
|
||||
#ifdef CONFIG_SWITCH
|
||||
struct switch_dev switch_hdmi;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_SWITCH
|
||||
struct switch_dev switch_hdmi;
|
||||
#endif
|
||||
|
||||
struct workqueue_struct *workqueue;
|
||||
struct delayed_work delay_work;
|
||||
|
||||
spinlock_t irq_lock;
|
||||
|
||||
spinlock_t irq_lock;
|
||||
struct mutex enable_mutex;
|
||||
|
||||
|
||||
int wait;
|
||||
struct completion complete;
|
||||
|
||||
struct completion complete;
|
||||
|
||||
int suspend;
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
struct early_suspend early_suspend;
|
||||
struct early_suspend early_suspend;
|
||||
#endif
|
||||
|
||||
|
||||
struct hdmi_edid edid;
|
||||
int enable; // Enable HDMI output or not
|
||||
int vic; // HDMI output video mode code
|
||||
struct hdmi_audio audio; // HDMI output audio type.
|
||||
|
||||
int pwr_mode; // power mode
|
||||
int hotplug; // hot plug status
|
||||
int state; // hdmi state machine status
|
||||
int autoconfig; // if true, auto config hdmi output mode according to EDID.
|
||||
int command; // HDMI configuration command
|
||||
int display; // HDMI display status
|
||||
int xscale; // x direction scale value
|
||||
int yscale; // y directoon scale value
|
||||
int tmdsclk; // TDMS Clock frequency
|
||||
int pixclock; //Pixel Clcok frequency
|
||||
int enable; /* Enable HDMI output or not */
|
||||
int vic; /* HDMI output video mode code */
|
||||
struct hdmi_audio audio; /* HDMI output audio type */
|
||||
|
||||
int pwr_mode; /* power mode */
|
||||
int hotplug; /* hot plug status */
|
||||
int state; /* hdmi state machine status */
|
||||
int autoconfig; /* if true, auto config hdmi output mode
|
||||
* according to EDID
|
||||
*/
|
||||
int command; /* HDMI configuration command */
|
||||
int display; /* HDMI display status */
|
||||
int xscale; /* x direction scale value */
|
||||
int yscale; /* y directoon scale value */
|
||||
int tmdsclk; /* TDMS Clock frequency */
|
||||
int pixclock; /* Pixel Clcok frequency */
|
||||
|
||||
struct list_head pwrlist_head;
|
||||
|
||||
int (*insert)(struct hdmi *hdmi);
|
||||
int (*remove)(struct hdmi *hdmi);
|
||||
void (*control_output)(struct hdmi *hdmi, int enable);
|
||||
int (*config_video)(struct hdmi *hdmi, struct hdmi_video_para *vpara);
|
||||
int (*config_audio)(struct hdmi *hdmi, struct hdmi_audio *audio);
|
||||
int (*detect_hotplug)(struct hdmi *hdmi);
|
||||
// call back for edid
|
||||
int (*read_edid)(struct hdmi *hdmi, int block, unsigned char *buff);
|
||||
int (*set_vif)(struct hdmi *hdmi, struct rk_screen *screen, bool connect);
|
||||
|
||||
// call back for hdcp operatoion
|
||||
void (*hdcp_cb)(void);
|
||||
void (*hdcp_irq_cb)(int);
|
||||
int (*hdcp_power_on_cb)(void);
|
||||
void (*hdcp_power_off_cb)(void);
|
||||
int (*insert) (struct hdmi *hdmi);
|
||||
int (*remove) (struct hdmi *hdmi);
|
||||
void (*control_output) (struct hdmi *hdmi, int enable);
|
||||
int (*config_video) (struct hdmi *hdmi,
|
||||
struct hdmi_video_para *vpara);
|
||||
int (*config_audio) (struct hdmi *hdmi, struct hdmi_audio *audio);
|
||||
int (*detect_hotplug) (struct hdmi *hdmi);
|
||||
/* call back for edid */
|
||||
int (*read_edid) (struct hdmi *hdmi, int block, unsigned char *buff);
|
||||
int (*set_vif) (struct hdmi *hdmi, struct rk_screen *screen,
|
||||
bool connect);
|
||||
|
||||
/* call back for hdcp operatoion */
|
||||
void (*hdcp_cb) (void);
|
||||
void (*hdcp_irq_cb) (int);
|
||||
int (*hdcp_power_on_cb) (void);
|
||||
void (*hdcp_power_off_cb) (void);
|
||||
};
|
||||
|
||||
#define hdmi_err(dev, format, arg...) \
|
||||
dev_printk(KERN_ERR , dev , format , ## arg)
|
||||
dev_err(dev , format , ## arg)
|
||||
|
||||
#ifdef HDMI_DEBUG
|
||||
#define hdmi_dbg(dev, format, arg...) \
|
||||
dev_printk(KERN_INFO , dev , format , ## arg)
|
||||
dev_info(dev , format , ## arg)
|
||||
#else
|
||||
#define hdmi_dbg(dev, format, arg...)
|
||||
#define hdmi_dbg(dev, format, arg...)
|
||||
#endif
|
||||
|
||||
extern int hdmi_drv_register(struct hdmi *hdmi_drv);
|
||||
extern int hdmi_get_hotplug(void);
|
||||
extern int hdmi_set_info(struct rk_screen *screen, unsigned int vic);
|
||||
extern void hdmi_init_lcdc(struct rk_screen *screen, struct rk29lcd_info *lcd_info);
|
||||
extern void hdmi_init_lcdc(struct rk_screen *screen,
|
||||
struct rk29lcd_info *lcd_info);
|
||||
extern int hdmi_sys_init(struct hdmi *hdmi_drv);
|
||||
extern int hdmi_sys_parse_edid(struct hdmi* hdmi_drv);
|
||||
extern int hdmi_sys_parse_edid(struct hdmi *hdmi_drv);
|
||||
extern const char *hdmi_get_video_mode_name(unsigned char vic);
|
||||
extern int hdmi_videomode_to_vic(struct fb_videomode *vmode);
|
||||
extern const struct fb_videomode* hdmi_vic_to_videomode(int vic);
|
||||
extern int hdmi_add_videomode(const struct fb_videomode *mode, struct list_head *head);
|
||||
extern struct hdmi_video_timing * hdmi_find_mode(int vic);
|
||||
extern int hdmi_find_best_mode(struct hdmi* hdmi_drv, int vic);
|
||||
extern const struct fb_videomode *hdmi_vic_to_videomode(int vic);
|
||||
extern int hdmi_add_videomode(const struct fb_videomode *mode,
|
||||
struct list_head *head);
|
||||
extern struct hdmi_video_timing *hdmi_find_mode(int vic);
|
||||
extern int hdmi_find_best_mode(struct hdmi *hdmi_drv, int vic);
|
||||
extern int hdmi_ouputmode_select(struct hdmi *hdmi_drv, int edid_ok);
|
||||
extern int hdmi_switch_fb(struct hdmi *hdmi_drv, int vic);
|
||||
extern int hdmi_init_video_para(struct hdmi *hdmi_drv, struct hdmi_video_para *video);
|
||||
extern int hdmi_init_video_para(struct hdmi *hdmi_drv,
|
||||
struct hdmi_video_para *video);
|
||||
extern void hdmi_work(struct work_struct *work);
|
||||
extern void hdmi_register_display_sysfs(struct hdmi *hdmi_drv, struct device *parent);
|
||||
extern void hdmi_register_display_sysfs(struct hdmi *hdmi_drv,
|
||||
struct device *parent);
|
||||
extern void hdmi_unregister_display_sysfs(struct hdmi *hdmi_drv);
|
||||
|
||||
int rk_hdmi_parse_dt(struct hdmi *hdmi_drv);
|
||||
|
||||
@@ -1,208 +1,211 @@
|
||||
#include "rk_hdmi.h"
|
||||
#include "../../edid.h"
|
||||
|
||||
#define hdmi_edid_error(fmt, ...) \
|
||||
printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
|
||||
|
||||
#if 0
|
||||
#define hdmi_edid_debug(fmt, ...) \
|
||||
printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
|
||||
#else
|
||||
#define hdmi_edid_debug(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef enum HDMI_EDID_ERRORCODE
|
||||
{
|
||||
E_HDMI_EDID_SUCCESS = 0,
|
||||
E_HDMI_EDID_PARAM,
|
||||
E_HDMI_EDID_HEAD,
|
||||
E_HDMI_EDID_CHECKSUM,
|
||||
E_HDMI_EDID_VERSION,
|
||||
E_HDMI_EDID_UNKOWNDATA,
|
||||
E_HDMI_EDID_NOMEMORY
|
||||
}HDMI_EDID_ErrorCode;
|
||||
|
||||
static const unsigned int double_aspect_vic[] = {3, 7, 9, 11, 13, 15, 18, 22, 24, 26, 28, 30, 36, 38, 43, 45, 49, 51, 53, 55, 57, 59};
|
||||
static int hdmi_edid_checksum(unsigned char *buf)
|
||||
{
|
||||
int i;
|
||||
int checksum = 0;
|
||||
|
||||
for(i = 0; i < HDMI_EDID_BLOCK_SIZE; i++)
|
||||
checksum += buf[i];
|
||||
|
||||
checksum &= 0xff;
|
||||
|
||||
if(checksum == 0)
|
||||
return E_HDMI_EDID_SUCCESS;
|
||||
else
|
||||
return E_HDMI_EDID_CHECKSUM;
|
||||
}
|
||||
|
||||
/*
|
||||
@Des Parse Detail Timing Descriptor.
|
||||
@Param buf : pointer to DTD data.
|
||||
@Param pvic: VIC of DTD descripted.
|
||||
*/
|
||||
static int hdmi_edid_parse_dtd(unsigned char *block, struct fb_videomode *mode)
|
||||
{
|
||||
mode->xres = H_ACTIVE;
|
||||
mode->yres = V_ACTIVE;
|
||||
mode->pixclock = PIXEL_CLOCK;
|
||||
// mode->pixclock /= 1000;
|
||||
// mode->pixclock = KHZ2PICOS(mode->pixclock);
|
||||
mode->right_margin = H_SYNC_OFFSET;
|
||||
mode->left_margin = (H_ACTIVE + H_BLANKING) -
|
||||
(H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH);
|
||||
mode->upper_margin = V_BLANKING - V_SYNC_OFFSET -
|
||||
V_SYNC_WIDTH;
|
||||
mode->lower_margin = V_SYNC_OFFSET;
|
||||
mode->hsync_len = H_SYNC_WIDTH;
|
||||
mode->vsync_len = V_SYNC_WIDTH;
|
||||
if (HSYNC_POSITIVE)
|
||||
mode->sync |= FB_SYNC_HOR_HIGH_ACT;
|
||||
if (VSYNC_POSITIVE)
|
||||
mode->sync |= FB_SYNC_VERT_HIGH_ACT;
|
||||
mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) *
|
||||
(V_ACTIVE + V_BLANKING));
|
||||
if (INTERLACED) {
|
||||
mode->yres *= 2;
|
||||
mode->upper_margin *= 2;
|
||||
mode->lower_margin *= 2;
|
||||
mode->vsync_len *= 2;
|
||||
mode->vmode |= FB_VMODE_INTERLACED;
|
||||
}
|
||||
mode->flag = FB_MODE_IS_DETAILED;
|
||||
|
||||
hdmi_edid_debug("<<<<<<<<Detailed Time>>>>>>>>>\n");
|
||||
hdmi_edid_debug("%d KHz Refresh %d Hz", PIXEL_CLOCK/1000, mode->refresh);
|
||||
hdmi_edid_debug("%d %d %d %d ", H_ACTIVE, H_ACTIVE + H_SYNC_OFFSET,
|
||||
H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH, H_ACTIVE + H_BLANKING);
|
||||
hdmi_edid_debug("%d %d %d %d ", V_ACTIVE, V_ACTIVE + V_SYNC_OFFSET,
|
||||
V_ACTIVE + V_SYNC_OFFSET + V_SYNC_WIDTH, V_ACTIVE + V_BLANKING);
|
||||
hdmi_edid_debug("%sHSync %sVSync\n\n", (HSYNC_POSITIVE) ? "+" : "-",
|
||||
(VSYNC_POSITIVE) ? "+" : "-");
|
||||
return E_HDMI_EDID_SUCCESS;
|
||||
}
|
||||
|
||||
static int hdmi_edid_parse_base(unsigned char *buf, int *extend_num, struct hdmi_edid *pedid)
|
||||
{
|
||||
int rc, i;
|
||||
|
||||
if(buf == NULL || extend_num == NULL)
|
||||
return E_HDMI_EDID_PARAM;
|
||||
|
||||
#ifdef DEBUG
|
||||
for(i = 0; i < HDMI_EDID_BLOCK_SIZE; i++)
|
||||
{
|
||||
hdmi_edid_debug("%02x ", buf[i]&0xff);
|
||||
if((i+1) % 16 == 0)
|
||||
hdmi_edid_debug("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check first 8 byte to ensure it is an edid base block.
|
||||
if( buf[0] != 0x00 ||
|
||||
buf[1] != 0xFF ||
|
||||
buf[2] != 0xFF ||
|
||||
buf[3] != 0xFF ||
|
||||
buf[4] != 0xFF ||
|
||||
buf[5] != 0xFF ||
|
||||
buf[6] != 0xFF ||
|
||||
buf[7] != 0x00)
|
||||
{
|
||||
hdmi_edid_error("[EDID] check header error\n");
|
||||
return E_HDMI_EDID_HEAD;
|
||||
}
|
||||
|
||||
*extend_num = buf[0x7e];
|
||||
#ifdef DEBUG
|
||||
hdmi_edid_debug("[EDID] extend block num is %d\n", buf[0x7e]);
|
||||
#endif
|
||||
|
||||
// Checksum
|
||||
rc = hdmi_edid_checksum(buf);
|
||||
if( rc != E_HDMI_EDID_SUCCESS)
|
||||
{
|
||||
hdmi_edid_error("[EDID] base block checksum error\n");
|
||||
return E_HDMI_EDID_CHECKSUM;
|
||||
}
|
||||
|
||||
pedid->specs = kzalloc(sizeof(struct fb_monspecs), GFP_KERNEL);
|
||||
if(pedid->specs == NULL)
|
||||
return E_HDMI_EDID_NOMEMORY;
|
||||
|
||||
fb_edid_to_monspecs(buf, pedid->specs);
|
||||
|
||||
return E_HDMI_EDID_SUCCESS;
|
||||
}
|
||||
|
||||
// Parse CEA Short Video Descriptor
|
||||
static int hdmi_edid_get_cea_svd(unsigned char *buf, struct hdmi_edid *pedid)
|
||||
{
|
||||
const struct fb_videomode *mode;
|
||||
int count, i, j, vic;
|
||||
|
||||
count = buf[0] & 0x1F;
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
hdmi_edid_debug("[EDID-CEA] %02x VID %d native %d\n", buf[1 + i], buf[1 + i] & 0x7f, buf[1 + i] >> 7);
|
||||
#include "rk_hdmi.h"
|
||||
#include "../../edid.h"
|
||||
|
||||
#define hdmi_edid_error(fmt, ...) \
|
||||
printk(pr_fmt(fmt), ##__VA_ARGS__)
|
||||
|
||||
#if 0
|
||||
#define hdmi_edid_debug(fmt, ...) \
|
||||
printk(pr_fmt(fmt), ##__VA_ARGS__)
|
||||
#else
|
||||
#define hdmi_edid_debug(fmt, ...)
|
||||
#endif
|
||||
|
||||
enum HDMI_EDID_ERRORCODE {
|
||||
E_HDMI_EDID_SUCCESS = 0,
|
||||
E_HDMI_EDID_PARAM,
|
||||
E_HDMI_EDID_HEAD,
|
||||
E_HDMI_EDID_CHECKSUM,
|
||||
E_HDMI_EDID_VERSION,
|
||||
E_HDMI_EDID_UNKOWNDATA,
|
||||
E_HDMI_EDID_NOMEMORY
|
||||
};
|
||||
|
||||
static const unsigned int double_aspect_vic[] = {
|
||||
3, 7, 9, 11, 13, 15, 18, 22, 24, 26, 28, 30,
|
||||
36, 38, 43, 45, 49, 51, 53, 55, 57, 59
|
||||
};
|
||||
|
||||
static int hdmi_edid_checksum(unsigned char *buf)
|
||||
{
|
||||
int i;
|
||||
int checksum = 0;
|
||||
|
||||
for (i = 0; i < HDMI_EDID_BLOCK_SIZE; i++)
|
||||
checksum += buf[i];
|
||||
|
||||
checksum &= 0xff;
|
||||
|
||||
if (checksum == 0)
|
||||
return E_HDMI_EDID_SUCCESS;
|
||||
else
|
||||
return E_HDMI_EDID_CHECKSUM;
|
||||
}
|
||||
|
||||
/*
|
||||
* @Des Parse Detail Timing Descriptor.
|
||||
* @Param buf : pointer to DTD data.
|
||||
* @Param pvic: VIC of DTD descripted.
|
||||
*/
|
||||
static int hdmi_edid_parse_dtd(unsigned char *block, struct fb_videomode *mode)
|
||||
{
|
||||
mode->xres = H_ACTIVE;
|
||||
mode->yres = V_ACTIVE;
|
||||
mode->pixclock = PIXEL_CLOCK;
|
||||
/*
|
||||
mode->pixclock /= 1000;
|
||||
mode->pixclock = KHZ2PICOS(mode->pixclock);
|
||||
*/
|
||||
mode->right_margin = H_SYNC_OFFSET;
|
||||
mode->left_margin = (H_ACTIVE + H_BLANKING) -
|
||||
(H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH);
|
||||
mode->upper_margin = V_BLANKING - V_SYNC_OFFSET -
|
||||
V_SYNC_WIDTH;
|
||||
mode->lower_margin = V_SYNC_OFFSET;
|
||||
mode->hsync_len = H_SYNC_WIDTH;
|
||||
mode->vsync_len = V_SYNC_WIDTH;
|
||||
if (HSYNC_POSITIVE)
|
||||
mode->sync |= FB_SYNC_HOR_HIGH_ACT;
|
||||
if (VSYNC_POSITIVE)
|
||||
mode->sync |= FB_SYNC_VERT_HIGH_ACT;
|
||||
mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) *
|
||||
(V_ACTIVE + V_BLANKING));
|
||||
if (INTERLACED) {
|
||||
mode->yres *= 2;
|
||||
mode->upper_margin *= 2;
|
||||
mode->lower_margin *= 2;
|
||||
mode->vsync_len *= 2;
|
||||
mode->vmode |= FB_VMODE_INTERLACED;
|
||||
}
|
||||
mode->flag = FB_MODE_IS_DETAILED;
|
||||
|
||||
hdmi_edid_debug("<<<<<<<<Detailed Time>>>>>>>>>\n");
|
||||
hdmi_edid_debug("%d KHz Refresh %d Hz", PIXEL_CLOCK/1000,
|
||||
mode->refresh);
|
||||
hdmi_edid_debug("%d %d %d %d ", H_ACTIVE, H_ACTIVE + H_SYNC_OFFSET,
|
||||
H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH, H_ACTIVE + H_BLANKING);
|
||||
hdmi_edid_debug("%d %d %d %d ", V_ACTIVE, V_ACTIVE + V_SYNC_OFFSET,
|
||||
V_ACTIVE + V_SYNC_OFFSET + V_SYNC_WIDTH, V_ACTIVE + V_BLANKING);
|
||||
hdmi_edid_debug("%sHSync %sVSync\n\n", (HSYNC_POSITIVE) ? "+" : "-",
|
||||
(VSYNC_POSITIVE) ? "+" : "-");
|
||||
return E_HDMI_EDID_SUCCESS;
|
||||
}
|
||||
|
||||
static int hdmi_edid_parse_base(unsigned char *buf, int *extend_num,
|
||||
struct hdmi_edid *pedid)
|
||||
{
|
||||
int rc, i;
|
||||
|
||||
if (buf == NULL || extend_num == NULL)
|
||||
return E_HDMI_EDID_PARAM;
|
||||
|
||||
#ifdef DEBUG
|
||||
for (i = 0; i < HDMI_EDID_BLOCK_SIZE; i++) {
|
||||
hdmi_edid_debug("%02x ", buf[i]&0xff);
|
||||
if ((i+1) % 16 == 0)
|
||||
hdmi_edid_debug("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check first 8 byte to ensure it is an edid base block. */
|
||||
if (buf[0] != 0x00 ||
|
||||
buf[1] != 0xFF ||
|
||||
buf[2] != 0xFF ||
|
||||
buf[3] != 0xFF ||
|
||||
buf[4] != 0xFF ||
|
||||
buf[5] != 0xFF ||
|
||||
buf[6] != 0xFF ||
|
||||
buf[7] != 0x00) {
|
||||
hdmi_edid_error("[EDID] check header error\n");
|
||||
return E_HDMI_EDID_HEAD;
|
||||
}
|
||||
|
||||
*extend_num = buf[0x7e];
|
||||
#ifdef DEBUG
|
||||
hdmi_edid_debug("[EDID] extend block num is %d\n", buf[0x7e]);
|
||||
#endif
|
||||
|
||||
/* Checksum */
|
||||
rc = hdmi_edid_checksum(buf);
|
||||
if (rc != E_HDMI_EDID_SUCCESS) {
|
||||
hdmi_edid_error("[EDID] base block checksum error\n");
|
||||
return E_HDMI_EDID_CHECKSUM;
|
||||
}
|
||||
|
||||
pedid->specs = kzalloc(sizeof(struct fb_monspecs), GFP_KERNEL);
|
||||
if (pedid->specs == NULL)
|
||||
return E_HDMI_EDID_NOMEMORY;
|
||||
|
||||
fb_edid_to_monspecs(buf, pedid->specs);
|
||||
|
||||
return E_HDMI_EDID_SUCCESS;
|
||||
}
|
||||
|
||||
/* Parse CEA Short Video Descriptor */
|
||||
static int hdmi_edid_get_cea_svd(unsigned char *buf, struct hdmi_edid *pedid)
|
||||
{
|
||||
const struct fb_videomode *mode;
|
||||
int count, i, j, vic;
|
||||
|
||||
count = buf[0] & 0x1F;
|
||||
for (i = 0; i < count; i++) {
|
||||
hdmi_edid_debug("[EDID-CEA] %02x VID %d native %d\n",
|
||||
buf[1 + i],
|
||||
buf[1 + i] & 0x7f,
|
||||
buf[1 + i] >> 7);
|
||||
#ifndef HDMI_VERSION_2
|
||||
vic = buf[1 + i] & 0x7f;
|
||||
vic = buf[1 + i] & 0x7f;
|
||||
#else
|
||||
vic = buf[1 + i] & 0xff;
|
||||
#endif
|
||||
for(j = 0; j < ARRAY_SIZE(double_aspect_vic); j++)
|
||||
{
|
||||
if(vic == double_aspect_vic[j])
|
||||
{
|
||||
vic--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(vic)
|
||||
{
|
||||
mode = hdmi_vic_to_videomode(vic);
|
||||
if(mode)
|
||||
{
|
||||
hdmi_add_videomode(mode, &pedid->modelist);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Parse CEA Short Audio Descriptor
|
||||
static int hdmi_edid_parse_cea_sad(unsigned char *buf, struct hdmi_edid *pedid)
|
||||
{
|
||||
int i, count;
|
||||
|
||||
count = buf[0] & 0x1F;
|
||||
pedid->audio = kmalloc((count/3)*sizeof(struct hdmi_audio), GFP_KERNEL);
|
||||
if(pedid->audio == NULL)
|
||||
return E_HDMI_EDID_NOMEMORY;
|
||||
pedid->audio_num = count/3;
|
||||
for(i = 0; i < pedid->audio_num; i++)
|
||||
{
|
||||
pedid->audio[i].type = (buf[1 + i*3] >> 3) & 0x0F;
|
||||
pedid->audio[i].channel = (buf[1 + i*3] & 0x07) + 1;
|
||||
pedid->audio[i].rate = buf[1 + i*3 + 1];
|
||||
if(pedid->audio[i].type == HDMI_AUDIO_LPCM)//LPCM
|
||||
{
|
||||
pedid->audio[i].word_length = buf[1 + i*3 + 2];
|
||||
}
|
||||
// printk("[EDID-CEA] type %d channel %d rate %d word length %d\n",
|
||||
// pedid->audio[i].type, pedid->audio[i].channel, pedid->audio[i].rate, pedid->audio[i].word_length);
|
||||
}
|
||||
return E_HDMI_EDID_SUCCESS;
|
||||
}
|
||||
for (j = 0; j < ARRAY_SIZE(double_aspect_vic); j++) {
|
||||
if (vic == double_aspect_vic[j]) {
|
||||
vic--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (vic) {
|
||||
mode = hdmi_vic_to_videomode(vic);
|
||||
if (mode)
|
||||
hdmi_add_videomode(mode, &pedid->modelist);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Parse CEA Vendor Specific Data Block
|
||||
static int hdmi_edid_parse_cea_sdb(unsigned char * buf, struct hdmi_edid *pedid)
|
||||
/* Parse CEA Short Audio Descriptor */
|
||||
static int hdmi_edid_parse_cea_sad(unsigned char *buf, struct hdmi_edid *pedid)
|
||||
{
|
||||
int i, count;
|
||||
|
||||
count = buf[0] & 0x1F;
|
||||
pedid->audio = kmalloc((count / 3) * sizeof(struct hdmi_audio),
|
||||
GFP_KERNEL);
|
||||
if (pedid->audio == NULL)
|
||||
return E_HDMI_EDID_NOMEMORY;
|
||||
|
||||
pedid->audio_num = count / 3;
|
||||
for (i = 0; i < pedid->audio_num; i++) {
|
||||
pedid->audio[i].type = (buf[1 + i * 3] >> 3) & 0x0F;
|
||||
pedid->audio[i].channel = (buf[1 + i * 3] & 0x07) + 1;
|
||||
pedid->audio[i].rate = buf[1 + i * 3 + 1];
|
||||
if (pedid->audio[i].type == HDMI_AUDIO_LPCM) /* LPCM */
|
||||
pedid->audio[i].word_length = buf[1 + i * 3 + 2];
|
||||
/*
|
||||
printk("[EDID-CEA] type %d channel %d rate %d word length %d\n",
|
||||
pedid->audio[i].type, pedid->audio[i].channel,
|
||||
pedid->audio[i].rate, pedid->audio[i].word_length);
|
||||
*/
|
||||
}
|
||||
return E_HDMI_EDID_SUCCESS;
|
||||
}
|
||||
|
||||
/* Parse CEA Vendor Specific Data Block */
|
||||
static int hdmi_edid_parse_cea_sdb(unsigned char *buf, struct hdmi_edid *pedid)
|
||||
{
|
||||
unsigned int count = 0, cur_offset = 0, i = 0;
|
||||
unsigned int IEEEOUI = 0;
|
||||
unsigned int supports_ai, dc_48bit, dc_36bit, dc_30bit, dc_y444;
|
||||
unsigned int supports_ai, dc_48bit, dc_36bit, dc_30bit, dc_y444;
|
||||
unsigned int len_3d, len_4k;
|
||||
unsigned char vic = 0;
|
||||
const struct fb_videomode *mode;
|
||||
@@ -214,7 +217,7 @@ static int hdmi_edid_parse_cea_sdb(unsigned char * buf, struct hdmi_edid *pedid)
|
||||
IEEEOUI <<= 8;
|
||||
IEEEOUI += buf[1];
|
||||
hdmi_edid_debug("[EDID-CEA] IEEEOUI is 0x%08x.\n", IEEEOUI);
|
||||
if(IEEEOUI == 0x0c03)
|
||||
if (IEEEOUI == 0x0c03)
|
||||
pedid->sink_hdmi = 1;
|
||||
|
||||
if (count > 5) {
|
||||
@@ -224,11 +227,14 @@ static int hdmi_edid_parse_cea_sdb(unsigned char * buf, struct hdmi_edid *pedid)
|
||||
dc_36bit = (buf[6] >> 5) & 0x1;
|
||||
dc_30bit = (buf[6] >> 4) & 0x1;
|
||||
dc_y444 = (buf[6] >> 3) & 0x1;
|
||||
hdmi_edid_debug("[EDID-CEA] supports_ai %d dc_48bit %d dc_36bit %d dc_30bit %d dc_y444 %d \n", supports_ai, dc_48bit, dc_36bit, dc_30bit, dc_y444);
|
||||
hdmi_edid_debug("[EDID-CEA] supports_ai %d\n"
|
||||
"dc_48bit %d dc_36bit %d dc_30bit %d dc_y444 %d\n",
|
||||
supports_ai,
|
||||
dc_48bit, dc_36bit, dc_30bit, dc_y444);
|
||||
}
|
||||
if (count > 6) {
|
||||
if (count > 6)
|
||||
pedid->maxtmdsclock = buf[7] * 5000000;
|
||||
}
|
||||
|
||||
if (count > 7) {
|
||||
pedid->latency_fields_present = (buf[8] & 0x80) ? 1 : 0;
|
||||
pedid->i_latency_fields_present = (buf[8] & 0x40) ? 1 : 0;
|
||||
@@ -241,13 +247,13 @@ static int hdmi_edid_parse_cea_sdb(unsigned char * buf, struct hdmi_edid *pedid)
|
||||
pedid->video_latency = buf[cur_offset++];
|
||||
pedid->audio_latency = buf[cur_offset++];
|
||||
}
|
||||
if(count >= cur_offset && pedid->i_latency_fields_present) {
|
||||
if (count >= cur_offset && pedid->i_latency_fields_present) {
|
||||
pedid->interlaced_video_latency = buf[cur_offset++];
|
||||
pedid->interlaced_audio_latency = buf[cur_offset++];
|
||||
}
|
||||
}
|
||||
|
||||
if(pedid->video_present == 0)
|
||||
if (pedid->video_present == 0)
|
||||
return E_HDMI_EDID_SUCCESS;
|
||||
|
||||
if (count >= cur_offset) {
|
||||
@@ -258,209 +264,209 @@ static int hdmi_edid_parse_cea_sdb(unsigned char * buf, struct hdmi_edid *pedid)
|
||||
cur_offset++;
|
||||
}
|
||||
if (count >= cur_offset && len_4k > 0) {
|
||||
for(i = 0; i < len_4k; i++) {
|
||||
for (i = 0; i < len_4k; i++) {
|
||||
#ifndef HDMI_VERSION_2
|
||||
vic = buf[cur_offset + i] & 0x7f;
|
||||
if (vic > 0 && vic < 5) {
|
||||
if (vic > 0 && vic < 5)
|
||||
vic = (vic == 4) ? 98 : (96 - vic);
|
||||
}
|
||||
hdmi_edid_debug("[EDID-CEA] %02x VID %d native %d\n", buf[cur_offset + i], vic, buf[cur_offset + i] >> 7);
|
||||
hdmi_edid_debug("[EDID-CEA] %02x VID %d native %d\n",
|
||||
buf[cur_offset + i],
|
||||
vic,
|
||||
buf[cur_offset + i] >> 7);
|
||||
#else
|
||||
vic = buf[cur_offset + i] & 0xff;
|
||||
hdmi_edid_debug("[EDID-CEA] %02x VID %d native %d\n", buf[cur_offset + i], vic);
|
||||
hdmi_edid_debug("[EDID-CEA] %02x VID %d native %d\n",
|
||||
buf[cur_offset + i], vic);
|
||||
#endif
|
||||
if (vic) {
|
||||
mode = hdmi_vic_to_videomode(vic);
|
||||
if (mode) {
|
||||
hdmi_add_videomode(mode, &pedid->modelist);
|
||||
}
|
||||
if (mode)
|
||||
hdmi_add_videomode(mode,
|
||||
&pedid->modelist);
|
||||
}
|
||||
}
|
||||
cur_offset += i;
|
||||
}
|
||||
|
||||
/* TODO Daisen wait to add
|
||||
if (count >= cur_offset && pedid->support_3d && len_3d > 0) {
|
||||
//TODO Daisen wait to add
|
||||
|
||||
}
|
||||
*/
|
||||
return E_HDMI_EDID_SUCCESS;
|
||||
}
|
||||
|
||||
/* Parse CEA 861 Serial Extension. */
|
||||
static int hdmi_edid_parse_extensions_cea(unsigned char *buf,
|
||||
struct hdmi_edid *pedid)
|
||||
{
|
||||
unsigned int ddc_offset, native_dtd_num, cur_offset = 4;
|
||||
unsigned int underscan_support, baseaudio_support;
|
||||
unsigned int tag;
|
||||
|
||||
if (buf == NULL)
|
||||
return E_HDMI_EDID_PARAM;
|
||||
|
||||
/* Check ces extension version */
|
||||
if (buf[1] != 3) {
|
||||
hdmi_edid_error("[EDID-CEA] error version.\n");
|
||||
return E_HDMI_EDID_VERSION;
|
||||
}
|
||||
|
||||
ddc_offset = buf[2];
|
||||
underscan_support = (buf[3] >> 7) & 0x01;
|
||||
baseaudio_support = (buf[3] >> 6) & 0x01;
|
||||
pedid->ycbcr444 = (buf[3] >> 5) & 0x01;
|
||||
pedid->ycbcr422 = (buf[3] >> 4) & 0x01;
|
||||
native_dtd_num = buf[3] & 0x0F;
|
||||
pedid->base_audio_support = baseaudio_support;
|
||||
|
||||
/* Parse data block */
|
||||
while (cur_offset < ddc_offset) {
|
||||
tag = buf[cur_offset] >> 5;
|
||||
switch (tag) {
|
||||
case 0x02: /* Video Data Block */
|
||||
hdmi_edid_debug("[EDID-CEA] It is a Video Data Block.\n");
|
||||
hdmi_edid_get_cea_svd(buf + cur_offset, pedid);
|
||||
break;
|
||||
case 0x01: /* Audio Data Block */
|
||||
hdmi_edid_debug("[EDID-CEA] It is a Audio Data Block.\n");
|
||||
hdmi_edid_parse_cea_sad(buf + cur_offset, pedid);
|
||||
break;
|
||||
case 0x04: /* Speaker Allocation Data Block */
|
||||
hdmi_edid_debug("[EDID-CEA] It is a Speaker Allocation Data Block.\n");
|
||||
break;
|
||||
case 0x03: /* Vendor Specific Data Block */
|
||||
hdmi_edid_debug("[EDID-CEA] It is a Vendor Specific Data Block.\n");
|
||||
hdmi_edid_parse_cea_sdb(buf + cur_offset, pedid);
|
||||
break;
|
||||
case 0x05: /* VESA DTC Data Block */
|
||||
hdmi_edid_debug("[EDID-CEA] It is a VESA DTC Data Block.\n");
|
||||
break;
|
||||
case 0x07: /* Use Extended Tag */
|
||||
hdmi_edid_debug("[EDID-CEA] It is a Use Extended Tag Data Block.\n");
|
||||
break;
|
||||
default:
|
||||
hdmi_edid_error("[EDID-CEA] unkowned data block tag.\n");
|
||||
break;
|
||||
}
|
||||
cur_offset += (buf[cur_offset] & 0x1F) + 1;
|
||||
}
|
||||
#if 1
|
||||
{
|
||||
/* Parse DTD */
|
||||
struct fb_videomode *vmode = kmalloc(sizeof(struct fb_videomode),
|
||||
GFP_KERNEL);
|
||||
if (vmode == NULL)
|
||||
return E_HDMI_EDID_SUCCESS;
|
||||
/* buf[126] = 0 and buf[127] = checksum */
|
||||
while (ddc_offset < HDMI_EDID_BLOCK_SIZE - 2) {
|
||||
if (!buf[ddc_offset] && !buf[ddc_offset + 1])
|
||||
break;
|
||||
memset(vmode, 0, sizeof(struct fb_videomode));
|
||||
hdmi_edid_parse_dtd(buf + ddc_offset, vmode);
|
||||
hdmi_add_videomode(vmode, &pedid->modelist);
|
||||
ddc_offset += 18;
|
||||
}
|
||||
kfree(vmode);
|
||||
}
|
||||
#endif
|
||||
return E_HDMI_EDID_SUCCESS;
|
||||
}
|
||||
|
||||
static int hdmi_edid_parse_extensions(unsigned char *buf,
|
||||
struct hdmi_edid *pedid)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (buf == NULL || pedid == NULL)
|
||||
return E_HDMI_EDID_PARAM;
|
||||
|
||||
/* Checksum */
|
||||
rc = hdmi_edid_checksum(buf);
|
||||
if (rc != E_HDMI_EDID_SUCCESS) {
|
||||
hdmi_edid_error("[EDID] extensions block checksum error\n");
|
||||
return E_HDMI_EDID_CHECKSUM;
|
||||
}
|
||||
|
||||
switch (buf[0]) {
|
||||
case 0xF0:
|
||||
hdmi_edid_debug("[EDID-EXTEND] It is a extensions block map.\n");
|
||||
break;
|
||||
case 0x02:
|
||||
hdmi_edid_debug("[EDID-EXTEND] It is a CEA 861 Series Extension.\n");
|
||||
hdmi_edid_parse_extensions_cea(buf, pedid);
|
||||
break;
|
||||
case 0x10:
|
||||
hdmi_edid_debug("[EDID-EXTEND] It is a Video Timing Block Extension.\n");
|
||||
break;
|
||||
case 0x40:
|
||||
hdmi_edid_debug("[EDID-EXTEND] It is a Display Information Extension.\n");
|
||||
break;
|
||||
case 0x50:
|
||||
hdmi_edid_debug("[EDID-EXTEND] It is a Localized String Extension.\n");
|
||||
break;
|
||||
case 0x60:
|
||||
hdmi_edid_debug("[EDID-EXTEND] It is a Digital Packet Video Link Extension.\n");
|
||||
break;
|
||||
default:
|
||||
hdmi_edid_error("[EDID-EXTEND] Unkowned extension.\n");
|
||||
return E_HDMI_EDID_UNKOWNDATA;
|
||||
}
|
||||
|
||||
return E_HDMI_EDID_SUCCESS;
|
||||
}
|
||||
|
||||
// Parse CEA 861 Serial Extension.
|
||||
static int hdmi_edid_parse_extensions_cea(unsigned char *buf, struct hdmi_edid *pedid)
|
||||
{
|
||||
unsigned int ddc_offset, native_dtd_num, cur_offset = 4;
|
||||
unsigned int underscan_support, baseaudio_support;
|
||||
unsigned int tag;
|
||||
|
||||
if(buf == NULL)
|
||||
return E_HDMI_EDID_PARAM;
|
||||
|
||||
// Check ces extension version
|
||||
if(buf[1] != 3)
|
||||
{
|
||||
hdmi_edid_error("[EDID-CEA] error version.\n");
|
||||
return E_HDMI_EDID_VERSION;
|
||||
}
|
||||
|
||||
ddc_offset = buf[2];
|
||||
underscan_support = (buf[3] >> 7) & 0x01;
|
||||
baseaudio_support = (buf[3] >> 6) & 0x01;
|
||||
pedid->ycbcr444 = (buf[3] >> 5) & 0x01;
|
||||
pedid->ycbcr422 = (buf[3] >> 4) & 0x01;
|
||||
native_dtd_num = buf[3] & 0x0F;
|
||||
pedid->base_audio_support = baseaudio_support;
|
||||
|
||||
// Parse data block
|
||||
while(cur_offset < ddc_offset)
|
||||
{
|
||||
tag = buf[cur_offset] >> 5;
|
||||
switch(tag)
|
||||
{
|
||||
case 0x02: // Video Data Block
|
||||
hdmi_edid_debug("[EDID-CEA] It is a Video Data Block.\n");
|
||||
hdmi_edid_get_cea_svd(buf + cur_offset, pedid);
|
||||
break;
|
||||
case 0x01: // Audio Data Block
|
||||
hdmi_edid_debug("[EDID-CEA] It is a Audio Data Block.\n");
|
||||
hdmi_edid_parse_cea_sad(buf + cur_offset, pedid);
|
||||
break;
|
||||
case 0x04: // Speaker Allocation Data Block
|
||||
hdmi_edid_debug("[EDID-CEA] It is a Speaker Allocatio Data Block.\n");
|
||||
break;
|
||||
case 0x03: // Vendor Specific Data Block
|
||||
hdmi_edid_debug("[EDID-CEA] It is a Vendor Specific Data Block.\n");
|
||||
hdmi_edid_parse_cea_sdb(buf + cur_offset, pedid);
|
||||
break;
|
||||
case 0x05: // VESA DTC Data Block
|
||||
hdmi_edid_debug("[EDID-CEA] It is a VESA DTC Data Block.\n");
|
||||
break;
|
||||
case 0x07: // Use Extended Tag
|
||||
hdmi_edid_debug("[EDID-CEA] It is a Use Extended Tag Data Block.\n");
|
||||
break;
|
||||
default:
|
||||
hdmi_edid_error("[EDID-CEA] unkowned data block tag.\n");
|
||||
break;
|
||||
}
|
||||
cur_offset += (buf[cur_offset] & 0x1F) + 1;
|
||||
}
|
||||
#if 1
|
||||
{
|
||||
// Parse DTD
|
||||
struct fb_videomode *vmode = kmalloc(sizeof(struct fb_videomode), GFP_KERNEL);
|
||||
if(vmode == NULL)
|
||||
return E_HDMI_EDID_SUCCESS;
|
||||
while(ddc_offset < HDMI_EDID_BLOCK_SIZE - 2) //buf[126] = 0 and buf[127] = checksum
|
||||
{
|
||||
if(!buf[ddc_offset] && !buf[ddc_offset + 1])
|
||||
break;
|
||||
memset(vmode, 0, sizeof(struct fb_videomode));
|
||||
hdmi_edid_parse_dtd(buf + ddc_offset, vmode);
|
||||
hdmi_add_videomode(vmode, &pedid->modelist);
|
||||
ddc_offset += 18;
|
||||
}
|
||||
kfree(vmode);
|
||||
}
|
||||
#endif
|
||||
return E_HDMI_EDID_SUCCESS;
|
||||
}
|
||||
|
||||
static int hdmi_edid_parse_extensions(unsigned char *buf, struct hdmi_edid *pedid)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if(buf == NULL || pedid == NULL)
|
||||
return E_HDMI_EDID_PARAM;
|
||||
|
||||
// Checksum
|
||||
rc = hdmi_edid_checksum(buf);
|
||||
if( rc != E_HDMI_EDID_SUCCESS)
|
||||
{
|
||||
hdmi_edid_error("[EDID] extensions block checksum error\n");
|
||||
return E_HDMI_EDID_CHECKSUM;
|
||||
}
|
||||
|
||||
switch(buf[0])
|
||||
{
|
||||
case 0xF0:
|
||||
hdmi_edid_debug("[EDID-EXTEND] It is a extensions block map.\n");
|
||||
break;
|
||||
case 0x02:
|
||||
hdmi_edid_debug("[EDID-EXTEND] It is a CEA 861 Series Extension.\n");
|
||||
hdmi_edid_parse_extensions_cea(buf, pedid);
|
||||
break;
|
||||
case 0x10:
|
||||
hdmi_edid_debug("[EDID-EXTEND] It is a Video Timing Block Extension.\n");
|
||||
break;
|
||||
case 0x40:
|
||||
hdmi_edid_debug("[EDID-EXTEND] It is a Display Information Extension.\n");
|
||||
break;
|
||||
case 0x50:
|
||||
hdmi_edid_debug("[EDID-EXTEND] It is a Localized String Extension.\n");
|
||||
break;
|
||||
case 0x60:
|
||||
hdmi_edid_debug("[EDID-EXTEND] It is a Digital Packet Video Link Extension.\n");
|
||||
break;
|
||||
default:
|
||||
hdmi_edid_error("[EDID-EXTEND] Unkowned extension.\n");
|
||||
return E_HDMI_EDID_UNKOWNDATA;
|
||||
}
|
||||
|
||||
return E_HDMI_EDID_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int hdmi_sys_parse_edid(struct hdmi* hdmi)
|
||||
{
|
||||
struct hdmi_edid *pedid;
|
||||
unsigned char *buff = NULL;
|
||||
int rc = HDMI_ERROR_SUCESS, extendblock = 0, i;
|
||||
|
||||
if(hdmi == NULL)
|
||||
return HDMI_ERROR_FALSE;
|
||||
|
||||
pedid = &(hdmi->edid);
|
||||
memset(pedid, 0, sizeof(struct hdmi_edid));
|
||||
INIT_LIST_HEAD(&pedid->modelist);
|
||||
|
||||
buff = kmalloc(HDMI_EDID_BLOCK_SIZE, GFP_KERNEL);
|
||||
if(buff == NULL)
|
||||
{
|
||||
hdmi_dbg(hdmi->dev, "[%s] can not allocate memory for edid buff.\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
// Read base block edid.
|
||||
memset(buff, 0 , HDMI_EDID_BLOCK_SIZE);
|
||||
rc = hdmi->read_edid(hdmi, 0, buff);
|
||||
if(rc)
|
||||
{
|
||||
dev_err(hdmi->dev, "[HDMI] read edid base block error\n");
|
||||
goto out;
|
||||
}
|
||||
rc = hdmi_edid_parse_base(buff, &extendblock, pedid);
|
||||
if(rc)
|
||||
{
|
||||
dev_err(hdmi->dev, "[HDMI] parse edid base block error\n");
|
||||
goto out;
|
||||
}
|
||||
for(i = 1; i < extendblock + 1; i++)
|
||||
{
|
||||
memset(buff, 0 , HDMI_EDID_BLOCK_SIZE);
|
||||
rc = hdmi->read_edid(hdmi, i, buff);
|
||||
if(rc)
|
||||
{
|
||||
printk("[HDMI] read edid block %d error\n", i);
|
||||
goto out;
|
||||
}
|
||||
rc = hdmi_edid_parse_extensions(buff, pedid);
|
||||
if(rc)
|
||||
{
|
||||
dev_err(hdmi->dev, "[HDMI] parse edid block %d error\n", i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
out:
|
||||
if(buff)
|
||||
kfree(buff);
|
||||
rc = hdmi_ouputmode_select(hdmi, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int hdmi_sys_parse_edid(struct hdmi *hdmi)
|
||||
{
|
||||
struct hdmi_edid *pedid;
|
||||
unsigned char *buff = NULL;
|
||||
int rc = HDMI_ERROR_SUCESS, extendblock = 0, i;
|
||||
|
||||
if (hdmi == NULL)
|
||||
return HDMI_ERROR_FALSE;
|
||||
|
||||
pedid = &(hdmi->edid);
|
||||
memset(pedid, 0, sizeof(struct hdmi_edid));
|
||||
INIT_LIST_HEAD(&pedid->modelist);
|
||||
|
||||
buff = kmalloc(HDMI_EDID_BLOCK_SIZE, GFP_KERNEL);
|
||||
if (buff == NULL) {
|
||||
hdmi_dbg(hdmi->dev,
|
||||
"[%s] can not allocate memory for edid buff.\n",
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read base block edid. */
|
||||
memset(buff, 0 , HDMI_EDID_BLOCK_SIZE);
|
||||
rc = hdmi->read_edid(hdmi, 0, buff);
|
||||
if (rc) {
|
||||
dev_err(hdmi->dev, "[HDMI] read edid base block error\n");
|
||||
goto out;
|
||||
}
|
||||
rc = hdmi_edid_parse_base(buff, &extendblock, pedid);
|
||||
if (rc) {
|
||||
dev_err(hdmi->dev, "[HDMI] parse edid base block error\n");
|
||||
goto out;
|
||||
}
|
||||
for (i = 1; i < extendblock + 1; i++) {
|
||||
memset(buff, 0 , HDMI_EDID_BLOCK_SIZE);
|
||||
rc = hdmi->read_edid(hdmi, i, buff);
|
||||
if (rc) {
|
||||
printk("[HDMI] read edid block %d error\n", i);
|
||||
goto out;
|
||||
}
|
||||
rc = hdmi_edid_parse_extensions(buff, pedid);
|
||||
if (rc) {
|
||||
dev_err(hdmi->dev, "[HDMI] parse edid block %d error\n",
|
||||
i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
out:
|
||||
kfree(buff);
|
||||
rc = hdmi_ouputmode_select(hdmi, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -8,68 +8,74 @@
|
||||
#define SWAP_RB 0
|
||||
#define LCD_ACLK 800000000
|
||||
|
||||
static struct hdmi *m_hdmi_drv = NULL;
|
||||
struct hdmi *m_hdmi_drv;
|
||||
|
||||
static const struct fb_videomode hdmi_mode [] = {
|
||||
//name refresh xres yres pixclock h_bp h_fp v_bp v_fp h_pw v_pw polariry PorI flag(used for vic)
|
||||
//{ "640x480p@60Hz", 60, 640, 480, 25175000, 48, 16, 33, 10, 96, 2, 0, 0, 1 },
|
||||
//{ "720x480i@60Hz", 60, 720, 480, 27000000, 114, 38, 15, 4, 124, 3, 0, 1, 6 },
|
||||
//{ "720x576i@50Hz", 50, 720, 576, 27000000, 138, 24, 19, 2, 126, 3, 0, 1, 21 },
|
||||
{ "720x480p@60Hz", 60, 720, 480, 27000000, 60, 16, 30, 9, 62, 6, 0, 0, 2 },
|
||||
{ "720x576p@50Hz", 50, 720, 576, 27000000, 68, 12, 39, 5, 64, 5, 0, 0, 17 },
|
||||
//{ "1280x720p@24Hz", 24, 1280, 720, 59400000, 220, 1760, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 60 },
|
||||
//{ "1280x720p@25Hz", 25, 1280, 720, 74250000, 220, 2420, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 61 },
|
||||
//{ "1280x720p@30Hz", 30, 1280, 720, 74250000, 220, 1760, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 62 },
|
||||
{ "1280x720p@50Hz", 50, 1280, 720, 74250000, 220, 440, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 19 },
|
||||
{ "1280x720p@60Hz", 60, 1280, 720, 74250000, 220, 110, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 4 },
|
||||
//{ "1920x1080p@24Hz", 24, 1920, 1080, 74250000, 148, 638, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 32 },
|
||||
//{ "1920x1080p@25Hz", 25, 1920, 1080, 74250000, 148, 528, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 33 },
|
||||
//{ "1920x1080p@30Hz", 30, 1920, 1080, 74250000, 148, 88, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 34 },
|
||||
//{ "1920x1080i@50Hz_2", 50, 1920, 1080, 72000000, 184, 32, 57, 23, 168, 5, FB_SYNC_HOR_HIGH_ACT, 1, 39 },
|
||||
//{ "1920x1080i@50Hz", 50, 1920, 1080, 74250000, 148, 528, 15, 2, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 1, 20 },
|
||||
//{ "1920x1080i@60Hz", 60, 1920, 1080, 74250000, 148, 88, 15, 2, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 1, 5 },
|
||||
{ "1920x1080p@50Hz", 50, 1920, 1080, 148500000, 148, 528, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 31 },
|
||||
{ "1920x1080p@60Hz", 60, 1920, 1080, 148500000, 148, 88, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 16 },
|
||||
static const struct fb_videomode hdmi_mode[] = {
|
||||
/* name refresh xres yres pixclock h_bp h_fp v_bp v_fp h_pw v_pw polariry PorI flag(used for vic) */
|
||||
/*
|
||||
{ "1440x288p@50Hz", 50, 720, 480, 27000000, 138, 24, 19, 2, 126, 3, 0, 0, 23 },
|
||||
{ "2880x576i@50Hz", 50, 1440, 240, 54000000, 276, 48, 19, 2, 252, 3, 0, 1, 25 },
|
||||
{ "2880x288p@50Hz", 50, 2880, 480, 54000000, 276, 48, 19, 3, 252, 3, 0, 0, 27 },
|
||||
{ "1440x576p@50Hz", 50, 2880, 480, 54000000, 136, 24, 39, 5, 128, 5, 0, 0, 29 },
|
||||
{ "2880x576p@50Hz", 50, 1920, 1080, 108000000, 272, 48, 39, 5, 256, 5, 0, 0, 37 },
|
||||
{ "1440x240p@60Hz", 60, 1440, 240, 27000000, 114, 38, 15, 4, 124, 3, 0, 0, 8 },
|
||||
{ "2880x480i@60Hz", 60, 2880, 480, 54000000, 228, 76, 15, 4, 248, 3, 0, 1, 10 },
|
||||
{ "2880x480p@60Hz", 60, 2880, 480, 54000000, 228, 76, 15, 4, 248, 3, 0, 0, 12 },
|
||||
{ "1440x480p@60Hz", 60, 1440, 480, 54000000, 120, 32, 30, 9, 124, 6, 0, 0, 14 },
|
||||
{ "2880x480p@60Hz", 60, 2880, 480, 54000000, 240, 64, 30, 9, 248, 6, 0, 0, 35 },
|
||||
|
||||
{ "1920x1080i@100Hz", 100, 1920, 1080, 148500000, 148, 528, 15, 2, 44, 5, 1, 1, 40 },
|
||||
{ "1280x720p@100Hz", 100, 1280, 720, 148500000, 220, 440, 20, 5, 40, 5, 1, 0, 41 },
|
||||
{ "720x576p@100Hz", 100, 720, 576, 54000000, 68, 12, 39, 5, 64, 5, 0, 0, 42 },
|
||||
{ "1440x576i@100Hz", 100, 1440, 576, 54000000, 138, 24, 19, 2, 12, 3, 0, 1, 44 },
|
||||
{ "1920x1080p@100Hz", 100, 1920, 1080, 297000000, 148, 528, 36, 4, 44, 5, 1, 0, 64 },
|
||||
|
||||
{ "1920x1080i@120Hz", 120, 1920, 1080, 148500000, 148, 88, 15, 2, 44, 5, 1, 1, 46 },
|
||||
{ "1280x720p@120Hz", 120, 1280, 720, 148500000, 220, 110, 20, 5, 40, 5, 1, 0, 47 },
|
||||
{ "720x480p@120Hz", 120, 720, 480, 54000000, 60, 16, 30, 9, 62, 6, 0, 0, 48 },
|
||||
{ "1440x480i@120Hz", 120, 1440, 480, 54000000, 114, 38, 15, 4, 12, 3, 0, 1, 50 },
|
||||
{ "1920x1080p@120Hz", 120, 1920, 1080, 297000000, 148, 88, 36, 4, 44, 5, 1, 0, 63 },
|
||||
|
||||
{ "720x576p@200Hz", 200, 720, 576, 108000000, 68, 12, 39, 5, 64, 5, 0, 0, 52 },
|
||||
{ "1440x576i@200Hz", 200, 1920, 1080, 108000000, 138, 24, 19, 2, 12, 3, 0, 1, 54 },
|
||||
|
||||
{ "720x480p@240Hz", 240, 720, 480, 108000000, 60, 16, 30, 9, 62, 6, 0, 0, 56 },
|
||||
{ "1440x480i@240Hz", 240, 1440, 480, 108000000, 114, 38, 15, 4, 12, 3, 0, 1, 58 },
|
||||
{"640x480p@60Hz", 60, 640, 480, 25175000, 48, 16, 33, 10, 96, 2, 0, 0, 1 },
|
||||
{"720x480i@60Hz", 60, 720, 480, 27000000, 114, 38, 15, 4, 124, 3, 0, 1, 6 },
|
||||
{"720x576i@50Hz", 50, 720, 576, 27000000, 138, 24, 19, 2, 126, 3, 0, 1, 21},
|
||||
*/
|
||||
{ "3840x2160p@24Hz", 24, 3840, 2160, 297000000, 296, 1276, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 93 },
|
||||
{ "3840x2160p@25Hz", 25, 3840, 2160, 297000000, 296, 1056, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 94 },
|
||||
{ "3840x2160p@30Hz", 30, 3840, 2160, 297000000, 296, 176, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 95 },
|
||||
{ "3840x2160p@50Hz", 50, 3840, 2160, 594000000, 296, 1056, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 96 },
|
||||
{ "3840x2160p@60Hz", 60, 3840, 2160, 594000000, 296, 176, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 97 },
|
||||
{ "4096x2160p@24Hz", 24, 4096, 2160, 297000000, 296, 1020, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 98 },
|
||||
{ "4096x2160p@25Hz", 25, 4096, 2160, 297000000, 128, 968, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 99 },
|
||||
{ "4096x2160p@30Hz", 30, 4096, 2160, 297000000, 128, 88, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 100 },
|
||||
{ "4096x2160p@50Hz", 50, 4096, 2160, 594000000, 128, 968, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 101 },
|
||||
{ "4096x2160p@60Hz", 60, 4096, 2160, 594000000, 128, 88, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 102 },
|
||||
{"720x480p@60Hz", 60, 720, 480, 27000000, 60, 16, 30, 9, 62, 6, 0, 0, 2 },
|
||||
{"720x576p@50Hz", 50, 720, 576, 27000000, 68, 12, 39, 5, 64, 5, 0, 0, 17},
|
||||
/*
|
||||
{"1280x720p@24Hz", 24, 1280, 720, 59400000, 220, 1760, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 60},
|
||||
{"1280x720p@25Hz", 25, 1280, 720, 74250000, 220, 2420, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 61},
|
||||
{"1280x720p@30Hz", 30, 1280, 720, 74250000, 220, 1760, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 62},
|
||||
*/
|
||||
{"1280x720p@50Hz", 50, 1280, 720, 74250000, 220, 440, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 19},
|
||||
{"1280x720p@60Hz", 60, 1280, 720, 74250000, 220, 110, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 4 },
|
||||
/*
|
||||
{"1920x1080p@24Hz", 24, 1920, 1080, 74250000, 148, 638, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 32},
|
||||
{"1920x1080p@25Hz", 25, 1920, 1080, 74250000, 148, 528, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 33},
|
||||
{"1920x1080p@30Hz", 30, 1920, 1080, 74250000, 148, 88, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 34},
|
||||
{"1920x1080i@50Hz_2", 50, 1920, 1080, 72000000, 184, 32, 57, 23, 168, 5, FB_SYNC_HOR_HIGH_ACT, 1, 39},
|
||||
{"1920x1080i@50Hz", 50, 1920, 1080, 74250000, 148, 528, 15, 2, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 1, 20},
|
||||
{"1920x1080i@60Hz", 60, 1920, 1080, 74250000, 148, 88, 15, 2, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 1, 5 },
|
||||
*/
|
||||
{"1920x1080p@50Hz", 50, 1920, 1080, 148500000, 148, 528, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 31},
|
||||
{"1920x1080p@60Hz", 60, 1920, 1080, 148500000, 148, 88, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 16},
|
||||
/*
|
||||
{"1440x288p@50Hz", 50, 720, 480, 27000000, 138, 24, 19, 2, 126, 3, 0, 0, 23},
|
||||
{"2880x576i@50Hz", 50, 1440, 240, 54000000, 276, 48, 19, 2, 252, 3, 0, 1, 25},
|
||||
{"2880x288p@50Hz", 50, 2880, 480, 54000000, 276, 48, 19, 3, 252, 3, 0, 0, 27},
|
||||
{"1440x576p@50Hz", 50, 2880, 480, 54000000, 136, 24, 39, 5, 128, 5, 0, 0, 29},
|
||||
{"2880x576p@50Hz", 50, 1920, 1080, 108000000, 272, 48, 39, 5, 256, 5, 0, 0, 37},
|
||||
{"1440x240p@60Hz", 60, 1440, 240, 27000000, 114, 38, 15, 4, 124, 3, 0, 0, 8 },
|
||||
{"2880x480i@60Hz", 60, 2880, 480, 54000000, 228, 76, 15, 4, 248, 3, 0, 1, 10},
|
||||
{"2880x480p@60Hz", 60, 2880, 480, 54000000, 228, 76, 15, 4, 248, 3, 0, 0, 12},
|
||||
{"1440x480p@60Hz", 60, 1440, 480, 54000000, 120, 32, 30, 9, 124, 6, 0, 0, 14},
|
||||
{"2880x480p@60Hz", 60, 2880, 480, 54000000, 240, 64, 30, 9, 248, 6, 0, 0, 35},
|
||||
|
||||
{"1920x1080i@100Hz", 100, 1920, 1080, 148500000, 148, 528, 15, 2, 44, 5, 1, 1, 40},
|
||||
{"1280x720p@100Hz", 100, 1280, 720, 148500000, 220, 440, 20, 5, 40, 5, 1, 0, 41},
|
||||
{"720x576p@100Hz", 100, 720, 576, 54000000, 68, 12, 39, 5, 64, 5, 0, 0, 42},
|
||||
{"1440x576i@100Hz", 100, 1440, 576, 54000000, 138, 24, 19, 2, 12, 3, 0, 1, 44},
|
||||
{"1920x1080p@100Hz", 100, 1920, 1080, 297000000, 148, 528, 36, 4, 44, 5, 1, 0, 64},
|
||||
|
||||
{"1920x1080i@120Hz", 120, 1920, 1080, 148500000, 148, 88, 15, 2, 44, 5, 1, 1, 46},
|
||||
{"1280x720p@120Hz", 120, 1280, 720, 148500000, 220, 110, 20, 5, 40, 5, 1, 0, 47},
|
||||
{"720x480p@120Hz", 120, 720, 480, 54000000, 60, 16, 30, 9, 62, 6, 0, 0, 48},
|
||||
{"1440x480i@120Hz", 120, 1440, 480, 54000000, 114, 38, 15, 4, 12, 3, 0, 1, 50},
|
||||
{"1920x1080p@120Hz", 120, 1920, 1080, 297000000, 148, 88, 36, 4, 44, 5, 1, 0, 63},
|
||||
|
||||
{"720x576p@200Hz", 200, 720, 576, 108000000, 68, 12, 39, 5, 64, 5, 0, 0, 52},
|
||||
{"1440x576i@200Hz", 200, 1920, 1080, 108000000, 138, 24, 19, 2, 12, 3, 0, 1, 54},
|
||||
|
||||
{"720x480p@240Hz", 240, 720, 480, 108000000, 60, 16, 30, 9, 62, 6, 0, 0, 56},
|
||||
{"1440x480i@240Hz", 240, 1440, 480, 108000000, 114, 38, 15, 4, 12, 3, 0, 1, 58},
|
||||
*/
|
||||
{"3840x2160p@24Hz", 24, 3840, 2160, 297000000, 296, 1276, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 93},
|
||||
{"3840x2160p@25Hz", 25, 3840, 2160, 297000000, 296, 1056, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 94},
|
||||
{"3840x2160p@30Hz", 30, 3840, 2160, 297000000, 296, 176, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 95},
|
||||
{"3840x2160p@50Hz", 50, 3840, 2160, 594000000, 296, 1056, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 96},
|
||||
{"3840x2160p@60Hz", 60, 3840, 2160, 594000000, 296, 176, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 97},
|
||||
{"4096x2160p@24Hz", 24, 4096, 2160, 297000000, 296, 1020, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 98},
|
||||
{"4096x2160p@25Hz", 25, 4096, 2160, 297000000, 128, 968, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 99},
|
||||
{"4096x2160p@30Hz", 30, 4096, 2160, 297000000, 128, 88, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 100},
|
||||
{"4096x2160p@50Hz", 50, 4096, 2160, 594000000, 128, 968, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 101},
|
||||
{"4096x2160p@60Hz", 60, 4096, 2160, 594000000, 128, 88, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 102},
|
||||
|
||||
};
|
||||
|
||||
@@ -80,36 +86,35 @@ void hdmi_init_lcdc(struct rk_screen *screen, struct rk29lcd_info *lcd_info)
|
||||
|
||||
int hdmi_set_info(struct rk_screen *screen, unsigned int vic)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(screen == NULL)
|
||||
return -1;
|
||||
|
||||
if(vic == 0)
|
||||
vic = HDMI_VIDEO_DEFAULT_MODE;
|
||||
|
||||
for(i = 0; i < ARRAY_SIZE(hdmi_mode); i++)
|
||||
{
|
||||
if(hdmi_mode[i].flag == vic)
|
||||
break;
|
||||
}
|
||||
if(i == ARRAY_SIZE(hdmi_mode))
|
||||
return -1;
|
||||
|
||||
memset(screen, 0, sizeof(struct rk_screen));
|
||||
|
||||
/* screen type & face */
|
||||
screen->type = OUT_TYPE;
|
||||
screen->face = OUT_FACE;
|
||||
int i;
|
||||
|
||||
/* Screen size */
|
||||
screen->mode.xres = hdmi_mode[i].xres;
|
||||
screen->mode.yres = hdmi_mode[i].yres;
|
||||
|
||||
/* Timing */
|
||||
screen->mode.pixclock = hdmi_mode[i].pixclock;
|
||||
screen->mode.refresh = hdmi_mode[i].refresh;
|
||||
//screen->lcdc_aclk = LCD_ACLK;
|
||||
if (screen == NULL)
|
||||
return -1;
|
||||
|
||||
if (vic == 0)
|
||||
vic = HDMI_VIDEO_DEFAULT_MODE;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
|
||||
if (hdmi_mode[i].flag == vic)
|
||||
break;
|
||||
}
|
||||
if (i == ARRAY_SIZE(hdmi_mode))
|
||||
return -1;
|
||||
|
||||
memset(screen, 0, sizeof(struct rk_screen));
|
||||
|
||||
/* screen type & face */
|
||||
screen->type = OUT_TYPE;
|
||||
screen->face = OUT_FACE;
|
||||
|
||||
/* Screen size */
|
||||
screen->mode.xres = hdmi_mode[i].xres;
|
||||
screen->mode.yres = hdmi_mode[i].yres;
|
||||
|
||||
/* Timing */
|
||||
screen->mode.pixclock = hdmi_mode[i].pixclock;
|
||||
screen->mode.refresh = hdmi_mode[i].refresh;
|
||||
/* screen->lcdc_aclk = LCD_ACLK; */
|
||||
screen->mode.left_margin = hdmi_mode[i].left_margin;
|
||||
screen->mode.right_margin = hdmi_mode[i].right_margin;
|
||||
screen->mode.hsync_len = hdmi_mode[i].hsync_len;
|
||||
@@ -122,13 +127,13 @@ int hdmi_set_info(struct rk_screen *screen, unsigned int vic)
|
||||
#if defined(CONFIG_HDMI_RK616) && !defined(CONFIG_ARCH_RK3026)
|
||||
screen->pin_hsync = 0;
|
||||
screen->pin_vsync = 0;
|
||||
#else
|
||||
#else
|
||||
screen->pin_hsync = 0;
|
||||
if(FB_SYNC_HOR_HIGH_ACT & hdmi_mode[i].sync)
|
||||
if (FB_SYNC_HOR_HIGH_ACT & hdmi_mode[i].sync)
|
||||
screen->pin_hsync = 1;
|
||||
else
|
||||
screen->pin_hsync = 0;
|
||||
if(FB_SYNC_VERT_HIGH_ACT & hdmi_mode[i].sync)
|
||||
if (FB_SYNC_VERT_HIGH_ACT & hdmi_mode[i].sync)
|
||||
screen->pin_vsync = 1;
|
||||
else
|
||||
screen->pin_vsync = 0;
|
||||
@@ -137,19 +142,21 @@ int hdmi_set_info(struct rk_screen *screen, unsigned int vic)
|
||||
screen->pin_dclk = DCLK_POL;
|
||||
|
||||
/* Swap rule */
|
||||
screen->swap_rb = SWAP_RB;
|
||||
screen->swap_rg = 0;
|
||||
screen->swap_gb = 0;
|
||||
screen->swap_delta = 0;
|
||||
screen->swap_dumy = 0;
|
||||
screen->swap_rb = SWAP_RB;
|
||||
screen->swap_rg = 0;
|
||||
screen->swap_gb = 0;
|
||||
screen->swap_delta = 0;
|
||||
screen->swap_dumy = 0;
|
||||
|
||||
/* Operation function*/
|
||||
screen->init = NULL;
|
||||
screen->standby = NULL;
|
||||
/* Operation function */
|
||||
screen->init = NULL;
|
||||
screen->standby = NULL;
|
||||
|
||||
/*Init Default Overscan Value: TODO modify the value according to your need adjust value*/
|
||||
switch(vic) {
|
||||
case 16: /*1080p-60Hz*/
|
||||
/* Init Default Overscan Value:
|
||||
* TODO modify the value according to your need adjust value
|
||||
*/
|
||||
switch (vic) {
|
||||
case 16: /* 1080p-60Hz */
|
||||
screen->overscan.left = 97;
|
||||
screen->overscan.top = 97;
|
||||
screen->overscan.right = 97;
|
||||
@@ -162,8 +169,8 @@ int hdmi_set_info(struct rk_screen *screen, unsigned int vic)
|
||||
screen->overscan.bottom = 96;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hdmi_show_sink_info(struct hdmi *hdmi)
|
||||
@@ -175,87 +182,85 @@ static void hdmi_show_sink_info(struct hdmi *hdmi)
|
||||
struct hdmi_audio *audio;
|
||||
|
||||
hdmi_dbg(hdmi->dev, "******** Show Sink Info ********\n");
|
||||
hdmi_dbg(hdmi->dev, "Support video mode: \n");
|
||||
hdmi_dbg(hdmi->dev, "Support video mode:\n");
|
||||
list_for_each(pos, head) {
|
||||
modelist = list_entry(pos, struct fb_modelist, list);
|
||||
m = &modelist->mode;
|
||||
hdmi_dbg(hdmi->dev, " %s.\n", m->name);
|
||||
}
|
||||
|
||||
for(i = 0; i < hdmi->edid.audio_num; i++)
|
||||
{
|
||||
|
||||
for (i = 0; i < hdmi->edid.audio_num; i++) {
|
||||
audio = &(hdmi->edid.audio[i]);
|
||||
switch(audio->type)
|
||||
{
|
||||
case HDMI_AUDIO_LPCM:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: LPCM\n");
|
||||
break;
|
||||
case HDMI_AUDIO_AC3:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: AC3\n");
|
||||
break;
|
||||
case HDMI_AUDIO_MPEG1:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: MPEG1\n");
|
||||
break;
|
||||
case HDMI_AUDIO_MP3:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: MP3\n");
|
||||
break;
|
||||
case HDMI_AUDIO_MPEG2:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: MPEG2\n");
|
||||
break;
|
||||
case HDMI_AUDIO_AAC_LC:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: AAC\n");
|
||||
break;
|
||||
case HDMI_AUDIO_DTS:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: DTS\n");
|
||||
break;
|
||||
case HDMI_AUDIO_ATARC:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: ATARC\n");
|
||||
break;
|
||||
case HDMI_AUDIO_DSD:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: DSD\n");
|
||||
break;
|
||||
case HDMI_AUDIO_E_AC3:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: E-AC3\n");
|
||||
break;
|
||||
case HDMI_AUDIO_DTS_HD:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: DTS-HD\n");
|
||||
break;
|
||||
case HDMI_AUDIO_MLP:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: MLP\n");
|
||||
break;
|
||||
case HDMI_AUDIO_DST:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: DST\n");
|
||||
break;
|
||||
case HDMI_AUDIO_WMA_PRO:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: WMP-PRO\n");
|
||||
break;
|
||||
default:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: Unkown\n");
|
||||
break;
|
||||
switch (audio->type) {
|
||||
case HDMI_AUDIO_LPCM:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: LPCM\n");
|
||||
break;
|
||||
case HDMI_AUDIO_AC3:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: AC3\n");
|
||||
break;
|
||||
case HDMI_AUDIO_MPEG1:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: MPEG1\n");
|
||||
break;
|
||||
case HDMI_AUDIO_MP3:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: MP3\n");
|
||||
break;
|
||||
case HDMI_AUDIO_MPEG2:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: MPEG2\n");
|
||||
break;
|
||||
case HDMI_AUDIO_AAC_LC:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: AAC\n");
|
||||
break;
|
||||
case HDMI_AUDIO_DTS:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: DTS\n");
|
||||
break;
|
||||
case HDMI_AUDIO_ATARC:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: ATARC\n");
|
||||
break;
|
||||
case HDMI_AUDIO_DSD:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: DSD\n");
|
||||
break;
|
||||
case HDMI_AUDIO_E_AC3:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: E-AC3\n");
|
||||
break;
|
||||
case HDMI_AUDIO_DTS_HD:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: DTS-HD\n");
|
||||
break;
|
||||
case HDMI_AUDIO_MLP:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: MLP\n");
|
||||
break;
|
||||
case HDMI_AUDIO_DST:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: DST\n");
|
||||
break;
|
||||
case HDMI_AUDIO_WMA_PRO:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: WMP-PRO\n");
|
||||
break;
|
||||
default:
|
||||
hdmi_dbg(hdmi->dev, "Support audio type: Unkown\n");
|
||||
break;
|
||||
}
|
||||
|
||||
hdmi_dbg(hdmi->dev, "Support audio sample rate: \n");
|
||||
if(audio->rate & HDMI_AUDIO_FS_32000)
|
||||
|
||||
hdmi_dbg(hdmi->dev, "Support audio sample rate:\n");
|
||||
if (audio->rate & HDMI_AUDIO_FS_32000)
|
||||
hdmi_dbg(hdmi->dev, " 32000\n");
|
||||
if(audio->rate & HDMI_AUDIO_FS_44100)
|
||||
if (audio->rate & HDMI_AUDIO_FS_44100)
|
||||
hdmi_dbg(hdmi->dev, " 44100\n");
|
||||
if(audio->rate & HDMI_AUDIO_FS_48000)
|
||||
if (audio->rate & HDMI_AUDIO_FS_48000)
|
||||
hdmi_dbg(hdmi->dev, " 48000\n");
|
||||
if(audio->rate & HDMI_AUDIO_FS_88200)
|
||||
if (audio->rate & HDMI_AUDIO_FS_88200)
|
||||
hdmi_dbg(hdmi->dev, " 88200\n");
|
||||
if(audio->rate & HDMI_AUDIO_FS_96000)
|
||||
if (audio->rate & HDMI_AUDIO_FS_96000)
|
||||
hdmi_dbg(hdmi->dev, " 96000\n");
|
||||
if(audio->rate & HDMI_AUDIO_FS_176400)
|
||||
if (audio->rate & HDMI_AUDIO_FS_176400)
|
||||
hdmi_dbg(hdmi->dev, " 176400\n");
|
||||
if(audio->rate & HDMI_AUDIO_FS_192000)
|
||||
if (audio->rate & HDMI_AUDIO_FS_192000)
|
||||
hdmi_dbg(hdmi->dev, " 192000\n");
|
||||
|
||||
hdmi_dbg(hdmi->dev, "Support audio word lenght: \n");
|
||||
if(audio->rate & HDMI_AUDIO_WORD_LENGTH_16bit)
|
||||
|
||||
hdmi_dbg(hdmi->dev, "Support audio word lenght:\n");
|
||||
if (audio->rate & HDMI_AUDIO_WORD_LENGTH_16bit)
|
||||
hdmi_dbg(hdmi->dev, " 16bit\n");
|
||||
if(audio->rate & HDMI_AUDIO_WORD_LENGTH_20bit)
|
||||
if (audio->rate & HDMI_AUDIO_WORD_LENGTH_20bit)
|
||||
hdmi_dbg(hdmi->dev, " 20bit\n");
|
||||
if(audio->rate & HDMI_AUDIO_WORD_LENGTH_24bit)
|
||||
if (audio->rate & HDMI_AUDIO_WORD_LENGTH_24bit)
|
||||
hdmi_dbg(hdmi->dev, " 24bit\n");
|
||||
}
|
||||
hdmi_dbg(hdmi->dev, "******** Show Sink Info ********\n");
|
||||
@@ -269,68 +274,73 @@ static void hdmi_show_sink_info(struct hdmi *hdmi)
|
||||
int hdmi_ouputmode_select(struct hdmi *hdmi, int edid_ok)
|
||||
{
|
||||
struct list_head *head = &hdmi->edid.modelist;
|
||||
struct fb_monspecs *specs = hdmi->edid.specs;
|
||||
struct fb_monspecs *specs = hdmi->edid.specs;
|
||||
struct fb_videomode *modedb = NULL;
|
||||
int i, pixclock;
|
||||
|
||||
if(edid_ok != HDMI_ERROR_SUCESS) {
|
||||
dev_err(hdmi->dev, "warning: EDID error, assume sink as HDMI and asume minitor support audio output!!!!");
|
||||
|
||||
if (edid_ok != HDMI_ERROR_SUCESS) {
|
||||
dev_err(hdmi->dev,
|
||||
"warning: EDID error, assume sink as HDMI and asume minitor support audio output!!!!");
|
||||
hdmi->edid.sink_hdmi = 1;
|
||||
//if edid error,asume monitor support audio output.
|
||||
/* if edid error,asume monitor support audio output */
|
||||
hdmi->edid.base_audio_support = 1;
|
||||
}
|
||||
|
||||
if(edid_ok != HDMI_ERROR_SUCESS) {
|
||||
if (edid_ok != HDMI_ERROR_SUCESS) {
|
||||
hdmi->edid.ycbcr444 = 0;
|
||||
hdmi->edid.ycbcr422 = 0;
|
||||
hdmi->autoconfig = HDMI_DISABLE;
|
||||
}
|
||||
if(head->next == head) {
|
||||
dev_info(hdmi->dev, "warning: no CEA video mode parsed from EDID !!!!");
|
||||
// If EDID get error, list all system supported mode.
|
||||
// If output mode is set to DVI and EDID is ok, check
|
||||
// the output timing.
|
||||
|
||||
if(hdmi->edid.sink_hdmi == 0 && specs && specs->modedb_len) {
|
||||
if (head->next == head) {
|
||||
dev_info(hdmi->dev,
|
||||
"warning: no CEA video mode parsed from EDID !!!!");
|
||||
/* If EDID get error, list all system supported mode.
|
||||
* If output mode is set to DVI and EDID is ok, check
|
||||
* the output timing.
|
||||
*/
|
||||
|
||||
if (hdmi->edid.sink_hdmi == 0 && specs && specs->modedb_len) {
|
||||
/* Get max resolution timing */
|
||||
modedb = &specs->modedb[0];
|
||||
for (i = 0; i < specs->modedb_len; i++) {
|
||||
if(specs->modedb[i].xres > modedb->xres)
|
||||
if (specs->modedb[i].xres > modedb->xres)
|
||||
modedb = &specs->modedb[i];
|
||||
else if(specs->modedb[i].yres > modedb->yres)
|
||||
else if (specs->modedb[i].yres > modedb->yres)
|
||||
modedb = &specs->modedb[i];
|
||||
}
|
||||
// For some monitor, the max pixclock read from EDID is smaller
|
||||
// than the clock of max resolution mode supported. We fix it.
|
||||
/* For some monitor, the max pixclock read from EDID
|
||||
* is smaller than the clock of
|
||||
* max resolution mode supported.
|
||||
*/
|
||||
pixclock = PICOS2KHZ(modedb->pixclock);
|
||||
pixclock /= 250;
|
||||
pixclock *= 250;
|
||||
pixclock *= 1000;
|
||||
if(pixclock == 148250000)
|
||||
if (pixclock == 148250000)
|
||||
pixclock = 148500000;
|
||||
if(pixclock > specs->dclkmax)
|
||||
if (pixclock > specs->dclkmax)
|
||||
specs->dclkmax = pixclock;
|
||||
}
|
||||
|
||||
for(i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
|
||||
if(modedb) {
|
||||
if( (hdmi_mode[i].pixclock < specs->dclkmin) ||
|
||||
(hdmi_mode[i].pixclock > specs->dclkmax) ||
|
||||
(hdmi_mode[i].refresh < specs->vfmin) ||
|
||||
(hdmi_mode[i].refresh > specs->vfmax) ||
|
||||
(hdmi_mode[i].xres > modedb->xres) ||
|
||||
(hdmi_mode[i].yres > modedb->yres) )
|
||||
continue;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
|
||||
if (modedb) {
|
||||
if ((hdmi_mode[i].pixclock < specs->dclkmin) ||
|
||||
(hdmi_mode[i].pixclock > specs->dclkmax) ||
|
||||
(hdmi_mode[i].refresh < specs->vfmin) ||
|
||||
(hdmi_mode[i].refresh > specs->vfmax) ||
|
||||
(hdmi_mode[i].xres > modedb->xres) ||
|
||||
(hdmi_mode[i].yres > modedb->yres))
|
||||
continue;
|
||||
}
|
||||
hdmi_add_videomode(&hdmi_mode[i], head);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HDMI_DEBUG
|
||||
#ifdef HDMI_DEBUG
|
||||
hdmi_show_sink_info(hdmi);
|
||||
#endif
|
||||
#endif
|
||||
return HDMI_ERROR_SUCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdmi_videomode_compare - compare 2 videomodes
|
||||
* @mode1: first videomode
|
||||
@@ -340,29 +350,27 @@ int hdmi_ouputmode_select(struct hdmi *hdmi, int edid_ok)
|
||||
* 1 if mode1 > mode2, 0 if mode1 = mode2, -1 mode1 < mode2
|
||||
*/
|
||||
static int hdmi_videomode_compare(const struct fb_videomode *mode1,
|
||||
const struct fb_videomode *mode2)
|
||||
const struct fb_videomode *mode2)
|
||||
{
|
||||
if(mode1->xres > mode2->xres)
|
||||
if (mode1->xres > mode2->xres)
|
||||
return 1;
|
||||
else if(mode1->xres == mode2->xres)
|
||||
{
|
||||
if(mode1->yres > mode2->yres)
|
||||
else if (mode1->xres == mode2->xres) {
|
||||
if (mode1->yres > mode2->yres)
|
||||
return 1;
|
||||
else if(mode1->yres == mode2->yres)
|
||||
{
|
||||
if(mode1->pixclock > mode2->pixclock)
|
||||
else if (mode1->yres == mode2->yres) {
|
||||
if (mode1->pixclock > mode2->pixclock)
|
||||
return 1;
|
||||
else if(mode1->pixclock == mode2->pixclock)
|
||||
{
|
||||
if(mode1->refresh > mode2->refresh)
|
||||
else if (mode1->pixclock == mode2->pixclock) {
|
||||
if (mode1->refresh > mode2->refresh)
|
||||
return 1;
|
||||
else if(mode1->refresh == mode2->refresh)
|
||||
else if (mode1->refresh == mode2->refresh)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdmi_add_videomode: adds videomode entry to modelist
|
||||
* @mode: videomode to add
|
||||
@@ -378,67 +386,61 @@ int hdmi_add_videomode(const struct fb_videomode *mode, struct list_head *head)
|
||||
struct fb_videomode *m;
|
||||
int i, found = 0;
|
||||
|
||||
for(i = 0; i < ARRAY_SIZE(hdmi_mode); i++)
|
||||
{
|
||||
m =(struct fb_videomode*) &hdmi_mode[i];
|
||||
if (fb_mode_is_equal(m, mode)) {
|
||||
for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
|
||||
m = (struct fb_videomode *)&hdmi_mode[i];
|
||||
if (fb_mode_is_equal(m, mode)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
list_for_each(pos, head) {
|
||||
modelist = list_entry(pos, struct fb_modelist, list);
|
||||
m = &modelist->mode;
|
||||
if (fb_mode_is_equal(m, mode)) {
|
||||
// m == mode
|
||||
/* m == mode */
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(hdmi_videomode_compare(m, mode) == -1) {
|
||||
} else {
|
||||
if (hdmi_videomode_compare(m, mode) == -1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
modelist_new = kmalloc(sizeof(struct fb_modelist),
|
||||
GFP_KERNEL);
|
||||
modelist_new = kmalloc(sizeof(struct fb_modelist), GFP_KERNEL);
|
||||
if (!modelist_new)
|
||||
return -ENOMEM;
|
||||
return -ENOMEM;
|
||||
modelist_new->mode = hdmi_mode[i];
|
||||
list_add_tail(&modelist_new->list, pos);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdmi_videomode_to_vic: transverse video mode to vic
|
||||
* @vmode: videomode to transverse
|
||||
*
|
||||
*
|
||||
*/
|
||||
int hdmi_videomode_to_vic(struct fb_videomode *vmode)
|
||||
{
|
||||
unsigned char vic = 0;
|
||||
int i = 0;
|
||||
|
||||
for(i = 0; i < ARRAY_SIZE(hdmi_mode); i++)
|
||||
{
|
||||
if( vmode->vmode == hdmi_mode[i].vmode &&
|
||||
vmode->refresh == hdmi_mode[i].refresh &&
|
||||
vmode->xres == hdmi_mode[i].xres &&
|
||||
vmode->left_margin == hdmi_mode[i].left_margin &&
|
||||
vmode->right_margin == hdmi_mode[i].right_margin &&
|
||||
vmode->upper_margin == hdmi_mode[i].upper_margin &&
|
||||
vmode->lower_margin == hdmi_mode[i].lower_margin &&
|
||||
vmode->hsync_len == hdmi_mode[i].hsync_len &&
|
||||
vmode->vsync_len == hdmi_mode[i].vsync_len)
|
||||
{
|
||||
if( (vmode->vmode == FB_VMODE_NONINTERLACED && vmode->yres == hdmi_mode[i].yres) ||
|
||||
(vmode->vmode == FB_VMODE_INTERLACED && vmode->yres == hdmi_mode[i].yres/2))
|
||||
{
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
|
||||
if (vmode->vmode == hdmi_mode[i].vmode &&
|
||||
vmode->refresh == hdmi_mode[i].refresh &&
|
||||
vmode->xres == hdmi_mode[i].xres &&
|
||||
vmode->left_margin == hdmi_mode[i].left_margin &&
|
||||
vmode->right_margin == hdmi_mode[i].right_margin &&
|
||||
vmode->upper_margin == hdmi_mode[i].upper_margin &&
|
||||
vmode->lower_margin == hdmi_mode[i].lower_margin &&
|
||||
vmode->hsync_len == hdmi_mode[i].hsync_len &&
|
||||
vmode->vsync_len == hdmi_mode[i].vsync_len) {
|
||||
if ((vmode->vmode == FB_VMODE_NONINTERLACED
|
||||
&& vmode->yres == hdmi_mode[i].yres)
|
||||
|| (vmode->vmode == FB_VMODE_INTERLACED
|
||||
&& vmode->yres == hdmi_mode[i].yres / 2)) {
|
||||
vic = hdmi_mode[i].flag;
|
||||
break;
|
||||
}
|
||||
@@ -450,18 +452,17 @@ int hdmi_videomode_to_vic(struct fb_videomode *vmode)
|
||||
/**
|
||||
* hdmi_vic_to_videomode: transverse vic mode to video mode
|
||||
* @vmode: vic to transverse
|
||||
*
|
||||
*
|
||||
*/
|
||||
const struct fb_videomode* hdmi_vic_to_videomode(int vic)
|
||||
const struct fb_videomode *hdmi_vic_to_videomode(int vic)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(vic == 0)
|
||||
|
||||
if (vic == 0)
|
||||
return NULL;
|
||||
|
||||
for(i = 0; i < ARRAY_SIZE(hdmi_mode); i++)
|
||||
{
|
||||
if(hdmi_mode[i].flag == vic)
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
|
||||
if (hdmi_mode[i].flag == vic)
|
||||
return &hdmi_mode[i];
|
||||
}
|
||||
return NULL;
|
||||
@@ -469,37 +470,34 @@ const struct fb_videomode* hdmi_vic_to_videomode(int vic)
|
||||
|
||||
/**
|
||||
* hdmi_find_best_mode: find the video mode nearest to input vic
|
||||
* @hdmi:
|
||||
* @hdmi:
|
||||
* @vic: input vic
|
||||
*
|
||||
*
|
||||
* NOTES:
|
||||
* If vic is zero, return the high resolution video mode vic.
|
||||
*/
|
||||
int hdmi_find_best_mode(struct hdmi* hdmi, int vic)
|
||||
int hdmi_find_best_mode(struct hdmi *hdmi, int vic)
|
||||
{
|
||||
struct list_head *pos, *head = &hdmi->edid.modelist;
|
||||
struct fb_modelist *modelist;
|
||||
struct fb_videomode *m = NULL;
|
||||
int found = 0;
|
||||
|
||||
if(vic)
|
||||
{
|
||||
|
||||
if (vic) {
|
||||
list_for_each(pos, head) {
|
||||
modelist = list_entry(pos, struct fb_modelist, list);
|
||||
m = &modelist->mode;
|
||||
if(m->flag == vic)
|
||||
{
|
||||
found = 1;
|
||||
if (m->flag == vic) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( (vic == 0 || found == 0) && head->next != head)
|
||||
{
|
||||
if ((vic == 0 || found == 0) && head->next != head) {
|
||||
modelist = list_entry(head->next, struct fb_modelist, list);
|
||||
m = &modelist->mode;
|
||||
}
|
||||
if(m != NULL)
|
||||
if (m != NULL)
|
||||
return m->flag;
|
||||
else
|
||||
return 0;
|
||||
@@ -508,13 +506,12 @@ int hdmi_find_best_mode(struct hdmi* hdmi, int vic)
|
||||
const char *hdmi_get_video_mode_name(unsigned char vic)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < ARRAY_SIZE(hdmi_mode); i++)
|
||||
{
|
||||
if(vic == hdmi_mode[i].flag)
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
|
||||
if (vic == hdmi_mode[i].flag)
|
||||
break;
|
||||
}
|
||||
if(i == ARRAY_SIZE(hdmi_mode))
|
||||
if (i == ARRAY_SIZE(hdmi_mode))
|
||||
return NULL;
|
||||
else
|
||||
return hdmi_mode[i].name;
|
||||
@@ -522,40 +519,38 @@ const char *hdmi_get_video_mode_name(unsigned char vic)
|
||||
|
||||
/**
|
||||
* hdmi_switch_fb: switch lcdc mode to required video mode
|
||||
* @hdmi:
|
||||
* @hdmi:
|
||||
* @type:
|
||||
*
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
*
|
||||
*/
|
||||
int hdmi_switch_fb(struct hdmi *hdmi, int vic)
|
||||
{
|
||||
int rc = 0;
|
||||
struct rk_screen *screen;
|
||||
|
||||
|
||||
screen = kzalloc(sizeof(struct rk_screen), GFP_KERNEL);
|
||||
if(screen == NULL)
|
||||
|
||||
screen = kzalloc(sizeof(struct rk_screen), GFP_KERNEL);
|
||||
if (screen == NULL)
|
||||
return -1;
|
||||
|
||||
if(hdmi->vic == 0)
|
||||
|
||||
if (hdmi->vic == 0)
|
||||
hdmi->vic = HDMI_VIDEO_DEFAULT_MODE;
|
||||
|
||||
|
||||
rc = hdmi_set_info(screen, hdmi->vic);
|
||||
|
||||
if(rc == 0) {
|
||||
if(hdmi->set_vif)
|
||||
hdmi->set_vif(hdmi,screen,0); //turn off vif for jettab
|
||||
if (rc == 0) {
|
||||
if (hdmi->set_vif) /* turn off vif for jettab */
|
||||
hdmi->set_vif(hdmi, screen, 0);
|
||||
rk_fb_switch_screen(screen, 1, hdmi->lcdc->id);
|
||||
rk_fb_disp_scale(hdmi->xscale, hdmi->yscale, hdmi->lcdc->id);
|
||||
if(hdmi->set_vif)
|
||||
hdmi->set_vif(hdmi,screen,1);
|
||||
if (hdmi->set_vif)
|
||||
hdmi->set_vif(hdmi, screen, 1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
kfree(screen);
|
||||
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -570,11 +565,14 @@ int hdmi_init_video_para(struct hdmi *hdmi_drv, struct hdmi_video_para *video)
|
||||
memset(video, 0, sizeof(struct hdmi_video_para));
|
||||
video->vic = hdmi_drv->vic;
|
||||
video->input_mode = VIDEO_INPUT_RGB_YCBCR_444;
|
||||
video->input_color = VIDEO_INPUT_COLOR_RGB;//VIDEO_INPUT_COLOR_YCBCR
|
||||
video->input_color = VIDEO_INPUT_COLOR_RGB;
|
||||
video->output_mode = hdmi_drv->edid.sink_hdmi;
|
||||
video->format_3d = 0; /*TODO modify according to EDID if need*/
|
||||
video->format_3d = 0; /* TODO modify according to EDID if need */
|
||||
video->pixel_repet = 0;
|
||||
video->color_limit_range = 1; //0:IT Video Format 1:CE Video Format --TODO modify according to EDID
|
||||
/* 0:IT Video Format 1:CE Video Format
|
||||
* TODO modify according to EDID
|
||||
*/
|
||||
video->color_limit_range = 1;
|
||||
|
||||
#ifdef SOURCE_ABOVE_10BIT
|
||||
if (hdmi_drv->edid.deepcolor & HDMI_COLOR_DEPTH_16BIT)
|
||||
@@ -595,7 +593,7 @@ int hdmi_init_video_para(struct hdmi *hdmi_drv, struct hdmi_video_para *video)
|
||||
else
|
||||
video->output_color = VIDEO_OUTPUT_RGB444;
|
||||
|
||||
/*For DVI, output RGB*/
|
||||
/*For DVI, output RGB */
|
||||
if (hdmi_drv->edid.sink_hdmi == 0)
|
||||
video->output_color = VIDEO_OUTPUT_RGB444;
|
||||
|
||||
@@ -616,13 +614,13 @@ int hdmi_drv_register(struct hdmi *hdmi_drv)
|
||||
|
||||
/**
|
||||
* hdmi_get_status: get hdmi hotplug status
|
||||
*
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
*
|
||||
*/
|
||||
int hdmi_get_hotplug(void)
|
||||
{
|
||||
if(m_hdmi_drv)
|
||||
if (m_hdmi_drv)
|
||||
return m_hdmi_drv->hotplug;
|
||||
else
|
||||
return HDMI_HPD_REMOVED;
|
||||
|
||||
@@ -4,14 +4,13 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
|
||||
|
||||
/* rk hdmi power control parse from dts
|
||||
*
|
||||
*/
|
||||
int rk_hdmi_pwr_ctr_parse_dt(struct hdmi *dev_drv)
|
||||
{
|
||||
struct device_node *root = of_find_node_by_name(dev_drv->dev->of_node,
|
||||
"power_ctr_hdmi");
|
||||
struct device_node *root = of_find_node_by_name(dev_drv->dev->of_node,
|
||||
"power_ctr_hdmi");
|
||||
struct device_node *child;
|
||||
struct rk_disp_pwr_ctr_list *pwr_ctr;
|
||||
struct list_head *pos;
|
||||
@@ -22,26 +21,34 @@ int rk_hdmi_pwr_ctr_parse_dt(struct hdmi *dev_drv)
|
||||
|
||||
INIT_LIST_HEAD(&dev_drv->pwrlist_head);
|
||||
if (!root) {
|
||||
dev_err(dev_drv->dev, "can't find power_ctr node %d\n",dev_drv->id);
|
||||
dev_err(dev_drv->dev, "can't find power_ctr node %d\n",
|
||||
dev_drv->id);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
for_each_child_of_node(root, child) {
|
||||
pwr_ctr = kmalloc(sizeof(struct rk_disp_pwr_ctr_list), GFP_KERNEL);
|
||||
pwr_ctr = kmalloc(sizeof(struct rk_disp_pwr_ctr_list),
|
||||
GFP_KERNEL);
|
||||
strcpy(pwr_ctr->pwr_ctr.name, child->name);
|
||||
if (!of_property_read_u32(child, "rockchip,power_type", &val)) {
|
||||
if (val == GPIO) {
|
||||
pwr_ctr->pwr_ctr.type = GPIO;
|
||||
pwr_ctr->pwr_ctr.gpio = of_get_gpio_flags(child, 0, &flags);
|
||||
pwr_ctr->pwr_ctr.gpio =
|
||||
of_get_gpio_flags(child, 0, &flags);
|
||||
if (!gpio_is_valid(pwr_ctr->pwr_ctr.gpio)) {
|
||||
dev_err(dev_drv->dev, "%s ivalid gpio\n", child->name);
|
||||
dev_err(dev_drv->dev,
|
||||
"%s ivalid gpio\n",
|
||||
child->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
pwr_ctr->pwr_ctr.atv_val = flags & OF_GPIO_ACTIVE_LOW;
|
||||
ret = gpio_request(pwr_ctr->pwr_ctr.gpio,child->name);
|
||||
pwr_ctr->pwr_ctr.atv_val =
|
||||
flags & OF_GPIO_ACTIVE_LOW;
|
||||
ret = gpio_request(pwr_ctr->pwr_ctr.gpio,
|
||||
child->name);
|
||||
if (ret) {
|
||||
dev_err(dev_drv->dev, "request %s gpio fail:%d\n",
|
||||
child->name,ret);
|
||||
dev_err(dev_drv->dev,
|
||||
"request %s gpio fail:%d\n",
|
||||
child->name, ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -61,17 +68,17 @@ int rk_hdmi_pwr_ctr_parse_dt(struct hdmi *dev_drv)
|
||||
|
||||
if (debug) {
|
||||
list_for_each(pos, &dev_drv->pwrlist_head) {
|
||||
pwr_ctr = list_entry(pos, struct rk_disp_pwr_ctr_list, list);
|
||||
printk(KERN_INFO "pwr_ctr_name:%s\n"
|
||||
"pwr_type:%s\n"
|
||||
"gpio:%d\n"
|
||||
"atv_val:%d\n"
|
||||
"delay:%d\n\n",
|
||||
pwr_ctr->pwr_ctr.name,
|
||||
(pwr_ctr->pwr_ctr.type == GPIO) ? "gpio" : "regulator",
|
||||
pwr_ctr->pwr_ctr.gpio,
|
||||
pwr_ctr->pwr_ctr.atv_val,
|
||||
pwr_ctr->pwr_ctr.delay);
|
||||
pwr_ctr = list_entry(pos, struct rk_disp_pwr_ctr_list,
|
||||
list);
|
||||
dev_info(dev_drv->dev, "pwr_ctr_name:%s\n"
|
||||
"pwr_type:%s\n" "gpio:%d\n"
|
||||
"atv_val:%d\n" "delay:%d\n\n",
|
||||
pwr_ctr->pwr_ctr.name,
|
||||
(pwr_ctr->pwr_ctr.type == GPIO) ?
|
||||
"gpio" : "regulator",
|
||||
pwr_ctr->pwr_ctr.gpio,
|
||||
pwr_ctr->pwr_ctr.atv_val,
|
||||
pwr_ctr->pwr_ctr.delay);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,13 +96,14 @@ int rk_hdmi_pwr_enable(struct hdmi *dev_drv)
|
||||
return 0;
|
||||
|
||||
list_for_each(pos, &dev_drv->pwrlist_head) {
|
||||
pwr_ctr_list = list_entry(pos, struct rk_disp_pwr_ctr_list, list);
|
||||
pwr_ctr_list = list_entry(pos, struct rk_disp_pwr_ctr_list,
|
||||
list);
|
||||
pwr_ctr = &pwr_ctr_list->pwr_ctr;
|
||||
if (pwr_ctr->type == GPIO) {
|
||||
gpio_direction_output(pwr_ctr->gpio,pwr_ctr->atv_val);
|
||||
gpio_direction_output(pwr_ctr->gpio, pwr_ctr->atv_val);
|
||||
mdelay(pwr_ctr->delay);
|
||||
if(pwr_ctr->is_rst == 1) {
|
||||
if(pwr_ctr->atv_val == 1)
|
||||
if (pwr_ctr->is_rst == 1) {
|
||||
if (pwr_ctr->atv_val == 1)
|
||||
gpio_set_value(pwr_ctr->gpio, 0);
|
||||
else
|
||||
gpio_set_value(pwr_ctr->gpio, 1);
|
||||
@@ -118,12 +126,13 @@ int rk_hdmi_pwr_disable(struct hdmi *dev_drv)
|
||||
return 0;
|
||||
|
||||
list_for_each(pos, &dev_drv->pwrlist_head) {
|
||||
pwr_ctr_list = list_entry(pos, struct rk_disp_pwr_ctr_list, list);
|
||||
pwr_ctr_list = list_entry(pos, struct rk_disp_pwr_ctr_list,
|
||||
list);
|
||||
pwr_ctr = &pwr_ctr_list->pwr_ctr;
|
||||
if (pwr_ctr->type == GPIO) {
|
||||
gpio_set_value(pwr_ctr->gpio,pwr_ctr->atv_val);
|
||||
if(pwr_ctr->is_rst == 1) {
|
||||
if(pwr_ctr->atv_val == 1)
|
||||
gpio_set_value(pwr_ctr->gpio, pwr_ctr->atv_val);
|
||||
if (pwr_ctr->is_rst == 1) {
|
||||
if (pwr_ctr->atv_val == 1)
|
||||
gpio_set_value(pwr_ctr->gpio, 0);
|
||||
else
|
||||
gpio_set_value(pwr_ctr->gpio, 1);
|
||||
@@ -137,16 +146,16 @@ int rk_hdmi_pwr_disable(struct hdmi *dev_drv)
|
||||
int rk_hdmi_parse_dt(struct hdmi *hdmi_drv)
|
||||
{
|
||||
struct device_node *np = hdmi_drv->dev->of_node;
|
||||
int ret = 0,gpio = 0;
|
||||
int ret = 0, gpio = 0;
|
||||
|
||||
if (!np) {
|
||||
dev_err(hdmi_drv->dev, "could not find hdmi node\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gpio = of_get_named_gpio(np,"rockchips,hdmi_irq_gpio", 0);
|
||||
gpio = of_get_named_gpio(np, "rockchips,hdmi_irq_gpio", 0);
|
||||
if (!gpio_is_valid(gpio))
|
||||
dev_info(hdmi_drv->dev, "invalid hdmi_irq_gpio: %d\n",gpio);
|
||||
dev_info(hdmi_drv->dev, "invalid hdmi_irq_gpio: %d\n", gpio);
|
||||
hdmi_drv->irq = gpio;
|
||||
|
||||
ret = rk_hdmi_pwr_ctr_parse_dt(hdmi_drv);
|
||||
@@ -170,4 +179,3 @@ int rk_hdmi_parse_dt(struct hdmi *hdmi_drv)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -8,43 +8,43 @@ static int hdmi_get_enable(struct rk_display_device *device)
|
||||
{
|
||||
struct hdmi *hdmi = device->priv_data;
|
||||
int enable;
|
||||
|
||||
|
||||
mutex_lock(&hdmi->enable_mutex);
|
||||
enable = hdmi->enable;
|
||||
mutex_unlock(&hdmi->enable_mutex);
|
||||
|
||||
|
||||
return enable;
|
||||
}
|
||||
|
||||
static int hdmi_set_enable(struct rk_display_device *device, int enable)
|
||||
{
|
||||
struct hdmi *hdmi = device->priv_data;
|
||||
|
||||
|
||||
mutex_lock(&hdmi->enable_mutex);
|
||||
if(hdmi->enable == enable) {
|
||||
if (hdmi->enable == enable) {
|
||||
mutex_unlock(&hdmi->enable_mutex);
|
||||
return 0;
|
||||
}
|
||||
hdmi->enable = enable;
|
||||
|
||||
if(hdmi->suspend ) {
|
||||
|
||||
if (hdmi->suspend) {
|
||||
mutex_unlock(&hdmi->enable_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(enable == 0) {
|
||||
if(hdmi->irq)
|
||||
|
||||
if (enable == 0) {
|
||||
if (hdmi->irq)
|
||||
disable_irq(hdmi->irq);
|
||||
mutex_unlock(&hdmi->enable_mutex);
|
||||
hdmi->command = HDMI_CONFIG_ENABLE;
|
||||
queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, 0);
|
||||
}
|
||||
else {
|
||||
if(hdmi->irq)
|
||||
} else {
|
||||
if (hdmi->irq)
|
||||
enable_irq(hdmi->irq);
|
||||
#if defined(CONFIG_HDMI_RK610) || defined(CONFIG_HDMI_RK2928) || defined(CONFIG_HDMI_CAT66121) || defined(CONFIG_HDMI_RK616)
|
||||
queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, 0);
|
||||
#endif
|
||||
#if defined(CONFIG_HDMI_RK610) || defined(CONFIG_HDMI_RK2928)
|
||||
|| defined(CONFIG_HDMI_CAT66121) || defined(CONFIG_HDMI_RK616)
|
||||
queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, 0);
|
||||
#endif
|
||||
mutex_unlock(&hdmi->enable_mutex);
|
||||
}
|
||||
return 0;
|
||||
@@ -53,70 +53,74 @@ static int hdmi_set_enable(struct rk_display_device *device, int enable)
|
||||
static int hdmi_get_status(struct rk_display_device *device)
|
||||
{
|
||||
struct hdmi *hdmi = device->priv_data;
|
||||
if(hdmi->hotplug == HDMI_HPD_ACTIVED)
|
||||
if (hdmi->hotplug == HDMI_HPD_ACTIVED)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_get_modelist(struct rk_display_device *device, struct list_head **modelist)
|
||||
static int hdmi_get_modelist(struct rk_display_device *device,
|
||||
struct list_head **modelist)
|
||||
{
|
||||
struct hdmi *hdmi = device->priv_data;
|
||||
if(!hdmi->hotplug)
|
||||
if (!hdmi->hotplug)
|
||||
return -1;
|
||||
*modelist = &hdmi->edid.modelist;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_set_mode(struct rk_display_device *device, struct fb_videomode *mode)
|
||||
static int hdmi_set_mode(struct rk_display_device *device,
|
||||
struct fb_videomode *mode)
|
||||
{
|
||||
struct hdmi *hdmi = device->priv_data;
|
||||
int vic = hdmi_videomode_to_vic(mode);
|
||||
|
||||
|
||||
hdmi->autoconfig = HDMI_DISABLE;
|
||||
if(vic && hdmi->vic != vic)
|
||||
{
|
||||
if (vic && hdmi->vic != vic) {
|
||||
hdmi->vic = vic;
|
||||
if(!hdmi->hotplug)
|
||||
if (!hdmi->hotplug)
|
||||
return 0;
|
||||
hdmi->command = HDMI_CONFIG_VIDEO;
|
||||
init_completion(&hdmi->complete);
|
||||
hdmi->wait = 1;
|
||||
queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, 0);
|
||||
wait_for_completion_interruptible_timeout(&hdmi->complete,
|
||||
msecs_to_jiffies(10000));
|
||||
msecs_to_jiffies
|
||||
(10000));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_get_mode(struct rk_display_device *device, struct fb_videomode *mode)
|
||||
static int hdmi_get_mode(struct rk_display_device *device,
|
||||
struct fb_videomode *mode)
|
||||
{
|
||||
struct hdmi *hdmi = device->priv_data;
|
||||
struct fb_videomode *vmode;
|
||||
|
||||
if(!hdmi->hotplug)
|
||||
|
||||
if (!hdmi->hotplug)
|
||||
return -1;
|
||||
|
||||
vmode = (struct fb_videomode*) hdmi_vic_to_videomode(hdmi->vic);
|
||||
if(unlikely(vmode == NULL))
|
||||
|
||||
vmode = (struct fb_videomode *)hdmi_vic_to_videomode(hdmi->vic);
|
||||
if (unlikely(vmode == NULL))
|
||||
return -1;
|
||||
*mode = *vmode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_set_scale(struct rk_display_device *device, int direction, int value)
|
||||
static int hdmi_set_scale(struct rk_display_device *device, int direction,
|
||||
int value)
|
||||
{
|
||||
struct hdmi *hdmi = device->priv_data;
|
||||
|
||||
if(!hdmi || value < 0 || value > 100)
|
||||
|
||||
if (!hdmi || value < 0 || value > 100)
|
||||
return -1;
|
||||
|
||||
if(!hdmi->hotplug)
|
||||
return 0;
|
||||
|
||||
if(direction == DISPLAY_SCALE_X)
|
||||
if (!hdmi->hotplug)
|
||||
return 0;
|
||||
|
||||
if (direction == DISPLAY_SCALE_X)
|
||||
hdmi->xscale = value;
|
||||
else if(direction == DISPLAY_SCALE_Y)
|
||||
else if (direction == DISPLAY_SCALE_Y)
|
||||
hdmi->yscale = value;
|
||||
else
|
||||
return -1;
|
||||
@@ -127,13 +131,13 @@ static int hdmi_set_scale(struct rk_display_device *device, int direction, int v
|
||||
static int hdmi_get_scale(struct rk_display_device *device, int direction)
|
||||
{
|
||||
struct hdmi *hdmi = device->priv_data;
|
||||
|
||||
if(!hdmi)
|
||||
|
||||
if (!hdmi)
|
||||
return -1;
|
||||
|
||||
if(direction == DISPLAY_SCALE_X)
|
||||
|
||||
if (direction == DISPLAY_SCALE_X)
|
||||
return hdmi->xscale;
|
||||
else if(direction == DISPLAY_SCALE_Y)
|
||||
else if (direction == DISPLAY_SCALE_Y)
|
||||
return hdmi->yscale;
|
||||
else
|
||||
return -1;
|
||||
@@ -156,11 +160,11 @@ static int hdmi_display_probe(struct rk_display_device *device, void *devdata)
|
||||
device->owner = THIS_MODULE;
|
||||
strcpy(device->type, "HDMI");
|
||||
device->priority = DISPLAY_PRIORITY_HDMI;
|
||||
// device->name = kmalloc(strlen(name), GFP_KERNEL);
|
||||
// if(device->name)
|
||||
// {
|
||||
// strcpy(device->name, name);
|
||||
// }
|
||||
/*
|
||||
device->name = kmalloc(strlen(name), GFP_KERNEL);
|
||||
if(device->name)
|
||||
strcpy(device->name, name);
|
||||
*/
|
||||
device->priv_data = devdata;
|
||||
device->ops = &hdmi_display_ops;
|
||||
return 1;
|
||||
@@ -170,22 +174,24 @@ static struct rk_display_driver display_hdmi = {
|
||||
.probe = hdmi_display_probe,
|
||||
};
|
||||
|
||||
static struct rk_display_device *display_device_hdmi = NULL;
|
||||
static struct rk_display_device *display_device_hdmi;
|
||||
#ifdef CONFIG_DRM_ROCKCHIP
|
||||
extern void rk_drm_display_register(struct rk_display_ops *extend_ops, void *displaydata,int type);
|
||||
extern void rk_drm_display_register(struct rk_display_ops *extend_ops,
|
||||
void *displaydata, int type);
|
||||
#endif
|
||||
|
||||
void hdmi_register_display_sysfs(struct hdmi *hdmi, struct device *parent)
|
||||
{
|
||||
display_device_hdmi = rk_display_device_register(&display_hdmi, parent, hdmi);
|
||||
display_device_hdmi =
|
||||
rk_display_device_register(&display_hdmi, parent, hdmi);
|
||||
#ifdef CONFIG_DRM_ROCKCHIP
|
||||
rk_drm_display_register(&hdmi_display_ops,hdmi,SCREEN_HDMI);
|
||||
rk_drm_display_register(&hdmi_display_ops, hdmi, SCREEN_HDMI);
|
||||
#endif
|
||||
}
|
||||
|
||||
void hdmi_unregister_display_sysfs(struct hdmi *hdmi)
|
||||
{
|
||||
if(display_device_hdmi)
|
||||
if (display_device_hdmi)
|
||||
rk_display_device_unregister(display_device_hdmi);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -8,58 +8,57 @@
|
||||
#define HDMI_MAX_TRY_TIMES 1
|
||||
#define HDMI_MAX_ID 1
|
||||
|
||||
static char *envp[] = {"INTERFACE=HDMI", NULL};
|
||||
static char *envp[] = { "INTERFACE=HDMI", NULL };
|
||||
|
||||
static void hdmi_sys_show_state(struct hdmi *hdmi)
|
||||
{
|
||||
switch(hdmi->state)
|
||||
{
|
||||
case HDMI_SLEEP:
|
||||
hdmi_dbg(hdmi->dev, "HDMI_SLEEP\n");
|
||||
break;
|
||||
case HDMI_INITIAL:
|
||||
hdmi_dbg(hdmi->dev, "HDMI_INITIAL\n");
|
||||
break;
|
||||
case WAIT_HOTPLUG:
|
||||
hdmi_dbg(hdmi->dev, "WAIT_HOTPLUG\n");
|
||||
break;
|
||||
case READ_PARSE_EDID:
|
||||
hdmi_dbg(hdmi->dev, "READ_PARSE_EDID\n");
|
||||
break;
|
||||
case WAIT_HDMI_ENABLE:
|
||||
hdmi_dbg(hdmi->dev, "WAIT_HDMI_ENABLE\n");
|
||||
break;
|
||||
case SYSTEM_CONFIG:
|
||||
hdmi_dbg(hdmi->dev, "SYSTEM_CONFIG\n");
|
||||
break;
|
||||
case CONFIG_VIDEO:
|
||||
hdmi_dbg(hdmi->dev, "CONFIG_VIDEO\n");
|
||||
break;
|
||||
case CONFIG_AUDIO:
|
||||
hdmi_dbg(hdmi->dev, "CONFIG_AUDIO\n");
|
||||
break;
|
||||
case PLAY_BACK:
|
||||
hdmi_dbg(hdmi->dev, "PLAY_BACK\n");
|
||||
break;
|
||||
default:
|
||||
hdmi_dbg(hdmi->dev, "Unkown State %d\n", hdmi->state);
|
||||
break;
|
||||
switch (hdmi->state) {
|
||||
case HDMI_SLEEP:
|
||||
hdmi_dbg(hdmi->dev, "HDMI_SLEEP\n");
|
||||
break;
|
||||
case HDMI_INITIAL:
|
||||
hdmi_dbg(hdmi->dev, "HDMI_INITIAL\n");
|
||||
break;
|
||||
case WAIT_HOTPLUG:
|
||||
hdmi_dbg(hdmi->dev, "WAIT_HOTPLUG\n");
|
||||
break;
|
||||
case READ_PARSE_EDID:
|
||||
hdmi_dbg(hdmi->dev, "READ_PARSE_EDID\n");
|
||||
break;
|
||||
case WAIT_HDMI_ENABLE:
|
||||
hdmi_dbg(hdmi->dev, "WAIT_HDMI_ENABLE\n");
|
||||
break;
|
||||
case SYSTEM_CONFIG:
|
||||
hdmi_dbg(hdmi->dev, "SYSTEM_CONFIG\n");
|
||||
break;
|
||||
case CONFIG_VIDEO:
|
||||
hdmi_dbg(hdmi->dev, "CONFIG_VIDEO\n");
|
||||
break;
|
||||
case CONFIG_AUDIO:
|
||||
hdmi_dbg(hdmi->dev, "CONFIG_AUDIO\n");
|
||||
break;
|
||||
case PLAY_BACK:
|
||||
hdmi_dbg(hdmi->dev, "PLAY_BACK\n");
|
||||
break;
|
||||
default:
|
||||
hdmi_dbg(hdmi->dev, "Unkown State %d\n", hdmi->state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int hdmi_sys_init(struct hdmi *hdmi)
|
||||
{
|
||||
hdmi->hotplug = HDMI_HPD_REMOVED;
|
||||
hdmi->state = HDMI_SLEEP;
|
||||
hdmi->enable = HDMI_ENABLE;
|
||||
hdmi->autoconfig = HDMI_AUTO_CONFIGURE;
|
||||
hdmi->display = HDMI_DISABLE;
|
||||
|
||||
hdmi->vic = HDMI_VIDEO_DEFAULT_MODE;
|
||||
hdmi->audio.channel = HDMI_AUDIO_DEFAULT_CHANNEL;
|
||||
hdmi->audio.rate = HDMI_AUDIO_DEFAULT_RATE;
|
||||
hdmi->audio.word_length = HDMI_AUDIO_DEFAULT_WORD_LENGTH;
|
||||
|
||||
hdmi->hotplug = HDMI_HPD_REMOVED;
|
||||
hdmi->state = HDMI_SLEEP;
|
||||
hdmi->enable = HDMI_ENABLE;
|
||||
hdmi->autoconfig = HDMI_AUTO_CONFIGURE;
|
||||
hdmi->display = HDMI_DISABLE;
|
||||
|
||||
hdmi->vic = HDMI_VIDEO_DEFAULT_MODE;
|
||||
hdmi->audio.channel = HDMI_AUDIO_DEFAULT_CHANNEL;
|
||||
hdmi->audio.rate = HDMI_AUDIO_DEFAULT_RATE;
|
||||
hdmi->audio.word_length = HDMI_AUDIO_DEFAULT_WORD_LENGTH;
|
||||
|
||||
memset(&hdmi->edid, 0, sizeof(struct hdmi_edid));
|
||||
INIT_LIST_HEAD(&hdmi->edid.modelist);
|
||||
return 0;
|
||||
@@ -69,40 +68,38 @@ void hdmi_sys_remove(struct hdmi *hdmi)
|
||||
{
|
||||
int audio_need;
|
||||
|
||||
audio_need = hdmi->edid.base_audio_support == 1 && hdmi->edid.sink_hdmi == 1;
|
||||
|
||||
audio_need = hdmi->edid.base_audio_support == 1
|
||||
&& hdmi->edid.sink_hdmi == 1;
|
||||
|
||||
fb_destroy_modelist(&hdmi->edid.modelist);
|
||||
if(hdmi->edid.audio)
|
||||
kfree(hdmi->edid.audio);
|
||||
if(hdmi->edid.specs)
|
||||
{
|
||||
if(hdmi->edid.specs->modedb)
|
||||
kfree(hdmi->edid.specs->modedb);
|
||||
kfree(hdmi->edid.audio);
|
||||
if (hdmi->edid.specs) {
|
||||
kfree(hdmi->edid.specs->modedb);
|
||||
kfree(hdmi->edid.specs);
|
||||
}
|
||||
memset(&hdmi->edid, 0, sizeof(struct hdmi_edid));
|
||||
INIT_LIST_HEAD(&hdmi->edid.modelist);
|
||||
hdmi->display = HDMI_DISABLE;
|
||||
if(hdmi->set_vif)
|
||||
hdmi->set_vif(hdmi,hdmi->lcdc->screen1,0);
|
||||
hdmi->display = HDMI_DISABLE;
|
||||
if (hdmi->set_vif)
|
||||
hdmi->set_vif(hdmi, hdmi->lcdc->screen1, 0);
|
||||
rk_fb_switch_screen(hdmi->lcdc->screen1, 0, hdmi->lcdc->id);
|
||||
kobject_uevent_env(&hdmi->dev->kobj, KOBJ_REMOVE, envp);
|
||||
|
||||
#ifdef CONFIG_SWITCH
|
||||
if(audio_need)
|
||||
#ifdef CONFIG_SWITCH
|
||||
if (audio_need)
|
||||
switch_set_state(&(hdmi->switch_hdmi), 0);
|
||||
#endif
|
||||
#endif
|
||||
rockchip_clear_system_status(SYS_STATUS_HDMI);
|
||||
}
|
||||
|
||||
static void hdmi_sys_sleep(struct hdmi *hdmi)
|
||||
{
|
||||
mutex_lock(&hdmi->enable_mutex);
|
||||
if(hdmi->enable && hdmi->irq)
|
||||
disable_irq(hdmi->irq);
|
||||
if (hdmi->enable && hdmi->irq)
|
||||
disable_irq(hdmi->irq);
|
||||
hdmi->state = HDMI_SLEEP;
|
||||
hdmi->remove(hdmi);
|
||||
if(hdmi->enable && hdmi->irq)
|
||||
if (hdmi->enable && hdmi->irq)
|
||||
enable_irq(hdmi->irq);
|
||||
mutex_unlock(&hdmi->enable_mutex);
|
||||
}
|
||||
@@ -110,59 +107,54 @@ static void hdmi_sys_sleep(struct hdmi *hdmi)
|
||||
static int hdmi_process_command(struct hdmi *hdmi)
|
||||
{
|
||||
int change, state = hdmi->state;
|
||||
|
||||
|
||||
change = hdmi->command;
|
||||
if(change != HDMI_CONFIG_NONE)
|
||||
{
|
||||
if (change != HDMI_CONFIG_NONE) {
|
||||
hdmi->command = HDMI_CONFIG_NONE;
|
||||
switch(change)
|
||||
{
|
||||
case HDMI_CONFIG_ENABLE:
|
||||
/* disable HDMI */
|
||||
mutex_lock(&hdmi->enable_mutex);
|
||||
if(!hdmi->enable || hdmi->suspend)
|
||||
{
|
||||
if(hdmi->hotplug != HDMI_HPD_REMOVED) {
|
||||
hdmi->hotplug = HDMI_HPD_REMOVED;
|
||||
hdmi_sys_remove(hdmi);
|
||||
}
|
||||
hdmi->state = HDMI_SLEEP;
|
||||
hdmi->remove(hdmi);
|
||||
state = HDMI_SLEEP;
|
||||
switch (change) {
|
||||
case HDMI_CONFIG_ENABLE:
|
||||
/* disable HDMI */
|
||||
mutex_lock(&hdmi->enable_mutex);
|
||||
if (!hdmi->enable || hdmi->suspend) {
|
||||
if (hdmi->hotplug != HDMI_HPD_REMOVED) {
|
||||
hdmi->hotplug = HDMI_HPD_REMOVED;
|
||||
hdmi_sys_remove(hdmi);
|
||||
}
|
||||
mutex_unlock(&hdmi->enable_mutex);
|
||||
if(hdmi->wait == 1) {
|
||||
hdmi->state = HDMI_SLEEP;
|
||||
hdmi->remove(hdmi);
|
||||
state = HDMI_SLEEP;
|
||||
}
|
||||
mutex_unlock(&hdmi->enable_mutex);
|
||||
if (hdmi->wait == 1) {
|
||||
complete(&hdmi->complete);
|
||||
hdmi->wait = 0;
|
||||
}
|
||||
break;
|
||||
case HDMI_CONFIG_COLOR:
|
||||
if (state > CONFIG_VIDEO)
|
||||
state = CONFIG_VIDEO;
|
||||
break;
|
||||
case HDMI_CONFIG_HDCP:
|
||||
break;
|
||||
case HDMI_CONFIG_DISPLAY:
|
||||
break;
|
||||
case HDMI_CONFIG_AUDIO:
|
||||
if (state > CONFIG_AUDIO)
|
||||
state = CONFIG_AUDIO;
|
||||
break;
|
||||
case HDMI_CONFIG_VIDEO:
|
||||
default:
|
||||
if (state > SYSTEM_CONFIG)
|
||||
state = SYSTEM_CONFIG;
|
||||
else {
|
||||
if (hdmi->wait == 1) {
|
||||
complete(&hdmi->complete);
|
||||
hdmi->wait = 0;
|
||||
hdmi->wait = 0;
|
||||
}
|
||||
break;
|
||||
case HDMI_CONFIG_COLOR:
|
||||
if(state > CONFIG_VIDEO)
|
||||
state = CONFIG_VIDEO;
|
||||
break;
|
||||
case HDMI_CONFIG_HDCP:
|
||||
break;
|
||||
case HDMI_CONFIG_DISPLAY:
|
||||
break;
|
||||
case HDMI_CONFIG_AUDIO:
|
||||
if(state > CONFIG_AUDIO)
|
||||
state = CONFIG_AUDIO;
|
||||
break;
|
||||
case HDMI_CONFIG_VIDEO:
|
||||
default:
|
||||
if(state > SYSTEM_CONFIG)
|
||||
state = SYSTEM_CONFIG;
|
||||
else
|
||||
{
|
||||
if(hdmi->wait == 1) {
|
||||
complete(&hdmi->complete);
|
||||
hdmi->wait = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(state == HDMI_SLEEP)
|
||||
} else if (state == HDMI_SLEEP)
|
||||
state = WAIT_HOTPLUG;
|
||||
return state;
|
||||
}
|
||||
@@ -174,129 +166,130 @@ void hdmi_work(struct work_struct *work)
|
||||
int hotplug, state_last;
|
||||
int rc = HDMI_ERROR_SUCESS, trytimes = 0;
|
||||
struct hdmi_video_para video;
|
||||
struct delayed_work *delay_work = container_of(work, struct delayed_work, work);
|
||||
struct delayed_work *delay_work =
|
||||
container_of(work, struct delayed_work, work);
|
||||
struct hdmi *hdmi = container_of(delay_work, struct hdmi, delay_work);
|
||||
|
||||
mutex_lock(&work_mutex);
|
||||
/* Process hdmi command */
|
||||
hdmi->state = hdmi_process_command(hdmi);
|
||||
|
||||
if(!hdmi->enable || hdmi->suspend) {
|
||||
|
||||
if (!hdmi->enable || hdmi->suspend) {
|
||||
mutex_unlock(&work_mutex);
|
||||
return;
|
||||
}
|
||||
hotplug = hdmi->detect_hotplug(hdmi);
|
||||
hdmi_dbg(hdmi->dev, "[%s] hotplug %02x curvalue %d\n", __FUNCTION__, hotplug, hdmi->hotplug);
|
||||
|
||||
if(hotplug != hdmi->hotplug)
|
||||
{
|
||||
if(hotplug == HDMI_HPD_ACTIVED){
|
||||
if(hdmi->insert)
|
||||
hdmi_dbg(hdmi->dev, "[%s] hotplug %02x curvalue %d\n", __func__,
|
||||
hotplug, hdmi->hotplug);
|
||||
|
||||
if (hotplug != hdmi->hotplug) {
|
||||
if (hotplug == HDMI_HPD_ACTIVED) {
|
||||
if (hdmi->insert)
|
||||
hdmi->insert(hdmi);
|
||||
hdmi->state = READ_PARSE_EDID;
|
||||
}
|
||||
else if(hdmi->hotplug == HDMI_HPD_ACTIVED) {
|
||||
} else if (hdmi->hotplug == HDMI_HPD_ACTIVED) {
|
||||
hdmi->hotplug = hotplug;
|
||||
hdmi_sys_remove(hdmi);
|
||||
if(hotplug == HDMI_HPD_REMOVED)
|
||||
if (hotplug == HDMI_HPD_REMOVED)
|
||||
hdmi_sys_sleep(hdmi);
|
||||
else {
|
||||
hdmi->state = WAIT_HOTPLUG;
|
||||
hdmi->remove(hdmi);
|
||||
}
|
||||
if(hdmi->wait == 1) {
|
||||
if (hdmi->wait == 1) {
|
||||
complete(&hdmi->complete);
|
||||
hdmi->wait = 0;
|
||||
hdmi->wait = 0;
|
||||
}
|
||||
mutex_unlock(&work_mutex);
|
||||
return;
|
||||
}
|
||||
else if(hotplug == HDMI_HPD_REMOVED) {
|
||||
} else if (hotplug == HDMI_HPD_REMOVED) {
|
||||
hdmi->state = HDMI_SLEEP;
|
||||
hdmi->remove(hdmi);
|
||||
}
|
||||
hdmi->hotplug = hotplug;
|
||||
}
|
||||
else if(hotplug == HDMI_HPD_REMOVED)
|
||||
hdmi->hotplug = hotplug;
|
||||
} else if (hotplug == HDMI_HPD_REMOVED)
|
||||
hdmi_sys_sleep(hdmi);
|
||||
|
||||
|
||||
do {
|
||||
hdmi_sys_show_state(hdmi);
|
||||
state_last = hdmi->state;
|
||||
switch(hdmi->state)
|
||||
{
|
||||
case READ_PARSE_EDID:
|
||||
rc = hdmi_sys_parse_edid(hdmi);
|
||||
if(rc == HDMI_ERROR_SUCESS)
|
||||
{
|
||||
hdmi->state = SYSTEM_CONFIG;
|
||||
kobject_uevent_env(&hdmi->dev->kobj, KOBJ_ADD, envp);
|
||||
hdmi_dbg(hdmi->dev,"[%s] base_audio_support =%d,sink_hdmi = %d\n", __FUNCTION__, hdmi->edid.base_audio_support, hdmi->edid.sink_hdmi);
|
||||
#ifdef CONFIG_SWITCH
|
||||
if(hdmi->edid.base_audio_support == 1 && hdmi->edid.sink_hdmi == 1)
|
||||
switch_set_state(&(hdmi->switch_hdmi), 1);
|
||||
#endif
|
||||
rockchip_set_system_status(SYS_STATUS_HDMI);
|
||||
}
|
||||
break;
|
||||
case SYSTEM_CONFIG:
|
||||
#ifdef CONFIG_HDMI_RK616
|
||||
hdmi->remove(hdmi);
|
||||
#endif
|
||||
if(hdmi->autoconfig)
|
||||
hdmi->vic = hdmi_find_best_mode(hdmi, 0);
|
||||
switch (hdmi->state) {
|
||||
case READ_PARSE_EDID:
|
||||
rc = hdmi_sys_parse_edid(hdmi);
|
||||
if (rc == HDMI_ERROR_SUCESS) {
|
||||
hdmi->state = SYSTEM_CONFIG;
|
||||
kobject_uevent_env(&hdmi->dev->kobj, KOBJ_ADD,
|
||||
envp);
|
||||
hdmi_dbg(hdmi->dev,
|
||||
"[%s] base_audio_support =%d,sink_hdmi = %d\n",
|
||||
__func__,
|
||||
hdmi->edid.base_audio_support,
|
||||
hdmi->edid.sink_hdmi);
|
||||
#ifdef CONFIG_SWITCH
|
||||
if (hdmi->edid.base_audio_support == 1
|
||||
&& hdmi->edid.sink_hdmi == 1)
|
||||
switch_set_state(&(hdmi->switch_hdmi),
|
||||
1);
|
||||
#endif
|
||||
rockchip_set_system_status(SYS_STATUS_HDMI);
|
||||
}
|
||||
break;
|
||||
case SYSTEM_CONFIG:
|
||||
#ifdef CONFIG_HDMI_RK616
|
||||
hdmi->remove(hdmi);
|
||||
#endif
|
||||
if (hdmi->autoconfig)
|
||||
hdmi->vic = hdmi_find_best_mode(hdmi, 0);
|
||||
else
|
||||
hdmi->vic =
|
||||
hdmi_find_best_mode(hdmi, hdmi->vic);
|
||||
rc = hdmi_switch_fb(hdmi, hdmi->vic);
|
||||
if (rc == HDMI_ERROR_SUCESS)
|
||||
hdmi->state = CONFIG_VIDEO;
|
||||
break;
|
||||
case CONFIG_VIDEO:
|
||||
hdmi->display = HDMI_DISABLE;
|
||||
hdmi_init_video_para(hdmi, &video);
|
||||
rc = hdmi->config_video(hdmi, &video);
|
||||
if (rc == HDMI_ERROR_SUCESS) {
|
||||
if (hdmi->edid.sink_hdmi)
|
||||
hdmi->state = CONFIG_AUDIO;
|
||||
else
|
||||
hdmi->vic = hdmi_find_best_mode(hdmi, hdmi->vic);
|
||||
rc = hdmi_switch_fb(hdmi, hdmi->vic);
|
||||
if(rc == HDMI_ERROR_SUCESS)
|
||||
hdmi->state = CONFIG_VIDEO;
|
||||
break;
|
||||
case CONFIG_VIDEO:
|
||||
hdmi->display = HDMI_DISABLE;
|
||||
hdmi_init_video_para(hdmi, &video);
|
||||
rc = hdmi->config_video(hdmi, &video);
|
||||
if(rc == HDMI_ERROR_SUCESS)
|
||||
{
|
||||
if(hdmi->edid.sink_hdmi)
|
||||
hdmi->state = CONFIG_AUDIO;
|
||||
else
|
||||
hdmi->state = PLAY_BACK;
|
||||
}
|
||||
break;
|
||||
case CONFIG_AUDIO:
|
||||
rc = hdmi->config_audio(hdmi, &(hdmi->audio));
|
||||
|
||||
if(rc == HDMI_ERROR_SUCESS)
|
||||
hdmi->state = PLAY_BACK;
|
||||
break;
|
||||
case PLAY_BACK:
|
||||
if(hdmi->display != HDMI_ENABLE) {
|
||||
hdmi->control_output(hdmi, HDMI_ENABLE);
|
||||
hdmi->display = HDMI_ENABLE;
|
||||
if(hdmi->hdcp_cb) {
|
||||
hdmi->hdcp_cb();
|
||||
}
|
||||
}
|
||||
|
||||
if(hdmi->wait == 1) {
|
||||
complete(&hdmi->complete);
|
||||
hdmi->wait = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CONFIG_AUDIO:
|
||||
rc = hdmi->config_audio(hdmi, &(hdmi->audio));
|
||||
|
||||
if (rc == HDMI_ERROR_SUCESS)
|
||||
hdmi->state = PLAY_BACK;
|
||||
break;
|
||||
case PLAY_BACK:
|
||||
if (hdmi->display != HDMI_ENABLE) {
|
||||
hdmi->control_output(hdmi, HDMI_ENABLE);
|
||||
hdmi->display = HDMI_ENABLE;
|
||||
if (hdmi->hdcp_cb)
|
||||
hdmi->hdcp_cb();
|
||||
}
|
||||
|
||||
if (hdmi->wait == 1) {
|
||||
complete(&hdmi->complete);
|
||||
hdmi->wait = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(rc != HDMI_ERROR_SUCESS)
|
||||
{
|
||||
if (rc != HDMI_ERROR_SUCESS) {
|
||||
trytimes++;
|
||||
msleep(10);
|
||||
msleep(20);
|
||||
}
|
||||
if(hdmi->state != state_last)
|
||||
if (hdmi->state != state_last)
|
||||
trytimes = 0;
|
||||
|
||||
}while((hdmi->state != state_last || (rc != HDMI_ERROR_SUCESS) ) && trytimes < HDMI_MAX_TRY_TIMES);
|
||||
|
||||
hdmi_dbg(hdmi->dev, "[%s] done\n", __FUNCTION__);
|
||||
|
||||
} while ((hdmi->state != state_last || (rc != HDMI_ERROR_SUCESS))
|
||||
&& trytimes < HDMI_MAX_TRY_TIMES);
|
||||
|
||||
hdmi_dbg(hdmi->dev, "[%s] done\n", __func__);
|
||||
mutex_unlock(&work_mutex);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user