Display: slimport porting - update to V0.3

1. slimport basic function
2. set gpio 50 as 27M clock (function_2, refer to document 80-N7752-2 p.435)
3. request USB_ID pin (gpio 77) to let detect pin work
4. the version history:

V0.1
The gerenal slimport ANX7808 driver for customer evalutaion and application.

2013-01-08
V0.2
1. Add pull down ID_OUT pin once the slimport accessary is plugged, and left it to default status
   once the accessay is unplugged.
2. If the incoming video is YUV, convert it to RGB colorspace, since our RGB dangle only support RGB.

2013-01-29
V0.3
1. Correct the error in eye diagram test.
2. Correct the phy auto test.

Change-Id: I0d35945b5682ca736ec00b3d5166001f2ab5dfc3
Change-Id: Ibdf3ba27e119f0ae361b28b1f33f7522d5fdf758
Reviewed-on: http://mcrd1-5.corpnet.asus/code-review/master/67937
Reviewed-by: Yetta Wu <Yetta_Wu@asus.com>
Tested-by: Yetta Wu <Yetta_Wu@asus.com>
Reviewed-by: Warlock Tai <warlock_tai@asus.com>
This commit is contained in:
yetta_wu 2013-01-30 11:33:41 +08:00 committed by Iliyan Malchev
parent 845eed07b9
commit c25e012c4e
13 changed files with 1020 additions and 538 deletions

View file

@ -382,6 +382,7 @@ CONFIG_FB_MSM_OVERLAY1_WRITEBACK=y
CONFIG_FB_MSM_MIPI_NOVATEK_VIDEO_MODE=y
CONFIG_FB_MSM_MIPI_LG_VIDEO_MODE=y
CONFIG_FB_MSM_HDMI_MSM_PANEL=y
CONFIG_SLIMPORT_ANX7808=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_SOUND=y

View file

@ -229,6 +229,7 @@ struct msm_gpiomux_config vcap_configs[] = {
[GPIOMUX_ACTIVE] = &gpio_vcap_config[3],
}
},
#if 0
{
.gpio = 7,
.settings = {
@ -236,6 +237,7 @@ struct msm_gpiomux_config vcap_configs[] = {
[GPIOMUX_ACTIVE] = &gpio_vcap_config[7],
}
},
#endif
{
.gpio = 6,
.settings = {
@ -378,14 +380,14 @@ static struct gpiomux_setting gsbi1_uart_config = {
.drv = GPIOMUX_DRV_16MA,
.pull = GPIOMUX_PULL_NONE,
};
/*
static struct gpiomux_setting ext_regulator_config = {
.func = GPIOMUX_FUNC_GPIO,
.drv = GPIOMUX_DRV_8MA,
.pull = GPIOMUX_PULL_NONE,
.dir = GPIOMUX_OUT_LOW,
};
*/
static struct gpiomux_setting gsbi7_func1_cfg = {
.func = GPIOMUX_FUNC_1,
.drv = GPIOMUX_DRV_8MA,
@ -786,14 +788,14 @@ static struct msm_gpiomux_config apq8064_audio_codec_configs[] __initdata = {
};
/* External 3.3 V regulator enable */
static struct msm_gpiomux_config apq8064_ext_regulator_configs[] __initdata = {
/*static struct msm_gpiomux_config apq8064_ext_regulator_configs[] __initdata = {
{
.gpio = APQ8064_EXT_3P3V_REG_EN_GPIO,
.settings = {
[GPIOMUX_SUSPENDED] = &ext_regulator_config,
},
},
};
};*/
static struct gpiomux_setting ap2mdm_cfg = {
.func = GPIOMUX_FUNC_GPIO,
@ -921,6 +923,7 @@ static struct msm_gpiomux_config mdm_i2s_configs[] __initdata = {
[GPIOMUX_SUSPENDED] = &ap2mdm_soft_reset_cfg,
}
},
#if 0
/* AP2MDM_WAKEUP */
{
.gpio = 44,
@ -928,6 +931,7 @@ static struct msm_gpiomux_config mdm_i2s_configs[] __initdata = {
[GPIOMUX_SUSPENDED] = &ap2mdm_wakeup,
}
},
#endif
/* MDM2AP_PBL_READY*/
{
.gpio = 81,
@ -1308,6 +1312,51 @@ static struct msm_gpiomux_config apq8064_bcm2079x_nfc_configs[] __initdata = {
},
};
static struct gpiomux_setting sp_clk_config = {
.func = GPIOMUX_FUNC_2,
.drv = GPIOMUX_DRV_2MA,
.pull = GPIOMUX_PULL_NONE,
};
static struct gpiomux_setting sp_gpio_config = {
.func = GPIOMUX_FUNC_GPIO,
.drv = GPIOMUX_DRV_2MA,
.pull = GPIOMUX_PULL_NONE,
.dir = GPIOMUX_IN,
};
//add slimport gpio
static struct msm_gpiomux_config msm8064_sp_gpio_config[] __initdata = {
{
.gpio = 7, /* SP_CBL_DET */
.settings = {
[GPIOMUX_SUSPENDED] = &sp_gpio_config,
[GPIOMUX_ACTIVE]= &sp_gpio_config,
},
},
{
.gpio = 44, /* SP_INT */
.settings = {
[GPIOMUX_SUSPENDED] = &sp_gpio_config,
[GPIOMUX_ACTIVE]= &sp_gpio_config,
},
},
{
.gpio = 50, /* slimport 27M clock */
.settings = {
[GPIOMUX_SUSPENDED] = &sp_clk_config,
[GPIOMUX_ACTIVE]= &sp_clk_config,
},
},
{
.gpio = 77, /* APQ_USB_ID */
.settings = {
[GPIOMUX_SUSPENDED] = &sp_gpio_config,
[GPIOMUX_ACTIVE]= &sp_gpio_config,
},
},
};
void __init apq8064_init_gpiomux(void)
{
int rc;
@ -1362,10 +1411,10 @@ void __init apq8064_init_gpiomux(void)
machine_is_mpq8064_dtv())
msm_gpiomux_install(mpq8064_mi2s_configs,
ARRAY_SIZE(mpq8064_mi2s_configs));
/*
msm_gpiomux_install(apq8064_ext_regulator_configs,
ARRAY_SIZE(apq8064_ext_regulator_configs));
*/
if (machine_is_apq8064_flo() || machine_is_apq8064_deb()) {
if (SOCINFO_VERSION_MINOR(platform_version) == 1)
msm_gpiomux_install(mdm_i2s_configs,
@ -1421,4 +1470,8 @@ void __init apq8064_init_gpiomux(void)
if (machine_is_apq8064_flo() || machine_is_apq8064_deb())
msm_gpiomux_install(apq8064_bcm2079x_nfc_configs,
ARRAY_SIZE(apq8064_bcm2079x_nfc_configs));
#ifdef CONFIG_SLIMPORT_ANX7808
msm_gpiomux_install(msm8064_sp_gpio_config,
ARRAY_SIZE(msm8064_sp_gpio_config));
#endif
}

View file

@ -133,6 +133,8 @@ static struct pm8xxx_gpio_init pm8921_gpios[] __initdata = {
//PM8921_GPIO_OUTPUT_VIN(30, 1, PM_GPIO_VIN_VPH), /* SMB349 susp line */
PM8921_GPIO_OUTPUT_FUNC_L17(26, 0, PM_GPIO_FUNC_2), /* Bl: Off, PWM mode */
PM8921_GPIO_OUTPUT_L17(30, 0, LOW), /* BL_EN */
PM8921_GPIO_OUTPUT(2, 1, HIGH), /* SLIMPORT_PWR_DWN */
PM8921_GPIO_OUTPUT(1, 0, HIGH), /* SLIMPORT_RESET_N */
PM8921_GPIO_OUTPUT_BUFCONF(36, 1, LOW, OPEN_DRAIN),
PM8921_GPIO_OUTPUT_FUNC(44, 0, PM_GPIO_FUNC_2),
PM8921_GPIO_OUTPUT(33, 0, HIGH),

View file

@ -144,6 +144,7 @@ VREG_CONSUMERS(L27) = {
VREG_CONSUMERS(L28) = {
REGULATOR_SUPPLY("8921_l28", NULL),
REGULATOR_SUPPLY("core_vdd", "pil_qdsp6v4.1"),
REGULATOR_SUPPLY("slimport_1p0", NULL),
};
VREG_CONSUMERS(L29) = {
REGULATOR_SUPPLY("8921_l29", NULL),
@ -238,7 +239,7 @@ VREG_CONSUMERS(EXT_MPP8) = {
REGULATOR_SUPPLY("ext_mpp8", NULL),
REGULATOR_SUPPLY("vbus", "msm_ehci_host.1"),
};
VREG_CONSUMERS(EXT_3P3V) = {
/*VREG_CONSUMERS(EXT_3P3V) = {
REGULATOR_SUPPLY("ext_3p3v", NULL),
REGULATOR_SUPPLY("vdd_io", "spi0.2"),
REGULATOR_SUPPLY("mhl_usb_hs_switch", "msm_otg"),
@ -247,7 +248,7 @@ VREG_CONSUMERS(EXT_3P3V) = {
REGULATOR_SUPPLY("hdmi_mux_vdd", "hdmi_msm.0"),
REGULATOR_SUPPLY("pcie_ext_3p3v", "msm_pcie"),
};
/*VREG_CONSUMERS(EXT_TS_SW) = {
VREG_CONSUMERS(EXT_TS_SW) = {
REGULATOR_SUPPLY("ext_ts_sw", NULL),
REGULATOR_SUPPLY("vdd_ana", "3-005b"),
};*/
@ -552,9 +553,9 @@ struct gpio_regulator_platform_data
apq8064_gpio_regulator_pdata[] __devinitdata = {
/* ID vreg_name gpio_label gpio supply */
GPIO_VREG(EXT_5V, "ext_5v", "ext_5v_en", PM8921_MPP_PM_TO_SYS(7), NULL),
GPIO_VREG(EXT_3P3V, "ext_3p3v", "ext_3p3v_en",
/* GPIO_VREG(EXT_3P3V, "ext_3p3v", "ext_3p3v_en",
APQ8064_EXT_3P3V_REG_EN_GPIO, NULL),
/* GPIO_VREG(EXT_TS_SW, "ext_ts_sw", "ext_ts_sw_en",
GPIO_VREG(EXT_TS_SW, "ext_ts_sw", "ext_ts_sw_en",
PM8921_GPIO_PM_TO_SYS(23), "ext_3p3v"),*/
GPIO_VREG(EXT_MPP8, "ext_mpp8", "ext_mpp8_en",
PM8921_MPP_PM_TO_SYS(8), NULL),

View file

@ -75,6 +75,9 @@
#include <mach/msm_pcie.h>
#include <mach/restart.h>
#include <mach/msm_iomap.h>
#ifdef CONFIG_SLIMPORT_ANX7808
#include <linux/platform_data/slimport_device.h>
#endif
#include "msm_watchdog.h"
#include "board-flo.h"
@ -2244,7 +2247,7 @@ static struct platform_device apq8064_device_ext_mpp8_vreg __devinitdata = {
= &apq8064_gpio_regulator_pdata[GPIO_VREG_ID_EXT_MPP8],
},
};
/*
static struct platform_device apq8064_device_ext_3p3v_vreg __devinitdata = {
.name = GPIO_REGULATOR_DEV_NAME,
.id = APQ8064_EXT_3P3V_REG_EN_GPIO,
@ -2253,7 +2256,7 @@ static struct platform_device apq8064_device_ext_3p3v_vreg __devinitdata = {
&apq8064_gpio_regulator_pdata[GPIO_VREG_ID_EXT_3P3V],
},
};
*/
static struct platform_device apq8064_device_ext_ts_sw_vreg __devinitdata = {
.name = GPIO_REGULATOR_DEV_NAME,
.id = PM8921_GPIO_PM_TO_SYS(23),
@ -2307,7 +2310,7 @@ static struct platform_device *early_common_devices[] __initdata = {
static struct platform_device *pm8921_common_devices[] __initdata = {
&apq8064_device_ext_5v_vreg,
&apq8064_device_ext_mpp8_vreg,
&apq8064_device_ext_3p3v_vreg,
//&apq8064_device_ext_3p3v_vreg,
&apq8064_device_ssbi_pmic1,
&apq8064_device_ssbi_pmic2,
&apq8064_device_ext_ts_sw_vreg,
@ -2315,7 +2318,7 @@ static struct platform_device *pm8921_common_devices[] __initdata = {
static struct platform_device *pm8917_common_devices[] __initdata = {
&apq8064_device_ext_mpp8_vreg,
&apq8064_device_ext_3p3v_vreg,
//&apq8064_device_ext_3p3v_vreg,
&apq8064_device_ssbi_pmic1,
&apq8064_device_ssbi_pmic2,
&apq8064_device_ext_ts_sw_vreg,
@ -3113,6 +3116,106 @@ static void __init apq8064_pm8917_pdata_fixup(void)
cdp_keys_data.nbuttons = ARRAY_SIZE(cdp_keys_pm8917);
}
#ifdef CONFIG_SLIMPORT_ANX7808
#define GPIO_SLIMPORT_CBL_DET 7
#define GPIO_SLIMPORT_PWR_DWN PM8921_GPIO_PM_TO_SYS(2)
#define GPIO_SLIMPORT_RESET_N PM8921_GPIO_PM_TO_SYS(1)
#define GPIO_SLIMPORT_INT_N 44
#define GPIO_SLIMPORT_27M_CLOCK 50
static int anx7808_switch_onoff(bool on)
{
static bool power_state = 0;
static struct regulator *anx7808_power_1p0 = NULL;
int rc = 0;
if (power_state == on) {
pr_info("anx7808_power_1p0 is already %s \n", power_state ? "on" : "off");
goto out;
}
if (!anx7808_power_1p0) {
anx7808_power_1p0= regulator_get(NULL, "slimport_1p0");
if (IS_ERR(anx7808_power_1p0)) {
rc = PTR_ERR(anx7808_power_1p0);
pr_err("%s: regulator_get anx7808_power_1p0 failed. rc=%d\n",
__func__, rc);
anx7808_power_1p0 = NULL;
goto out;
}
rc = regulator_set_voltage(anx7808_power_1p0, 1050000, 1050000);
if (rc ) {
pr_err("%s: regulator_set_voltage anx7808_power_1p0 failed\
rc=%d\n", __func__, rc);
goto out;
}
}
if (on) {
rc = regulator_set_optimum_mode(anx7808_power_1p0, 100000);
if (rc < 0) {
pr_err("%s : set optimum mode 100000, anx7808_power_1p0 failed \
(%d)\n", __func__, rc);
goto out;
}
rc = regulator_enable(anx7808_power_1p0);
if (rc) {
pr_err("%s : anx7808_power_1p0 enable failed (%d)\n",
__func__, rc);
goto out;
}
}
else {
rc = regulator_disable(anx7808_power_1p0);
if (rc) {
pr_err("%s : anx7808_power_1p0 disable failed (%d)\n",
__func__, rc);
goto out;
}
rc = regulator_set_optimum_mode(anx7808_power_1p0, 100);
if (rc < 0) {
pr_err("%s : set optimum mode 100, anx7808_power_1p0 failed \
(%d)\n", __func__, rc);
goto out;
}
}
power_state = on;
out:
return rc;
}
static struct anx7808_platform_data anx7808_pdata = {
.gpio_p_dwn = GPIO_SLIMPORT_PWR_DWN,
.gpio_reset = GPIO_SLIMPORT_RESET_N,
.gpio_int = GPIO_SLIMPORT_INT_N,
.gpio_cbl_det = GPIO_SLIMPORT_CBL_DET,
.switch_power = anx7808_switch_onoff,
};
struct i2c_board_info i2c_anx7808_info[] = {
{
I2C_BOARD_INFO("anx7808", 0x72 >> 1),
.platform_data = &anx7808_pdata,
},
};
static struct i2c_registry i2c_anx7808_devices __initdata = {
I2C_SURF | I2C_FFA | I2C_RUMI,
APQ_8064_GSBI1_QUP_I2C_BUS_ID,
i2c_anx7808_info,
ARRAY_SIZE(i2c_anx7808_info),
};
static void __init add_i2c_anx7808_device(void)
{
i2c_register_board_info(i2c_anx7808_devices.bus,
i2c_anx7808_devices.info,
i2c_anx7808_devices.len);
}
#endif
static void __init apq8064_common_init(void)
{
u32 platform_version;
@ -3203,6 +3306,9 @@ static void __init apq8064_common_init(void)
if (machine_is_apq8064_flo() || machine_is_apq8064_deb())
nfc_init();
#ifdef CONFIG_SLIMPORT_ANX7808
add_i2c_anx7808_device();
#endif
}
static void __init apq8064_allocate_memory_regions(void)

View file

@ -5295,7 +5295,7 @@ static struct clk_lookup msm_clocks_8064[] = {
CLK_LOOKUP("cfpb_a_clk", cfpb_a_clk.c, "clock-8960"),
CLK_LOOKUP("core_clk", gp0_clk.c, ""),
CLK_LOOKUP("core_clk", gp1_clk.c, ""),
CLK_LOOKUP("core_clk", gp1_clk.c, "slimport"),
CLK_LOOKUP("core_clk", gp2_clk.c, ""),
#ifdef CONFIG_MACH_LGE
CLK_LOOKUP("core_clk", gsbi1_uart_clk.c, ""),

View file

@ -1,5 +1,5 @@
/*
* Copyright(c) 2012, LG Electronics Inc. All rights reserved.
* Copyright(c) 2012, Analogix Semiconductor. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -27,6 +27,12 @@
#include <linux/slimport.h>
#include "slimport_tx_drv.h"
#include <asm/mach-types.h>
#include <linux/clk.h>
#include <linux/err.h>
#define GPIO_SLIMPORT_27M_CLOCK 50
#define GPIO_APQ_USB_ID 77
struct i2c_client *anx7808_client;
@ -44,7 +50,7 @@ static bool hdcp_enable = 1;
static bool hdcp_enable = 0;
#endif
static unchar slimport_link_bw = 0;
//extern void msm_otg_id_pin_irq_enabled(bool enabled);
int sp_read_reg(uint8_t slave_addr, uint8_t offset, uint8_t *buf)
{
@ -53,8 +59,8 @@ int sp_read_reg(uint8_t slave_addr, uint8_t offset, uint8_t *buf)
anx7808_client->addr = (slave_addr >> 1);
ret = i2c_smbus_read_byte_data(anx7808_client, offset);
if (ret < 0) {
pr_err("%s: failed to read i2c addr=%x\n",
__func__, slave_addr);
SP_DEV_ERR("%s: failed to read i2c addr=%x\n",
__func__, slave_addr);
return ret;
}
*buf = (uint8_t) ret;
@ -69,39 +75,54 @@ int sp_write_reg(uint8_t slave_addr, uint8_t offset, uint8_t value)
anx7808_client->addr = (slave_addr >> 1);
ret = i2c_smbus_write_byte_data(anx7808_client, offset, value);
if (ret < 0) {
pr_err("%s: failed to write i2c addr=%x\n",
__func__, slave_addr);
SP_DEV_ERR("%s: failed to write i2c addr=%x\n",
__func__, slave_addr);
}
return ret;
}
void sp_tx_hardware_poweron(void)
void sp_tx_hardware_poweron(struct i2c_client *client)
{
struct anx7808_platform_data *pdata = anx7808_client->dev.platform_data;
struct anx7808_platform_data *pdata = client->dev.platform_data;
struct clk *gp_clk_b1 = clk_get_sys("slimport", "core_clk");
int ret = 0;
WARN(IS_ERR(gp_clk_b1), "gp_clk_b1 not found (%ld)\n", PTR_ERR(gp_clk_b1));
ret = clk_set_rate(gp_clk_b1, 27000000);
WARN(ret, "gp_clk_b1 rate was not set (%d)\n", ret);
ret = clk_prepare_enable(gp_clk_b1);
WARN(ret, "gp_clk_b1 not enabled (%d)\n", ret);
mdelay(5);
gpio_set_value(pdata->gpio_reset, 0);
msleep(1);
gpio_set_value(pdata->gpio_p_dwn, 0);
msleep(2);
pdata->dvdd_power(1);
pdata->switch_power(1);
msleep(20);
gpio_set_value(pdata->gpio_reset, 1);
pr_info("%s: anx7808 power on\n", __func__);
SP_DEV_DBG("%s: anx7808 power on\n", __func__);
}
void sp_tx_hardware_powerdown(void)
void sp_tx_hardware_powerdown(struct i2c_client *client)
{
struct anx7808_platform_data *pdata = anx7808_client->dev.platform_data;
struct anx7808_platform_data *pdata = client->dev.platform_data;
struct clk *gp_clk_b1 = clk_get_sys("slimport", "core_clk");
gpio_set_value(pdata->gpio_reset, 0);
msleep(1);
pdata->dvdd_power(0);
pdata->switch_power(0);
msleep(5);
gpio_set_value(pdata->gpio_p_dwn, 1);
mdelay(5);
WARN(IS_ERR(gp_clk_b1), "gp_clk_b1 not found (%ld)\n", PTR_ERR(gp_clk_b1));
clk_disable_unprepare(gp_clk_b1);
msleep(1);
pr_info("%s: anx7808 power down\n", __func__);
SP_DEV_DBG("%s: anx7808 power down\n", __func__);
}
int slimport_read_edid_block(int block, uint8_t *edid_buf)
@ -122,9 +143,10 @@ EXPORT_SYMBOL(slimport_read_edid_block);
static void sp_tx_power_down_and_init(void)
{
sp_tx_vbus_powerdown();
sp_tx_pull_down_id(FALSE);
sp_tx_power_down(SP_TX_PWR_REG);
sp_tx_power_down(SP_TX_PWR_TOTAL);
sp_tx_hardware_powerdown();
sp_tx_hardware_powerdown(anx7808_client);
sp_tx_pd_mode = 1;
sp_tx_link_config_done = 0;
sp_tx_hw_lt_enable = 0;
@ -136,9 +158,8 @@ static void sp_tx_power_down_and_init(void)
static void slimport_cable_plug_proc(struct anx7808_data *anx7808)
{
struct anx7808_platform_data *pdata = anx7808->pdata;
if (gpio_get_value_cansleep(pdata->gpio_cbl_det)) {
if (gpio_get_value_cansleep(anx7808->pdata->gpio_cbl_det)) {
/* Previously, if sp tx is turned on, turn it off to
* avoid the cable detection erorr.
*/
@ -146,18 +167,19 @@ static void slimport_cable_plug_proc(struct anx7808_data *anx7808)
sp_tx_power_down_and_init();
/* debounce time for avoiding glitch */
msleep(50);
if (gpio_get_value_cansleep(pdata->gpio_cbl_det)) {
if (gpio_get_value_cansleep(anx7808->pdata->gpio_cbl_det)) {
if (sp_tx_pd_mode) {
sp_tx_pd_mode = 0;
sp_tx_hardware_poweron();
sp_tx_hardware_poweron(anx7808_client);
sp_tx_power_on(SP_TX_PWR_REG);
sp_tx_power_on(SP_TX_PWR_TOTAL);
sp_tx_pull_down_id(TRUE);
hdmi_rx_initialization();
sp_tx_initialization();
sp_tx_vbus_poweron();
msleep(200);
if (!sp_tx_get_cable_type()) {
pr_err("%s:AUX ERR\n", __func__);
SP_DEV_ERR("%s:AUX ERR\n", __func__);
sp_tx_power_down_and_init();
return;
}
@ -194,7 +216,7 @@ static void slimport_edid_proc(void)
sp_tx_edid_read();
if (bedid_break)
pr_err("%s: EDID corruption!\n", __func__);
SP_DEV_ERR("%s: EDID corruption!\n", __func__);
hdmi_rx_set_hpd(1);
hdmi_rx_set_termination(1);
sp_tx_set_sys_state(STATE_CONFIG_HDMI);
@ -212,8 +234,6 @@ static void slimport_config_output(void)
static void slimport_playback_proc(void)
{
if (!anx7808_ver_ba)
sp_tx_set_3d_packets();
}
static void slimport_main_proc(struct anx7808_data *anx7808)
@ -245,7 +265,7 @@ static void slimport_main_proc(struct anx7808_data *anx7808)
if (sp_tx_system_state == STATE_HDCP_AUTH) {
if (hdcp_enable &&
((sp_tx_rx_type == RX_HDMI) ||
( sp_tx_rx_type == RX_DP))) {
( sp_tx_rx_type ==RX_DP))) {
sp_tx_hdcp_process();
} else {
sp_tx_power_down(SP_TX_PWR_HDCP);
@ -268,10 +288,14 @@ static uint8_t anx7808_chip_detect(void)
static void anx7808_chip_initial(void)
{
#ifdef EYE_TEST
sp_tx_eye_diagram_test();
#else
sp_tx_variable_init();
sp_tx_vbus_powerdown();
sp_tx_hardware_powerdown();
sp_tx_hardware_powerdown(anx7808_client);
sp_tx_set_sys_state(STATE_CABLE_PLUG);
#endif
}
static void anx7808_free_gpio(struct anx7808_data *anx7808)
@ -281,51 +305,50 @@ static void anx7808_free_gpio(struct anx7808_data *anx7808)
gpio_free(anx7808->pdata->gpio_reset);
gpio_free(anx7808->pdata->gpio_p_dwn);
}
static int anx7808_init_gpio(struct anx7808_data *anx7808)
{
int ret = 0;
pr_info("anx7808 init gpio\n");
SP_DEV_DBG("anx7808 init gpio\n");
ret = gpio_request_one(anx7808->pdata->gpio_p_dwn,
GPIOF_OUT_INIT_HIGH, "anx_p_dwn_ctl");
ret = gpio_request(anx7808->pdata->gpio_p_dwn, "anx_p_dwn_ctl");
if (ret) {
pr_err("%s : failed to request gpio %d \n", __func__,
SP_DEV_ERR("%s : failed to request gpio %d\n", __func__,
anx7808->pdata->gpio_p_dwn);
goto out;
}
ret = gpio_request_one(anx7808->pdata->gpio_reset,
GPIOF_OUT_INIT_LOW, "anx7808_reset_n");
if (ret) {
pr_err("%s : failed to request gpio %d \n", __func__,
anx7808->pdata->gpio_reset);
goto err0;
}
gpio_direction_output(anx7808->pdata->gpio_p_dwn, 1);
ret = gpio_request_one(anx7808->pdata->gpio_int,
GPIOF_IN, "anx7808_int_n");
ret = gpio_request(anx7808->pdata->gpio_reset, "anx7808_reset_n");
if (ret) {
pr_err("%s : failed to request gpio %d \n", __func__,
anx7808->pdata->gpio_int);
SP_DEV_ERR("%s : failed to request gpio %d\n", __func__,
anx7808->pdata->gpio_reset);
goto err1;
}
gpio_direction_output(anx7808->pdata->gpio_reset, 0);
ret = gpio_request_one(anx7808->pdata->gpio_cbl_det,
GPIOF_IN, "anx7808_cbl_det");
ret = gpio_request(anx7808->pdata->gpio_int, "anx7808_int_n");
if (ret) {
pr_err("%s : failed to request gpio %d \n", __func__,
anx7808->pdata->gpio_cbl_det);
SP_DEV_ERR("%s : failed to request gpio %d\n", __func__,
anx7808->pdata->gpio_int);
goto err2;
}
gpio_direction_input(anx7808->pdata->gpio_int);
ret = gpio_request(anx7808->pdata->gpio_cbl_det, "anx7808_cbl_det");
if (ret) {
SP_DEV_ERR("%s : failed to request gpio %d\n", __func__,
anx7808->pdata->gpio_cbl_det);
goto err3;
}
gpio_direction_input(anx7808->pdata->gpio_cbl_det);
gpio_set_value(anx7808->pdata->gpio_reset, 0);
gpio_set_value(anx7808->pdata->gpio_p_dwn, 1);
goto out;
err3:
gpio_free(anx7808->pdata->gpio_cbl_det);
err2:
gpio_free(anx7808->pdata->gpio_int);
err1:
@ -342,7 +365,7 @@ static int anx7808_system_init(void)
ret = anx7808_chip_detect();
if (ret == 0) {
pr_err("%s : failed to detect anx7808\n", __func__);
SP_DEV_ERR("%s : failed to detect anx7808\n", __func__);
return -ENODEV;
}
@ -352,17 +375,22 @@ static int anx7808_system_init(void)
static irqreturn_t anx7808_cbl_det_isr(int irq, void *data)
{
struct anx7808_data *anx7808 = data;
struct anx7808_data *anx7808 = (struct anx7808_data *)data;
int status;
SP_DEV_DBG("%s : gpio_get_value(anx7808->pdata->gpio_cbl_det) = %d\n", __func__,gpio_get_value(anx7808->pdata->gpio_cbl_det));
if (gpio_get_value(anx7808->pdata->gpio_cbl_det)) {
wake_lock(&anx7808->slimport_lock);
pr_info("%s : detect cable insertion\n", __func__);
SP_DEV_DBG("%s : detect cable insertion\n", __func__);
queue_delayed_work(anx7808->workqueue, &anx7808->work, 0);
//msm_otg_id_pin_irq_enabled(false);
} else {
pr_info("%s : detect cable removal\n", __func__);
cancel_delayed_work_sync(&anx7808->work);
SP_DEV_DBG("%s : detect cable removal\n", __func__);
status = cancel_delayed_work_sync(&anx7808->work);
if(status == 0)
flush_workqueue(anx7808 ->workqueue);
wake_unlock(&anx7808->slimport_lock);
wake_lock_timeout(&anx7808->slimport_lock, 2*HZ);
//msm_otg_id_pin_irq_enabled(true);
}
return IRQ_HANDLED;
}
@ -386,25 +414,24 @@ static int anx7808_i2c_probe(struct i2c_client *client,
struct anx7808_data *anx7808;
int ret = 0;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_I2C_BLOCK)) {
pr_err("%s: i2c bus does not support the anx7808\n", __func__);
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
SP_DEV_ERR("%s: i2c bus does not support the anx7808\n", __func__);
ret = -ENODEV;
goto exit;
}
anx7808 = kzalloc(sizeof(struct anx7808_data), GFP_KERNEL);
if (!anx7808) {
pr_err("%s: failed to allocate driver data\n", __func__);
SP_DEV_ERR("%s: failed to allocate driver data\n", __func__);
ret = -ENOMEM;
goto exit;
}
anx7808->pdata = client->dev.platform_data;
i2c_set_clientdata(client, anx7808);
anx7808_client = client;
memcpy(&anx7808_client, &client, sizeof(client));
mutex_init(&anx7808->lock);
spin_lock_init(&anx7808->pdata->lock);
if (!anx7808->pdata) {
ret = -EINVAL;
@ -413,25 +440,40 @@ static int anx7808_i2c_probe(struct i2c_client *client,
ret = anx7808_init_gpio(anx7808);
if (ret) {
pr_err("%s: failed to initialize gpio\n", __func__);
SP_DEV_ERR("%s: failed to initialize gpio\n", __func__);
goto err0;
}
INIT_DELAYED_WORK(&anx7808->work, anx7808_work_func);
anx7808->workqueue = create_singlethread_workqueue("anx7808_work");
if (!anx7808->workqueue) {
pr_err("%s: failed to create work queue\n", __func__);
if (anx7808->workqueue == NULL) {
SP_DEV_ERR("%s: failed to create work queue\n", __func__);
ret = -ENOMEM;
goto err1;
}
anx7808->pdata->avdd_power(1);
anx7808->pdata->dvdd_power(1);
ret = gpio_request(GPIO_SLIMPORT_27M_CLOCK, "slimport_27M_clk");
if (ret) {
pr_err("'%s: (%d) gpio_request failed, ret=%d\n",
"GPIO_SLIMPORT_27M_CLOCK", GPIO_SLIMPORT_27M_CLOCK, ret);
goto err2;
}
ret = gpio_request(GPIO_APQ_USB_ID, "msm_otg_id_pin");
if (ret) {
pr_err("'%s: (%d) gpio_request failed, ret=%d\n",
"GPIO_APQ_USB_ID", GPIO_APQ_USB_ID, ret);
goto err2;
}
ret = gpio_direction_input(GPIO_APQ_USB_ID);
if (ret) {
printk("%s: gpio %d unavaliable for input \n", __func__, GPIO_APQ_USB_ID);
}
ret = anx7808_system_init();
if (ret) {
pr_err("%s: failed to initialize anx7808\n", __func__);
SP_DEV_ERR("%s: failed to initialize anx7808\n", __func__);
goto err2;
}
@ -440,24 +482,26 @@ static int anx7808_i2c_probe(struct i2c_client *client,
client->irq = gpio_to_irq(anx7808->pdata->gpio_cbl_det);
if (client->irq < 0) {
pr_err("%s : failed to get gpio irq\n", __func__);
SP_DEV_ERR("%s : failed to get gpio irq\n", __func__);
goto err3;
}
//detect pin would not work if we don't configure and request USB_ID pin (gpio 77)
ret = request_threaded_irq(client->irq, NULL, anx7808_cbl_det_isr,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
"anx7808", anx7808);
"anx7808_cabel_det", anx7808);
if (ret < 0) {
pr_err("%s : failed to request irq \n", __func__);
SP_DEV_ERR("%s : failed to request irq\n", __func__);
goto err3;
}
ret = enable_irq_wake(client->irq);
if (ret < 0) {
pr_err("%s : Enable irq for cable detect"
"interrupt wake enable fail\n", __func__);
SP_DEV_ERR("%s : Enable irq for cable detect", __func__);
SP_DEV_ERR("interrupt wake enable fail\n");
goto err4;
}
goto exit;
err4:
@ -469,7 +513,6 @@ err2:
err1:
anx7808_free_gpio(anx7808);
err0:
anx7808_client = NULL;
kfree(anx7808);
exit:
return ret;
@ -489,9 +532,9 @@ bool slimport_is_connected(void)
spin_lock(&pdata->lock);
if (gpio_get_value_cansleep(pdata->gpio_cbl_det)) {
if (gpio_get_value(pdata->gpio_cbl_det)) {
mdelay(10);
if (gpio_get_value_cansleep(pdata->gpio_cbl_det)) {
if (gpio_get_value(pdata->gpio_cbl_det)) {
pr_info("%s : Slimport Dongle is detected\n", __func__);
result = true;
}
@ -503,17 +546,11 @@ bool slimport_is_connected(void)
}
EXPORT_SYMBOL(slimport_is_connected);
unchar sp_get_link_bw(void)
unchar slimport_get_link_bw(void)
{
return slimport_link_bw;
}
EXPORT_SYMBOL(sp_get_link_bw);
void sp_set_link_bw(unchar link_bw)
{
slimport_link_bw = link_bw;
}
EXPORT_SYMBOL(sp_set_link_bw);
EXPORT_SYMBOL(slimport_get_link_bw);
static int anx7808_i2c_remove(struct i2c_client *client)
{
@ -548,10 +585,9 @@ static struct i2c_driver anx7808_driver = {
static int __init anx7808_init(void)
{
int ret = 0;
ret = i2c_add_driver(&anx7808_driver);
if (ret < 0)
pr_err("%s: failed to register anx7808 i2c drivern", __func__);
SP_DEV_ERR("%s: failed to register anx7808 i2c drivern", __func__);
return ret;
}
@ -560,9 +596,10 @@ static void __exit anx7808_exit(void)
i2c_del_driver(&anx7808_driver);
}
module_init(anx7808_init);
late_initcall(anx7808_init);
module_exit(anx7808_exit);
MODULE_DESCRIPTION("Slimport transmitter ANX7808 driver");
MODULE_AUTHOR("ChoongRyeol Lee <choongryeol.lee@lge.com>");
MODULE_AUTHOR("FeiWang <fwang@analogixsemi.com>");
MODULE_LICENSE("GPL");
MODULE_VERSION("V0.3");

File diff suppressed because it is too large Load diff

View file

@ -12,14 +12,17 @@
*
*/
#ifndef __SP_TX_DRV_H
#define __SP_TX_DRV_H
#ifndef _SP_TX_DRV_H
#define _SP_TX_DRV_H
#define FALSE 0
#define TRUE 1
/*#define D(fmt, arg...) printk("<1>```%s:%d: " fmt, __func__, __LINE__, ##arg)*/
#define MAX_BUF_CNT 10
#define VID_DVI_MODE 0x00
#define VID_HDMI_MODE 0x01
#define VIDEO_STABLE_TH 3
@ -30,8 +33,9 @@
extern unchar bedid_extblock[128];
extern unchar bedid_firstblock[128];
extern unchar slimport_link_bw;
extern bool anx7808_ver_ba;
enum SP_TX_System_State {
STATE_INIT = 1,
@ -122,7 +126,6 @@ enum RX_CBL_TYPE {
RX_VGA = 0x03,
RX_NULL = 0x00
};
void sp_tx_variable_init(void);
void sp_tx_initialization(void);
void sp_tx_show_infomation(void);
@ -139,7 +142,6 @@ unchar sp_tx_hw_link_training(void);
unchar sp_tx_lt_pre_config(void);
void sp_tx_video_mute(unchar enable);
void sp_tx_set_colorspace(void);
void sp_tx_set_3d_packets(void);
void sp_tx_int_irq_handler(void);
void sp_tx_send_message(enum SP_TX_SEND_MSG message);
void sp_tx_hdcp_process(void);
@ -153,6 +155,7 @@ uint sp_tx_link_err_check(void);
void sp_tx_eye_diagram_test(void);
void sp_tx_phy_auto_test(void);
void sp_tx_enable_video_input(unchar enable);
void sp_tx_pull_down_id(bool enable);
/* ***************************************************************** */
/* Functions protoype for HDMI Input */

View file

@ -12,10 +12,10 @@
*
*/
#ifndef __SP_TX_REG_DEF_H
#define __SP_TX_REG_DEF_H
#ifndef _SP_TX_REG_DEF_H
#define _SP_TX_REG_DEF_H
#define TX_P0 0x78
#define TX_P0 0x70
#define TX_P1 0x7A
#define TX_P2 0x72
@ -56,8 +56,6 @@
#define HDMI_RX_SYS_PWDN1_REG 0X18
#define PWDN_CTRL 0X01
#define HDMI_RX_PIO_CTRL 0X1B
#define HDMI_RX_AEC_CTRL_REG 0X20
#define AVC_OE 0x80
#define AAC_OE 0X40
@ -309,7 +307,6 @@
#define SP_TX_HDCP_LINK_CHK_FRAME_NUM 0x03
#define SP_TX_HDCP_CTRL2_REG 0x04
#define SP_TX_HDCP_KEY_STATUS 0x1E
#define SP_TX_VID_BLANK_SET1 0X2C
@ -504,6 +501,15 @@
#define SP_TX_VID_CTRL3_REG 0x0A
#define HPD_OUT 0x40
#define SP_TX_VID_CTRL5_REG 0x0C
#define CSC_STD_SEL 0x80
#define RANGE_Y2R 0x20
#define CSPACE_Y2R 0x10
#define SP_TX_VID_CTRL6_REG 0x0D
#define VIDEO_PROCESS_EN 0x40
#define UP_SAMPLE 0x02
#define DOWN_SAMPLE 0x01
#define SP_TX_TOTAL_LINE_STA_L 0x24
#define SP_TX_TOTAL_LINE_STA_H 0x25
#define SP_TX_ACT_LINE_STA_L 0x26
@ -554,6 +560,9 @@
#define CH_NUM_8 0xE0
#define AUD_LAYOUT 0x01
#define SP_TX_ANAOG_DBG_REG1 0xDC
#define PULL_DOWN_ID 0x80
#define SP_TX_ANALOG_DEBUG_REG2 0xDD
#define POWERON_TIME_1P5MS 0X06

View file

@ -1458,7 +1458,7 @@ static void hdmi_edid_detail_desc(const uint8 *data_buf, uint32 *disp_mode)
static void limit_supported_video_format(uint32 *video_format)
{
switch(sp_get_link_bw()){
switch(slimport_get_link_bw()){
case 0x0a:
if((*video_format == HDMI_VFRMT_1920x1080p60_16_9) ||
(*video_format == HDMI_VFRMT_2880x480p60_4_3)||

View file

@ -24,8 +24,7 @@ struct anx7808_platform_data
spinlock_t lock;
int (*dvdd_power)(bool on);
int (*avdd_power)(bool on);
int (*switch_power)(bool on);
};
#endif

View file

@ -1,5 +1,5 @@
/*
* Copyright(c) 2012, LG Electronics Inc. All rights reserved.
* Copyright(c) 2012, Analogix Semiconductor. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -12,9 +12,19 @@
*
*/
#ifndef __SLIMPORT_H
#define __SLIMPORT_H
#ifndef _SLIMPORT_H
#define _SLIMPORT_H
#define DEBUG
#ifdef DEBUG
#define SP_DEV_DBG(args... ) pr_info(args)
#else
#define SP_DEV_DBG(args... ) (void)0
#endif
#define SP_DEV_NOTICE(args... ) pr_notice(args)
#define SP_DEV_ERR(args... ) pr_err(args)
#define SSC_EN
#define HDCP_EN
@ -28,26 +38,26 @@
#define AUX_ERR 1
#define AUX_OK 0
extern unchar sp_tx_hw_lt_done;
extern bool sp_tx_hw_lt_enable;
extern unchar sp_tx_link_config_done ;
extern bool sp_tx_hw_lt_done;
extern bool sp_tx_hw_lt_enable;
extern bool sp_tx_link_config_done ;
extern enum SP_TX_System_State sp_tx_system_state;
extern enum RX_CBL_TYPE sp_tx_rx_type;
extern enum RX_CBL_TYPE sp_tx_rx_type_backup;
extern unchar sp_tx_pd_mode;
extern unchar bedid_break;
extern struct i2c_client *anx7808_client;
int sp_read_reg(uint8_t slave_addr, uint8_t offset, uint8_t *buf);
int sp_write_reg(uint8_t slave_addr, uint8_t offset, uint8_t value);
void sp_tx_hardware_poweron(void);
void sp_tx_hardware_powerdown(void);
void sp_tx_hardware_poweron(struct i2c_client *client);
void sp_tx_hardware_powerdown(struct i2c_client *client);
int slimport_read_edid_block(int block, uint8_t *edid_buf);
#ifdef CONFIG_SLIMPORT_ANX7808
bool slimport_is_connected(void);
unchar sp_get_link_bw(void);
void sp_set_link_bw(unchar link_bw);
unchar slimport_get_link_bw(void);
#else
static inline bool slimport_is_connected(void)
{
@ -57,8 +67,6 @@ static inline unchar sp_get_link_bw(void)
{
return 0;
}
static inline void sp_set_link_bw(unchar link_bw)
{
}
#endif
#endif