mirror of
https://github.com/torvalds/linux.git
synced 2026-06-10 23:53:52 +02:00
add new hdmi driver and update sdmmc driver
This commit is contained in:
parent
289204a92f
commit
3901afba10
|
|
@ -640,7 +640,7 @@ static struct i2c_board_info __initdata board_i2c1_devices[] = {
|
|||
.flags = 0,
|
||||
},
|
||||
#endif
|
||||
#if defined (CONFIG_ANX7150)
|
||||
#if defined (CONFIG_ANX7150) || defined (CONFIG_ANX7150_NEW)
|
||||
{
|
||||
.type = "anx7150",
|
||||
.addr = 0x39, //0x39, 0x3d
|
||||
|
|
|
|||
|
|
@ -80,9 +80,10 @@ enum {
|
|||
MRQ_RESET_CTRL_ERR, //15
|
||||
MRQ_RESET_CTRL_DONE, //16
|
||||
MRQ_DMA_SET_ERR, //17
|
||||
MRQ_STOP_DMA, //18
|
||||
MRQ_DMA_DONE, //19
|
||||
MRQ_REQUEST_DONE, //20
|
||||
MRQ_START_DMA, //18
|
||||
MRQ_STOP_DMA, //19
|
||||
MRQ_DMA_DONE, //20
|
||||
MRQ_REQUEST_DONE, //21
|
||||
};
|
||||
enum rk29_sdmmc_state {
|
||||
STATE_IDLE = 0,
|
||||
|
|
@ -461,6 +462,24 @@ static int send_stop_cmd(struct rk29_sdmmc *host)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
static void rk29_sdmmc_dma_cleanup(struct rk29_sdmmc *host)
|
||||
{
|
||||
struct mmc_data *data = host->mrq->data;
|
||||
if (data)
|
||||
dma_unmap_sg(host->dev, data->sg, data->sg_len,
|
||||
((data->flags & MMC_DATA_WRITE)
|
||||
? DMA_TO_DEVICE : DMA_FROM_DEVICE));
|
||||
}
|
||||
|
||||
static void rk29_sdmmc_stop_dma(struct rk29_sdmmc *host)
|
||||
{
|
||||
rk29_sdmmc_set_mrq_status(host, MRQ_STOP_DMA);
|
||||
rk29_sdmmc_dma_cleanup(host);
|
||||
rk29_dma_ctrl(host->dma_info.chn,RK29_DMAOP_STOP);
|
||||
rk29_dma_ctrl(host->dma_info.chn,RK29_DMAOP_FLUSH);
|
||||
rk29_sdmmc_write(host->regs, SDMMC_CTRL,
|
||||
(rk29_sdmmc_read(host->regs, SDMMC_CTRL))&(~SDMMC_CTRL_DMA_ENABLE));
|
||||
}
|
||||
|
||||
static void rk29_sdmmc_request_done(struct rk29_sdmmc *host,struct mmc_request *mrq)
|
||||
{
|
||||
|
|
@ -471,6 +490,10 @@ static void rk29_sdmmc_request_done(struct rk29_sdmmc *host,struct mmc_request *
|
|||
rk29_sdmmc_write(host->regs, SDMMC_INTMASK,
|
||||
rk29_sdmmc_read(host->regs, SDMMC_INTMASK) &
|
||||
~(SDMMC_INT_CMD_DONE | SDMMC_INT_DTO | RK29_SDMMC_ERROR_FLAGS));
|
||||
|
||||
if(!rk29_sdmmc_test_mrq_status(host, MRQ_STOP_DMA) &&
|
||||
rk29_sdmmc_test_mrq_status(host, MRQ_START_DMA))
|
||||
rk29_sdmmc_stop_dma(host);
|
||||
if(mrq->stop && !rk29_sdmmc_test_mrq_status(host, MRQ_STOP_START_DONE))
|
||||
send_stop_cmd(host);
|
||||
if(mrq->cmd->opcode == 17|| mrq->cmd->opcode == 51){
|
||||
|
|
@ -668,7 +691,8 @@ static int rk29_sdmmc_submit_data(struct rk29_sdmmc *host, struct mmc_data *data
|
|||
for (i = 0; i < dma_len; i++)
|
||||
rk29_dma_enqueue(host->dma_info.chn, host, sg_dma_address(&data->sg[i]),sg_dma_len(&data->sg[i])); // data->sg->dma_address, data->sg->length);
|
||||
rk29_sdmmc_write(host->regs, SDMMC_CTRL, (rk29_sdmmc_read(host->regs, SDMMC_CTRL))|SDMMC_CTRL_DMA_ENABLE);// enable dma
|
||||
rk29_dma_ctrl(host->dma_info.chn, RK29_DMAOP_START);
|
||||
rk29_dma_ctrl(host->dma_info.chn, RK29_DMAOP_START);
|
||||
rk29_sdmmc_set_mrq_status(host, MRQ_START_DMA);
|
||||
return 0;
|
||||
}
|
||||
static int rk29_sdmmc_test_cmd_start(struct rk29_sdmmc *host)
|
||||
|
|
@ -748,6 +772,12 @@ static void rk29_sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
|||
dev_info(host->dev, "mrq = NULL!!!!!\n");
|
||||
if(host->mrq)
|
||||
rk29_sdmmc_show_info(host);
|
||||
|
||||
if((!rk29_sdmmc_test_mrq_status(host, MRQ_STOP_DMA) &&
|
||||
rk29_sdmmc_test_mrq_status(host, MRQ_START_DMA)) ||
|
||||
(rk29_sdmmc_test_mrq_status(host, MRQ_STOP_DMA) &&
|
||||
!rk29_sdmmc_test_mrq_status(host, MRQ_START_DMA)))
|
||||
dev_warn(host->dev, "start_dma but no stop_dma, or no start_dma but stop_dma\n");
|
||||
WARN_ON(host->mrq);
|
||||
host->old_mrq_status = host->mrq_status;
|
||||
host->mrq_status = 0;
|
||||
|
|
@ -831,24 +861,6 @@ static void rk29_sdmmc_request_end(struct rk29_sdmmc *host)
|
|||
if(host->mrq)
|
||||
rk29_sdmmc_request_done(host, host->mrq);
|
||||
}
|
||||
static void rk29_sdmmc_dma_cleanup(struct rk29_sdmmc *host)
|
||||
{
|
||||
struct mmc_data *data = host->mrq->data;
|
||||
if (data)
|
||||
dma_unmap_sg(host->dev, data->sg, data->sg_len,
|
||||
((data->flags & MMC_DATA_WRITE)
|
||||
? DMA_TO_DEVICE : DMA_FROM_DEVICE));
|
||||
}
|
||||
|
||||
static void rk29_sdmmc_stop_dma(struct rk29_sdmmc *host)
|
||||
{
|
||||
rk29_sdmmc_set_mrq_status(host, MRQ_STOP_DMA);
|
||||
rk29_sdmmc_dma_cleanup(host);
|
||||
rk29_dma_ctrl(host->dma_info.chn,RK29_DMAOP_STOP);
|
||||
rk29_dma_ctrl(host->dma_info.chn,RK29_DMAOP_FLUSH);
|
||||
rk29_sdmmc_write(host->regs, SDMMC_CTRL,
|
||||
(rk29_sdmmc_read(host->regs, SDMMC_CTRL))&(~SDMMC_CTRL_DMA_ENABLE));
|
||||
}
|
||||
|
||||
static void rk29_sdmmc_command_complete(struct rk29_sdmmc *host,
|
||||
struct mmc_command *cmd)
|
||||
|
|
|
|||
|
|
@ -1,19 +1,32 @@
|
|||
#
|
||||
# Display drivers configuration
|
||||
#
|
||||
|
||||
menu "HDMI support"
|
||||
|
||||
menu "HDMI"
|
||||
config HDMI
|
||||
tristate "hdmi support"
|
||||
tristate "HDMI support"
|
||||
|
||||
if HDMI
|
||||
|
||||
config HDMI_OLD
|
||||
default y
|
||||
bool "old hdmi support"
|
||||
help
|
||||
nothing
|
||||
if HDMI
|
||||
source "drivers/video/hdmi/chips/Kconfig"
|
||||
if HDMI_OLD
|
||||
source "drivers/video/hdmi/hdmi-old/Kconfig"
|
||||
endif
|
||||
|
||||
config HDMI_NEW
|
||||
bool "new hdmi support"
|
||||
help
|
||||
nothing
|
||||
if HDMI_NEW
|
||||
source "drivers/video/hdmi/hdmi-new/Kconfig"
|
||||
endif
|
||||
|
||||
config HDMI_DEBUG
|
||||
bool "hdmi debug"
|
||||
help
|
||||
nothing
|
||||
|
||||
endif
|
||||
|
||||
endmenu
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
obj-$(CONFIG_HDMI) += hdmi-core.o hdmi-sysfs.o hdmi-fb.o hdmi-codec.o
|
||||
obj-$(CONFIG_HDMI) += chips/
|
||||
obj-$(CONFIG_HDMI_OLD) += hdmi-old/
|
||||
obj-$(CONFIG_HDMI_NEW) += hdmi-new/
|
||||
|
|
|
|||
5
drivers/video/hdmi/hdmi-new/Kconfig
Normal file
5
drivers/video/hdmi/hdmi-new/Kconfig
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#
|
||||
# Display drivers configuration
|
||||
#
|
||||
|
||||
source "drivers/video/hdmi/hdmi-new/chips/Kconfig"
|
||||
2
drivers/video/hdmi/hdmi-new/Makefile
Normal file
2
drivers/video/hdmi/hdmi-new/Makefile
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
obj-y += hdmi-core.o hdmi-sysfs.o hdmi-fb.o hdmi-codec.o
|
||||
obj-y += chips/
|
||||
7
drivers/video/hdmi/hdmi-new/chips/Kconfig
Normal file
7
drivers/video/hdmi/hdmi-new/chips/Kconfig
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
choice
|
||||
prompt "HDMI chips select"
|
||||
config ANX7150_NEW
|
||||
bool "anx7150"
|
||||
config ANX9030_NEW
|
||||
bool "anx9030"
|
||||
endchoice
|
||||
2
drivers/video/hdmi/hdmi-new/chips/Makefile
Normal file
2
drivers/video/hdmi/hdmi-new/chips/Makefile
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
obj-$(CONFIG_ANX7150_NEW) += anx7150_hw.o anx7150.o
|
||||
|
||||
315
drivers/video/hdmi/hdmi-new/chips/anx7150.c
Executable file
315
drivers/video/hdmi/hdmi-new/chips/anx7150.c
Executable file
|
|
@ -0,0 +1,315 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/hdmi-new.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 anx7150_param_chg(struct anx7150_pdata *anx)
|
||||
{
|
||||
int resolution_real;
|
||||
|
||||
hdmi_switch_fb(anx->hdmi, anx->hdmi->display_on);
|
||||
resolution_real = ANX7150_Get_Optimal_resolution(anx->hdmi->resolution);
|
||||
HDMI_Set_Video_Format(resolution_real);
|
||||
HDMI_Set_Audio_Fs(anx->hdmi->audio_fs);
|
||||
ANX7150_API_HDCP_ONorOFF(anx->hdmi->hdcp_on);
|
||||
ANX7150_API_System_Config();
|
||||
ANX7150_Config_Video(anx->client);
|
||||
|
||||
ANX7150_Config_Audio(anx->client);
|
||||
ANX7150_Config_Packet(anx->client);
|
||||
ANX7150_HDCP_Process(anx->client, anx->hdmi->display_on);
|
||||
ANX7150_PLAYBACK_Process();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int anx7150_insert(struct hdmi *hdmi)
|
||||
{
|
||||
int tmo = 10;
|
||||
struct anx7150_pdata *anx = hdmi_priv(hdmi);
|
||||
|
||||
anx7150_plug(anx->client);
|
||||
if(anx->is_changed) {
|
||||
if(ANX7150_Parse_EDID(anx->client,&anx->dev) < 0)
|
||||
{
|
||||
dev_info(&anx->client->dev, "parse EDID error\n");
|
||||
anx7150_unplug(anx->client);
|
||||
return -1;
|
||||
}
|
||||
while(--tmo && ANX7150_GET_SENSE_STATE(anx->client) != 1)
|
||||
mdelay(10);
|
||||
if(tmo <= 0)
|
||||
{
|
||||
anx7150_unplug(anx->client);
|
||||
return -1;
|
||||
}
|
||||
anx->is_changed = 0;
|
||||
}
|
||||
|
||||
anx7150_param_chg(anx);
|
||||
return 0;
|
||||
}
|
||||
static int anx7150_remove(struct hdmi *hdmi)
|
||||
{
|
||||
struct anx7150_pdata *anx = hdmi_priv(hdmi);
|
||||
|
||||
anx7150_unplug(anx->client);
|
||||
hdmi_switch_fb(hdmi, HDMI_DISABLE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int anx7150_display_on(struct hdmi* hdmi)
|
||||
{
|
||||
struct anx7150_pdata *anx = hdmi_priv(hdmi);
|
||||
|
||||
hdmi->display_on = HDMI_ENABLE;
|
||||
hdmi_dbg(hdmi->dev, "hdmi display on\n");
|
||||
anx7150_param_chg(anx);
|
||||
return 0;
|
||||
}
|
||||
static int anx7150_display_off(struct hdmi* hdmi)
|
||||
{
|
||||
struct anx7150_pdata *anx = hdmi_priv(hdmi);
|
||||
|
||||
hdmi->display_on = HDMI_DISABLE;
|
||||
anx->dev.hdmi_enable = HDMI_DISABLE;
|
||||
hdmi_dbg(hdmi->dev, "hdmi display off\n");
|
||||
anx7150_param_chg(anx);
|
||||
return 0;
|
||||
}
|
||||
static int anx7150_set_param(struct hdmi *hdmi)
|
||||
{
|
||||
struct anx7150_pdata *anx = hdmi_priv(hdmi);
|
||||
|
||||
anx7150_param_chg(anx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int anx7150_hdmi_precent(struct hdmi *hdmi)
|
||||
{
|
||||
struct anx7150_pdata *anx = hdmi_priv(hdmi);
|
||||
|
||||
return gpio_get_value(anx->client->irq)?0:1;
|
||||
}
|
||||
static struct hdmi_ops anx7150_ops = {
|
||||
.display_on = anx7150_display_on,
|
||||
.display_off = anx7150_display_off,
|
||||
.set_param = anx7150_set_param,
|
||||
.hdmi_precent = anx7150_hdmi_precent,
|
||||
.insert = anx7150_insert,
|
||||
.remove = anx7150_remove,
|
||||
};
|
||||
static irqreturn_t anx7150_detect_irq(int irq, void *dev_id);
|
||||
static void anx7150_detect_work(struct work_struct *work)
|
||||
{
|
||||
int ret = 0;
|
||||
struct anx7150_pdata *anx = container_of(work, struct anx7150_pdata, work.work);
|
||||
|
||||
free_irq(anx->irq, anx);
|
||||
ret = request_irq(anx->irq, anx7150_detect_irq,
|
||||
anx7150_hdmi_precent(anx->hdmi)? IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING,NULL,anx);
|
||||
dev_info(&anx->client->dev, "det = %d,hpd_status = %d\n",
|
||||
gpio_get_value(anx->client->irq), anx7150_get_hpd(anx->client));
|
||||
anx->is_changed = 1;
|
||||
if(!anx->is_early_suspend)
|
||||
hdmi_changed(anx->hdmi, 0);
|
||||
}
|
||||
|
||||
static irqreturn_t anx7150_detect_irq(int irq, void *dev_id)
|
||||
{
|
||||
|
||||
struct anx7150_pdata *anx = (struct anx7150_pdata *)dev_id;
|
||||
|
||||
disable_irq_nosync(anx->irq);
|
||||
schedule_delayed_work(&anx->work, msecs_to_jiffies(200));
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
static void anx7150_early_suspend(struct early_suspend *h)
|
||||
{
|
||||
struct anx7150_pdata *anx = container_of(h,
|
||||
struct anx7150_pdata,
|
||||
early_suspend);
|
||||
dev_info(&anx->client->dev, "anx7150 enter early suspend\n");
|
||||
anx->is_early_suspend = 1;
|
||||
flush_delayed_work(&anx->work);
|
||||
hdmi_suspend(anx->hdmi);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void anx7150_early_resume(struct early_suspend *h)
|
||||
{
|
||||
int ret = 0;
|
||||
struct anx7150_pdata *anx = container_of(h,
|
||||
struct anx7150_pdata,
|
||||
early_suspend);
|
||||
dev_info(&anx->client->dev, "anx7150 exit early suspend\n");
|
||||
anx->is_early_suspend = 0;
|
||||
ret = hdmi_resume(anx->hdmi);
|
||||
return;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static int anx7150_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id)
|
||||
{
|
||||
int ret = 0;
|
||||
struct hdmi *hdmi = NULL;
|
||||
struct anx7150_pdata *anx = NULL;
|
||||
|
||||
hdmi = hdmi_register(sizeof(struct anx7150_pdata), &client->dev);
|
||||
if (!hdmi)
|
||||
{
|
||||
dev_err(&client->dev, "fail to register hdmi\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
hdmi->ops = &anx7150_ops;
|
||||
hdmi->display_on = HDMI_ENABLE;
|
||||
hdmi->auto_switch = HDMI_DISABLE;
|
||||
hdmi->hdcp_on = HDMI_DISABLE;
|
||||
hdmi->audio_fs = HDMI_I2S_DEFAULT_Fs;
|
||||
hdmi->resolution = HDMI_DEFAULT_RESOLUTION;
|
||||
|
||||
anx = hdmi_priv(hdmi);
|
||||
anx->hdmi = hdmi;
|
||||
i2c_set_clientdata(client, anx);
|
||||
anx->client = client;
|
||||
|
||||
if((ret = gpio_request(client->irq, "hdmi gpio")) < 0)
|
||||
{
|
||||
dev_err(&client->dev, "fail to request gpio %d\n", client->irq);
|
||||
goto err_hdmi_unregister;
|
||||
}
|
||||
gpio_pull_updown(client->irq,0);
|
||||
gpio_direction_input(client->irq);
|
||||
|
||||
anx->irq = gpio_to_irq(client->irq);
|
||||
INIT_DELAYED_WORK(&anx->work, anx7150_detect_work);
|
||||
if((ret = request_irq(anx->irq, anx7150_detect_irq,
|
||||
anx7150_hdmi_precent(hdmi)?IRQF_TRIGGER_RISING:IRQF_TRIGGER_FALLING, NULL, anx)) <0)
|
||||
{
|
||||
dev_err(&client->dev, "fail to request hdmi irq\n");
|
||||
goto err_gpio_free;
|
||||
}
|
||||
if(anx7150_detect_device(anx) < 0)
|
||||
{
|
||||
dev_err(&client->dev, "anx7150 is not exist\n");
|
||||
ret = -EIO;
|
||||
goto err_free_irq;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
anx->early_suspend.suspend = anx7150_early_suspend;
|
||||
anx->early_suspend.resume = anx7150_early_resume;
|
||||
anx->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 1;
|
||||
register_early_suspend(&anx->early_suspend);
|
||||
#endif
|
||||
anx->is_early_suspend = 0;
|
||||
anx->is_changed = 1;
|
||||
|
||||
hdmi_changed(hdmi, 200);
|
||||
dev_info(&client->dev, "anx7150 i2c probe ok\n");
|
||||
return 0;
|
||||
err_free_irq:
|
||||
free_irq(anx->irq, hdmi);
|
||||
err_gpio_free:
|
||||
gpio_free(client->irq);
|
||||
err_hdmi_unregister:
|
||||
hdmi_unregister(hdmi);
|
||||
anx = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
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->hdmi;
|
||||
|
||||
free_irq(anx->irq, anx);
|
||||
gpio_free(client->irq);
|
||||
hdmi_unregister(hdmi);
|
||||
anx = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int anx7150_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
|
||||
{
|
||||
struct anx7150_pdata *anx = (struct anx7150_pdata *)i2c_get_clientdata(client);
|
||||
|
||||
return hdmi_suspend(anx->hdmi);
|
||||
}
|
||||
static int anx7150_i2c_resume(struct i2c_client *client)
|
||||
{
|
||||
int ret = 0;
|
||||
struct anx7150_pdata *anx = (struct anx7150_pdata *)i2c_get_clientdata(client);
|
||||
|
||||
ret = hdmi_resume(anx->hdmi);
|
||||
return ret;
|
||||
}
|
||||
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,
|
||||
//.suspend = &anx7150_i2c_suspend,
|
||||
//.resume = &anx7150_i2c_resume,
|
||||
.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);
|
||||
|
||||
|
||||
100
drivers/video/hdmi/hdmi-new/chips/anx7150.h
Executable file
100
drivers/video/hdmi/hdmi-new/chips/anx7150.h
Executable file
|
|
@ -0,0 +1,100 @@
|
|||
#ifndef _ANX7150_H
|
||||
#define _ANX7150_H
|
||||
|
||||
#include <linux/hdmi-new.h>
|
||||
#include <linux/earlysuspend.h>
|
||||
|
||||
|
||||
#define ANX7150_I2C_ADDR0 0X39
|
||||
#define ANX7150_I2C_ADDR1 0X3d
|
||||
|
||||
#define ANX7150_SCL_RATE 100 * 1000
|
||||
|
||||
|
||||
|
||||
/* 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
|
||||
|
||||
/* 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;
|
||||
int is_early_suspend;
|
||||
int is_changed;
|
||||
struct delayed_work work;
|
||||
struct hdmi *hdmi;
|
||||
struct i2c_client *client;
|
||||
struct anx7150_dev_s dev;
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
struct early_suspend early_suspend;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
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
|
||||
4230
drivers/video/hdmi/hdmi-new/chips/anx7150_hw.c
Executable file
4230
drivers/video/hdmi/hdmi-new/chips/anx7150_hw.c
Executable file
File diff suppressed because it is too large
Load Diff
1267
drivers/video/hdmi/hdmi-new/chips/anx7150_hw.h
Executable file
1267
drivers/video/hdmi/hdmi-new/chips/anx7150_hw.h
Executable file
File diff suppressed because it is too large
Load Diff
6
drivers/video/hdmi/hdmi-new/hdmi-codec.c
Normal file
6
drivers/video/hdmi/hdmi-new/hdmi-codec.c
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#include <linux/hdmi-new.h>
|
||||
|
||||
int hdmi_codec_set_audio_fs(unsigned char audio_fs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
163
drivers/video/hdmi/hdmi-new/hdmi-core.c
Executable file
163
drivers/video/hdmi/hdmi-new/hdmi-core.c
Executable file
|
|
@ -0,0 +1,163 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <linux/hdmi-new.h>
|
||||
|
||||
struct class *hdmi_class;
|
||||
struct hdmi_id_ref_info {
|
||||
struct hdmi *hdmi;
|
||||
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_changed(struct hdmi *hdmi, int msec)
|
||||
{
|
||||
schedule_delayed_work(&hdmi->changed_work, msecs_to_jiffies(msec));
|
||||
}
|
||||
int hdmi_suspend(struct hdmi *hdmi)
|
||||
{
|
||||
flush_delayed_work(&hdmi->changed_work);
|
||||
return hdmi->ops->remove(hdmi);
|
||||
}
|
||||
int hdmi_resume(struct hdmi *hdmi)
|
||||
{
|
||||
hdmi_changed(hdmi, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hdmi_changed_work(struct work_struct *work)
|
||||
{
|
||||
int precent, ret = 0;
|
||||
struct hdmi *hdmi = container_of(work, struct hdmi,
|
||||
changed_work.work);
|
||||
|
||||
precent = hdmi->ops->hdmi_precent(hdmi);
|
||||
hdmi_dbg(hdmi->dev, "hdmi %s\n", (precent)?"insert" : "remove");
|
||||
|
||||
if(precent)
|
||||
ret = hdmi->ops->insert(hdmi);
|
||||
else
|
||||
ret = hdmi->ops->remove(hdmi);
|
||||
if(ret < 0)
|
||||
dev_warn(hdmi->dev, "hdmi changed error\n");
|
||||
kobject_uevent(&hdmi->dev->kobj, KOBJ_CHANGE);
|
||||
}
|
||||
|
||||
void *hdmi_priv(struct hdmi *hdmi)
|
||||
{
|
||||
return (void *)hdmi->priv;
|
||||
}
|
||||
|
||||
struct hdmi *hdmi_register(int extra, struct device *parent)
|
||||
{
|
||||
int rc = 0, i;
|
||||
char name[8];
|
||||
struct hdmi *hdmi = kzalloc(sizeof(struct hdmi)+ extra, GFP_KERNEL);
|
||||
|
||||
if(!hdmi)
|
||||
return NULL;
|
||||
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)
|
||||
{
|
||||
kfree(hdmi);
|
||||
return NULL;
|
||||
}
|
||||
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);
|
||||
ref_info[i].hdmi = hdmi;
|
||||
|
||||
INIT_DELAYED_WORK(&hdmi->changed_work, hdmi_changed_work);
|
||||
|
||||
rc = hdmi_create_attrs(hdmi);
|
||||
if (rc)
|
||||
goto create_attrs_failed;
|
||||
|
||||
goto success;
|
||||
|
||||
create_attrs_failed:
|
||||
device_unregister(hdmi->dev);
|
||||
dev_create_failed:
|
||||
hdmi_remove_attrs(hdmi);
|
||||
kfree(hdmi);
|
||||
return NULL;
|
||||
success:
|
||||
return hdmi;
|
||||
}
|
||||
void hdmi_unregister(struct hdmi *hdmi)
|
||||
{
|
||||
flush_scheduled_work();
|
||||
hdmi_remove_attrs(hdmi);
|
||||
device_unregister(hdmi->dev);
|
||||
|
||||
kfree(hdmi);
|
||||
hdmi = NULL;
|
||||
ref_info[hdmi->id].ref = 0;
|
||||
ref_info[hdmi->id].hdmi = NULL;
|
||||
}
|
||||
struct hdmi *get_hdmi_struct(int nr)
|
||||
{
|
||||
if(ref_info[nr].ref == 0)
|
||||
return NULL;
|
||||
else
|
||||
return ref_info[nr].hdmi;
|
||||
}
|
||||
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;
|
||||
ref_info[i].hdmi = NULL;
|
||||
}
|
||||
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);
|
||||
EXPORT_SYMBOL(get_hdmi_struct);
|
||||
|
||||
subsys_initcall(hdmi_class_init);
|
||||
module_exit(hdmi_class_exit);
|
||||
|
||||
295
drivers/video/hdmi/hdmi-new/hdmi-fb.c
Executable file
295
drivers/video/hdmi/hdmi-new/hdmi-fb.c
Executable file
|
|
@ -0,0 +1,295 @@
|
|||
#include <linux/console.h>
|
||||
#include <linux/fb.h>
|
||||
|
||||
#include <linux/completion.h>
|
||||
#include "../../display/screen/screen.h"
|
||||
#include <linux/hdmi-new.h>
|
||||
#include "../../rk29_fb.h"
|
||||
|
||||
|
||||
/* Base */
|
||||
#define LCD_ACLK 500000000// 312000000
|
||||
|
||||
#define OUT_TYPE SCREEN_HDMI
|
||||
#define OUT_FACE OUT_P888
|
||||
#define DCLK_POL 1
|
||||
#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
|
||||
|
||||
/* 1080p@50Hz Timing */
|
||||
#define OUT_CLK4 148500000
|
||||
#define H_PW4 44
|
||||
#define H_BP4 148
|
||||
#define H_VD4 1920
|
||||
#define H_FP4 528
|
||||
#define V_PW4 5
|
||||
#define V_BP4 35
|
||||
#define V_VD4 1080
|
||||
#define V_FP4 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;
|
||||
struct rk29fb_screen *screen4 = screen + 3;
|
||||
|
||||
/* ****************** 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;
|
||||
screen4->lcdc_aclk = LCD_ACLK;
|
||||
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->lcdc_aclk = LCD_ACLK;
|
||||
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->lcdc_aclk = LCD_ACLK;
|
||||
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;
|
||||
/* ****************** 1080p@50Hz ******************* */
|
||||
/* screen type & face */
|
||||
screen4->type = OUT_TYPE;
|
||||
screen4->face = OUT_FACE;
|
||||
|
||||
/* Screen size */
|
||||
screen4->x_res = H_VD4;
|
||||
screen4->y_res = V_VD4;
|
||||
|
||||
/* Timing */
|
||||
screen4->pixclock = OUT_CLK4;
|
||||
screen4->lcdc_aclk = LCD_ACLK;
|
||||
screen4->left_margin = H_BP4;
|
||||
screen4->right_margin = H_FP4;
|
||||
screen4->hsync_len = H_PW4;
|
||||
screen4->upper_margin = V_BP4;
|
||||
screen4->lower_margin = V_FP4;
|
||||
screen4->vsync_len = V_PW4;
|
||||
|
||||
/* Pin polarity */
|
||||
screen4->pin_hsync = 0;
|
||||
screen4->pin_vsync = 0;
|
||||
screen4->pin_den = 0;
|
||||
screen4->pin_dclk = DCLK_POL;
|
||||
|
||||
/* Swap rule */
|
||||
screen4->swap_rb = SWAP_RB;
|
||||
screen4->swap_rg = 0;
|
||||
screen4->swap_gb = 0;
|
||||
screen4->swap_delta = 0;
|
||||
screen4->swap_dumy = 0;
|
||||
|
||||
/* Operation function*/
|
||||
screen4->init = anx7150_init;
|
||||
screen4->standby = anx7150_standby;
|
||||
}
|
||||
|
||||
int hdmi_switch_fb(struct hdmi *hdmi, int type)
|
||||
{
|
||||
int rc = 0;
|
||||
struct rk29fb_screen hdmi_info[4];
|
||||
|
||||
hdmi_set_info(&hdmi_info[0]);
|
||||
|
||||
switch(hdmi->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;
|
||||
case HDMI_1920x1080p_50Hz:
|
||||
rc = FB_Switch_Screen(&hdmi_info[3], type);
|
||||
break;
|
||||
default:
|
||||
rc = FB_Switch_Screen(&hdmi_info[1], type);
|
||||
break;
|
||||
}
|
||||
if(hdmi->wait == 1) {
|
||||
complete(&hdmi->complete);
|
||||
hdmi->wait = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
int hdmi_resolution_changed(struct hdmi *hdmi, int xres, int yres, int video_on)
|
||||
{
|
||||
int ret = 0;
|
||||
if(hdmi->display_on == 0|| hdmi->plug == 0)
|
||||
return ret;
|
||||
if(xres > 1280 && hdmi->resolution != HDMI_1920x1080p_50Hz)
|
||||
{
|
||||
hdmi->resolution = HDMI_1920x1080p_50Hz;
|
||||
hdmi->display_on = 1;
|
||||
hdmi->ops->set_param(hdmi);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
|
||||
else if(xres >1024 && xres <= 1280 && hdmi->resolution != HDMI_1280x720p_50Hz){
|
||||
hdmi->resolution = HDMI_1280x720p_50Hz;
|
||||
hdmi->display_on = 1;
|
||||
hdmi->ops->set_param(hdmi);
|
||||
ret = 1;
|
||||
}
|
||||
/*
|
||||
else {
|
||||
if(hdmi->display_on == 1)
|
||||
hdmi->hdmi_display_off(hdmi);
|
||||
}*/
|
||||
return ret;
|
||||
}
|
||||
|
||||
int hdmi_get_default_resolution(void *screen)
|
||||
{
|
||||
struct rk29fb_screen hdmi_info[4];
|
||||
|
||||
hdmi_set_info(&hdmi_info[0]);
|
||||
memcpy((struct rk29fb_screen*)screen, &hdmi_info[HDMI_DEFAULT_RESOLUTION], sizeof(struct rk29fb_screen));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
EXPORT_SYMBOL(hdmi_resolution_changed);
|
||||
179
drivers/video/hdmi/hdmi-new/hdmi-sysfs.c
Executable file
179
drivers/video/hdmi/hdmi-new/hdmi-sysfs.c
Executable file
|
|
@ -0,0 +1,179 @@
|
|||
#include <linux/ctype.h>
|
||||
#include <linux/hdmi-new.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"
|
||||
"3 -- 1920x1080p_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)
|
||||
{
|
||||
int ret = 0;
|
||||
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");
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
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");
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
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");
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
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");
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
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");
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
if(hdmi->ops->set_param)
|
||||
ret = hdmi->ops->set_param(hdmi);
|
||||
else
|
||||
{
|
||||
dev_err(dev, "hdmi device is not exist\n");
|
||||
return ret = 0;
|
||||
}
|
||||
exit:
|
||||
if(ret < 0)
|
||||
dev_err(dev, "hdmi_restore_state_attrs err\n");
|
||||
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, ret = 0;
|
||||
struct hdmi *hdmi = dev_get_drvdata(dev);
|
||||
|
||||
sscanf(buf, "%d", &display_on);
|
||||
|
||||
if(hdmi->display_on == HDMI_DISABLE && display_on)
|
||||
ret = hdmi->ops->display_on(hdmi);
|
||||
else if(hdmi->display_on == HDMI_ENABLE && !display_on)
|
||||
ret = hdmi->ops->display_off(hdmi);
|
||||
|
||||
if(ret < 0)
|
||||
dev_err(dev, "hdmi_restore_switch_attrs err\n");
|
||||
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]);
|
||||
}
|
||||
|
||||
|
||||
5
drivers/video/hdmi/hdmi-old/Kconfig
Normal file
5
drivers/video/hdmi/hdmi-old/Kconfig
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#
|
||||
# Display drivers configuration
|
||||
#
|
||||
|
||||
source "drivers/video/hdmi/hdmi-old/chips/Kconfig"
|
||||
2
drivers/video/hdmi/hdmi-old/Makefile
Normal file
2
drivers/video/hdmi/hdmi-old/Makefile
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
obj-y += hdmi-core.o hdmi-sysfs.o hdmi-fb.o hdmi-codec.o
|
||||
obj-y += chips/
|
||||
|
|
@ -2,9 +2,9 @@
|
|||
#include <linux/fb.h>
|
||||
|
||||
#include <linux/completion.h>
|
||||
#include "../display/screen/screen.h"
|
||||
#include "../../display/screen/screen.h"
|
||||
#include <linux/hdmi.h>
|
||||
#include "../rk29_fb.h"
|
||||
#include "../../rk29_fb.h"
|
||||
|
||||
|
||||
/* Base */
|
||||
|
|
@ -292,4 +292,4 @@ int hdmi_get_default_resolution(void *screen)
|
|||
}
|
||||
|
||||
|
||||
EXPORT_SYMBOL(hdmi_resolution_changed);
|
||||
EXPORT_SYMBOL(hdmi_resolution_changed);
|
||||
94
include/linux/hdmi-new.h
Executable file
94
include/linux/hdmi-new.h
Executable file
|
|
@ -0,0 +1,94 @@
|
|||
/* 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>
|
||||
#include <linux/completion.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_DISABLE 0
|
||||
#define HDMI_ENABLE 1
|
||||
/* resolution */
|
||||
#define HDMI_1280x720p_50Hz 0
|
||||
#define HDMI_1280x720p_60Hz 1
|
||||
#define HDMI_720x576p_50Hz 2
|
||||
#define HDMI_1920x1080p_50Hz 3
|
||||
/* 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_44100
|
||||
|
||||
|
||||
#define HDMI_MAX_ID 32
|
||||
struct hdmi;
|
||||
struct hdmi_ops{
|
||||
int (*display_on)(struct hdmi *);
|
||||
int (*display_off)(struct hdmi *);
|
||||
int (*set_param)(struct hdmi *);
|
||||
int (*hdmi_precent)(struct hdmi *);
|
||||
int (*insert)(struct hdmi *);
|
||||
int (*remove)(struct hdmi *);
|
||||
int (*power_off)(struct hdmi *);
|
||||
};
|
||||
struct hdmi {
|
||||
int id;
|
||||
int wait;
|
||||
BOOL display_on;
|
||||
BOOL plug;
|
||||
BOOL auto_switch;
|
||||
BOOL hdcp_on;
|
||||
BOOL param_conf;
|
||||
|
||||
u8 resolution;
|
||||
u8 audio_fs;
|
||||
|
||||
struct device *dev;
|
||||
struct delayed_work changed_work;
|
||||
struct completion complete;
|
||||
const struct hdmi_ops *ops;
|
||||
|
||||
unsigned long priv[0] ____cacheline_aligned;
|
||||
};
|
||||
extern void *hdmi_priv(struct hdmi *hdmi);
|
||||
extern struct hdmi *hdmi_register(int extra, struct device *parent);
|
||||
extern void hdmi_unregister(struct hdmi *hdmi);
|
||||
extern void hdmi_changed(struct hdmi *hdmi, int msec);
|
||||
extern int hdmi_suspend(struct hdmi *hdmi);
|
||||
extern int hdmi_resume(struct hdmi *hdmi);
|
||||
|
||||
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(struct hdmi *hdmi, int type);
|
||||
extern int hdmi_resolution_changed(struct hdmi *hdmi, int xres, int yres, int video_on);
|
||||
|
||||
extern struct hdmi *get_hdmi_struct(int nr);
|
||||
|
||||
extern int hdmi_get_default_resolution(void *screen);
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue
Block a user