mirror of
https://github.com/torvalds/linux.git
synced 2026-06-09 07:03:37 +02:00
add hdmi driver
This commit is contained in:
parent
6d4d225869
commit
04f88ca2ad
9
arch/arm/mach-rk29/board-rk29sdk.c
Normal file → Executable file
9
arch/arm/mach-rk29/board-rk29sdk.c
Normal file → Executable file
|
|
@ -521,6 +521,15 @@ static struct i2c_board_info __initdata board_i2c1_devices[] = {
|
|||
.irq = RK29_PIN4_PA1,
|
||||
},
|
||||
#endif
|
||||
#if defined (CONFIG_ANX7150)
|
||||
{
|
||||
.type = "anx7150",
|
||||
.addr = 0x39, //0x39, 0x3d
|
||||
.flags = 0,
|
||||
.irq = RK29_PIN1_PD7,
|
||||
},
|
||||
#endif
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -2183,6 +2183,7 @@ source "drivers/video/omap/Kconfig"
|
|||
|
||||
source "drivers/video/backlight/Kconfig"
|
||||
source "drivers/video/display/Kconfig"
|
||||
source "drivers/video/hdmi/Kconfig"
|
||||
|
||||
if VT
|
||||
source "drivers/video/console/Kconfig"
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ fb-objs := $(fb-y)
|
|||
|
||||
obj-$(CONFIG_VT) += console/
|
||||
obj-$(CONFIG_LOGO) += logo/
|
||||
obj-y += backlight/ display/
|
||||
obj-y += backlight/ display/ hdmi/
|
||||
|
||||
obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
|
||||
obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#include <mach/board.h>
|
||||
|
||||
typedef enum _SCREEN_TYPE {
|
||||
SCREEN_NULL = 0,
|
||||
SCREEN_RGB,
|
||||
|
|
|
|||
19
drivers/video/hdmi/Kconfig
Normal file
19
drivers/video/hdmi/Kconfig
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#
|
||||
# Display drivers configuration
|
||||
#
|
||||
|
||||
menu "HDMI support"
|
||||
|
||||
config HDMI
|
||||
tristate "hdmi support"
|
||||
help
|
||||
nothing
|
||||
if HDMI
|
||||
source "drivers/video/hdmi/chips/Kconfig"
|
||||
config HDMI_DEBUG
|
||||
bool "hdmi debug"
|
||||
help
|
||||
nothing
|
||||
endif
|
||||
|
||||
endmenu
|
||||
2
drivers/video/hdmi/Makefile
Normal file
2
drivers/video/hdmi/Makefile
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
obj-$(CONFIG_HDMI) += hdmi-core.o hdmi-sysfs.o hdmi-fb.o hdmi-codec.o
|
||||
obj-$(CONFIG_HDMI) += chips/
|
||||
7
drivers/video/hdmi/chips/Kconfig
Normal file
7
drivers/video/hdmi/chips/Kconfig
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
choice
|
||||
prompt "HDMI chips select"
|
||||
config ANX7150
|
||||
bool "anx7150"
|
||||
config ANX9030
|
||||
bool "anx9030"
|
||||
endchoice
|
||||
2
drivers/video/hdmi/chips/Makefile
Normal file
2
drivers/video/hdmi/chips/Makefile
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
obj-$(CONFIG_ANX7150) += anx7150_hw.o anx7150.o
|
||||
|
||||
461
drivers/video/hdmi/chips/anx7150.c
Executable file
461
drivers/video/hdmi/chips/anx7150.c
Executable file
|
|
@ -0,0 +1,461 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/hdmi.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/iomux.h>
|
||||
|
||||
#include "anx7150.h"
|
||||
#include "anx7150_hw.h"
|
||||
|
||||
int anx7150_i2c_read_p0_reg(struct i2c_client *client, char reg, char *val)
|
||||
{
|
||||
client->addr = ANX7150_I2C_ADDR0;
|
||||
return i2c_master_reg8_recv(client, reg, val, 1, ANX7150_SCL_RATE) > 0? 0: -EINVAL;
|
||||
}
|
||||
int anx7150_i2c_write_p0_reg(struct i2c_client *client, char reg, char *val)
|
||||
{
|
||||
client->addr = ANX7150_I2C_ADDR0;
|
||||
return i2c_master_reg8_send(client, reg, val, 1, ANX7150_SCL_RATE) > 0? 0: -EINVAL;
|
||||
}
|
||||
int anx7150_i2c_read_p1_reg(struct i2c_client *client, char reg, char *val)
|
||||
{
|
||||
client->addr = ANX7150_I2C_ADDR1;
|
||||
return i2c_master_reg8_recv(client, reg, val, 1, ANX7150_SCL_RATE) > 0? 0: -EINVAL;
|
||||
}
|
||||
int anx7150_i2c_write_p1_reg(struct i2c_client *client, char reg, char *val)
|
||||
{
|
||||
client->addr = ANX7150_I2C_ADDR1;
|
||||
return i2c_master_reg8_send(client, reg, val, 1, ANX7150_SCL_RATE) > 0? 0: -EINVAL;
|
||||
}
|
||||
|
||||
static int rk29_hdmi_enter(struct anx7150_dev_s *dev)
|
||||
{
|
||||
if(dev->rk29_output_status == RK29_OUTPUT_STATUS_LCD) {
|
||||
printk("%s, resolution = %d\n", __func__, dev->resolution_real);
|
||||
if(hdmi_switch_fb(dev->resolution_real, 1) < 0)
|
||||
return -1;
|
||||
dev->hdmi->resolution = dev->resolution_real;
|
||||
dev->rk29_output_status = RK29_OUTPUT_STATUS_HDMI;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int rk29_hdmi_exit(struct anx7150_dev_s *dev)
|
||||
{
|
||||
if(dev->rk29_output_status == RK29_OUTPUT_STATUS_HDMI) {
|
||||
printk("%s\n", __func__);
|
||||
if(hdmi_switch_fb(dev->resolution_real, 0) < 0)
|
||||
return -1;
|
||||
dev->rk29_output_status = RK29_OUTPUT_STATUS_LCD;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int anx7150_display_on(struct hdmi* hdmi)
|
||||
{
|
||||
struct anx7150_pdata *anx = hdmi_get_privdata(hdmi);
|
||||
|
||||
rk29_hdmi_enter(&anx->dev);
|
||||
hdmi->display_on = HDMI_ENABLE;
|
||||
anx->dev.hdmi_enable = HDMI_ENABLE;
|
||||
anx->dev.parameter_config = 1;
|
||||
hdmi_dbg(hdmi->dev, "hdmi display on\n");
|
||||
return 0;
|
||||
}
|
||||
static int anx7150_display_off(struct hdmi* hdmi)
|
||||
{
|
||||
struct anx7150_pdata *anx = hdmi_get_privdata(hdmi);
|
||||
|
||||
rk29_hdmi_exit(&anx->dev);
|
||||
hdmi->display_on = HDMI_DISABLE;
|
||||
anx->dev.hdmi_enable = HDMI_DISABLE;
|
||||
anx->dev.parameter_config = 1;
|
||||
hdmi_dbg(hdmi->dev, "hdmi display off\n");
|
||||
return 0;
|
||||
}
|
||||
static int anx7150_set_param(struct hdmi *hdmi)
|
||||
{
|
||||
struct anx7150_pdata *anx = hdmi_get_privdata(hdmi);
|
||||
|
||||
anx->dev.resolution_set = hdmi->resolution;
|
||||
anx->dev.i2s_Fs = hdmi->audio_fs;
|
||||
anx->dev.hdcp_enable = hdmi->hdcp_on;
|
||||
anx->dev.hdmi_auto_switch = hdmi->auto_switch;
|
||||
anx->dev.parameter_config = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int anx7150_core_init(struct hdmi *hdmi)
|
||||
{
|
||||
//struct anx7150_pdata *anx = hdmi_get_privdata(hdmi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static irqreturn_t anx7150_detect_irq(int irq, void *dev_id)
|
||||
{
|
||||
//struct hdmi *hdmi = (struct hdmi *)dev_id;
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
void anx7150_task(struct anx7150_pdata *anx)
|
||||
{
|
||||
int state;
|
||||
int ret;
|
||||
|
||||
//anx->dev.anx7150_detect = anx7150_detect_device(anx);
|
||||
if(anx->dev.anx7150_detect == 0)
|
||||
goto out;
|
||||
|
||||
state = ANX7150_Get_System_State();
|
||||
|
||||
if(anx->dev.parameter_config){
|
||||
if(state > WAIT_HDMI_ENABLE)
|
||||
state = WAIT_HDMI_ENABLE;
|
||||
anx->dev.parameter_config = 0;
|
||||
anx->dev.fb_switch_state = 1;
|
||||
}
|
||||
if(anx->dev.hdmi_enable == HDMI_DISABLE && anx->dev.hdmi_auto_switch == HDMI_DISABLE){
|
||||
//if(state > WAIT_HDMI_ENABLE)
|
||||
state = HDMI_INITIAL;
|
||||
}
|
||||
|
||||
state = ANX7150_Interrupt_Process(anx, state);
|
||||
|
||||
switch(state){
|
||||
case HDMI_INITIAL:
|
||||
if(anx->dev.hdmi_auto_switch)
|
||||
rk29_hdmi_exit(&anx->dev);
|
||||
ANX7150_API_Initial(anx->client);
|
||||
state = WAIT_HOTPLUG;
|
||||
if(anx->dev.hdmi_auto_switch)
|
||||
anx->dev.rate = 1;
|
||||
else
|
||||
anx->dev.rate = 100;
|
||||
break;
|
||||
|
||||
case WAIT_HOTPLUG:
|
||||
if(anx->dev.hdmi_auto_switch)
|
||||
rk29_hdmi_exit(&anx->dev);
|
||||
if(anx->dev.HPD_status){
|
||||
anx7150_plug(anx->client);
|
||||
state = READ_PARSE_EDID;
|
||||
}
|
||||
if(anx->dev.hdmi_auto_switch)
|
||||
anx->dev.rate = 50;
|
||||
else
|
||||
anx->dev.rate = 100;
|
||||
break;
|
||||
|
||||
case READ_PARSE_EDID:
|
||||
ret = ANX7150_Parse_EDID(anx->client,&anx->dev);
|
||||
if(ret != 0){
|
||||
dev_err(&anx->client->dev, "Parse_EDID err, ret=%d\n", ret);
|
||||
}
|
||||
|
||||
state = WAIT_RX_SENSE;
|
||||
if(anx->dev.hdmi_auto_switch)
|
||||
anx->dev.rate = 50;
|
||||
else
|
||||
anx->dev.rate = 100;
|
||||
|
||||
break;
|
||||
|
||||
case WAIT_RX_SENSE:
|
||||
if(ANX7150_GET_SENSE_STATE(anx->client) == 1){
|
||||
hdmi_dbg(&anx->client->dev, "reciver active\n");
|
||||
state = WAIT_HDMI_ENABLE;
|
||||
anx->dev.reciver_status = HDMI_RECIVER_ACTIVE;
|
||||
hdmi_changed(anx->dev.hdmi, 1);
|
||||
}
|
||||
|
||||
if(anx->dev.hdmi_auto_switch)
|
||||
anx->dev.rate = 50;
|
||||
else
|
||||
anx->dev.rate = 100;
|
||||
|
||||
break;
|
||||
|
||||
case WAIT_HDMI_ENABLE:
|
||||
if(!anx->dev.hdmi_enable && anx->dev.hdmi_auto_switch)
|
||||
rk29_hdmi_exit(&anx->dev);
|
||||
if(anx->dev.hdmi_enable &&
|
||||
(anx->dev.hdmi_auto_switch || anx->init ||anx->dev.parameter_config)) {
|
||||
rk29_hdmi_enter(&anx->dev);
|
||||
anx->init = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
if(1 || anx->dev.rk29_output_status == RK29_OUTPUT_STATUS_HDMI){
|
||||
state = SYSTEM_CONFIG;
|
||||
anx->dev.rate = 1;
|
||||
}
|
||||
*/
|
||||
state = SYSTEM_CONFIG;
|
||||
if(anx->dev.hdmi_auto_switch)
|
||||
anx->dev.rate = 50;
|
||||
else
|
||||
anx->dev.rate = 100;
|
||||
|
||||
break;
|
||||
|
||||
case SYSTEM_CONFIG:
|
||||
anx->dev.resolution_real = ANX7150_Get_Optimal_resolution(anx->dev.resolution_set);
|
||||
HDMI_Set_Video_Format(anx->dev.resolution_real);
|
||||
HDMI_Set_Audio_Fs(anx->dev.i2s_Fs);
|
||||
ANX7150_API_HDCP_ONorOFF(anx->dev.hdcp_enable);
|
||||
ANX7150_API_System_Config();
|
||||
state = CONFIG_VIDEO;
|
||||
|
||||
anx->dev.rate = 1;
|
||||
if(anx->dev.fb_switch_state && anx->dev.rk29_output_status == RK29_OUTPUT_STATUS_HDMI) {
|
||||
anx->dev.rk29_output_status = RK29_OUTPUT_STATUS_LCD;
|
||||
rk29_hdmi_enter(&anx->dev);
|
||||
anx->dev.fb_switch_state = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case CONFIG_VIDEO:
|
||||
if(ANX7150_Config_Video(anx->client) == 0){
|
||||
if(ANX7150_GET_RECIVER_TYPE() == 1)
|
||||
state = CONFIG_AUDIO;
|
||||
else
|
||||
state = HDCP_AUTHENTICATION;
|
||||
|
||||
anx->dev.rate = 50;
|
||||
}
|
||||
|
||||
anx->dev.rate = 10;
|
||||
break;
|
||||
|
||||
case CONFIG_AUDIO:
|
||||
ANX7150_Config_Audio(anx->client);
|
||||
state = CONFIG_PACKETS;
|
||||
anx->dev.rate = 1;
|
||||
break;
|
||||
|
||||
case CONFIG_PACKETS:
|
||||
ANX7150_Config_Packet(anx->client);
|
||||
state = HDCP_AUTHENTICATION;
|
||||
anx->dev.rate = 1;
|
||||
break;
|
||||
|
||||
case HDCP_AUTHENTICATION:
|
||||
ANX7150_HDCP_Process(anx->client);
|
||||
state = PLAY_BACK;
|
||||
anx->dev.rate = 100;
|
||||
break;
|
||||
|
||||
case PLAY_BACK:
|
||||
ret = ANX7150_PLAYBACK_Process();
|
||||
if(ret == 1){
|
||||
state = CONFIG_PACKETS;
|
||||
anx->dev.rate = 1;
|
||||
}
|
||||
|
||||
anx->dev.rate = 100;
|
||||
break;
|
||||
|
||||
default:
|
||||
state = HDMI_INITIAL;
|
||||
anx->dev.rate = 100;
|
||||
break;
|
||||
}
|
||||
|
||||
if(state != ANX7150_Get_System_State()){
|
||||
ANX7150_Set_System_State(anx->client, state);
|
||||
}
|
||||
|
||||
out:
|
||||
return;
|
||||
}
|
||||
|
||||
static void anx7150_work_func(struct work_struct * work)
|
||||
{
|
||||
struct anx7150_dev_s *dev = container_of((void *)work, struct anx7150_dev_s, delay_work);
|
||||
struct hdmi *hdmi = dev->hdmi;
|
||||
struct anx7150_pdata *anx = hdmi_get_privdata(hdmi);
|
||||
|
||||
anx7150_task(anx);
|
||||
/*
|
||||
if(dev->hdmi_auto_switch)
|
||||
{
|
||||
if(dev->HPD_status == HDMI_RECIVER_PLUG)
|
||||
{
|
||||
rk29_hdmi_enter(dev);
|
||||
}
|
||||
else
|
||||
{
|
||||
rk29_hdmi_exit(dev);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dev->hdmi_enable)
|
||||
{
|
||||
rk29_hdmi_enter(dev);
|
||||
}
|
||||
else
|
||||
{
|
||||
rk29_hdmi_exit(dev);
|
||||
}
|
||||
}
|
||||
*/
|
||||
if(dev->anx7150_detect)
|
||||
{
|
||||
queue_delayed_work(dev->workqueue, &dev->delay_work, dev->rate);
|
||||
}
|
||||
else
|
||||
{
|
||||
hdmi_dbg(hdmi->dev, "ANX7150 not exist!\n");
|
||||
rk29_hdmi_exit(dev);
|
||||
}
|
||||
return;
|
||||
}
|
||||
static int anx7150_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id)
|
||||
{
|
||||
int rc = 0;
|
||||
struct hdmi *hdmi = NULL;
|
||||
struct anx7150_pdata *anx = NULL;
|
||||
|
||||
hdmi = kzalloc(sizeof(struct hdmi), GFP_KERNEL);
|
||||
if (!hdmi)
|
||||
{
|
||||
dev_err(&client->dev, "no memory for state\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
anx = kzalloc(sizeof(struct anx7150_pdata), GFP_KERNEL);
|
||||
if(!anx)
|
||||
{
|
||||
dev_err(&client->dev, "no memory for state\n");
|
||||
goto err_kzalloc_anx;
|
||||
}
|
||||
anx->client = client;
|
||||
anx->dev.anx7150_detect = 0;
|
||||
anx->dev.resolution_set = HDMI_DEFAULT_RESOLUTION;
|
||||
anx->dev.i2s_Fs = HDMI_I2S_DEFAULT_Fs;
|
||||
anx->dev.hdmi_enable = HDMI_ENABLE;
|
||||
anx->dev.hdmi_auto_switch = HDMI_AUTO_SWITCH;
|
||||
anx->dev.reciver_status = HDMI_RECIVER_INACTIVE;
|
||||
anx->dev.HPD_status = HDMI_RECIVER_UNPLUG;
|
||||
anx->dev.HPD_change_cnt = 0;
|
||||
anx->dev.rk29_output_status = RK29_OUTPUT_STATUS_LCD;
|
||||
anx->dev.hdcp_enable = ANX7150_HDCP_EN;
|
||||
|
||||
anx->init = 1;
|
||||
|
||||
anx->dev.workqueue = create_singlethread_workqueue("ANX7150_WORKQUEUE");
|
||||
INIT_DELAYED_WORK(&anx->dev.delay_work, anx7150_work_func);
|
||||
|
||||
hdmi->display_on = 0;
|
||||
hdmi->auto_switch = anx->dev.hdmi_auto_switch;
|
||||
hdmi->hdcp_on = anx->dev.hdcp_enable;
|
||||
hdmi->audio_fs = anx->dev.i2s_Fs;
|
||||
hdmi->resolution = anx->dev.resolution_set;
|
||||
hdmi->dev = &client->dev;
|
||||
hdmi->hdmi_display_on = anx7150_display_on;
|
||||
hdmi->hdmi_display_off = anx7150_display_off;
|
||||
hdmi->hdmi_set_param = anx7150_set_param;
|
||||
hdmi->hdmi_core_init = anx7150_core_init;
|
||||
|
||||
if((rc = hdmi_register(&client->dev, hdmi)) < 0)
|
||||
{
|
||||
dev_err(&client->dev, "fail to register hdmi\n");
|
||||
goto err_hdmi_register;
|
||||
}
|
||||
|
||||
if((rc = gpio_request(client->irq, "hdmi gpio")) < 0)
|
||||
{
|
||||
dev_err(&client->dev, "fail to request gpio %d\n", client->irq);
|
||||
goto err_request_gpio;
|
||||
}
|
||||
|
||||
anx->irq = gpio_to_irq(client->irq);
|
||||
anx->gpio = client->irq;
|
||||
|
||||
anx->dev.hdmi = hdmi;
|
||||
hdmi_set_privdata(hdmi, anx);
|
||||
|
||||
i2c_set_clientdata(client, anx);
|
||||
gpio_pull_updown(client->irq,GPIOPullUp);
|
||||
|
||||
if((rc = request_irq(anx->irq, anx7150_detect_irq,IRQF_TRIGGER_FALLING,NULL,hdmi)) <0)
|
||||
{
|
||||
dev_err(&client->dev, "fail to request hdmi irq\n");
|
||||
goto err_request_irq;
|
||||
}
|
||||
anx->dev.anx7150_detect = anx7150_detect_device(anx);
|
||||
if(anx->dev.anx7150_detect) {
|
||||
ANX7150_API_Initial(client);
|
||||
queue_delayed_work(anx->dev.workqueue, &anx->dev.delay_work, 200);
|
||||
}
|
||||
hdmi_dbg(&client->dev, "anx7150 i2c probe ok\n");
|
||||
return 0;
|
||||
|
||||
err_request_irq:
|
||||
gpio_free(client->irq);
|
||||
err_request_gpio:
|
||||
hdmi_unregister(hdmi);
|
||||
err_hdmi_register:
|
||||
destroy_workqueue(anx->dev.workqueue);
|
||||
kfree(anx);
|
||||
anx = NULL;
|
||||
err_kzalloc_anx:
|
||||
kfree(hdmi);
|
||||
hdmi = NULL;
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
static int __devexit anx7150_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct anx7150_pdata *anx = (struct anx7150_pdata *)i2c_get_clientdata(client);
|
||||
struct hdmi *hdmi = anx->dev.hdmi;
|
||||
|
||||
free_irq(anx->irq, NULL);
|
||||
gpio_free(client->irq);
|
||||
hdmi_unregister(hdmi);
|
||||
destroy_workqueue(anx->dev.workqueue);
|
||||
kfree(anx);
|
||||
anx = NULL;
|
||||
kfree(hdmi);
|
||||
hdmi = NULL;
|
||||
|
||||
hdmi_dbg(hdmi->dev, "%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id anx7150_id[] = {
|
||||
{ "anx7150", 0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct i2c_driver anx7150_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "anx7150",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = &anx7150_i2c_probe,
|
||||
.remove = &anx7150_i2c_remove,
|
||||
.id_table = anx7150_id,
|
||||
};
|
||||
|
||||
|
||||
static int __init anx7150_init(void)
|
||||
{
|
||||
return i2c_add_driver(&anx7150_i2c_driver);
|
||||
}
|
||||
|
||||
static void __exit anx7150_exit(void)
|
||||
{
|
||||
i2c_del_driver(&anx7150_i2c_driver);
|
||||
}
|
||||
|
||||
//module_init(anx7150_init);
|
||||
fs_initcall(anx7150_init);
|
||||
module_exit(anx7150_exit);
|
||||
|
||||
|
||||
102
drivers/video/hdmi/chips/anx7150.h
Executable file
102
drivers/video/hdmi/chips/anx7150.h
Executable file
|
|
@ -0,0 +1,102 @@
|
|||
#ifndef _ANX7150_H
|
||||
#define _ANX7150_H
|
||||
|
||||
#include <linux/hdmi.h>
|
||||
|
||||
#define ANX7150_I2C_ADDR0 0X39
|
||||
#define ANX7150_I2C_ADDR1 0X3d
|
||||
|
||||
#define ANX7150_SCL_RATE 100 * 1000
|
||||
|
||||
/* HDMI STATUS */
|
||||
#define HDMI_DISABLE 0
|
||||
#define HDMI_ENABLE 1
|
||||
|
||||
/* HDMI auto switch */
|
||||
#define HDMI_AUTO_SWITCH HDMI_ENABLE
|
||||
|
||||
/* HDMI reciver status */
|
||||
#define HDMI_RECIVER_INACTIVE 0
|
||||
#define HDMI_RECIVER_ACTIVE 1
|
||||
|
||||
/* ANX7150 reciver HPD Status */
|
||||
#define HDMI_RECIVER_UNPLUG 0
|
||||
#define HDMI_RECIVER_PLUG 1
|
||||
|
||||
#define LCD 0
|
||||
#define HDMI 1
|
||||
|
||||
#define RK29_OUTPUT_STATUS_LCD LCD
|
||||
#define RK29_OUTPUT_STATUS_HDMI HDMI
|
||||
|
||||
/* HDMI HDCP ENABLE */
|
||||
#define ANX7150_HDCP_EN HDMI_DISABLE
|
||||
|
||||
/* HDMI default resolution */
|
||||
#define HDMI_DEFAULT_RESOLUTION HDMI_1280x720p_50Hz
|
||||
/* I2S Fs */
|
||||
#define HDMI_I2S_Fs_44100 0
|
||||
#define HDMI_I2S_Fs_48000 2
|
||||
|
||||
/* I2S default sample rate */
|
||||
#define HDMI_I2S_DEFAULT_Fs HDMI_I2S_Fs_48000
|
||||
|
||||
/* ANX7150 state machine */
|
||||
enum{
|
||||
HDMI_INITIAL = 1,
|
||||
WAIT_HOTPLUG,
|
||||
READ_PARSE_EDID,
|
||||
WAIT_RX_SENSE,
|
||||
WAIT_HDMI_ENABLE,
|
||||
SYSTEM_CONFIG,
|
||||
CONFIG_VIDEO,
|
||||
CONFIG_AUDIO,
|
||||
CONFIG_PACKETS,
|
||||
HDCP_AUTHENTICATION,
|
||||
PLAY_BACK,
|
||||
RESET_LINK,
|
||||
UNKNOWN,
|
||||
};
|
||||
|
||||
|
||||
struct anx7150_dev_s{
|
||||
struct i2c_driver *i2c_driver;
|
||||
struct fasync_struct *async_queue;
|
||||
struct workqueue_struct *workqueue;
|
||||
struct delayed_work delay_work;
|
||||
struct miscdevice *mdev;
|
||||
void (*notifier_callback)(struct anx7150_dev_s *);
|
||||
int anx7150_detect;
|
||||
int resolution_set;
|
||||
int resolution_real;
|
||||
int i2s_Fs;
|
||||
int hdmi_enable;
|
||||
int hdmi_auto_switch;
|
||||
int reciver_status;
|
||||
int HPD_change_cnt;
|
||||
int HPD_status;
|
||||
int rk29_output_status;
|
||||
int hdcp_enable;
|
||||
int parameter_config;
|
||||
int rate;
|
||||
int fb_switch_state;
|
||||
|
||||
struct hdmi *hdmi;
|
||||
};
|
||||
|
||||
struct anx7150_pdata {
|
||||
int irq;
|
||||
int gpio;
|
||||
int init;
|
||||
struct i2c_client *client;
|
||||
struct anx7150_dev_s dev;
|
||||
};
|
||||
|
||||
|
||||
|
||||
int anx7150_i2c_read_p0_reg(struct i2c_client *client, char reg, char *val);
|
||||
int anx7150_i2c_write_p0_reg(struct i2c_client *client, char reg, char *val);
|
||||
int anx7150_i2c_read_p1_reg(struct i2c_client *client, char reg, char *val);
|
||||
int anx7150_i2c_write_p1_reg(struct i2c_client *client, char reg, char *val);
|
||||
|
||||
#endif
|
||||
4196
drivers/video/hdmi/chips/anx7150_hw.c
Executable file
4196
drivers/video/hdmi/chips/anx7150_hw.c
Executable file
File diff suppressed because it is too large
Load Diff
1263
drivers/video/hdmi/chips/anx7150_hw.h
Executable file
1263
drivers/video/hdmi/chips/anx7150_hw.h
Executable file
File diff suppressed because it is too large
Load Diff
492
drivers/video/hdmi/chips/anx7150_sys.c
Executable file
492
drivers/video/hdmi/chips/anx7150_sys.c
Executable file
|
|
@ -0,0 +1,492 @@
|
|||
// ANALOGIX Company
|
||||
// ANX7150 Demo Firmware
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/hdmi.h>
|
||||
|
||||
|
||||
#include "anx7150_sys.h"
|
||||
|
||||
|
||||
/******** define uint8 and WORD, by kfx *******/
|
||||
int anx7150_tmds_enable(struct hdmi *hdmi)
|
||||
{
|
||||
int rc = 0;
|
||||
char c;
|
||||
|
||||
/* andio stream enable */
|
||||
if((rc = anx7150_i2c_read_p0_reg(hdmi->client, ANX7150_HDMI_AUDCTRL1_REG, &c)) < 0)
|
||||
return rc;
|
||||
c |= (ANX7150_HDMI_AUDCTRL1_IN_EN);
|
||||
|
||||
if((rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_HDMI_AUDCTRL1_REG, &c)) < 0)
|
||||
return rc;
|
||||
|
||||
/* video stream enable */
|
||||
if((rc = anx7150_i2c_read_p0_reg(hdmi->client, ANX7150_VID_CTRL_REG, &c)) < 0)
|
||||
return rc;
|
||||
c |= (ANX7150_VID_CTRL_IN_EN);
|
||||
|
||||
if((rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_VID_CTRL_REG, &c)) < 0)
|
||||
return rc;
|
||||
|
||||
/* TMDS enable */
|
||||
if((rc = anx7150_i2c_read_p0_reg(hdmi->client, ANX7150_TMDS_CLKCH_CONFIG_REG, &c)) < 0)
|
||||
return rc;
|
||||
c |= (ANX7150_TMDS_CLKCH_MUTE);
|
||||
|
||||
if((rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_TMDS_CLKCH_CONFIG_REG, &c)) < 0)
|
||||
return rc;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int anx7150_tmds_disable(struct hdmi *hdmi)
|
||||
{
|
||||
int rc = 0;
|
||||
char c;
|
||||
|
||||
/* andio stream disable */
|
||||
if((rc = anx7150_i2c_read_p0_reg(hdmi->client, ANX7150_HDMI_AUDCTRL1_REG, &c)) < 0)
|
||||
return rc;
|
||||
c &= (~ANX7150_HDMI_AUDCTRL1_IN_EN);
|
||||
|
||||
if((rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_HDMI_AUDCTRL1_REG, &c)) < 0)
|
||||
return rc;
|
||||
|
||||
/* video stream disable */
|
||||
if((rc = anx7150_i2c_read_p0_reg(hdmi->client, ANX7150_VID_CTRL_REG, &c)) < 0)
|
||||
return rc;
|
||||
c &= (~ANX7150_VID_CTRL_IN_EN);
|
||||
|
||||
if((rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_VID_CTRL_REG, &c)) < 0)
|
||||
return rc;
|
||||
|
||||
/* TMDS disable */
|
||||
if((rc = anx7150_i2c_read_p0_reg(hdmi->client, ANX7150_TMDS_CLKCH_CONFIG_REG, &c)) < 0)
|
||||
return rc;
|
||||
c &= (~ANX7150_TMDS_CLKCH_MUTE);
|
||||
|
||||
if((rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_TMDS_CLKCH_CONFIG_REG, &c)) < 0)
|
||||
return rc;
|
||||
|
||||
return rc;
|
||||
}
|
||||
static void anx7150_set_video_format(struct hdmi *hdmi)
|
||||
{
|
||||
struct anx7150_pdata *anx = hdmi_get_privdata(hdmi);
|
||||
|
||||
switch(hdmi->resolution)
|
||||
{
|
||||
case HDMI_720x576p_50Hz:
|
||||
anx->video_format = ANX7150_V720x576p_50Hz_4x3;
|
||||
break;
|
||||
case ANX7150_V1280x720p_50Hz:
|
||||
anx->video_format = ANX7150_V1280x720p_50Hz;
|
||||
break;
|
||||
case HDMI_1280x720p_60Hz:
|
||||
anx->video_format = ANX7150_V1280x720p_60Hz;
|
||||
break;
|
||||
default:
|
||||
anx->video_format = ANX7150_V1280x720p_50Hz;
|
||||
break;
|
||||
}
|
||||
anx->system_config_done = 0;
|
||||
return;
|
||||
}
|
||||
static void anx7150_set_audio_fs(struct hdmi *hdmi)
|
||||
{
|
||||
struct anx7150_pdata *anx = hdmi_get_privdata(hdmi);
|
||||
|
||||
anx->audio_format = hdmi->audio_fs;
|
||||
anx->system_config_done = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static void anx7150_set_system_state(struct hdmi *hdmi, unsigned char ss)
|
||||
{
|
||||
struct anx7150_pdata *anx = hdmi_get_privdata(hdmi);
|
||||
|
||||
anx->system_state = ss;
|
||||
switch (ss)
|
||||
{
|
||||
case ANX7150_INITIAL:
|
||||
dev_info(hdmi->dev, "system state: ANX7150_INITIAL\n");
|
||||
break;
|
||||
case ANX7150_WAIT_HOTPLUG:
|
||||
dev_info(hdmi->dev, "system state: ANX7150_WAIT_HOTPLUG\n");
|
||||
break;
|
||||
case ANX7150_READ_PARSE_EDID:
|
||||
dev_info(hdmi->dev, "system state: ANX7150_READ_PARSE_EDID\n");
|
||||
break;
|
||||
case ANX7150_WAIT_RX_SENSE:
|
||||
dev_info(hdmi->dev, "system state: ANX7150_WAIT_RX_SENSE\n");
|
||||
break;
|
||||
case ANX7150_CONFIG_VIDEO:
|
||||
dev_info(hdmi->dev, "system state: ANX7150_CONFIG_VIDEO\n");
|
||||
break;
|
||||
case ANX7150_CONFIG_AUDIO:
|
||||
dev_info(hdmi->dev, "system state: ANX7150_CONFIG_AUDIO\n");
|
||||
break;
|
||||
case ANX7150_CONFIG_PACKETS:
|
||||
dev_info(hdmi->dev, "system state: ANX7150_CONFIG_PACKETS\n");
|
||||
break;
|
||||
case ANX7150_HDCP_AUTHENTICATION:
|
||||
dev_info(hdmi->dev, "system state: ANX7150_HDCP_AUTHENTICATION\n");
|
||||
break;
|
||||
case ANX7150_RESET_LINK:
|
||||
dev_info(hdmi->dev, "system state: ANX7150_RESET_LINK\n");
|
||||
break;
|
||||
case ANX7150_PLAY_BACK:
|
||||
dev_info(hdmi->dev, "system state: ANX7150_PLAY_BACK\n");
|
||||
break;
|
||||
default:
|
||||
dev_info(hdmi->dev, "system state: ANX7150 unknown state\n");
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void anx7150_variable_initial(struct hdmi *hdmi)
|
||||
{
|
||||
int i;
|
||||
struct anx7150_pdata *anx = hdmi_get_privdata(hdmi);
|
||||
|
||||
anx7150_set_system_state(hdmi, ANX7150_INITIAL);
|
||||
|
||||
anx->anx7150_hdcp_auth_en = 0;
|
||||
anx->anx7150_ksv_srm_pass =0;
|
||||
anx->anx7150_srm_checked = 0;
|
||||
anx->anx7150_hdcp_auth_pass = 0;
|
||||
anx->anx7150_avmute_enable = 1;
|
||||
anx->anx7150_hdcp_auth_fail_counter =0;
|
||||
anx->anx7150_hdcp_encryption = 0;
|
||||
anx->anx7150_send_blue_screen = 0;
|
||||
anx->anx7150_hdcp_init_done = 0;
|
||||
anx->anx7150_hdcp_wait_100ms_needed = 1;
|
||||
anx->anx7150_auth_fully_pass = 0;
|
||||
anx->timer_slot = 0;
|
||||
/***************for video config***************/
|
||||
anx->anx7150_video_timing_id = 0;
|
||||
anx->anx7150_in_pix_rpt = 0;
|
||||
anx->anx7150_tx_pix_rpt = 0;
|
||||
anx->anx7150_new_csc = 0;
|
||||
anx->anx7150_new_vid_id = 0;
|
||||
anx->anx7150_new_hw_interface = 0;
|
||||
/*****************end of video config**********/
|
||||
|
||||
/********************for edid parse************/
|
||||
anx->edid.is_HDMI = 0;
|
||||
anx->edid.ycbcr422_supported = 0;
|
||||
anx->edid.ycbcr444_supported = 0;
|
||||
anx->edid.supported_720p_60Hz = 0;
|
||||
anx->edid.supported_720p_50Hz = 0;
|
||||
anx->edid.supported_576p_50Hz = 0;
|
||||
anx->edid.supported_576i_50Hz = 0;
|
||||
anx->edid.supported_1080i_60Hz = 0;
|
||||
anx->edid.supported_1080i_50Hz = 0;
|
||||
anx->edid.supported_640x480p_60Hz = 0;
|
||||
anx->edid.supported_720x480p_60Hz = 0;
|
||||
anx->edid.supported_720x480i_60Hz = 0;
|
||||
anx->edid.edid_errcode = 0;
|
||||
anx->edid.SpeakerFormat = 0;
|
||||
for (i = 0; i < 8; i ++)
|
||||
{
|
||||
anx->edid.AudioChannel[i] = 0;
|
||||
anx->edid.AudioFormat[i] = 0;
|
||||
anx->edid.AudioFs[i] = 0;
|
||||
anx->edid.AudioLength[i] = 0;
|
||||
}
|
||||
/********************end of edid****************/
|
||||
|
||||
anx->packets_config.packets_need_config = 0x03; //new avi infoframe
|
||||
anx->packets_config.avi_info.type = 0x82;
|
||||
anx->packets_config.avi_info.version = 0x02;
|
||||
anx->packets_config.avi_info.length = 0x0d;
|
||||
anx->packets_config.avi_info.pb_uint8[1] = 0x21;//YCbCr422
|
||||
anx->packets_config.avi_info.pb_uint8[2] = 0x08;
|
||||
anx->packets_config.avi_info.pb_uint8[3] = 0x00;
|
||||
anx->packets_config.avi_info.pb_uint8[4] = 0x00;
|
||||
anx->packets_config.avi_info.pb_uint8[5] = 0x00;
|
||||
anx->packets_config.avi_info.pb_uint8[6] = 0x00;
|
||||
anx->packets_config.avi_info.pb_uint8[7] = 0x00;
|
||||
anx->packets_config.avi_info.pb_uint8[8] = 0x00;
|
||||
anx->packets_config.avi_info.pb_uint8[9] = 0x00;
|
||||
anx->packets_config.avi_info.pb_uint8[10] = 0x00;
|
||||
anx->packets_config.avi_info.pb_uint8[11] = 0x00;
|
||||
anx->packets_config.avi_info.pb_uint8[12] = 0x00;
|
||||
anx->packets_config.avi_info.pb_uint8[13] = 0x00;
|
||||
|
||||
// audio infoframe
|
||||
anx->packets_config.audio_info.type = 0x84;
|
||||
anx->packets_config.audio_info.version = 0x01;
|
||||
anx->packets_config.audio_info.length = 0x0a;
|
||||
anx->packets_config.audio_info.pb_uint8[1] = 0x00; //zy 061123 for ATC
|
||||
anx->packets_config.audio_info.pb_uint8[2] = 0x00;
|
||||
anx->packets_config.audio_info.pb_uint8[3] = 0x00;
|
||||
anx->packets_config.audio_info.pb_uint8[4] = 0x00;
|
||||
anx->packets_config.audio_info.pb_uint8[5] = 0x00;
|
||||
anx->packets_config.audio_info.pb_uint8[6] = 0x00;
|
||||
anx->packets_config.audio_info.pb_uint8[7] = 0x00;
|
||||
anx->packets_config.audio_info.pb_uint8[8] = 0x00;
|
||||
anx->packets_config.audio_info.pb_uint8[9] = 0x00;
|
||||
anx->packets_config.audio_info.pb_uint8[10] = 0x00;
|
||||
|
||||
anx->anx7150_int_done = 0;
|
||||
}
|
||||
|
||||
|
||||
static void anx7150_hw_interface_variable_initial(struct hdmi *hdmi)
|
||||
{
|
||||
unsigned char c;
|
||||
struct anx7150_pdata *anx = hdmi_get_privdata(hdmi);
|
||||
|
||||
anx->anx7150_video_format_config = 0x00;
|
||||
anx->anx7150_rgborycbcr = 0x00;
|
||||
anx->anx7150_ddr_edge = ANX7150_IDCK_EDGE_DDR;
|
||||
|
||||
c = 0;
|
||||
c = (ANX7150_I2S_CH0_ENABLE << 2) | (ANX7150_I2S_CH1_ENABLE << 3) |
|
||||
(ANX7150_I2S_CH2_ENABLE << 4) | (ANX7150_I2S_CH3_ENABLE << 5);
|
||||
|
||||
anx->audio_config.audio_type = ANX7150_AUD_HW_INTERFACE; // input I2S
|
||||
anx->audio_config.down_sample = 0x00;
|
||||
anx->audio_config.i2s_config.audio_channel = c;//0x04;
|
||||
anx->audio_config.i2s_config.Channel_status1 =0x00;
|
||||
anx->audio_config.i2s_config.Channel_status1 = 0x00;
|
||||
anx->audio_config.i2s_config.Channel_status2 = 0x00;
|
||||
anx->audio_config.i2s_config.Channel_status3 = 0x00;
|
||||
anx->audio_config.i2s_config.Channel_status4 = 0x00;//0x02;//48k
|
||||
anx->audio_config.i2s_config.Channel_status5 = ANX7150_I2S_WORD_LENGTH;//0x0b;
|
||||
anx->audio_config.audio_layout = 0x00;
|
||||
|
||||
c = (ANX7150_I2S_SHIFT_CTRL << 3) | (ANX7150_I2S_DIR_CTRL << 2) |
|
||||
(ANX7150_I2S_WS_POL << 1) | ANX7150_I2S_JUST_CTRL;
|
||||
anx->audio_config.i2s_config.i2s_format = c;//0x00;
|
||||
|
||||
anx->freq_mclk= ANX7150_MCLK_Fs_RELATION;//set the relation of MCLK and WS
|
||||
anx->anx7150_audio_clock_edge = ANX7150_AUD_CLK_EDGE;
|
||||
return;
|
||||
}
|
||||
static int anx7150_hardware_initial(struct hdmi *hdmi)
|
||||
{
|
||||
int rc = 0;
|
||||
char c = 0;
|
||||
|
||||
//clear HDCP_HPD_RST
|
||||
rc = anx7150_i2c_read_p0_reg(hdmi->client, ANX7150_SYS_CTRL2_REG, &c);
|
||||
c |= (0x01);
|
||||
rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_SYS_CTRL2_REG, &c);
|
||||
|
||||
mdelay(10);
|
||||
|
||||
c &= (~0x01);
|
||||
rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_SYS_CTRL2_REG, &c);
|
||||
|
||||
//Power on I2C
|
||||
rc = anx7150_i2c_read_p0_reg(hdmi->client, ANX7150_SYS_CTRL3_REG, &c);
|
||||
c |= (ANX7150_SYS_CTRL3_I2C_PWON);
|
||||
rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_SYS_CTRL3_REG, &c);
|
||||
|
||||
c = 0x00;
|
||||
rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_SYS_CTRL2_REG, &c);
|
||||
c= 0x00;
|
||||
rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_SRST_REG, &c);
|
||||
|
||||
//clear HDCP_HPD_RST
|
||||
rc = anx7150_i2c_read_p0_reg(hdmi->client, ANX7150_SYS_CTRL1_REG, &c);
|
||||
c &= (0xbf);
|
||||
rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_SYS_CTRL1_REG, &c);
|
||||
|
||||
//Power on Audio capture and Video capture module clock
|
||||
rc = anx7150_i2c_read_p0_reg(hdmi->client, ANX7150_SYS_PD_REG, &c);
|
||||
c |= (0x06);
|
||||
rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_SYS_PD_REG, &c);
|
||||
|
||||
//Enable auto set clock range for video PLL
|
||||
rc = anx7150_i2c_read_p0_reg(hdmi->client, ANX7150_CHIP_CTRL_REG, &c);
|
||||
c &= (0x00);
|
||||
rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_CHIP_CTRL_REG, &c);
|
||||
|
||||
//Set registers value of Blue Screen when HDCP authentication failed--RGB mode,green field
|
||||
c = 0x10;
|
||||
rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_HDCP_BLUESCREEN0_REG, &c);
|
||||
c = 0xeb;
|
||||
rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_HDCP_BLUESCREEN1_REG, &c);
|
||||
c = 0x10;
|
||||
rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_HDCP_BLUESCREEN2_REG, &c);
|
||||
|
||||
//ANX7150_i2c_read_p0_reg(ANX7150_TMDS_CLKCH_CONFIG_REG, &c);
|
||||
//ANX7150_i2c_write_p0_reg(ANX7150_TMDS_CLKCH_CONFIG_REG, (c | 0x80));
|
||||
|
||||
rc = anx7150_i2c_read_p0_reg(hdmi->client, ANX7150_PLL_CTRL0_REG, &c);
|
||||
c = 0x00;
|
||||
rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_PLL_CTRL0_REG, &c);
|
||||
|
||||
rc = anx7150_i2c_read_p0_reg(hdmi->client, ANX7150_CHIP_DEBUG1_CTRL_REG, &c);
|
||||
c |= (0x08);
|
||||
rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_CHIP_DEBUG1_CTRL_REG, &c);
|
||||
|
||||
rc = anx7150_i2c_read_p0_reg(hdmi->client, ANX7150_PLL_TX_AMP, &c);//jack wen
|
||||
c |= (0x01);
|
||||
|
||||
rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_PLL_TX_AMP, &c); //TMDS swing
|
||||
|
||||
c = 0x00;
|
||||
rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_PLL_CTRL1_REG, &c); //Added for PLL unlock issue in high temperature - Feiw
|
||||
//if (ANX7150_AUD_HW_INTERFACE == 0x02) //jack wen, spdif
|
||||
|
||||
rc = anx7150_i2c_read_p0_reg(hdmi->client, ANX7150_I2S_CTRL_REG, &c);//jack wen, for spdif input from SD0.
|
||||
c &= (0xef);
|
||||
rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_I2S_CTRL_REG, &c);
|
||||
|
||||
c = 0xc7;
|
||||
rc = anx7150_i2c_write_p0_reg(hdmi->client, 0xE1, &c);
|
||||
|
||||
//ANX7150_i2c_read_p0_reg(ANX7150_SYS_CTRL1_REG, &c);
|
||||
c = 0x00;
|
||||
rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_SYS_CTRL1_REG, &c);//power down HDCP, 090630
|
||||
|
||||
rc = anx7150_i2c_read_p0_reg(hdmi->client, ANX7150_SYS_CTRL3_REG, &c);//jack wen, for spdif input from SD0.
|
||||
c &= (0xef);
|
||||
rc = anx7150_i2c_write_p0_reg(hdmi->client, ANX7150_SYS_CTRL3_REG, &c);//power down all, 090630
|
||||
|
||||
//anx7150_set_system_state(hdmi, ANX7150_WAIT_HOTPLUG);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int anx7150_initial(struct hdmi *hdmi)
|
||||
{
|
||||
int rc = 0;
|
||||
anx7150_variable_initial(hdmi);
|
||||
anx7150_hw_interface_variable_initial(hdmi);
|
||||
|
||||
rc = anx7150_hardware_initial(hdmi);
|
||||
return rc;
|
||||
}
|
||||
static void anx7150_set_hdcp_state(struct hdmi* hdmi)
|
||||
{
|
||||
struct anx7150_pdata *anx = hdmi_get_privdata(hdmi);
|
||||
|
||||
anx->hdcp_on = hdmi->hdcp_on;
|
||||
return;
|
||||
}
|
||||
int anx7150_system_init(struct hdmi *hdmi)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if((rc = anx7150_detect_device(hdmi)) < 0)
|
||||
{
|
||||
dev_err(hdmi->dev, "anx7150 api detectdevice err!\n");
|
||||
return rc;
|
||||
}
|
||||
anx7150_set_audio_fs(hdmi);
|
||||
|
||||
if((rc = anx7150_initial(hdmi)) < 0)
|
||||
{
|
||||
dev_err(hdmi->dev, "anx7150 initial err!\n");
|
||||
return rc;
|
||||
}
|
||||
anx7150_set_hdcp_state(hdmi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static u8 anx7150_detect_device(struct hdmi *hdmi)
|
||||
{
|
||||
int i, rc = 0;
|
||||
char d1, d2;
|
||||
|
||||
for (i=0; i<10; i++)
|
||||
{
|
||||
if((rc = anx7150_i2c_read_p0_reg(hdmi->client, ANX7150_DEV_IDL_REG, &d1)) < 0)
|
||||
continue;
|
||||
if((rc = anx7150_i2c_read_p0_reg(hdmi->client, ANX7150_DEV_IDH_REG, &d2)) < 0)
|
||||
continue;
|
||||
if (d1 == 0x50 && d2 == 0x71)
|
||||
{
|
||||
dev_info(hdmi->dev, "anx7150 detected!\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
dev_info(hdmi->dev, "anx7150 not detected");
|
||||
return 0;
|
||||
}
|
||||
static u8 anx7150_get_system_state(struct anx7150_pdata *anx)
|
||||
{
|
||||
return anx->anx7150_system_state;
|
||||
}
|
||||
static u8 anx7150_get_hpd(struct i2c_client *client)
|
||||
{
|
||||
char c;
|
||||
|
||||
if((rc = anx7150_i2c_read_p0_reg(hdmi->client, ANX7150_SYS_CTRL3_REG, &c)) < 0)
|
||||
return rc;
|
||||
if(c & ANX7150_SYS_CTRL3_PWON_ALL)
|
||||
{
|
||||
if((rc = anx7150_i2c_read_p0_reg(hdmi->client, ANX7150_SYS_STATE_REG, &c)) < 0)
|
||||
return rc;
|
||||
return (c & ANX7150_SYS_STATE_HP)? 1:0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((rc = anx7150_i2c_read_p0_reg(hdmi->client, ANX7150_INTR_STATE_REG, &c)) < 0)
|
||||
return rc;
|
||||
return (c)? 1:0;
|
||||
}
|
||||
}
|
||||
static u8 anx7150_interrupt_process(struct hdmi *hdmi, int state)
|
||||
{
|
||||
int hot_plug;
|
||||
int rc;
|
||||
|
||||
hot_plug = anx7150_get_hpd(hdmi->client);
|
||||
}
|
||||
|
||||
int anx7150_display_on_hw(struct hdmi *hdmi)
|
||||
{
|
||||
u8 state;
|
||||
struct anx7150_pdata *anx = hdmi_get_privdata(hdmi);
|
||||
|
||||
anx->anx7150_detect = anx7150_detect_device(hdmi);
|
||||
if(anx->anx7150_detect < 0)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
state = anx7150_get_system_state(anx);
|
||||
if(hdmi->display_on == 0 && hdmi->auto_switch == 0)
|
||||
{
|
||||
if(state > WAIT_HDMI_ENABLE)
|
||||
state = INITIAL;
|
||||
}
|
||||
if(hdmi->param_conf == 1)
|
||||
{
|
||||
if(state > WAIT_HDMI_ENABLE)
|
||||
state = WAIT_HDMI_ENABLE;
|
||||
hdmi->param_conf = 0;
|
||||
}
|
||||
|
||||
state = anx7150_interrupt_process();
|
||||
|
||||
}
|
||||
|
||||
|
||||
6
drivers/video/hdmi/hdmi-codec.c
Normal file
6
drivers/video/hdmi/hdmi-codec.c
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#include <linux/hdmi.h>
|
||||
|
||||
int hdmi_codec_set_audio_fs(unsigned char audio_fs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
129
drivers/video/hdmi/hdmi-core.c
Executable file
129
drivers/video/hdmi/hdmi-core.c
Executable file
|
|
@ -0,0 +1,129 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <linux/hdmi.h>
|
||||
|
||||
struct class *hdmi_class;
|
||||
struct hdmi_id_ref_info {
|
||||
int id;
|
||||
int ref;
|
||||
}ref_info[HDMI_MAX_ID];
|
||||
#ifdef CONFIG_SYSFS
|
||||
|
||||
extern int hdmi_create_attrs(struct hdmi *hdmi);
|
||||
extern void hdmi_remove_attrs(struct hdmi *hdmi);
|
||||
|
||||
#else
|
||||
|
||||
static inline int hdmi_create_attrs(struct hdmi *hdmi)
|
||||
{ return 0; }
|
||||
static inline void hdmi_remove_attrs(struct hdmi *hdmi) {}
|
||||
|
||||
#endif /* CONFIG_SYSFS */
|
||||
|
||||
void *hdmi_get_privdata(struct hdmi *hdmi)
|
||||
{
|
||||
return hdmi->priv;
|
||||
}
|
||||
void hdmi_set_privdata(struct hdmi *hdmi, void *data)
|
||||
{
|
||||
hdmi->priv = data;
|
||||
return;
|
||||
}
|
||||
|
||||
void hdmi_changed(struct hdmi *hdmi, int plug)
|
||||
{
|
||||
hdmi_dbg(hdmi->dev, "%s\n", __FUNCTION__);
|
||||
hdmi->plug = plug;
|
||||
schedule_work(&hdmi->changed_work);
|
||||
}
|
||||
|
||||
static void hdmi_changed_work(struct work_struct *work)
|
||||
{
|
||||
struct hdmi *hdmi = container_of(work, struct hdmi,
|
||||
changed_work);
|
||||
|
||||
hdmi_dbg(hdmi->dev, "%s\n", __FUNCTION__);
|
||||
|
||||
kobject_uevent(&hdmi->dev->kobj, KOBJ_CHANGE);
|
||||
}
|
||||
|
||||
int hdmi_register(struct device *parent, struct hdmi *hdmi)
|
||||
{
|
||||
int rc = 0, i;
|
||||
char name[8];
|
||||
|
||||
for(i = 0; i < HDMI_MAX_ID; i++)
|
||||
{
|
||||
if(ref_info[i].ref == 0)
|
||||
{
|
||||
ref_info[i].ref = 1;
|
||||
hdmi->id = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i == HDMI_MAX_ID)
|
||||
return -EINVAL;
|
||||
sprintf(name, "hdmi-%d", hdmi->id);
|
||||
|
||||
hdmi->dev = device_create(hdmi_class, parent, 0,
|
||||
"%s", name);
|
||||
if (IS_ERR(hdmi->dev)) {
|
||||
rc = PTR_ERR(hdmi->dev);
|
||||
goto dev_create_failed;
|
||||
}
|
||||
|
||||
dev_set_drvdata(hdmi->dev, hdmi);
|
||||
|
||||
INIT_WORK(&hdmi->changed_work, hdmi_changed_work);
|
||||
|
||||
rc = hdmi_create_attrs(hdmi);
|
||||
if (rc)
|
||||
goto create_attrs_failed;
|
||||
|
||||
//hdmi_changed(hdmi, 0);
|
||||
|
||||
goto success;
|
||||
|
||||
create_attrs_failed:
|
||||
device_unregister(hdmi->dev);
|
||||
dev_create_failed:
|
||||
success:
|
||||
return rc;
|
||||
}
|
||||
void hdmi_unregister(struct hdmi *hdmi)
|
||||
{
|
||||
flush_scheduled_work();
|
||||
hdmi_remove_attrs(hdmi);
|
||||
device_unregister(hdmi->dev);
|
||||
ref_info[hdmi->id].ref = 0;
|
||||
}
|
||||
|
||||
static int __init hdmi_class_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
hdmi_class = class_create(THIS_MODULE, "hdmi");
|
||||
|
||||
if (IS_ERR(hdmi_class))
|
||||
return PTR_ERR(hdmi_class);
|
||||
for(i = 0; i < HDMI_MAX_ID; i++) {
|
||||
ref_info[i].id = i;
|
||||
ref_info[i].ref = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit hdmi_class_exit(void)
|
||||
{
|
||||
class_destroy(hdmi_class);
|
||||
}
|
||||
EXPORT_SYMBOL(hdmi_changed);
|
||||
EXPORT_SYMBOL(hdmi_register);
|
||||
EXPORT_SYMBOL(hdmi_unregister);
|
||||
|
||||
subsys_initcall(hdmi_class_init);
|
||||
module_exit(hdmi_class_exit);
|
||||
|
||||
196
drivers/video/hdmi/hdmi-fb.c
Executable file
196
drivers/video/hdmi/hdmi-fb.c
Executable file
|
|
@ -0,0 +1,196 @@
|
|||
#include <linux/console.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/hdmi.h>
|
||||
|
||||
#include "../display/screen/screen.h"
|
||||
#include "../rk29_fb.h"
|
||||
|
||||
|
||||
/* Base */
|
||||
#define OUT_TYPE SCREEN_RGB
|
||||
#define OUT_FACE OUT_P888
|
||||
#define DCLK_POL 0
|
||||
#define SWAP_RB 0
|
||||
|
||||
/* 720p@60Hz Timing */
|
||||
#define OUT_CLK 74250000
|
||||
#define H_PW 40
|
||||
#define H_BP 220
|
||||
#define H_VD 1280
|
||||
#define H_FP 110
|
||||
#define V_PW 5
|
||||
#define V_BP 20
|
||||
#define V_VD 720
|
||||
#define V_FP 5
|
||||
|
||||
/* 720p@50Hz Timing */
|
||||
#define OUT_CLK2 74250000
|
||||
#define H_PW2 40
|
||||
#define H_BP2 220
|
||||
#define H_VD2 1280
|
||||
#define H_FP2 440
|
||||
#define V_PW2 5
|
||||
#define V_BP2 20
|
||||
#define V_VD2 720
|
||||
#define V_FP2 5
|
||||
|
||||
/* 576p@50Hz Timing */
|
||||
#define OUT_CLK3 27000000
|
||||
#define H_PW3 64
|
||||
#define H_BP3 68
|
||||
#define H_VD3 720
|
||||
#define H_FP3 12
|
||||
#define V_PW3 5
|
||||
#define V_BP3 39
|
||||
#define V_VD3 576
|
||||
#define V_FP3 5
|
||||
|
||||
extern int FB_Switch_Screen( struct rk29fb_screen *screen, u32 enable );
|
||||
|
||||
static int anx7150_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int anx7150_standby(u8 enable)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hdmi_set_info(struct rk29fb_screen *screen)
|
||||
{
|
||||
struct rk29fb_screen *screen2 = screen + 1;
|
||||
struct rk29fb_screen *screen3 = screen + 2;
|
||||
|
||||
/* ****************** 720p@60Hz ******************* */
|
||||
/* screen type & face */
|
||||
screen->type = OUT_TYPE;
|
||||
screen->face = OUT_FACE;
|
||||
|
||||
/* Screen size */
|
||||
screen->x_res = H_VD;
|
||||
screen->y_res = V_VD;
|
||||
|
||||
/* Timing */
|
||||
screen->pixclock = OUT_CLK;
|
||||
screen->left_margin = H_BP;
|
||||
screen->right_margin = H_FP;
|
||||
screen->hsync_len = H_PW;
|
||||
screen->upper_margin = V_BP;
|
||||
screen->lower_margin = V_FP;
|
||||
screen->vsync_len = V_PW;
|
||||
|
||||
/* Pin polarity */
|
||||
screen->pin_hsync = 0;
|
||||
screen->pin_vsync = 0;
|
||||
screen->pin_den = 0;
|
||||
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;
|
||||
|
||||
/* Operation function*/
|
||||
screen->init = anx7150_init;
|
||||
screen->standby = anx7150_standby;
|
||||
|
||||
|
||||
/* ****************** 720p@50Hz ******************* */
|
||||
/* screen type & face */
|
||||
screen2->type = OUT_TYPE;
|
||||
screen2->face = OUT_FACE;
|
||||
|
||||
/* Screen size */
|
||||
screen2->x_res = H_VD2;
|
||||
screen2->y_res = V_VD2;
|
||||
|
||||
/* Timing */
|
||||
screen2->pixclock = OUT_CLK2;
|
||||
screen2->left_margin = H_BP2;
|
||||
screen2->right_margin = H_FP2;
|
||||
screen2->hsync_len = H_PW2;
|
||||
screen2->upper_margin = V_BP2;
|
||||
screen2->lower_margin = V_FP2;
|
||||
screen2->vsync_len = V_PW2;
|
||||
|
||||
/* Pin polarity */
|
||||
screen2->pin_hsync = 0;
|
||||
screen2->pin_vsync = 0;
|
||||
screen2->pin_den = 0;
|
||||
screen2->pin_dclk = DCLK_POL;
|
||||
|
||||
/* Swap rule */
|
||||
screen2->swap_rb = SWAP_RB;
|
||||
screen2->swap_rg = 0;
|
||||
screen2->swap_gb = 0;
|
||||
screen2->swap_delta = 0;
|
||||
screen2->swap_dumy = 0;
|
||||
|
||||
/* Operation function*/
|
||||
screen2->init = anx7150_init;
|
||||
screen2->standby = anx7150_standby;
|
||||
|
||||
/* ****************** 576p@50Hz ******************* */
|
||||
/* screen type & face */
|
||||
screen3->type = OUT_TYPE;
|
||||
screen3->face = OUT_FACE;
|
||||
|
||||
/* Screen size */
|
||||
screen3->x_res = H_VD3;
|
||||
screen3->y_res = V_VD3;
|
||||
|
||||
/* Timing */
|
||||
screen3->pixclock = OUT_CLK3;
|
||||
screen3->left_margin = H_BP3;
|
||||
screen3->right_margin = H_FP3;
|
||||
screen3->hsync_len = H_PW3;
|
||||
screen3->upper_margin = V_BP3;
|
||||
screen3->lower_margin = V_FP3;
|
||||
screen3->vsync_len = V_PW3;
|
||||
|
||||
/* Pin polarity */
|
||||
screen3->pin_hsync = 0;
|
||||
screen3->pin_vsync = 0;
|
||||
screen3->pin_den = 0;
|
||||
screen3->pin_dclk = DCLK_POL;
|
||||
|
||||
/* Swap rule */
|
||||
screen3->swap_rb = SWAP_RB;
|
||||
screen3->swap_rg = 0;
|
||||
screen3->swap_gb = 0;
|
||||
screen3->swap_delta = 0;
|
||||
screen3->swap_dumy = 0;
|
||||
|
||||
/* Operation function*/
|
||||
screen3->init = anx7150_init;
|
||||
screen3->standby = anx7150_standby;
|
||||
}
|
||||
|
||||
int hdmi_switch_fb(int resolution, int type)
|
||||
{
|
||||
int rc = 0;
|
||||
struct rk29fb_screen hdmi_info[3];
|
||||
|
||||
hdmi_set_info(&hdmi_info[0]);
|
||||
|
||||
switch(resolution)
|
||||
{
|
||||
case HDMI_1280x720p_50Hz:
|
||||
rc = FB_Switch_Screen(&hdmi_info[1], type);
|
||||
break;
|
||||
case HDMI_1280x720p_60Hz:
|
||||
rc = FB_Switch_Screen(&hdmi_info[0], type);
|
||||
break;
|
||||
case HDMI_720x576p_50Hz:
|
||||
rc = FB_Switch_Screen(&hdmi_info[2], type);
|
||||
break;
|
||||
default:
|
||||
rc = FB_Switch_Screen(&hdmi_info[1], type);
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
162
drivers/video/hdmi/hdmi-sysfs.c
Executable file
162
drivers/video/hdmi/hdmi-sysfs.c
Executable file
|
|
@ -0,0 +1,162 @@
|
|||
#include <linux/ctype.h>
|
||||
#include <linux/hdmi.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
|
||||
static ssize_t hdmi_show_state_attrs(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct hdmi *hdmi = dev_get_drvdata(dev);
|
||||
|
||||
return sprintf(buf, "display_on=%d\n"
|
||||
"plug=%d\n"
|
||||
"--------------------------\n"
|
||||
"resolution support:\n"
|
||||
"0 -- 1280x720p_50Hz\n"
|
||||
"1 -- 1280x720p_60Hz\n"
|
||||
"2 -- 720x576p_50Hz\n"
|
||||
"--------------------------\n"
|
||||
"auto_switch=%d\n"
|
||||
"hdcp_on=%d\n"
|
||||
"audio_fs=%d\n"
|
||||
"resolution=%d\n",
|
||||
hdmi->display_on,hdmi->plug,
|
||||
hdmi->auto_switch, hdmi->hdcp_on,
|
||||
hdmi->audio_fs, hdmi->resolution);
|
||||
}
|
||||
static ssize_t hdmi_restore_state_attrs(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct hdmi *hdmi = dev_get_drvdata(dev);
|
||||
char *p;
|
||||
const char *q;
|
||||
int auto_switch = -1, hdcp_on = -1, audio_fs = -1, resolution = -1;
|
||||
|
||||
q = buf;
|
||||
do
|
||||
{
|
||||
if((p = strstr(q, "auto_switch=")) != NULL)
|
||||
{
|
||||
q = p + 12;
|
||||
if((sscanf(q, "%d", &auto_switch) == 1) &&
|
||||
(auto_switch == 0 || auto_switch == 1))
|
||||
hdmi->auto_switch = auto_switch;
|
||||
else
|
||||
{
|
||||
dev_err(dev, "failed to set hdmi configuration\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
else if((p = strstr(q, "hdcp_on=")) != NULL)
|
||||
{
|
||||
q = p + 8;
|
||||
if((sscanf(q, "%d", &hdcp_on) == 1) &&
|
||||
(hdcp_on == 0 || hdcp_on == 1))
|
||||
hdmi->hdcp_on = hdcp_on;
|
||||
else
|
||||
{
|
||||
dev_err(dev, "failed to set hdmi configuration\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
else if((p = strstr(q, "audio_fs=")) != NULL)
|
||||
{
|
||||
q = p + 9;
|
||||
if((sscanf(q, "%d", &audio_fs) == 1) &&
|
||||
(audio_fs >= 0))
|
||||
hdmi->audio_fs = audio_fs;
|
||||
else
|
||||
{
|
||||
dev_err(dev, "failed to set hdmi configuration\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
else if((p = strstr(q, "resolution=")) != NULL)
|
||||
{
|
||||
q = p + 11;
|
||||
if((sscanf(q, "%d", &resolution) == 1) &&
|
||||
(resolution >= 0))
|
||||
hdmi->resolution = resolution;
|
||||
else
|
||||
{
|
||||
dev_err(dev, "failed to set hdmi configuration\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
}while(*q != 0);
|
||||
if(auto_switch == -1 &&
|
||||
hdcp_on == -1 &&
|
||||
audio_fs == -1 &&
|
||||
resolution == -1)
|
||||
{
|
||||
dev_err(dev, "failed to set hdmi configuration\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if(hdmi->hdmi_set_param)
|
||||
hdmi->hdmi_set_param(hdmi);
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t hdmi_show_switch_attrs(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct hdmi *hdmi = dev_get_drvdata(dev);
|
||||
|
||||
return sprintf(buf, "%d\n", hdmi->display_on);
|
||||
}
|
||||
static ssize_t hdmi_restore_switch_attrs(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int display_on = 0;
|
||||
struct hdmi *hdmi = dev_get_drvdata(dev);
|
||||
|
||||
sscanf(buf, "%d", &display_on);
|
||||
|
||||
if(hdmi->hdmi_display_on && display_on == 1)
|
||||
hdmi->hdmi_display_on(hdmi);
|
||||
else if(hdmi->hdmi_display_off && display_on == 0)
|
||||
hdmi->hdmi_display_off(hdmi);
|
||||
|
||||
return size;
|
||||
}
|
||||
static struct device_attribute hdmi_attrs[] = {
|
||||
__ATTR(state, 0664, hdmi_show_state_attrs, hdmi_restore_state_attrs),
|
||||
__ATTR(enable, 0664, hdmi_show_switch_attrs, hdmi_restore_switch_attrs),
|
||||
};
|
||||
|
||||
int hdmi_create_attrs(struct hdmi *hdmi)
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(hdmi_attrs); i++) {
|
||||
rc = device_create_file(hdmi->dev, &hdmi_attrs[i]);
|
||||
if (rc)
|
||||
goto create_failed;
|
||||
}
|
||||
|
||||
goto succeed;
|
||||
|
||||
create_failed:
|
||||
while (i--)
|
||||
device_remove_file(hdmi->dev, &hdmi_attrs[i]);
|
||||
succeed:
|
||||
return rc;
|
||||
}
|
||||
|
||||
void hdmi_remove_attrs(struct hdmi *hdmi)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(hdmi_attrs); i++)
|
||||
device_remove_file(hdmi->dev, &hdmi_attrs[i]);
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
70
include/linux/hdmi.h
Executable file
70
include/linux/hdmi.h
Executable file
|
|
@ -0,0 +1,70 @@
|
|||
/* include/linux/hdmi.h
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_HDMI_CORE_H
|
||||
#define __LINUX_HDMI_CORE_H
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
#ifdef CONFIG_HDMI_DEBUG
|
||||
#define hdmi_dbg(dev, format, arg...) \
|
||||
dev_printk(KERN_INFO , dev , format , ## arg)
|
||||
#else
|
||||
#define hdmi_dbg(dev, format, arg...)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
typedef int BOOL;
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#define HDMI_1280x720p_50Hz 0
|
||||
#define HDMI_1280x720p_60Hz 1
|
||||
#define HDMI_720x576p_50Hz 2
|
||||
|
||||
#define HDMI_MAX_ID 32
|
||||
|
||||
|
||||
struct hdmi {
|
||||
struct device *dev;
|
||||
struct work_struct changed_work;
|
||||
int id;
|
||||
BOOL display_on;
|
||||
BOOL plug;
|
||||
BOOL auto_switch;
|
||||
BOOL hdcp_on;
|
||||
BOOL param_conf;
|
||||
|
||||
u8 resolution;
|
||||
u8 audio_fs;
|
||||
|
||||
void *priv;
|
||||
|
||||
int (*hdmi_display_on)(struct hdmi *);
|
||||
int (*hdmi_display_off)(struct hdmi *);
|
||||
int (*hdmi_set_param)(struct hdmi *);
|
||||
int (*hdmi_core_init)(struct hdmi *);
|
||||
};
|
||||
|
||||
extern void *hdmi_get_privdata(struct hdmi *hdmi);
|
||||
extern void hdmi_set_privdata(struct hdmi *hdmi, void *data);
|
||||
extern int hdmi_register(struct device *parent, struct hdmi *hdmi);
|
||||
extern void hdmi_unregister(struct hdmi *hdmi);
|
||||
extern void hdmi_changed(struct hdmi *hdmi, int plug);
|
||||
|
||||
extern int hdmi_codec_set_audio_fs(unsigned char audio_fs);
|
||||
extern int hdmi_fb_set_resolution(unsigned char resolution);
|
||||
|
||||
extern int hdmi_switch_fb(int resolution, int type);
|
||||
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue
Block a user