mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
lcd: add lcd driver for axg
PD#142470: lcd: add lcd driver for axg Change-Id: I58e2a2af474bafbbe3718f51493c9b46cb07cf31 Signed-off-by: Evoke Zhang <evoke.zhang@amlogic.com>
This commit is contained in:
@@ -13948,3 +13948,11 @@ F: include/linux/amlogic/unifykey/*
|
||||
AMLOGIC AXG ADD OSD DRIVER
|
||||
M: Pengcheng Chen <pengcheng.chen@amlogic.com>
|
||||
F: drivers/amlogic/media/osd/osd_io.c
|
||||
|
||||
AMLOGIC LCD driver
|
||||
M: Weiming Liu <weiming.liu@amlogic.com>
|
||||
F: drivers/amlogic/media/vout/backlight/*
|
||||
F: drivers/amlogic/media/vout/lcd/*
|
||||
F: include/linux/amlogic/media/vout/lcd/*
|
||||
F: arch/arm64/boot/dts/amlogic/mesongxm_q200-panel.dtsi
|
||||
F: arch/arm64/boot/dts/amlogic/mesonaxg_s400-panel.dtsi
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include "mesonaxg.dtsi"
|
||||
|
||||
#include "mesonaxg_s400-panel.dtsi"
|
||||
/ {
|
||||
model = "Amlogic";
|
||||
compatible = "amlogic, axg";
|
||||
@@ -399,6 +399,12 @@
|
||||
/* 0: 100.0M 1: 166.7M 2: 200.0M 3: 250.0M */
|
||||
};
|
||||
|
||||
vout {
|
||||
compatible = "amlogic, vout";
|
||||
dev_name = "vout";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* Sound iomap */
|
||||
aml_snd_iomap {
|
||||
compatible = "amlogic, snd_iomap";
|
||||
@@ -975,6 +981,13 @@
|
||||
function = "pdm";
|
||||
};
|
||||
};
|
||||
|
||||
bl_pwm_on_pins: bl_pwm_on_pin {
|
||||
mux {
|
||||
groups = "GPIOZ_4";
|
||||
function = "pwm_b";
|
||||
};
|
||||
};
|
||||
}; /* end of pinctrl_periphs */
|
||||
/* Audio Related End */
|
||||
|
||||
|
||||
159
arch/arm64/boot/dts/amlogic/mesonaxg_s400-panel.dtsi
Normal file
159
arch/arm64/boot/dts/amlogic/mesonaxg_s400-panel.dtsi
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* arch/arm64/boot/dts/amlogic/mesongxm_q200-panel.dtsi
|
||||
*
|
||||
* Copyright (C) 2016 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/ {
|
||||
lcd{
|
||||
compatible = "amlogic, lcd";
|
||||
dev_name = "lcd";
|
||||
mode = "tablet";
|
||||
status = "okay";
|
||||
key_valid = <0>;
|
||||
clocks = <&clkc CLKID_MIPI_DSI_HOST
|
||||
&clkc CLKID_MIPI_DSI_PHY
|
||||
&clkc CLKID_DSI_MEAS_COMP>;
|
||||
clock-names = "dsi_host",
|
||||
"dsi_phy",
|
||||
"dsi_meas";
|
||||
pinctrl_version = <1>; /* for uboot */
|
||||
|
||||
/* power type:
|
||||
* (0=cpu_gpio, 1=pmu_gpio, 2=signal,3=extern, 0xff=ending)
|
||||
* power index:
|
||||
* (point gpios_index, or extern_index,0xff=invalid)
|
||||
* power value:(0=output low, 1=output high, 2=input)
|
||||
* power delay:(unit in ms)
|
||||
*/
|
||||
lcd_cpu-gpios = <&gpio GPIOZ_6 GPIO_ACTIVE_HIGH>;
|
||||
lcd_cpu_gpio_names = "GPIOZ_6";
|
||||
|
||||
lcd_0{
|
||||
model_name = "B080XAN01";
|
||||
/*interface(ttl,lvds,mipi)*/
|
||||
interface = "mipi";
|
||||
/* basic_setting:
|
||||
* h_active,v_active,h_period,v_period,
|
||||
* lcd_bits,screen_widht,screen_height
|
||||
*/
|
||||
basic_setting = <768 1024 948 1140 8 119 159>;
|
||||
/* lcd_timing:
|
||||
* hs_width,hs_bp,hs_pol,vs_width,vs_bp,vs_pol
|
||||
*/
|
||||
lcd_timing = <64 56 0 50 30 0>;
|
||||
/* clk_attr:
|
||||
* fr_adj_type(0=clock,1=htotal,2=vtotal),
|
||||
* clk_ss_level,clk_auto_generate,
|
||||
* pixel_clk(unit in Hz)
|
||||
*/
|
||||
clk_attr = <0 0 1 64843200>;
|
||||
/* mipi_attr:
|
||||
* lane_num, bit_rate_max(MHz),
|
||||
* factor(*100, default 0 for auto),
|
||||
* operation_mode_init(0=video, 1=command),
|
||||
* operation_mode_display(0=video, 1=command),
|
||||
* video_mode_type
|
||||
* (0=sync_pulse,1=sync_event,2=burst),
|
||||
* clk_lp_continuous(0=stop,1=continue),
|
||||
* phy_stop_wait(0=auto,1=standard,2=slow)
|
||||
*/
|
||||
mipi_attr = <4 550 0 1 0 2 1 0>;
|
||||
/* dsi_init: data_type, num, data... */
|
||||
dsi_init_on = <0x05 1 0x11
|
||||
0xff 20 /* delay(ms) */
|
||||
0x05 1 0x29
|
||||
0xff 20 /* delay(ms) */
|
||||
0xff 0xff>; /* ending flag */
|
||||
dsi_init_off = <0x05 1 0x28
|
||||
0xff 10 /* delay(ms) */
|
||||
0x05 1 0x10
|
||||
0xff 10 /* delay(ms) */
|
||||
0xff 0xff>; /* ending flag */
|
||||
/* extern_init: 0xff for invalid */
|
||||
extern_init = <0xff>;
|
||||
/* power step: type,index,value,delay(ms) */
|
||||
power_on_step = <0 0 1 10
|
||||
0 0 0 20
|
||||
0 0 1 20
|
||||
2 0 0 0
|
||||
0xff 0 0 0>;
|
||||
power_off_step = <2 0 0 50
|
||||
0 0 0 100
|
||||
0xff 0 0 0>;
|
||||
backlight_index = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
lcd_extern{
|
||||
compatible = "amlogic, lcd_extern";
|
||||
dev_name = "lcd_extern";
|
||||
status = "okay";
|
||||
key_valid = <0>;
|
||||
|
||||
extern_1{
|
||||
index = <1>;
|
||||
extern_name = "mipi_KD080D13";
|
||||
status = "disabled";
|
||||
type = <2>; /* 0=i2c, 1=spi, 2=mipi */
|
||||
};
|
||||
};
|
||||
|
||||
backlight{
|
||||
compatible = "amlogic, backlight";
|
||||
dev_name = "backlight";
|
||||
status = "okay";
|
||||
key_valid = <0>;
|
||||
pinctrl-names = "pwm_on";
|
||||
pinctrl-0 = <&bl_pwm_on_pins>;
|
||||
pinctrl_version = <1>; /* for uboot */
|
||||
/* power index:(point gpios_index, 0xff=invalid)
|
||||
* power value:(0=output low, 1=output high, 2=input)
|
||||
* power delay:(unit in ms)
|
||||
*/
|
||||
bl-gpios = <&gpio GPIOZ_4 GPIO_ACTIVE_HIGH
|
||||
&gpio GPIOZ_5 GPIO_ACTIVE_HIGH>;
|
||||
bl_gpio_names = "GPIOZ_4","GPIOZ_5";
|
||||
|
||||
backlight_0{
|
||||
index = <0>;
|
||||
bl_name = "backlight_pwm";
|
||||
bl_level_default_uboot_kernel = <100 100>;
|
||||
/* level_attr: max, min, mid, mid_mapping */
|
||||
bl_level_attr = <255 10 128 102>;
|
||||
|
||||
bl_ctrl_method = <1>; /* 1=pwm, 2=pwm_combo, 3=extern */
|
||||
/* power_attr:
|
||||
* en_gpio_index, on_value, off_value,
|
||||
* on_delay(ms), off_delay(ms)
|
||||
*/
|
||||
bl_power_attr = <1 1 0 200 200>;
|
||||
/* pwm_port: PWM_A,PWM_B,PWM_C,PWM_D,PWM_VS */
|
||||
bl_pwm_port = "PWM_B";
|
||||
/* pwm_attr:
|
||||
* pwm_method: 0=negative, 1=positive
|
||||
* pwm_freq: pwm_vs: 1~4(vfreq multiple),
|
||||
* other pwm: real freq(Hz)
|
||||
* duty_max(%), duty_min(%)
|
||||
*/
|
||||
bl_pwm_attr = <0 180 100 25>;
|
||||
/* pwm_power:
|
||||
* pwm_gpio_index, pwm_gpio_off,
|
||||
* pwm_on_delay(ms), pwm_off_delay(ms)
|
||||
*/
|
||||
bl_pwm_power = <0 0 10 10>;
|
||||
};
|
||||
};
|
||||
};/* end of panel */
|
||||
|
||||
@@ -1051,6 +1051,50 @@
|
||||
};
|
||||
};
|
||||
|
||||
lcd_ttl_rgb_6bit_pins_on:lcd_ttl_rgb_6bit_on{
|
||||
mux {
|
||||
groups = "lcd_r2_7",
|
||||
"lcd_g2_7",
|
||||
"lcd_b2_7";
|
||||
function = "lcd_ttl";
|
||||
};
|
||||
};
|
||||
|
||||
lcd_ttl_rgb_8bit_pins_on:lcd_ttl_rgb_8bit_on{
|
||||
mux {
|
||||
groups = "lcd_r0_1", "lcd_r2_7",
|
||||
"lcd_g0_1", "lcd_g2_7",
|
||||
"lcd_b0_1", "lcd_b2_7";
|
||||
function = "lcd_ttl";
|
||||
};
|
||||
};
|
||||
/* DE + clk */
|
||||
lcd_ttl_de_on_pins:lcd_ttl_de_on_pin{
|
||||
mux {
|
||||
groups = "tcon_cph", /* clk */
|
||||
"tcon_oeh"; /* DE */
|
||||
function = "lcd_ttl";
|
||||
};
|
||||
};
|
||||
/* hvsync + clk */
|
||||
lcd_ttl_hvsync_on_pins:lcd_ttl_hvsync_on_pin{
|
||||
mux {
|
||||
groups = "tcon_cph", /* clk */
|
||||
"tcon_stv1", /* vs */
|
||||
"tcon_sth1"; /* hs */
|
||||
function = "lcd_ttl";
|
||||
};
|
||||
};
|
||||
/* DE + hvsync + clk */
|
||||
lcd_ttl_de_hvsync_on_pins:lcd_ttl_de_hvsync_on_pin{
|
||||
mux {
|
||||
groups = "tcon_cph", /* clk */
|
||||
"tcon_oeh", /* DE */
|
||||
"tcon_stv1", /* vs */
|
||||
"tcon_sth1"; /* hs */
|
||||
function = "lcd_ttl";
|
||||
};
|
||||
};
|
||||
}; /* end of pinctrl_periphs */
|
||||
|
||||
&periphs {
|
||||
|
||||
131
arch/arm64/boot/dts/amlogic/mesongxm_q200-panel.dtsi
Normal file
131
arch/arm64/boot/dts/amlogic/mesongxm_q200-panel.dtsi
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* arch/arm64/boot/dts/amlogic/mesongxm_q200-panel.dtsi
|
||||
*
|
||||
* Copyright (C) 2016 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/ {
|
||||
lcd{
|
||||
compatible = "amlogic, lcd";
|
||||
dev_name = "lcd";
|
||||
mode = "tablet";
|
||||
status = "okay";
|
||||
key_valid = <0>;
|
||||
/* clocks = <&clkc CLKID_VCLK2_ENCL
|
||||
* &clkc CLKID_VCLK2_VENCL>;
|
||||
* clock-names = "vencl_top",
|
||||
* "vencl_int";
|
||||
*/
|
||||
pinctrl_version = <1>; /* for uboot */
|
||||
pinctrl-names = "ttl_6bit_hvsync_de_on","ttl_6bit_hvsync_on",
|
||||
"ttl_6bit_de_on","ttl_8bit_hvsync_de_on",
|
||||
"ttl_8bit_hvsync_on","ttl_8bit_de_on";
|
||||
pinctrl-0 = <&lcd_ttl_rgb_6bit_pins_on
|
||||
&lcd_ttl_de_hvsync_on_pins>;
|
||||
pinctrl-1 = <&lcd_ttl_rgb_6bit_pins_on
|
||||
&lcd_ttl_hvsync_on_pins>;
|
||||
pinctrl-2 = <&lcd_ttl_rgb_6bit_pins_on
|
||||
&lcd_ttl_de_on_pins>;
|
||||
pinctrl-3 = <&lcd_ttl_rgb_8bit_pins_on
|
||||
&lcd_ttl_de_hvsync_on_pins>;
|
||||
pinctrl-4 = <&lcd_ttl_rgb_8bit_pins_on
|
||||
&lcd_ttl_hvsync_on_pins>;
|
||||
pinctrl-5 = <&lcd_ttl_rgb_8bit_pins_on
|
||||
&lcd_ttl_de_on_pins>;
|
||||
|
||||
/* power type:
|
||||
* (0=cpu_gpio, 1=pmu_gpio, 2=signal,3=extern, 0xff=ending)
|
||||
* power index:
|
||||
* (point gpios_index, or extern_index,0xff=invalid)
|
||||
* power value:(0=output low, 1=output high, 2=input)
|
||||
* power delay:(unit in ms)
|
||||
*/
|
||||
/*lcd_cpu-gpios = <&gpio GPIOX_3 1>;*/
|
||||
/*lcd_cpu_gpio_names = "GPIOX_3";*/
|
||||
|
||||
lcd_0{
|
||||
model_name = "LCD720P";
|
||||
/*interface(ttl,lvds,mipi)*/
|
||||
interface = "ttl";
|
||||
/* basic_setting:
|
||||
* h_active,v_active,h_period,v_period,
|
||||
* lcd_bits,screen_widht,screen_height
|
||||
*/
|
||||
basic_setting = <1280 720 1650 750 8 16 9>;
|
||||
/* lcd_timing:
|
||||
* hs_width,hs_bp,hs_pol,vs_width,vs_bp,vs_pol
|
||||
*/
|
||||
lcd_timing = <40 220 1 5 20 1>;
|
||||
/* clk_attr:
|
||||
* fr_adj_type(0=clock,1=htotal,2=vtotal),
|
||||
* clk_ss_level,clk_auto_generate,
|
||||
* pixel_clk(unit in Hz)
|
||||
*/
|
||||
clk_attr = <0 0 1 74250000>;
|
||||
/* ttl_attr:
|
||||
* clk_pol, de_valid, hvsync_valid,
|
||||
* rb_swap, bit_swap
|
||||
*/
|
||||
ttl_attr = <0 1 1 0 0>;
|
||||
/* power step: type,index,value,delay(ms) */
|
||||
power_on_step = <2 0 0 0
|
||||
0xff 0 0 0>;
|
||||
power_off_step = <2 0 0 50
|
||||
0xff 0 0 0>;
|
||||
backlight_index = <0xff>;
|
||||
};
|
||||
};
|
||||
|
||||
lcd_extern{
|
||||
compatible = "amlogic, lcd_extern";
|
||||
dev_name = "lcd_extern";
|
||||
status = "okay";
|
||||
key_valid = <0>;
|
||||
|
||||
extern_0{
|
||||
index = <0>;
|
||||
extern_name = "ext_default";
|
||||
status = "disabled";
|
||||
type = <0>; /* 0=i2c, 1=spi, 2=mipi */
|
||||
i2c_address = <0x1c>; /* 7bit i2c address */
|
||||
i2c_second_address = <0xff>; /* 7bit i2c address, 0xff for none */
|
||||
i2c_bus = "i2c_bus_d";
|
||||
cmd_size = <9>;
|
||||
/* init on/off: (type, value..., delay), must match cmd_size for every group */
|
||||
/* type: 0x00=cmd(bit[3:0]=1 for second_addr), 0x10=gpio, 0xff=ending*/
|
||||
/* value: i2c or spi cmd, or gpio index & level, fill 0x0 for no use */
|
||||
/* delay: unit ms */
|
||||
init_on = <0x00 0x20 0x01 0x02 0x00 0x40 0xFF 0x00 0x00
|
||||
0x00 0x80 0x02 0x00 0x40 0x62 0x51 0x73 0x00
|
||||
0x00 0x61 0x06 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0xC1 0x05 0x0F 0x00 0x08 0x70 0x00 0x00
|
||||
0x00 0x13 0x01 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x3D 0x02 0x01 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0xED 0x0D 0x01 0x00 0x00 0x00 0x00 0x00
|
||||
0x00 0x23 0x02 0x00 0x00 0x00 0x00 0x00 0x0A
|
||||
0xff 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00>;
|
||||
init_off = <0xff 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00>;
|
||||
};
|
||||
|
||||
extern_1{
|
||||
index = <2>;
|
||||
extern_name = "i2c_DLPC3439";
|
||||
status = "disabled";
|
||||
type = <0>; /* 0=i2c, 1=spi, 2=mipi */
|
||||
i2c_address = <0x1b>; /* 7bit i2c address */
|
||||
i2c_bus = "i2c_bus_d";
|
||||
};
|
||||
};
|
||||
};/* end of panel */
|
||||
|
||||
@@ -248,6 +248,12 @@ CONFIG_AMLOGIC_CVBS_OUTPUT=y
|
||||
CONFIG_AMLOGIC_WSS=y
|
||||
CONFIG_AMLOGIC_VDAC=y
|
||||
CONFIG_AMLOGIC_HDMITX=y
|
||||
CONFIG_AMLOGIC_LCD=y
|
||||
CONFIG_AMLOGIC_LCD_TV=y
|
||||
CONFIG_AMLOGIC_LCD_TABLET=y
|
||||
CONFIG_AMLOGIC_LCD_EXTERN=y
|
||||
CONFIG_AMLOGIC_LCD_EXTERN_MIPI_KD080D13=y
|
||||
CONFIG_AMLOGIC_BACKLIGHT=y
|
||||
CONFIG_AMLOGIC_VOUT_SERVE=y
|
||||
CONFIG_AMLOGIC_MEDIA_FB=y
|
||||
CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE=y
|
||||
@@ -365,6 +371,8 @@ CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
|
||||
CONFIG_MEDIA_USB_SUPPORT=y
|
||||
CONFIG_USB_VIDEO_CLASS=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_BACKLIGHT_LCD_SUPPORT=y
|
||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||
CONFIG_SOUND=y
|
||||
CONFIG_SND=y
|
||||
CONFIG_SND_USB_AUDIO=y
|
||||
|
||||
@@ -57,7 +57,8 @@
|
||||
#define GXL_GP0_CNTL4 0xc000004d
|
||||
#define GXL_GP0_CNTL5 0x00078000
|
||||
/* AXG */
|
||||
#define AXG_MIPI_CNTL0 0xa5b80000
|
||||
#define AXG_MIPI_CNTL0_ENABLE BIT(29)
|
||||
#define AXG_MIPI_CNTL0_BANDGAP BIT(26)
|
||||
#define AXG_PCIE_PLL_CNTL 0x40010242
|
||||
#define AXG_PCIE_PLL_CNTL1 0xc084b2ab
|
||||
#define AXG_PCIE_PLL_CNTL2 0xb75020be
|
||||
@@ -188,7 +189,9 @@ static int meson_axg_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
void *cntlbase = pll->base + p->reg_off;
|
||||
|
||||
if (!strcmp(clk_hw_get_name(hw), "pcie_pll")) {
|
||||
writel(AXG_MIPI_CNTL0, pll->base);
|
||||
reg = readl(pll->base);
|
||||
reg |= (AXG_MIPI_CNTL0_ENABLE | AXG_MIPI_CNTL0_BANDGAP);
|
||||
writel(reg, pll->base);
|
||||
writel(AXG_PCIE_PLL_CNTL, cntlbase + (u64)(0*4));
|
||||
writel(AXG_PCIE_PLL_CNTL1, cntlbase + (u64)(1*4));
|
||||
writel(AXG_PCIE_PLL_CNTL2, cntlbase + (u64)(2*4));
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
#include <linux/amlogic/media/vout/vout_notify.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#ifdef CONFIG_AML_LCD
|
||||
#include <linux/amlogic/media/vout/lcd_notify.h>
|
||||
#ifdef CONFIG_AMLOGIC_LCD
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_notify.h>
|
||||
#endif
|
||||
|
||||
#include "arch/vpp_regs.h"
|
||||
@@ -2923,7 +2923,7 @@ static void aml_vecm_dt_parse(struct platform_device *pdev)
|
||||
/* WRITE_VPP_REG_BITS(VPP_MISC, cm_en, 28, 1); */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AML_LCD
|
||||
#ifdef CONFIG_AMLOGIC_LCD
|
||||
static int aml_lcd_gamma_notifier(struct notifier_block *nb,
|
||||
unsigned long event, void *data)
|
||||
{
|
||||
@@ -2983,7 +2983,7 @@ static int aml_vecm_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
spin_lock_init(&vpp_lcd_gamma_lock);
|
||||
#ifdef CONFIG_AML_LCD
|
||||
#ifdef CONFIG_AMLOGIC_LCD
|
||||
ret = aml_lcd_notifier_register(&aml_lcd_gamma_nb);
|
||||
if (ret)
|
||||
pr_info("register aml_lcd_gamma_notifier failed\n");
|
||||
@@ -3047,7 +3047,7 @@ static int __exit aml_vecm_remove(struct platform_device *pdev)
|
||||
class_destroy(devp->clsp);
|
||||
unregister_chrdev_region(devp->devno, 1);
|
||||
kfree(devp);
|
||||
#ifdef CONFIG_AML_LCD
|
||||
#ifdef CONFIG_AMLOGIC_LCD
|
||||
aml_lcd_notifier_unregister(&aml_lcd_gamma_nb);
|
||||
#endif
|
||||
probe_ok = 0;
|
||||
|
||||
@@ -1553,7 +1553,7 @@ void vdin_set_def_wr_canvas(struct vdin_dev_s *devp)
|
||||
wr(offset, VDIN_WR_CTRL, (0x0bc01000 | def_canvas));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AML_LOCAL_DIMMING
|
||||
#ifdef CONFIG_AMLOGIC_LOCAL_DIMMING
|
||||
void vdin_set_ldim_max_init(unsigned int offset,
|
||||
int pic_h, int pic_v, int blk_vnum, int blk_hnum)
|
||||
{
|
||||
@@ -1660,7 +1660,7 @@ void vdin_set_vframe_prop_info(struct vframe_s *vf,
|
||||
{
|
||||
unsigned int offset = devp->addr_offset;
|
||||
struct vframe_bbar_s bbar = {0};
|
||||
#ifdef CONFIG_AML_LOCAL_DIMMING
|
||||
#ifdef CONFIG_AMLOGIC_LOCAL_DIMMING
|
||||
/*int i;*/
|
||||
#endif
|
||||
/* fetch hist info */
|
||||
@@ -1854,7 +1854,7 @@ void vdin_set_vframe_prop_info(struct vframe_s *vf,
|
||||
vf->prop.meas.vs_stamp = devp->stamp;
|
||||
vf->prop.meas.vs_cycle = devp->cycle;
|
||||
#if 0
|
||||
/*#ifdef CONFIG_AML_LOCAL_DIMMING*/
|
||||
/*#ifdef CONFIG_AMLOGIC_LOCAL_DIMMING*/
|
||||
/* get ldim max */
|
||||
if (vdin_ldim_max_en && is_meson_gxtvbb_cpu()) {
|
||||
wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 0,
|
||||
@@ -1884,7 +1884,7 @@ void vdin_set_all_regs(struct vdin_dev_s *devp)
|
||||
|
||||
/* bbar sub-module */
|
||||
vdin_set_bbar(devp->addr_offset, devp->v_active, devp->h_active);
|
||||
#ifdef CONFIG_AML_LOCAL_DIMMING
|
||||
#ifdef CONFIG_AMLOGIC_LOCAL_DIMMING
|
||||
/* ldim sub-module */
|
||||
/* vdin_set_ldim_max_init(devp->addr_offset, 1920, 1080, 8, 2); */
|
||||
vdin_set_ldim_max_init(devp->addr_offset, devp->h_active,
|
||||
|
||||
@@ -97,7 +97,7 @@ struct vdin_stat_s {
|
||||
unsigned int sum_pixel; /* VDIN_HIST_PIX_CNT_REG */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_AML_LOCAL_DIMMING
|
||||
#ifdef CONFIG_AMLOGIC_LOCAL_DIMMING
|
||||
struct ldim_max_s {
|
||||
/* general parameters */
|
||||
int ld_pic_rowmax;
|
||||
|
||||
@@ -360,7 +360,7 @@ static void vdin_write_mem(struct vdin_dev_s *devp, char *type, char *path)
|
||||
NULL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AML_LOCAL_DIMMING
|
||||
#ifdef CONFIG_AMLOGIC_LOCAL_DIMMING
|
||||
|
||||
static void vdin_dump_histgram_ldim(struct vdin_dev_s *devp,
|
||||
unsigned int hnum, unsigned int vnum)
|
||||
@@ -682,7 +682,7 @@ start_chk:
|
||||
} else if (!strcmp(parm[0], "histgram")) {
|
||||
vdin_dump_histgram(devp);
|
||||
}
|
||||
#ifdef CONFIG_AML_LOCAL_DIMMING
|
||||
#ifdef CONFIG_AMLOGIC_LOCAL_DIMMING
|
||||
else if (!strcmp(parm[0], "histgram_ldim")) {
|
||||
unsigned int hnum, vnum;
|
||||
|
||||
|
||||
@@ -1443,7 +1443,7 @@ irqreturn_t vdin_isr_simple(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
#if 0
|
||||
/*#ifdef CONFIG_AML_LOCAL_DIMMING*/
|
||||
/*#ifdef CONFIG_AMLOGIC_LOCAL_DIMMING*/
|
||||
unsigned int vdin_ldim_max_global[100] = {0};
|
||||
static void vdin_backup_histgram_ldim(struct vframe_s *vf,
|
||||
struct vdin_dev_s *devp)
|
||||
@@ -1696,7 +1696,7 @@ irqreturn_t vdin_isr(int irq, void *dev_id)
|
||||
vdin_set_drm_data(devp, curr_wr_vf);
|
||||
vdin_set_vframe_prop_info(curr_wr_vf, devp);
|
||||
vdin_backup_histgram(curr_wr_vf, devp);
|
||||
#ifdef CONFIG_AML_LOCAL_DIMMING
|
||||
#ifdef CONFIG_AMLOGIC_LOCAL_DIMMING
|
||||
/*vdin_backup_histgram_ldim(curr_wr_vf, devp);*/
|
||||
#endif
|
||||
if ((devp->parm.port >= TVIN_PORT_HDMI0) &&
|
||||
|
||||
@@ -17,6 +17,8 @@ if AMLOGIC_VOUT
|
||||
source "drivers/amlogic/media/vout/cvbs/Kconfig"
|
||||
source "drivers/amlogic/media/vout/vdac/Kconfig"
|
||||
source "drivers/amlogic/media/vout/hdmitx/Kconfig"
|
||||
source "drivers/amlogic/media/vout/lcd/Kconfig"
|
||||
source "drivers/amlogic/media/vout/backlight/Kconfig"
|
||||
source "drivers/amlogic/media/vout/vout_serve/Kconfig"
|
||||
|
||||
endif
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
obj-$(CONFIG_AMLOGIC_CVBS_OUTPUT) += cvbs/
|
||||
obj-$(CONFIG_AMLOGIC_VDAC) += vdac/
|
||||
obj-$(CONFIG_AMLOGIC_HDMITX) += hdmitx/
|
||||
obj-$(CONFIG_AMLOGIC_LCD) += lcd/
|
||||
obj-$(CONFIG_AMLOGIC_BACKLIGHT) += backlight/
|
||||
obj-$(CONFIG_AMLOGIC_VOUT_SERVE) += vout_serve/
|
||||
|
||||
|
||||
19
drivers/amlogic/media/vout/backlight/Kconfig
Normal file
19
drivers/amlogic/media/vout/backlight/Kconfig
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
menu "Amlogic Backlight Support"
|
||||
|
||||
config AMLOGIC_BACKLIGHT
|
||||
bool "Amlogic backlight support"
|
||||
depends on BACKLIGHT_LCD_SUPPORT
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
default n
|
||||
help
|
||||
Say Y here if you want to use the Amlogic backlight management.
|
||||
Backlight have five ways, including gpio, pwm, pwm_combo,
|
||||
local dimming, extern.
|
||||
|
||||
if AMLOGIC_BACKLIGHT
|
||||
source "drivers/amlogic/media/vout/backlight/bl_extern/Kconfig"
|
||||
source "drivers/amlogic/media/vout/backlight/aml_ldim/Kconfig"
|
||||
endif
|
||||
|
||||
endmenu
|
||||
2
drivers/amlogic/media/vout/backlight/Makefile
Normal file
2
drivers/amlogic/media/vout/backlight/Makefile
Normal file
@@ -0,0 +1,2 @@
|
||||
obj-$(CONFIG_AMLOGIC_BACKLIGHT) += aml_bl.o
|
||||
obj-$(CONFIG_AMLOGIC_BL_EXTERN) += bl_extern/
|
||||
2836
drivers/amlogic/media/vout/backlight/aml_bl.c
Normal file
2836
drivers/amlogic/media/vout/backlight/aml_bl.c
Normal file
File diff suppressed because it is too large
Load Diff
144
drivers/amlogic/media/vout/backlight/aml_bl.dts
Normal file
144
drivers/amlogic/media/vout/backlight/aml_bl.dts
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/backlight/aml_bl.dts
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
backlight{
|
||||
compatible = "amlogic, backlight";
|
||||
dev_name = "backlight";
|
||||
status = "okay";
|
||||
pinctrl-names = "pwm_on","pwm_off","pwm_vs_on","pwm_vs_off",
|
||||
"pwm_combo_on", "pwm_combo_off";
|
||||
pinctrl-0 = <&bl_pwm_on_pins>;
|
||||
pinctrl-1 = <&bl_pwm_off_pins>;
|
||||
pinctrl-2 = <&bl_pwm_vs_on_pins>;
|
||||
pinctrl-3 = <&bl_pwm_vs_off_pins>;
|
||||
pinctrl-4 = <&bl_pwm_combo_on_pins>;
|
||||
pinctrl-5 = <&bl_pwm_combo_off_pins>;
|
||||
|
||||
/* power index:(point gpios_index, 0xff=invalid) */
|
||||
/* power value:(0=output low, 1=output high, 2=input) */
|
||||
/* power delay:(unit in ms) */
|
||||
bl-gpios = <&gpio GPIOAO_4 GPIO_ACTIVE_HIGH
|
||||
&gpio GPIOY_13 GPIO_ACTIVE_HIGH
|
||||
&gpio GPIOY_8 GPIO_ACTIVE_HIGH>;
|
||||
bl_gpio_names = "GPIOAO_4","GPIOY_13","GPIOY_8";
|
||||
|
||||
backlight_0{
|
||||
index = <0>;
|
||||
bl_name = "backlight_0";
|
||||
bl_level_default_uboot_kernel = <100 100>;
|
||||
bl_level_attr = <255 10 128 102>;
|
||||
/* max, min, mid, mid_mapping */
|
||||
|
||||
bl_ctrl_method = <1>;
|
||||
/* 0=gpio, 1=pwm, 2=pwm_combo, 3=ldim, 4=extern */
|
||||
bl_power_attr = <0 1 0 200 200>;
|
||||
/* en_gpio_index, on_value, off_value,
|
||||
* on_delay, off_delay
|
||||
*/
|
||||
|
||||
/* pwm_method:(0=negative, 1=positive) */
|
||||
/* pwm_freq:(pwm_vs: 1~4 vfreq multiple,
|
||||
* other pwm: real freq unit: Hz)
|
||||
*/
|
||||
/* pwm_duty:(unit in %) */
|
||||
|
||||
bl_pwm_port = "PWM_B";
|
||||
/* PWM_A, PWM_B, PWM_C, PWM_D, PWM_VS */
|
||||
bl_pwm_attr = <1 180 100 25>;
|
||||
/* pwm_method, pwm_freq, duty_max, duty_min */
|
||||
bl_pwm_power = <1 0 10 10>;
|
||||
/* pwm_gpio_index, pwm_gpio_off,
|
||||
* pwm_on_delay, pwm_off_delay
|
||||
*/
|
||||
};
|
||||
backlight_1{
|
||||
index = <1>;
|
||||
bl_name = "backlight_1";
|
||||
bl_level_default_uboot_kernel = <100 100>;
|
||||
bl_level_attr = <255 10 128 102>;
|
||||
/* max, min, mid, mid_mapping */
|
||||
|
||||
bl_ctrl_method = <1>;
|
||||
/* 0=gpio, 1=pwm, 2=pwm_combo, 3=ldim, 4=extern */
|
||||
bl_power_attr = <0 1 0 200 200>;
|
||||
/* en_gpio_index, on_value, off_value,
|
||||
* on_delay, off_delay
|
||||
*/
|
||||
|
||||
/* pwm_method: 0=negative, 1=positive */
|
||||
/* pwm_freq: pwm_vs: 1~4(vfreq multiple),
|
||||
* other pwm: real freq(unit: Hz)
|
||||
*/
|
||||
/* duty_max, duty_min: unit in % */
|
||||
|
||||
bl_pwm_port = "PWM_VS";
|
||||
/* PWM_A, PWM_B, PWM_C, PWM_D, PWM_VS */
|
||||
bl_pwm_attr = <1 2 100 25>;
|
||||
/* pwm_method, pwm_freq, duty_max, duty_min */
|
||||
bl_pwm_power = <1 0 10 10>;
|
||||
/* pwm_gpio_index, pwm_off_value,
|
||||
* pwm_on_delay, pwm_off_delay
|
||||
*/
|
||||
};
|
||||
backlight_2{
|
||||
index = <2>;
|
||||
bl_name = "backlight_2";
|
||||
bl_level_attr = <255 10 128 102>;
|
||||
/* max, min, mid, mid_mapping */
|
||||
|
||||
bl_ctrl_method = <3>;
|
||||
/* 0=gpio, 1=pwm, 2=pwm_combo, 3=ldim, 4=extern */
|
||||
bl_power_attr = <0 1 0 200 200>;
|
||||
/* en_gpio_index, on_value,
|
||||
* off_value, on_delay, off_delay
|
||||
*/
|
||||
};
|
||||
backlight_3{
|
||||
index = <3>;
|
||||
bl_name = "backlight_3";
|
||||
bl_level_default_uboot_kernel = <100 100>;
|
||||
bl_level_attr = <255 10 128 102>;
|
||||
/* max, min, mid, mid_mapping */
|
||||
|
||||
bl_ctrl_method = <2>;
|
||||
/* 0=gpio, 1=pwm, 2=pwm_combo, 3=ldim, 4=extern */
|
||||
bl_power_attr = <0 1 0 200 200>;
|
||||
/* en_gpio_index, on_value,
|
||||
* off_value, on_delay, off_delay
|
||||
*/
|
||||
|
||||
/* pwm_method: 0=negative, 1=positive */
|
||||
/* pwm_freq: pwm_vs: 1~4(vfreq multiple),
|
||||
* other pwm: real freq(unit: Hz)
|
||||
*/
|
||||
/* duty_max, duty_min: unit in % */
|
||||
|
||||
bl_pwm_combo_level_mapping = <255 128 128 10>;
|
||||
/* level_max, level_min */
|
||||
bl_pwm_combo_port = "PWM_B","PWM_D";
|
||||
/* PWM_A, PWM_B, PWM_C, PWM_D, PWM_VS */
|
||||
bl_pwm_combo_attr = <1 180 100 25
|
||||
0 18000 100 25>;
|
||||
/* pwm_method, pwm_freq, duty_max, duty_min */
|
||||
bl_pwm_combo_power = <1 0 2 0 10 10>;
|
||||
/* pwm0_gpio_index, pwm0_gpio_off,
|
||||
* pwm1_gpio_index, pwm1_gpio_off,
|
||||
* pwm_on_delay, pwm_off_delay
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
91
drivers/amlogic/media/vout/backlight/aml_bl_reg.h
Normal file
91
drivers/amlogic/media/vout/backlight/aml_bl_reg.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/backlight/aml_bl_reg.h
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __AML_BL_REG_H__
|
||||
#define __AML_BL_REG_H__
|
||||
#include <linux/amlogic/iomap.h>
|
||||
|
||||
/* normal pwm reg: cbus */
|
||||
#define PWM_PWM_A 0x2154
|
||||
#define PWM_PWM_B 0x2155
|
||||
#define PWM_MISC_REG_AB 0x2156
|
||||
#define PWM_PWM_C 0x2190
|
||||
#define PWM_PWM_D 0x2191
|
||||
#define PWM_MISC_REG_CD 0x2192
|
||||
#define PWM_PWM_E 0x21b0
|
||||
#define PWM_PWM_F 0x21b1
|
||||
#define PWM_MISC_REG_EF 0x21b2
|
||||
/* normal pwm reg: cbus, txlx */
|
||||
#define PWM_PWM_A_TXLX 0x6c00
|
||||
#define PWM_PWM_B_TXLX 0x6c01
|
||||
#define PWM_MISC_REG_AB_TXLX 0x6c02
|
||||
#define PWM_PWM_C_TXLX 0x6800
|
||||
#define PWM_PWM_D_TXLX 0x6801
|
||||
#define PWM_MISC_REG_CD_TXLX 0x6802
|
||||
#define PWM_PWM_E_TXLX 0x6400
|
||||
#define PWM_PWM_F_TXLX 0x6401
|
||||
#define PWM_MISC_REG_EF_TXLX 0x6402
|
||||
|
||||
/* pwm_vs reg: vcbus */
|
||||
#define VPU_VPU_PWM_V0 0x2730
|
||||
#define VPU_VPU_PWM_V1 0x2731
|
||||
#define VPU_VPU_PWM_V2 0x2732
|
||||
#define VPU_VPU_PWM_V3 0x2733
|
||||
|
||||
#define ENCL_VIDEO_MAX_LNCNT 0x1cbb
|
||||
|
||||
|
||||
static inline unsigned int bl_cbus_read(unsigned int reg)
|
||||
{
|
||||
return aml_read_cbus(reg);
|
||||
};
|
||||
|
||||
static inline void bl_cbus_write(unsigned int reg, unsigned int value)
|
||||
{
|
||||
aml_write_cbus(reg, value);
|
||||
};
|
||||
|
||||
static inline void bl_cbus_setb(unsigned int reg, unsigned int value,
|
||||
unsigned int _start, unsigned int _len)
|
||||
{
|
||||
bl_cbus_write(reg, ((bl_cbus_read(reg) &
|
||||
(~(((1L << _len)-1) << _start))) |
|
||||
((value & ((1L << _len)-1)) << _start)));
|
||||
|
||||
}
|
||||
|
||||
static inline unsigned int bl_vcbus_read(unsigned int reg)
|
||||
{
|
||||
return aml_read_vcbus(reg);
|
||||
};
|
||||
|
||||
static inline void bl_vcbus_write(unsigned int reg, unsigned int value)
|
||||
{
|
||||
aml_write_vcbus(reg, value);
|
||||
};
|
||||
|
||||
static inline void bl_vcbus_setb(unsigned int reg, unsigned int value,
|
||||
unsigned int _start, unsigned int _len)
|
||||
{
|
||||
bl_vcbus_write(reg, ((bl_vcbus_read(reg) &
|
||||
(~(((1L << _len)-1) << _start))) |
|
||||
((value & ((1L << _len)-1)) << _start)));
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
12
drivers/amlogic/media/vout/backlight/aml_ldim/Kconfig
Normal file
12
drivers/amlogic/media/vout/backlight/aml_ldim/Kconfig
Normal file
@@ -0,0 +1,12 @@
|
||||
#
|
||||
# LDIM Device Driver Configuration
|
||||
#
|
||||
config AMLOGIC_LOCAL_DIMMING
|
||||
bool "Amlogic Local dimming"
|
||||
default n
|
||||
help
|
||||
Say Y if you want to use Amlogic Local dimming.
|
||||
The role of local dimming is according to each
|
||||
image information, calculate the corresponding
|
||||
brightness values, to improve the effect of image quality,
|
||||
|
||||
40
drivers/amlogic/media/vout/backlight/bl_extern/Kconfig
Normal file
40
drivers/amlogic/media/vout/backlight/bl_extern/Kconfig
Normal file
@@ -0,0 +1,40 @@
|
||||
|
||||
config AMLOGIC_BL_EXTERN
|
||||
bool "Amlogic backlight extern driver support"
|
||||
default n
|
||||
help
|
||||
Say Y if you want to use Amlogic backlight external controller.
|
||||
Amlogic backlight external driver support,
|
||||
such as i2c or mipi initial
|
||||
According to choose the corresponding bl_extern inside index bl_extern driver
|
||||
|
||||
config AMLOGIC_BL_EXTERN_PMU_AML1218
|
||||
bool "Amlogic backlight pmu aml1218"
|
||||
depends on AMLOGIC_BL_EXTERN
|
||||
default n
|
||||
help
|
||||
pmu aml1218 backlight controller support.
|
||||
Once the backlight power on, according to the timing requirements,
|
||||
through the aml1218 to write data to the backlight,
|
||||
make its initialization
|
||||
|
||||
|
||||
config AMLOGIC_BL_EXTERN_I2C_LP8556
|
||||
bool "Amlogic backlight i2c lp8556"
|
||||
depends on AMLOGIC_BL_EXTERN
|
||||
default n
|
||||
help
|
||||
i2c lp8556 backlight controller support.
|
||||
Once the backlight power on, according to the timing requirements,
|
||||
through the i2c_lp8556 to write data to the backlight,
|
||||
make its initialization
|
||||
|
||||
config AMLOGIC_BL_EXTERN_MIPI_LT070ME05
|
||||
bool "Amlogic backlight mipi LT070ME05"
|
||||
depends on AMLOGIC_BL_EXTERN
|
||||
default n
|
||||
help
|
||||
mipi LT070ME05 backlight controller support.
|
||||
Once the backlight power on, according to the timing requirements,
|
||||
through the mipi_LT070ME05 to write data to the backlight,
|
||||
make its initialization
|
||||
6
drivers/amlogic/media/vout/backlight/bl_extern/Makefile
Normal file
6
drivers/amlogic/media/vout/backlight/bl_extern/Makefile
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
obj-$(CONFIG_AMLOGIC_BL_EXTERN) += bl_extern.o
|
||||
obj-$(CONFIG_AMLOGIC_BL_EXTERN_I2C_LP8556) += i2c_lp8556.o
|
||||
obj-$(CONFIG_AMLOGIC_BL_EXTERN_PMU_AML1218) += pmu_aml1218.o
|
||||
obj-$(CONFIG_AMLOGIC_BL_EXTERN_MIPI_LT070ME05) += mipi_LT070ME05.o
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/backlight/bl_extern/aml_bl_extern.dts
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
bl_extern_pmu_aml1218{
|
||||
compatible = "amlogic, bl_pmu_aml1218";
|
||||
dev_name ="bl_pmu_aml1218";
|
||||
status = "disabled"; /** "disabled" or "okay" */
|
||||
GPIODV_28-gpios = <&gpio GPIODV_28 0>;
|
||||
gpio_enable_on_off = "GPIODV_28","1","0";
|
||||
/* gpio("n"for none),
|
||||
* on/off(1=output high, 0=output low, 2=input)
|
||||
*/
|
||||
type = <2>; /** bl_extern_driver type: 0=i2c, 1=spi, 2=other */
|
||||
dim_max_min = <0x1 0x1b>;
|
||||
};
|
||||
|
||||
|
||||
bl_extern_i2c_lp8556{
|
||||
compatible = "amlogic, bl_i2c_lp8556";
|
||||
dev_name ="bl_i2c_lp8556";
|
||||
status = "disabled"; /** "disabled" or "okay" */
|
||||
GPIODV_28-gpios = <&gpio GPIODV_28 0>;
|
||||
gpio_enable_on_off = "GPIODV_28","1","0";
|
||||
/* gpio("n"for none),
|
||||
* on/off(1=output high, 0=output low, 2=input)
|
||||
*/
|
||||
type = <0>; /** bl_extern_driver type: 0=i2c, 1=spi, 2=other */
|
||||
i2c_address = <0x2c>; /** 7bit i2c address */
|
||||
i2c_bus = "i2c_bus_b";
|
||||
dim_max_min = <255 10>;
|
||||
};
|
||||
|
||||
|
||||
bl_extern_mipi_LT070ME05{
|
||||
compatible = "amlogic, bl_mipi_LT070ME05";
|
||||
dev_name ="bl_mipi_LT070ME056";
|
||||
status = "disabled"; /** "disabled" or "okay" */
|
||||
GPIODV_28-gpios = <&gpio GPIODV_28 0>;
|
||||
gpio_enable_on_off = "GPIODV_28","1","0";
|
||||
/* gpio("n"for none),
|
||||
* on/off(1=output high, 0=output low, 2=input)
|
||||
*/
|
||||
type = <2>; /** bl_extern_driver type: 0=i2c, 1=spi, 2=other */
|
||||
dim_max_min = <255 10>;
|
||||
};
|
||||
234
drivers/amlogic/media/vout/backlight/bl_extern/bl_extern.c
Normal file
234
drivers/amlogic/media/vout/backlight/bl_extern/bl_extern.c
Normal file
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/backlight/bl_extern/bl_extern.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/amlogic/i2c-amlogic.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/amlogic/media/vout/lcd/aml_bl_extern.h>
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_vout.h>
|
||||
|
||||
#ifdef BL_EXT_DEBUG_INFO
|
||||
#define DBG_PRINT(...) pr_info(__VA_ARGS__)
|
||||
#else
|
||||
#define DBG_PRINT(...)
|
||||
#endif
|
||||
|
||||
static struct aml_bl_extern_driver_t bl_ext_driver = {
|
||||
.type = BL_EXTERN_MAX,
|
||||
.name = NULL,
|
||||
.power_on = NULL,
|
||||
.power_off = NULL,
|
||||
.set_level = NULL,
|
||||
|
||||
};
|
||||
|
||||
struct aml_bl_extern_driver_t *aml_bl_extern_get_driver(void)
|
||||
{
|
||||
return &bl_ext_driver;
|
||||
}
|
||||
|
||||
int bl_extern_driver_check(void)
|
||||
{
|
||||
struct aml_bl_extern_driver_t *bl_ext;
|
||||
|
||||
bl_ext = aml_bl_extern_get_driver();
|
||||
if (bl_ext) {
|
||||
if (bl_ext->type < BL_EXTERN_MAX) {
|
||||
pr_err("[warning]: bl_extern has already exist (%s)\n",
|
||||
bl_ext->name);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
pr_err("get bl_extern_driver failed\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_bl_extern_dt_data(struct device dev, struct bl_extern_config_t *pdata)
|
||||
{
|
||||
int ret;
|
||||
struct device_node *of_node = dev.of_node;
|
||||
u32 bl_para[2];
|
||||
const char *str;
|
||||
struct gpio_desc *bl_extern_gpio;
|
||||
|
||||
ret = of_property_read_string(of_node, "dev_name",
|
||||
(const char **)&pdata->name);
|
||||
if (ret) {
|
||||
pdata->name = "aml_bl_extern";
|
||||
pr_err("warning: get dev_name failed\n");
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(of_node, "type", &pdata->type);
|
||||
if (ret) {
|
||||
pdata->type = BL_EXTERN_MAX;
|
||||
pr_err("%s warning: get type failed, exit\n", pdata->name);
|
||||
return -1;
|
||||
}
|
||||
pdata->gpio_used = 0;
|
||||
ret = of_property_read_string_index(of_node,
|
||||
"gpio_enable_on_off", 0, &str);
|
||||
if (ret) {
|
||||
pr_warn("%s warning: get gpio_enable failed\n", pdata->name);
|
||||
} else {
|
||||
if (strncmp(str, "G", 1) == 0) {
|
||||
pdata->gpio_used = 1;
|
||||
bl_extern_gpio = gpiod_get(&dev, str);
|
||||
if (bl_extern_gpio) {
|
||||
pr_warn("%s warning:failed to alloc gpio (%s)\n",
|
||||
pdata->name, str);
|
||||
}
|
||||
pdata->gpio = bl_extern_gpio;
|
||||
}
|
||||
DBG_PRINT("%s: gpio_enable %s\n",
|
||||
pdata->name, ((pdata->gpio_used) ? str:"none"));
|
||||
}
|
||||
ret = of_property_read_string_index(of_node,
|
||||
"gpio_enable_on_off", 1, &str);
|
||||
if (ret) {
|
||||
pr_warn("%s warning: get gpio_enable_on failed\n", pdata->name);
|
||||
} else {
|
||||
if (strncmp(str, "2", 1) == 0)
|
||||
pdata->gpio_on = LCD_POWER_GPIO_INPUT;
|
||||
else if (strncmp(str, "0", 1) == 0)
|
||||
pdata->gpio_on = LCD_POWER_GPIO_OUTPUT_LOW;
|
||||
else
|
||||
pdata->gpio_on = LCD_POWER_GPIO_OUTPUT_HIGH;
|
||||
}
|
||||
ret = of_property_read_string_index(of_node,
|
||||
"gpio_enable_on_off", 2, &str);
|
||||
if (ret) {
|
||||
pr_warn("%s warning:get gpio_enable_off failed\n", pdata->name);
|
||||
} else {
|
||||
if (strncmp(str, "2", 1) == 0)
|
||||
pdata->gpio_off = LCD_POWER_GPIO_INPUT;
|
||||
else if (strncmp(str, "1", 1) == 0)
|
||||
pdata->gpio_off = LCD_POWER_GPIO_OUTPUT_HIGH;
|
||||
else
|
||||
pdata->gpio_off = LCD_POWER_GPIO_OUTPUT_LOW;
|
||||
}
|
||||
DBG_PRINT("%s: gpio_on = %d,", pdata->name, pdata->gpio_on);
|
||||
DBG_PRINT("gpio_off = %d\n", pdata->gpio_off);
|
||||
switch (pdata->type) {
|
||||
case BL_EXTERN_I2C:
|
||||
ret = of_property_read_u32(of_node, "i2c_address",
|
||||
&pdata->i2c_addr);
|
||||
if (ret) {
|
||||
pr_warn("%s warning: get i2c_address failed\n",
|
||||
pdata->name);
|
||||
pdata->i2c_addr = 0;
|
||||
}
|
||||
DBG_PRINT("%s: i2c_address=", pdata->name);
|
||||
DBG_PRINT("0x%02x\n", pdata->i2c_addr);
|
||||
ret = of_property_read_string(of_node, "i2c_bus", &str);
|
||||
if (ret) {
|
||||
pr_warn("%s warning: get i2c_bus failed,", pdata->name);
|
||||
pr_warn("use default i2c bus\n");
|
||||
pdata->i2c_bus = AML_I2C_MASTER_A;
|
||||
} else {
|
||||
if (strncmp(str, "i2c_bus_a", 9) == 0)
|
||||
pdata->i2c_bus = AML_I2C_MASTER_A;
|
||||
else if (strncmp(str, "i2c_bus_b", 9) == 0)
|
||||
pdata->i2c_bus = AML_I2C_MASTER_B;
|
||||
else if (strncmp(str, "i2c_bus_c", 9) == 0)
|
||||
pdata->i2c_bus = AML_I2C_MASTER_C;
|
||||
else if (strncmp(str, "i2c_bus_d", 9) == 0)
|
||||
pdata->i2c_bus = AML_I2C_MASTER_D;
|
||||
else if (strncmp(str, "i2c_bus_ao", 10) == 0)
|
||||
pdata->i2c_bus = AML_I2C_MASTER_AO;
|
||||
else
|
||||
pdata->i2c_bus = AML_I2C_MASTER_A;
|
||||
}
|
||||
DBG_PRINT("%s: i2c_bus=%s[%d]\n", pdata->name,
|
||||
str, pdata->i2c_bus);
|
||||
break;
|
||||
case BL_EXTERN_SPI:
|
||||
ret = of_property_read_string(of_node, "gpio_spi_cs", &str);
|
||||
if (ret) {
|
||||
pr_warn("%s warning: get spi gpio_spi_cs failed\n",
|
||||
pdata->name);
|
||||
pdata->spi_cs = NULL;
|
||||
} else {
|
||||
bl_extern_gpio = gpiod_get(&dev, str);
|
||||
if (bl_extern_gpio) {
|
||||
pdata->spi_cs = bl_extern_gpio;
|
||||
DBG_PRINT("spi_cs gpio = %s\n", str);
|
||||
} else {
|
||||
pr_warn("%s warning:failed to alloc gpio (%s)\n",
|
||||
pdata->name, str);
|
||||
pdata->spi_cs = NULL;
|
||||
}
|
||||
}
|
||||
ret = of_property_read_string(of_node, "gpio_spi_clk", &str);
|
||||
if (ret) {
|
||||
pr_warn("%s warning: get spi gpio_spi_clk failed\n",
|
||||
pdata->name);
|
||||
pdata->spi_clk = NULL;
|
||||
} else {
|
||||
bl_extern_gpio = gpiod_get(&dev, str);
|
||||
if (bl_extern_gpio) {
|
||||
pdata->spi_clk = bl_extern_gpio;
|
||||
DBG_PRINT("spi_cs gpio = %s\n", str);
|
||||
} else {
|
||||
pdata->spi_clk = NULL;
|
||||
pr_warn("%s warning:failed to alloc gpio (%s)\n",
|
||||
pdata->name, str);
|
||||
}
|
||||
}
|
||||
ret = of_property_read_string(of_node, "gpio_spi_data", &str);
|
||||
if (ret) {
|
||||
pr_warn("%s warning: get spi gpio_spi_data failed\n",
|
||||
pdata->name);
|
||||
pdata->spi_data = NULL;
|
||||
} else {
|
||||
bl_extern_gpio = gpiod_get(&dev, str);
|
||||
if (bl_extern_gpio) {
|
||||
pdata->spi_data = bl_extern_gpio;
|
||||
DBG_PRINT("spi_cs gpio = %s\n", str);
|
||||
} else {
|
||||
pdata->spi_data = NULL;
|
||||
pr_warn("%s warning:failed to alloc gpio (%s)\n",
|
||||
pdata->name, str);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BL_EXTERN_OTHER:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ret = of_property_read_u32_array(of_node, "dim_max_min",
|
||||
&bl_para[0], 2);
|
||||
if (ret) {
|
||||
pr_warn("%s warning: get dim_max_min failed\n", pdata->name);
|
||||
pdata->dim_max = 0;
|
||||
pdata->dim_min = 0;
|
||||
} else {
|
||||
pdata->dim_max = bl_para[0];
|
||||
pdata->dim_min = bl_para[1];
|
||||
}
|
||||
DBG_PRINT("%s dim_min = %d, dim_max = %d\n", pdata->name,
|
||||
pdata->dim_min, pdata->dim_max);
|
||||
return 0;
|
||||
}
|
||||
370
drivers/amlogic/media/vout/backlight/bl_extern/i2c_lp8556.c
Normal file
370
drivers/amlogic/media/vout/backlight/bl_extern/i2c_lp8556.c
Normal file
@@ -0,0 +1,370 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/backlight/bl_extern/i2c_lp8556.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/amlogic/i2c-amlogic.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/amlogic/media/vout/lcd/aml_bl_extern.h>
|
||||
|
||||
static struct bl_extern_config_t *bl_ext_config;
|
||||
|
||||
static struct i2c_client *aml_lp8556_i2c_client;
|
||||
|
||||
|
||||
#ifdef BL_EXT_DEBUG_INFO
|
||||
#define DBG_PRINT(...) pr_info(__VA_ARGS__)
|
||||
#else
|
||||
#define DBG_PRINT(...)
|
||||
#endif
|
||||
|
||||
#define BL_EXTERN_NAME "bl_i2c_lp8556"
|
||||
static unsigned int bl_status = 1;
|
||||
static unsigned int bl_level;
|
||||
|
||||
static unsigned char i2c_init_table[][2] = {
|
||||
{0xa1, 0x76}, /* hight bit(8~11)(0~0X66e set backlight) */
|
||||
{0xa0, 0x66}, /* low bit(0~7) 20mA */
|
||||
{0x16, 0x1F}, /* 5channel LED enable 0x1F */
|
||||
{0xa9, 0xA0}, /* VBOOST_MAX 25V */
|
||||
{0x9e, 0x12},
|
||||
{0xa2, 0x23},
|
||||
{0x01, 0x05}, /* 0x03 pwm+I2c set brightness,0x5 I2c set brightness */
|
||||
{0xff, 0xff}, /* ending flag */
|
||||
};
|
||||
|
||||
static int aml_i2c_write(struct i2c_client *i2client,
|
||||
unsigned char *buff, unsigned int len)
|
||||
{
|
||||
int res = 0;
|
||||
struct i2c_msg msg[] = {
|
||||
{
|
||||
.addr = i2client->addr,
|
||||
.flags = 0,
|
||||
.len = len,
|
||||
.buf = buff,
|
||||
}
|
||||
};
|
||||
|
||||
res = i2c_transfer(i2client->adapter, msg, 1);
|
||||
if (res < 0)
|
||||
pr_err("%s: i2c transfer failed [addr 0x%02x]\n",
|
||||
__func__, i2client->addr);
|
||||
|
||||
return res;
|
||||
}
|
||||
#if 0
|
||||
static int aml_i2c_read(struct i2c_client *i2client,
|
||||
unsigned char *buff, unsigned int len)
|
||||
{
|
||||
int res = 0;
|
||||
struct i2c_msg msgs[] = {
|
||||
{
|
||||
.addr = i2client->addr,
|
||||
.flags = 0,
|
||||
.len = 1,
|
||||
.buf = buff,
|
||||
},
|
||||
{
|
||||
.addr = i2client->addr,
|
||||
.flags = I2C_M_RD,
|
||||
.len = len,
|
||||
.buf = buff,
|
||||
}
|
||||
};
|
||||
res = i2c_transfer(i2client->adapter, msgs, 2);
|
||||
if (res < 0)
|
||||
pr_err("%s: i2c transfer failed [addr 0x%02x]\n",
|
||||
__func__, i2client->addr);
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int bl_extern_set_level(unsigned int level)
|
||||
{
|
||||
unsigned char tData[3];
|
||||
int ret = 0;
|
||||
struct aml_bl_drv_s *bl_drv = aml_bl_get_driver();
|
||||
unsigned int level_max, level_min;
|
||||
unsigned int dim_max, dim_min;
|
||||
|
||||
bl_level = level;
|
||||
|
||||
if (bl_ext_config == NULL) {
|
||||
pr_err("no %s driver\n", BL_EXTERN_NAME);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bl_drv == NULL)
|
||||
return -1;
|
||||
level_max = bl_drv->bconf->level_max;
|
||||
level_min = bl_drv->bconf->level_min;
|
||||
dim_max = bl_ext_config->dim_max;
|
||||
dim_min = bl_ext_config->dim_min;
|
||||
level = dim_min - ((level - level_min) * (dim_min - dim_max)) /
|
||||
(level_max - level_min);
|
||||
level &= 0xff;
|
||||
|
||||
if (bl_status) {
|
||||
tData[0] = 0x0;
|
||||
tData[1] = level;
|
||||
ret = aml_i2c_write(aml_lp8556_i2c_client, tData, 2);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bl_extern_power_on(void)
|
||||
{
|
||||
unsigned char tData[3];
|
||||
int i = 0, ending_flag = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (bl_ext_config->gpio) {
|
||||
if (bl_ext_config->gpio_on == 2) {
|
||||
bl_gpio_input(bl_ext_config->gpio);
|
||||
} else {
|
||||
bl_gpio_output(bl_ext_config->gpio,
|
||||
bl_ext_config->gpio_on);
|
||||
}
|
||||
}
|
||||
|
||||
while (ending_flag == 0) {
|
||||
if (i2c_init_table[i][0] == 0xff) {
|
||||
if (i2c_init_table[i][1] == 0xff)
|
||||
ending_flag = 1;
|
||||
else
|
||||
mdelay(i2c_init_table[i][1]);
|
||||
} else {
|
||||
tData[0] = i2c_init_table[i][0];
|
||||
tData[1] = i2c_init_table[i][1];
|
||||
ret = aml_i2c_write(aml_lp8556_i2c_client, tData, 2);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
bl_status = 1;
|
||||
bl_extern_set_level(bl_level);
|
||||
BLPR("%s\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bl_extern_power_off(void)
|
||||
{
|
||||
bl_status = 0;
|
||||
if (bl_ext_config->gpio) {
|
||||
if (bl_ext_config->gpio_off == 2) {
|
||||
bl_gpio_input(bl_ext_config->gpio);
|
||||
} else {
|
||||
bl_gpio_output(bl_ext_config->gpio,
|
||||
bl_ext_config->gpio_off);
|
||||
}
|
||||
}
|
||||
BLPR("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_bl_extern_config(struct device dev,
|
||||
struct bl_extern_config_t *bl_ext_cfg)
|
||||
{
|
||||
int ret = 0;
|
||||
struct aml_bl_extern_driver_t *bl_ext;
|
||||
|
||||
ret = get_bl_extern_dt_data(dev, bl_ext_cfg);
|
||||
if (ret) {
|
||||
BLPR("error %s: failed to get dt data\n", BL_EXTERN_NAME);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (bl_ext_cfg->dim_min > 0xff)
|
||||
bl_ext_cfg->dim_min = 0xff;
|
||||
if (bl_ext_cfg->dim_max > 0xff)
|
||||
bl_ext_cfg->dim_max = 0xff;
|
||||
|
||||
bl_ext = aml_bl_extern_get_driver();
|
||||
if (bl_ext) {
|
||||
bl_ext->type = bl_ext_cfg->type;
|
||||
bl_ext->name = bl_ext_cfg->name;
|
||||
bl_ext->power_on = bl_extern_power_on;
|
||||
bl_ext->power_off = bl_extern_power_off;
|
||||
bl_ext->set_level = bl_extern_set_level;
|
||||
} else {
|
||||
BLPR("error %s get bl_extern_driver failed\n",
|
||||
bl_ext_cfg->name);
|
||||
ret = -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aml_lp8556_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
|
||||
BLPR("error %s: functionality check failed\n",
|
||||
__func__);
|
||||
else
|
||||
aml_lp8556_i2c_client = client;
|
||||
BLPR("%s OK\n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aml_lp8556_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id aml_lp8556_i2c_id[] = {
|
||||
{BL_EXTERN_NAME, 0},
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct i2c_driver aml_lp8556_i2c_driver = {
|
||||
.probe = aml_lp8556_i2c_probe,
|
||||
.remove = aml_lp8556_i2c_remove,
|
||||
.id_table = aml_lp8556_i2c_id,
|
||||
.driver = {
|
||||
.name = BL_EXTERN_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int aml_lp8556_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_board_info i2c_info;
|
||||
struct i2c_adapter *adapter;
|
||||
struct i2c_client *i2c_client;
|
||||
int ret = 0;
|
||||
|
||||
if (bl_extern_driver_check())
|
||||
return -1;
|
||||
if (bl_ext_config == NULL)
|
||||
bl_ext_config = kzalloc(sizeof(*bl_ext_config), GFP_KERNEL);
|
||||
if (bl_ext_config == NULL) {
|
||||
BLPR("error %s probe: failed to alloc data\n", BL_EXTERN_NAME);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pdev->dev.platform_data = bl_ext_config;
|
||||
ret = get_bl_extern_config(pdev->dev, bl_ext_config);
|
||||
if (ret)
|
||||
goto bl_extern_probe_failed;
|
||||
|
||||
memset(&i2c_info, 0, sizeof(i2c_info));
|
||||
adapter = i2c_get_adapter(bl_ext_config->i2c_bus);
|
||||
if (!adapter) {
|
||||
BLPR("error %s£ºfailed get i2c adapter\n", BL_EXTERN_NAME);
|
||||
goto bl_extern_probe_failed;
|
||||
}
|
||||
|
||||
strncpy(i2c_info.type, bl_ext_config->name, I2C_NAME_SIZE);
|
||||
i2c_info.addr = bl_ext_config->i2c_addr;
|
||||
i2c_info.platform_data = bl_ext_config;
|
||||
i2c_info.flags = 0;
|
||||
if (i2c_info.addr > 0x7f)
|
||||
i2c_info.flags = 0x10;
|
||||
i2c_client = i2c_new_device(adapter, &i2c_info);
|
||||
if (!i2c_client) {
|
||||
BLPR("error %s :failed new i2c device\n", BL_EXTERN_NAME);
|
||||
goto bl_extern_probe_failed;
|
||||
} else{
|
||||
DBG_PRINT("error %s: new i2c device succeed\n",
|
||||
((struct bl_extern_data_t *)(bl_ext_config))->name);
|
||||
}
|
||||
|
||||
if (!aml_lp8556_i2c_client) {
|
||||
ret = i2c_add_driver(&aml_lp8556_i2c_driver);
|
||||
if (ret) {
|
||||
BLPR("error %s probe: add i2c_driver failed\n",
|
||||
BL_EXTERN_NAME);
|
||||
goto bl_extern_probe_failed;
|
||||
}
|
||||
}
|
||||
BLPR("%s ok\n", __func__);
|
||||
return ret;
|
||||
|
||||
bl_extern_probe_failed:
|
||||
kfree(bl_ext_config);
|
||||
bl_ext_config = NULL;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int aml_lp8556_remove(struct platform_device *pdev)
|
||||
{
|
||||
kfree(pdev->dev.platform_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USE_OF
|
||||
static const struct of_device_id aml_lp8556_dt_match[] = {
|
||||
{
|
||||
.compatible = "amlogic, bl_i2c_lp8556",
|
||||
},
|
||||
{},
|
||||
};
|
||||
#else
|
||||
#define aml_lp8556_dt_match NULL
|
||||
#endif
|
||||
|
||||
static struct platform_driver aml_lp8556_driver = {
|
||||
.probe = aml_lp8556_probe,
|
||||
.remove = aml_lp8556_remove,
|
||||
.driver = {
|
||||
.name = BL_EXTERN_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
#ifdef CONFIG_USE_OF
|
||||
.of_match_table = aml_lp8556_dt_match,
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
static int __init aml_lp8556_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
BLPR("%s\n", __func__);
|
||||
ret = platform_driver_register(&aml_lp8556_driver);
|
||||
if (ret) {
|
||||
BLPR("error %s failed to register bl extern driver\n",
|
||||
__func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit aml_lp8556_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&aml_lp8556_driver);
|
||||
}
|
||||
|
||||
module_init(aml_lp8556_init);
|
||||
module_exit(aml_lp8556_exit);
|
||||
|
||||
MODULE_AUTHOR("AMLOGIC");
|
||||
MODULE_DESCRIPTION("BL Extern driver for LP8556");
|
||||
MODULE_LICENSE("GPL");
|
||||
221
drivers/amlogic/media/vout/backlight/bl_extern/mipi_LT070ME05.c
Normal file
221
drivers/amlogic/media/vout/backlight/bl_extern/mipi_LT070ME05.c
Normal file
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/backlight/bl_extern/mipi_LT070ME05.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/amlogic/media/vout/lcd/aml_bl_extern.h>
|
||||
|
||||
#ifdef CONFIG_LCD_IF_MIPI_VALID
|
||||
static struct bl_extern_config_t *bl_ext_config;
|
||||
|
||||
#ifdef BL_EXT_DEBUG_INFO
|
||||
#define DBG_PRINT(...) pr_info(__VA_ARGS__)
|
||||
#else
|
||||
#define DBG_PRINT(...)
|
||||
#endif
|
||||
|
||||
#define BL_EXTERN_NAME "bl_mipi_LT070ME05"
|
||||
static unsigned int bl_status = 1;
|
||||
static unsigned int bl_level;
|
||||
|
||||
/******************** mipi command ********************
|
||||
* format: data_type, num, data....
|
||||
* special: data_type=0xff, num<0xff means delay ms, num=0xff means ending.
|
||||
*/
|
||||
static int bl_extern_set_level(unsigned int level)
|
||||
{
|
||||
unsigned char payload[] = {0x15, 2, 0x51, 0xe6, 0xff, 0xff};
|
||||
|
||||
bl_level = level;
|
||||
|
||||
if (bl_ext_config == NULL) {
|
||||
pr_err("no %s driver\n", BL_EXTERN_NAME);
|
||||
return -1;
|
||||
}
|
||||
get_bl_ext_level(bl_ext_config);
|
||||
level = bl_ext_config->dim_min -
|
||||
((level - bl_ext_config->level_min) *
|
||||
(bl_ext_config->dim_min - bl_ext_config->dim_max)) /
|
||||
(bl_ext_config->level_max - bl_ext_config->level_min);
|
||||
level &= 0xff;
|
||||
|
||||
if (bl_status) {
|
||||
payload[3] = level;
|
||||
dsi_write_cmd(payload);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bl_extern_power_on(void)
|
||||
{
|
||||
if (bl_ext_config->gpio_used > 0) {
|
||||
if (bl_ext_config->gpio_on == 2) {
|
||||
bl_extern_gpio_input(bl_ext_config->gpio);
|
||||
} else {
|
||||
bl_extern_gpio_output(bl_ext_config->gpio,
|
||||
bl_ext_config->gpio_on);
|
||||
}
|
||||
}
|
||||
bl_status = 1;
|
||||
bl_extern_set_level(bl_level);
|
||||
pr_info("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bl_extern_power_off(void)
|
||||
{
|
||||
if (bl_ext_config->gpio_used > 0) {
|
||||
if (bl_ext_config->gpio_off == 2) {
|
||||
bl_extern_gpio_input(bl_ext_config->gpio);
|
||||
} else {
|
||||
bl_extern_gpio_output(bl_ext_config->gpio,
|
||||
bl_ext_config->gpio_off);
|
||||
}
|
||||
}
|
||||
pr_info("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_bl_extern_config(struct device dev,
|
||||
struct bl_extern_config_t *bl_ext_cfg)
|
||||
{
|
||||
int ret = 0;
|
||||
struct aml_bl_extern_driver_t *bl_ext;
|
||||
|
||||
ret = get_bl_extern_dt_data(dev, bl_ext_cfg);
|
||||
if (ret) {
|
||||
pr_err("[error] %s: failed to get dt data\n", BL_EXTERN_NAME);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (bl_ext_cfg->dim_min > 0xff)
|
||||
bl_ext_cfg->dim_min = 0xff;
|
||||
if (bl_ext_cfg->dim_max > 0xff)
|
||||
bl_ext_cfg->dim_max = 0xff;
|
||||
|
||||
bl_ext = aml_bl_extern_get_driver();
|
||||
if (bl_ext) {
|
||||
bl_ext->type = bl_ext_cfg->type;
|
||||
bl_ext->name = bl_ext_cfg->name;
|
||||
bl_ext->power_on = bl_extern_power_on;
|
||||
bl_ext->power_off = bl_extern_power_off;
|
||||
bl_ext->set_level = bl_extern_set_level;
|
||||
} else {
|
||||
pr_err("[error] %s get bl_extern_driver failed\n",
|
||||
bl_ext_cfg->name);
|
||||
ret = -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aml_LT070ME05_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (bl_extern_driver_check())
|
||||
return -1;
|
||||
if (bl_ext_config == NULL)
|
||||
bl_ext_config = kzalloc(sizeof(*bl_ext_config), GFP_KERNEL);
|
||||
if (bl_ext_config == NULL) {
|
||||
pr_err("[error] %s probe: failed to alloc data\n",
|
||||
BL_EXTERN_NAME);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pdev->dev.platform_data = bl_ext_config;
|
||||
ret = get_bl_extern_config(pdev->dev, bl_ext_config);
|
||||
if (ret)
|
||||
goto bl_extern_probe_failed;
|
||||
|
||||
pr_info("%s ok\n", __func__);
|
||||
return ret;
|
||||
|
||||
bl_extern_probe_failed:
|
||||
kfree(bl_ext_config);
|
||||
bl_ext_config = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int aml_LT070ME05_remove(struct platform_device *pdev)
|
||||
{
|
||||
kfree(pdev->dev.platform_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USE_OF
|
||||
static const struct of_device_id aml_LT070ME05_dt_match[] = {
|
||||
{
|
||||
.compatible = "amlogic, bl_mipi_LT070ME05",
|
||||
},
|
||||
{},
|
||||
};
|
||||
#else
|
||||
#define aml_LT070ME05_dt_match NULL
|
||||
#endif
|
||||
|
||||
static struct platform_driver aml_LT070ME05_driver = {
|
||||
.probe = aml_LT070ME05_probe,
|
||||
.remove = aml_LT070ME05_remove,
|
||||
.driver = {
|
||||
.name = BL_EXTERN_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
#ifdef CONFIG_USE_OF
|
||||
.of_match_table = aml_LT070ME05_dt_match,
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
static int __init aml_LT070ME05_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DBG_PRINT("%s\n", __func__);
|
||||
|
||||
ret = platform_driver_register(&aml_LT070ME05_driver);
|
||||
if (ret) {
|
||||
pr_err("[error] %s failed to register bl extern driver\n",
|
||||
__func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit aml_LT070ME05_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&aml_LT070ME05_driver);
|
||||
}
|
||||
|
||||
rootfs_initcall(aml_LT070ME05_init);
|
||||
module_exit(aml_LT070ME05_exit);
|
||||
|
||||
MODULE_AUTHOR("AMLOGIC");
|
||||
MODULE_DESCRIPTION("BL Extern driver for LT070ME05");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
#endif
|
||||
328
drivers/amlogic/media/vout/backlight/bl_extern/pmu_aml1218.c
Normal file
328
drivers/amlogic/media/vout/backlight/bl_extern/pmu_aml1218.c
Normal file
@@ -0,0 +1,328 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/backlight/bl_extern/pmu_aml1218.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/amlogic/i2c-amlogic.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/amlogic/media/vout/lcd/aml_bl_extern.h>
|
||||
#ifdef CONFIG_AMLOGIC_BOARD_HAS_PMU
|
||||
#include <linux/amlogic/aml_pmu_common.h>
|
||||
#endif
|
||||
|
||||
static struct bl_extern_config_t *bl_ext_config;
|
||||
|
||||
|
||||
#ifdef BL_EXT_DEBUG_INFO
|
||||
#define DBG_PRINT(...) pr_info(__VA_ARGS__)
|
||||
#else
|
||||
#define DBG_PRINT(...)
|
||||
#endif
|
||||
|
||||
#define BL_EXTERN_NAME "bl_pmu_aml1218"
|
||||
|
||||
static int bl_extern_set_level(unsigned int level)
|
||||
{
|
||||
#ifdef CONFIG_AMLOGIC_BOARD_HAS_PMU
|
||||
struct aml_pmu_driver *pmu_driver;
|
||||
unsigned char temp;
|
||||
#endif
|
||||
int ret = 0;
|
||||
|
||||
if (bl_ext_config == NULL) {
|
||||
pr_err("no %s driver\n", BL_EXTERN_NAME);
|
||||
return -1;
|
||||
}
|
||||
get_bl_ext_level(bl_ext_config);
|
||||
level = bl_ext_config->dim_min -
|
||||
((level - bl_ext_config->level_min) *
|
||||
(bl_ext_config->dim_min - bl_ext_config->dim_max)) /
|
||||
(bl_ext_config->level_max - bl_ext_config->level_min);
|
||||
level &= 0x1f;
|
||||
#ifdef CONFIG_AMLOGIC_BOARD_HAS_PMU
|
||||
pmu_driver = aml_pmu_get_driver();
|
||||
if (pmu_driver == NULL) {
|
||||
pr_err("no pmu driver\n");
|
||||
} else {
|
||||
if ((pmu_driver->pmu_reg_write) && (pmu_driver->pmu_reg_read)) {
|
||||
ret = pmu_driver->pmu_reg_read(0x005f, &temp);
|
||||
temp &= ~(0x3f << 2);
|
||||
temp |= (level << 2);
|
||||
ret = pmu_driver->pmu_reg_write(0x005f, temp);
|
||||
} else {
|
||||
pr_err("no pmu_reg_read/write\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bl_extern_power_on(void)
|
||||
{
|
||||
#ifdef CONFIG_AMLOGIC_BOARD_HAS_PMU
|
||||
struct aml_pmu_driver *pmu_driver;
|
||||
unsigned char temp;
|
||||
#endif
|
||||
int ret = 0;
|
||||
|
||||
#ifdef CONFIG_AMLOGIC_BOARD_HAS_PMU
|
||||
pmu_driver = aml_pmu_get_driver();
|
||||
if (pmu_driver == NULL) {
|
||||
pr_err("no pmu driver\n");
|
||||
} else {
|
||||
if ((pmu_driver->pmu_reg_write) && (pmu_driver->pmu_reg_read)) {
|
||||
ret = pmu_driver->pmu_reg_read(0x005e, &temp);
|
||||
temp |= (1 << 7);
|
||||
ret = pmu_driver->pmu_reg_write(0x005e, temp);
|
||||
} else {
|
||||
pr_err("no pmu_reg_read/write\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (bl_ext_config->gpio_used > 0) {
|
||||
if (bl_ext_config->gpio_on == 2)
|
||||
bl_extern_gpio_input(bl_ext_config->gpio);
|
||||
else
|
||||
bl_extern_gpio_output(bl_ext_config->gpio,
|
||||
bl_ext_config->gpio_on);
|
||||
}
|
||||
pr_info("%s\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bl_extern_power_off(void)
|
||||
{
|
||||
#ifdef CONFIG_AMLOGIC_BOARD_HAS_PMU
|
||||
struct aml_pmu_driver *pmu_driver;
|
||||
unsigned char temp;
|
||||
#endif
|
||||
int ret = 0;
|
||||
|
||||
if (bl_ext_config->gpio_used > 0) {
|
||||
if (bl_ext_config->gpio_off == 2)
|
||||
bl_extern_gpio_input(bl_ext_config->gpio);
|
||||
else
|
||||
bl_extern_gpio_output(bl_ext_config->gpio,
|
||||
bl_ext_config->gpio_off);
|
||||
}
|
||||
#ifdef CONFIG_AMLOGIC_BOARD_HAS_PMU
|
||||
pmu_driver = aml_pmu_get_driver();
|
||||
if (pmu_driver == NULL) {
|
||||
pr_err("no pmu driver\n");
|
||||
} else {
|
||||
if ((pmu_driver->pmu_reg_write) && (pmu_driver->pmu_reg_read)) {
|
||||
ret = pmu_driver->pmu_reg_read(0x005e, &temp);
|
||||
temp &= ~(1 << 7);
|
||||
ret = pmu_driver->pmu_reg_write(0x005e, temp);
|
||||
} else {
|
||||
pr_err("no pmu_reg_read/write\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
pr_info("%s\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t bl_extern_debug(struct class *class,
|
||||
struct class_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
#ifdef CONFIG_AMLOGIC_BOARD_HAS_PMU
|
||||
struct aml_pmu_driver *pmu_driver;
|
||||
unsigned char temp;
|
||||
unsigned int t[2];
|
||||
#endif
|
||||
int ret = 0;
|
||||
|
||||
#ifdef CONFIG_AMLOGIC_BOARD_HAS_PMU
|
||||
pmu_driver = aml_pmu_get_driver();
|
||||
if (pmu_driver == NULL) {
|
||||
pr_err("no pmu driver\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (buf[0]) {
|
||||
case 'r':
|
||||
ret = sscanf(buf, "r %x", &t[0]);
|
||||
if ((pmu_driver->pmu_reg_write) && (pmu_driver->pmu_reg_read)) {
|
||||
ret = pmu_driver->pmu_reg_read(t[0], &temp);
|
||||
pr_info("read pmu reg: 0x%x=0x%x\n", t[0], temp);
|
||||
}
|
||||
break;
|
||||
case 'w':
|
||||
ret = sscanf(buf, "w %x %x", &t[0], &t[1]);
|
||||
if ((pmu_driver->pmu_reg_write) && (pmu_driver->pmu_reg_read)) {
|
||||
ret = pmu_driver->pmu_reg_write(t[0], t[1]);
|
||||
ret = pmu_driver->pmu_reg_read(t[0], &temp);
|
||||
pr_info("write pmu reg 0x%x: 0x%x, readback: 0x%x\n",
|
||||
t[0], t[1], temp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_err("wrong format of command.\n");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (ret != 1 || ret != 2)
|
||||
return -EINVAL;
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct class_attribute bl_extern_debug_class_attrs[] = {
|
||||
__ATTR(debug, 0644, NULL, bl_extern_debug),
|
||||
__ATTR_NULL
|
||||
};
|
||||
|
||||
static struct class bl_extern_debug_class = {
|
||||
.name = "bl_ext",
|
||||
.class_attrs = bl_extern_debug_class_attrs,
|
||||
};
|
||||
|
||||
static int get_bl_extern_config(struct device dev,
|
||||
struct bl_extern_config_t *bl_ext_cfg)
|
||||
{
|
||||
int ret = 0;
|
||||
struct aml_bl_extern_driver_t *bl_ext;
|
||||
|
||||
ret = get_bl_extern_dt_data(dev, bl_ext_cfg);
|
||||
if (ret) {
|
||||
pr_err("[error] %s: failed to get dt data\n", BL_EXTERN_NAME);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (bl_ext_cfg->dim_min > 0x1f)
|
||||
bl_ext_cfg->dim_min = 0x1f;
|
||||
if (bl_ext_cfg->dim_max > 0x1f)
|
||||
bl_ext_cfg->dim_max = 0x1f;
|
||||
|
||||
bl_ext = aml_bl_extern_get_driver();
|
||||
if (bl_ext) {
|
||||
bl_ext->type = bl_ext_cfg->type;
|
||||
bl_ext->name = bl_ext_cfg->name;
|
||||
bl_ext->power_on = bl_extern_power_on;
|
||||
bl_ext->power_off = bl_extern_power_off;
|
||||
bl_ext->set_level = bl_extern_set_level;
|
||||
} else {
|
||||
pr_err("[error] %s get bl_extern_driver failed\n",
|
||||
bl_ext_cfg->name);
|
||||
ret = -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aml_aml1218_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (bl_extern_driver_check())
|
||||
return -1;
|
||||
if (bl_ext_config == NULL)
|
||||
bl_ext_config = kzalloc(sizeof(*bl_ext_config), GFP_KERNEL);
|
||||
if (bl_ext_config == NULL) {
|
||||
pr_err("[error] %s probe: failed to alloc data\n",
|
||||
BL_EXTERN_NAME);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pdev->dev.platform_data = bl_ext_config;
|
||||
|
||||
ret = get_bl_extern_config(pdev->dev, bl_ext_config);
|
||||
if (ret)
|
||||
goto bl_extern_probe_failed;
|
||||
|
||||
ret = class_register(&bl_extern_debug_class);
|
||||
if (ret)
|
||||
pr_err("class register bl_extern_debug_class fail!\n");
|
||||
|
||||
pr_err("%s ok\n", __func__);
|
||||
return ret;
|
||||
|
||||
bl_extern_probe_failed:
|
||||
kfree(bl_ext_config);
|
||||
bl_ext_config = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int aml_aml1218_remove(struct platform_device *pdev)
|
||||
{
|
||||
kfree(pdev->dev.platform_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USE_OF
|
||||
static const struct of_device_id aml_aml1218_dt_match[] = {
|
||||
{
|
||||
.compatible = "amlogic, bl_pmu_aml1218",
|
||||
},
|
||||
{},
|
||||
};
|
||||
#else
|
||||
#define aml_aml1218_dt_match NULL
|
||||
#endif
|
||||
|
||||
static struct platform_driver aml_aml1218_driver = {
|
||||
.probe = aml_aml1218_probe,
|
||||
.remove = aml_aml1218_remove,
|
||||
.driver = {
|
||||
.name = BL_EXTERN_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
#ifdef CONFIG_USE_OF
|
||||
.of_match_table = aml_aml1218_dt_match,
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
static int __init aml_aml1218_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DBG_PRINT("%s\n", __func__);
|
||||
|
||||
ret = platform_driver_register(&aml_aml1218_driver);
|
||||
if (ret) {
|
||||
pr_err("[error] %s failed to register bl extern driver\n",
|
||||
__func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit aml_aml1218_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&aml_aml1218_driver);
|
||||
}
|
||||
|
||||
rootfs_initcall(aml_aml1218_init);
|
||||
module_exit(aml_aml1218_exit);
|
||||
|
||||
MODULE_AUTHOR("AMLOGIC");
|
||||
MODULE_DESCRIPTION("BL Extern driver for aml1218");
|
||||
MODULE_LICENSE("GPL");
|
||||
37
drivers/amlogic/media/vout/lcd/Kconfig
Normal file
37
drivers/amlogic/media/vout/lcd/Kconfig
Normal file
@@ -0,0 +1,37 @@
|
||||
#
|
||||
# Video output configuration
|
||||
#
|
||||
menu "Amlogic LCD Output Module"
|
||||
|
||||
config AMLOGIC_LCD
|
||||
bool "LCD Output Module"
|
||||
default n
|
||||
help
|
||||
LCD output module
|
||||
support tv mode and tablet mode
|
||||
Through the inside of the DTS file "mode" is
|
||||
to choose a TV mode or tablet mode
|
||||
|
||||
config AMLOGIC_LCD_TV
|
||||
bool "LCD TV Output Module"
|
||||
default n
|
||||
depends on AMLOGIC_LCD
|
||||
help
|
||||
LCD TV output module
|
||||
Configure the LCD output model for TV output
|
||||
TV mode mainly includes vbyone and an LVDS interface display
|
||||
Through the environment variable is to choose panel_type lcd_index
|
||||
|
||||
config AMLOGIC_LCD_TABLET
|
||||
bool "LCD Tablet Output Module"
|
||||
default n
|
||||
depends on AMLOGIC_LCD
|
||||
help
|
||||
LCD Tablet output module
|
||||
Configure the LCD output model for Tablet output
|
||||
|
||||
if AMLOGIC_LCD
|
||||
source "drivers/amlogic/media/vout/lcd/lcd_extern/Kconfig"
|
||||
endif
|
||||
|
||||
endmenu
|
||||
4
drivers/amlogic/media/vout/lcd/Makefile
Normal file
4
drivers/amlogic/media/vout/lcd/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
obj-$(CONFIG_AMLOGIC_LCD) += lcd_vout.o lcd_reg.o lcd_common.o lcd_notify.o lcd_debug.o lcd_clk_config.o lcd_unifykey.o
|
||||
obj-$(CONFIG_AMLOGIC_LCD_TV) += lcd_tv/
|
||||
obj-$(CONFIG_AMLOGIC_LCD_TABLET) += lcd_tablet/
|
||||
obj-$(CONFIG_AMLOGIC_LCD_EXTERN) += lcd_extern/
|
||||
1971
drivers/amlogic/media/vout/lcd/lcd_clk_config.c
Normal file
1971
drivers/amlogic/media/vout/lcd/lcd_clk_config.c
Normal file
File diff suppressed because it is too large
Load Diff
321
drivers/amlogic/media/vout/lcd/lcd_clk_config.h
Normal file
321
drivers/amlogic/media/vout/lcd/lcd_clk_config.h
Normal file
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_clk_config.h
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LCD_CLK_CONFIG_H
|
||||
#define _LCD_CLK_CONFIG_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_vout.h>
|
||||
|
||||
/* clk config */
|
||||
struct lcd_clk_config_s { /* unit: kHz */
|
||||
/* IN-OUT parameters */
|
||||
unsigned int fin;
|
||||
unsigned int fout;
|
||||
|
||||
/* pll parameters */
|
||||
unsigned int od_fb;
|
||||
unsigned int pll_m;
|
||||
unsigned int pll_n;
|
||||
unsigned int pll_fvco;
|
||||
unsigned int pll_od1_sel;
|
||||
unsigned int pll_od2_sel;
|
||||
unsigned int pll_od3_sel;
|
||||
unsigned int pll_level;
|
||||
unsigned int pll_frac;
|
||||
unsigned int pll_fout;
|
||||
unsigned int ss_level;
|
||||
unsigned int edp_div0;
|
||||
unsigned int edp_div1;
|
||||
unsigned int div_pre; /* m6, m8, m8b */
|
||||
unsigned int div_post; /* m6, m8, m8b */
|
||||
unsigned int div_sel; /* g9tv, g9bb, gxbb */
|
||||
unsigned int xd;
|
||||
|
||||
/* clk path node parameters */
|
||||
unsigned int ss_level_max;
|
||||
unsigned int pll_m_max;
|
||||
unsigned int pll_m_min;
|
||||
unsigned int pll_n_max;
|
||||
unsigned int pll_n_min;
|
||||
unsigned int pll_frac_range;
|
||||
unsigned int pll_od_sel_max;
|
||||
unsigned int div_pre_sel_max; /* m6, m8, m8b */
|
||||
unsigned int div_post_sel_max; /* m6, m8, m8b */
|
||||
unsigned int div_sel_max; /* g9tv, g9bb, gxbb */
|
||||
unsigned int xd_max;
|
||||
unsigned int pll_ref_fmax;
|
||||
unsigned int pll_ref_fmin;
|
||||
unsigned int pll_vco_fmax;
|
||||
unsigned int pll_vco_fmin;
|
||||
unsigned int pll_out_fmax;
|
||||
unsigned int pll_out_fmin;
|
||||
unsigned int div_post_out_fmax; /* m6, m8, m8b */
|
||||
unsigned int div_in_fmax; /* g9tv, g9bb, gxbb */
|
||||
unsigned int div_out_fmax; /* g9tv, g9bb, gxbb */
|
||||
unsigned int xd_out_fmax;
|
||||
unsigned int err_fmin;
|
||||
};
|
||||
|
||||
/* pll & clk parameter */
|
||||
/* ******** clk calculation ******** */
|
||||
#define PLL_WAIT_LOCK_CNT 200
|
||||
/* frequency unit: kHz */
|
||||
#define FIN_FREQ (24 * 1000)
|
||||
/* clk max error */
|
||||
#define MAX_ERROR (2 * 1000)
|
||||
|
||||
/* ******** register bit ******** */
|
||||
/* divider */
|
||||
#define CRT_VID_DIV_MAX 255
|
||||
|
||||
#define DIV_PRE_SEL_MAX 6
|
||||
#define EDP_DIV0_SEL_MAX 15
|
||||
#define EDP_DIV1_SEL_MAX 8
|
||||
|
||||
/* g9tv, g9bb, gxbb divider */
|
||||
#define CLK_DIV_I2O 0
|
||||
#define CLK_DIV_O2I 1
|
||||
enum div_sel_e {
|
||||
CLK_DIV_SEL_1 = 0,
|
||||
CLK_DIV_SEL_2, /* 1 */
|
||||
CLK_DIV_SEL_3, /* 2 */
|
||||
CLK_DIV_SEL_3p5, /* 3 */
|
||||
CLK_DIV_SEL_3p75, /* 4 */
|
||||
CLK_DIV_SEL_4, /* 5 */
|
||||
CLK_DIV_SEL_5, /* 6 */
|
||||
CLK_DIV_SEL_6, /* 7 */
|
||||
CLK_DIV_SEL_6p25, /* 8 */
|
||||
CLK_DIV_SEL_7, /* 9 */
|
||||
CLK_DIV_SEL_7p5, /* 10 */
|
||||
CLK_DIV_SEL_12, /* 11 */
|
||||
CLK_DIV_SEL_14, /* 12 */
|
||||
CLK_DIV_SEL_15, /* 13 */
|
||||
CLK_DIV_SEL_2p5, /* 14 */
|
||||
CLK_DIV_SEL_MAX,
|
||||
};
|
||||
|
||||
|
||||
/* GXTVBB */
|
||||
/* ******** register bit ******** */
|
||||
/* PLL_CNTL 0x10c8 */
|
||||
#define LCD_PLL_LOCK_GXTVBB 31
|
||||
#define LCD_PLL_EN_GXTVBB 30
|
||||
#define LCD_PLL_RST_GXTVBB 28
|
||||
#define LCD_PLL_N_GXTVBB 9
|
||||
#define LCD_PLL_M_GXTVBB 0
|
||||
|
||||
#define LCD_PLL_OD3_GXTVBB 18
|
||||
#define LCD_PLL_OD2_GXTVBB 22
|
||||
#define LCD_PLL_OD1_GXTVBB 16
|
||||
|
||||
/* ******** frequency limit (unit: kHz) ******** */
|
||||
/* pll */
|
||||
#define PLL_FRAC_OD_FB_GXTVBB 0
|
||||
#define SS_LEVEL_MAX_GXTVBB 5
|
||||
#define PLL_M_MIN_GXTVBB 2
|
||||
#define PLL_M_MAX_GXTVBB 511
|
||||
#define PLL_N_MIN_GXTVBB 1
|
||||
#define PLL_N_MAX_GXTVBB 1
|
||||
#define PLL_FRAC_RANGE_GXTVBB (1 << 10)
|
||||
#define PLL_OD_SEL_MAX_GXTVBB 3
|
||||
#define PLL_FREF_MIN_GXTVBB (5 * 1000)
|
||||
#define PLL_FREF_MAX_GXTVBB (25 * 1000)
|
||||
#define PLL_VCO_MIN_GXTVBB (3000 * 1000)
|
||||
#define PLL_VCO_MAX_GXTVBB (6000 * 1000)
|
||||
|
||||
/* video */
|
||||
#define CLK_DIV_IN_MAX_GXTVBB (3100 * 1000)
|
||||
#define CRT_VID_CLK_IN_MAX_GXTVBB (3100 * 1000)
|
||||
#define ENCL_CLK_IN_MAX_GXTVBB (620 * 1000)
|
||||
|
||||
/* GXL */
|
||||
/* ******** register bit ******** */
|
||||
/* PLL_CNTL 0x10c8 */
|
||||
#define LCD_PLL_LOCK_GXL 31
|
||||
#define LCD_PLL_EN_GXL 30
|
||||
#define LCD_PLL_RST_GXL 28
|
||||
#define LCD_PLL_N_GXL 9
|
||||
#define LCD_PLL_M_GXL 0
|
||||
|
||||
#define LCD_PLL_OD3_GXL 19
|
||||
#define LCD_PLL_OD2_GXL 23
|
||||
#define LCD_PLL_OD1_GXL 21
|
||||
|
||||
/* ******** frequency limit (unit: kHz) ******** */
|
||||
/* pll */
|
||||
#define PLL_FRAC_OD_FB_GXL 1
|
||||
#define SS_LEVEL_MAX_GXL 5
|
||||
#define PLL_M_MIN_GXL 2
|
||||
#define PLL_M_MAX_GXL 511
|
||||
#define PLL_N_MIN_GXL 1
|
||||
#define PLL_N_MAX_GXL 1
|
||||
#define PLL_FRAC_RANGE_GXL (1 << 10)
|
||||
#define PLL_OD_SEL_MAX_GXL 3
|
||||
#define PLL_FREF_MIN_GXL (5 * 1000)
|
||||
#define PLL_FREF_MAX_GXL (25 * 1000)
|
||||
#define PLL_VCO_MIN_GXL (3000 * 1000)
|
||||
#define PLL_VCO_MAX_GXL (6000 * 1000)
|
||||
|
||||
/* video */
|
||||
#define CLK_DIV_IN_MAX_GXL (3100 * 1000)
|
||||
#define CRT_VID_CLK_IN_MAX_GXL (3100 * 1000)
|
||||
#define ENCL_CLK_IN_MAX_GXL (620 * 1000)
|
||||
|
||||
/* GXM */
|
||||
/* ******** register bit ******** */
|
||||
/* PLL_CNTL 0x10c8 */
|
||||
#define LCD_PLL_LOCK_GXM 31
|
||||
#define LCD_PLL_EN_GXM 30
|
||||
#define LCD_PLL_RST_GXM 28
|
||||
#define LCD_PLL_N_GXM 9
|
||||
#define LCD_PLL_M_GXM 0
|
||||
|
||||
#define LCD_PLL_OD3_GXM 19
|
||||
#define LCD_PLL_OD2_GXM 23
|
||||
#define LCD_PLL_OD1_GXM 21
|
||||
|
||||
/* ******** frequency limit (unit: kHz) ******** */
|
||||
/* pll */
|
||||
#define PLL_FRAC_OD_FB_GXM 1
|
||||
#define SS_LEVEL_MAX_GXM 5
|
||||
#define PLL_M_MIN_GXM 2
|
||||
#define PLL_M_MAX_GXM 511
|
||||
#define PLL_N_MIN_GXM 1
|
||||
#define PLL_N_MAX_GXM 1
|
||||
#define PLL_FRAC_RANGE_GXM (1 << 10)
|
||||
#define PLL_OD_SEL_MAX_GXM 3
|
||||
#define PLL_FREF_MIN_GXM (5 * 1000)
|
||||
#define PLL_FREF_MAX_GXM (25 * 1000)
|
||||
#define PLL_VCO_MIN_GXM (3000 * 1000)
|
||||
#define PLL_VCO_MAX_GXM (6000 * 1000)
|
||||
|
||||
/* video */
|
||||
#define CLK_DIV_IN_MAX_GXM (3100 * 1000)
|
||||
#define CRT_VID_CLK_IN_MAX_GXM (3100 * 1000)
|
||||
#define ENCL_CLK_IN_MAX_GXM (620 * 1000)
|
||||
|
||||
/* TXL */
|
||||
/* ******** register bit ******** */
|
||||
/* PLL_CNTL 0x10c8 */
|
||||
#define LCD_PLL_LOCK_TXL 31
|
||||
#define LCD_PLL_EN_TXL 30
|
||||
#define LCD_PLL_RST_TXL 28
|
||||
#define LCD_PLL_N_TXL 9
|
||||
#define LCD_PLL_M_TXL 0
|
||||
|
||||
#define LCD_PLL_OD3_TXL 19
|
||||
#define LCD_PLL_OD2_TXL 23
|
||||
#define LCD_PLL_OD1_TXL 21
|
||||
|
||||
/* ******** frequency limit (unit: kHz) ******** */
|
||||
/* pll */
|
||||
#define PLL_FRAC_OD_FB_TXL 1
|
||||
#define SS_LEVEL_MAX_TXL 5
|
||||
#define PLL_M_MIN_TXL 2
|
||||
#define PLL_M_MAX_TXL 511
|
||||
#define PLL_N_MIN_TXL 1
|
||||
#define PLL_N_MAX_TXL 1
|
||||
#define PLL_FRAC_RANGE_TXL (1 << 10)
|
||||
#define PLL_OD_SEL_MAX_TXL 3
|
||||
#define PLL_FREF_MIN_TXL (5 * 1000)
|
||||
#define PLL_FREF_MAX_TXL (25 * 1000)
|
||||
#define PLL_VCO_MIN_TXL (3000 * 1000)
|
||||
#define PLL_VCO_MAX_TXL (6000 * 1000)
|
||||
|
||||
/* video */
|
||||
#define CLK_DIV_IN_MAX_TXL (3100 * 1000)
|
||||
#define CRT_VID_CLK_IN_MAX_TXL (3100 * 1000)
|
||||
#define ENCL_CLK_IN_MAX_TXL (620 * 1000)
|
||||
|
||||
/* TXLX */
|
||||
/* ******** register bit ******** */
|
||||
/* PLL_CNTL 0x10c8 */
|
||||
#define LCD_PLL_LOCK_TXLX 31
|
||||
#define LCD_PLL_EN_TXLX 30
|
||||
#define LCD_PLL_RST_TXLX 28
|
||||
#define LCD_PLL_N_TXLX 9
|
||||
#define LCD_PLL_M_TXLX 0
|
||||
|
||||
#define LCD_PLL_OD3_TXLX 19
|
||||
#define LCD_PLL_OD2_TXLX 23
|
||||
#define LCD_PLL_OD1_TXLX 21
|
||||
|
||||
/* ******** frequency limit (unit: kHz) ******** */
|
||||
/* pll */
|
||||
#define PLL_FRAC_OD_FB_TXLX 0
|
||||
#define SS_LEVEL_MAX_TXLX 6
|
||||
#define PLL_M_MIN_TXLX 2
|
||||
#define PLL_M_MAX_TXLX 511
|
||||
#define PLL_N_MIN_TXLX 1
|
||||
#define PLL_N_MAX_TXLX 1
|
||||
#define PLL_FRAC_RANGE_TXLX (1 << 10)
|
||||
#define PLL_OD_SEL_MAX_TXLX 3
|
||||
#define PLL_FREF_MIN_TXLX (5 * 1000)
|
||||
#define PLL_FREF_MAX_TXLX (25 * 1000)
|
||||
#define PLL_VCO_MIN_TXLX (3000 * 1000)
|
||||
#define PLL_VCO_MAX_TXLX (6000 * 1000)
|
||||
|
||||
/* video */
|
||||
#define CLK_DIV_IN_MAX_TXLX (3100 * 1000)
|
||||
#define CRT_VID_CLK_IN_MAX_TXLX (3100 * 1000)
|
||||
#define ENCL_CLK_IN_MAX_TXLX (620 * 1000)
|
||||
|
||||
/* AXG */
|
||||
/* ******** register bit ******** */
|
||||
/* PLL_CNTL */
|
||||
#define LCD_PLL_LOCK_AXG 31
|
||||
#define LCD_PLL_EN_AXG 30
|
||||
#define LCD_PLL_RST_AXG 29
|
||||
#define LCD_PLL_OD_AXG 16
|
||||
#define LCD_PLL_N_AXG 9
|
||||
#define LCD_PLL_M_AXG 0
|
||||
|
||||
/* ******** frequency limit (unit: kHz) ******** */
|
||||
/* pll */
|
||||
#define PLL_FRAC_OD_FB_AXG 0
|
||||
#define SS_LEVEL_MAX_AXG 5
|
||||
#define PLL_M_MIN_AXG 2
|
||||
#define PLL_M_MAX_AXG 511
|
||||
#define PLL_N_MIN_AXG 1
|
||||
#define PLL_N_MAX_AXG 1
|
||||
#define PLL_FRAC_RANGE_AXG (1 << 10)
|
||||
#define PLL_OD_SEL_MAX_AXG 3
|
||||
#define PLL_FREF_MIN_AXG (5 * 1000)
|
||||
#define PLL_FREF_MAX_AXG (25 * 1000)
|
||||
#define PLL_VCO_MIN_AXG (1500 * 1000)
|
||||
#define PLL_VCO_MAX_AXG (3000 * 1000)
|
||||
|
||||
/* video */
|
||||
#define CRT_VID_CLK_IN_MAX_AXG (3000 * 1000)
|
||||
#define ENCL_CLK_IN_MAX_AXG (200 * 1000)
|
||||
|
||||
|
||||
extern int meson_clk_measure(unsigned int clk_mux);
|
||||
extern struct lcd_clk_config_s *get_lcd_clk_config(void);
|
||||
extern void lcd_clk_config_print(void);
|
||||
extern int lcd_encl_clk_msr(void);
|
||||
extern void lcd_pll_reset(void);
|
||||
extern char *lcd_get_spread_spectrum(void);
|
||||
extern void lcd_set_spread_spectrum(void);
|
||||
extern void lcd_clk_update(struct lcd_config_s *pconf);
|
||||
extern void lcd_clk_set(struct lcd_config_s *pconf);
|
||||
extern void lcd_clk_disable(void);
|
||||
extern void lcd_clk_generate_parameter(struct lcd_config_s *pconf);
|
||||
extern void lcd_clk_config_probe(void);
|
||||
|
||||
#endif
|
||||
1007
drivers/amlogic/media/vout/lcd/lcd_common.c
Normal file
1007
drivers/amlogic/media/vout/lcd/lcd_common.c
Normal file
File diff suppressed because it is too large
Load Diff
78
drivers/amlogic/media/vout/lcd/lcd_common.h
Normal file
78
drivers/amlogic/media/vout/lcd/lcd_common.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_common.h
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __AML_LCD_COMMON_H__
|
||||
#define __AML_LCD_COMMON_H__
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_vout.h>
|
||||
#include "lcd_clk_config.h"
|
||||
|
||||
/* 20170505: add a113 support to linux4.9 */
|
||||
#define LCD_DRV_VERSION "20170505"
|
||||
|
||||
#define VPP_OUT_SATURATE (1 << 0)
|
||||
|
||||
extern struct mutex lcd_power_mutex;
|
||||
extern struct mutex lcd_vout_mutex;
|
||||
extern unsigned char lcd_resume_flag;
|
||||
extern int lcd_vout_serve_bypass;
|
||||
|
||||
/* lcd common */
|
||||
extern int lcd_type_str_to_type(const char *str);
|
||||
extern char *lcd_type_type_to_str(int type);
|
||||
extern unsigned char lcd_mode_str_to_mode(const char *str);
|
||||
extern char *lcd_mode_mode_to_str(int mode);
|
||||
|
||||
extern void lcd_cpu_gpio_register(unsigned int index);
|
||||
extern void lcd_cpu_gpio_set(unsigned int index, int value);
|
||||
extern unsigned int lcd_cpu_gpio_get(unsigned int index);
|
||||
extern void lcd_ttl_pinmux_set(int status);
|
||||
extern void lcd_vbyone_pinmux_set(int status);
|
||||
extern unsigned int lcd_lvds_channel_on_value(struct lcd_config_s *pconf);
|
||||
extern int lcd_power_load_from_dts(struct lcd_config_s *pconf,
|
||||
struct device_node *child);
|
||||
extern int lcd_power_load_from_unifykey(struct lcd_config_s *pconf,
|
||||
unsigned char *buf, int key_len, int len);
|
||||
|
||||
extern void lcd_hdr_vinfo_update(void);
|
||||
extern void lcd_tcon_config(struct lcd_config_s *pconf);
|
||||
extern int lcd_vmode_change(struct lcd_config_s *pconf);
|
||||
extern void lcd_venc_change(struct lcd_config_s *pconf);
|
||||
extern void lcd_clk_gate_switch(int status);
|
||||
extern void lcd_clktree_probe(void);
|
||||
|
||||
/* lcd debug */
|
||||
extern int lcd_class_creat(void);
|
||||
extern int lcd_class_remove(void);
|
||||
|
||||
/* lcd driver */
|
||||
#ifdef CONFIG_AMLOGIC_LCD_TV
|
||||
extern void lcd_vbyone_interrupt_enable(int flag);
|
||||
extern void lcd_tv_clk_update(struct lcd_config_s *pconf);
|
||||
extern void lcd_tv_vout_server_init(void);
|
||||
extern int lcd_tv_probe(struct device *dev);
|
||||
extern int lcd_tv_remove(struct device *dev);
|
||||
#endif
|
||||
#ifdef CONFIG_AMLOGIC_LCD_TABLET
|
||||
extern void lcd_tablet_clk_update(struct lcd_config_s *pconf);
|
||||
extern void lcd_tablet_vout_server_init(void);
|
||||
extern int lcd_tablet_probe(struct device *dev);
|
||||
extern int lcd_tablet_remove(struct device *dev);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
2067
drivers/amlogic/media/vout/lcd/lcd_debug.c
Normal file
2067
drivers/amlogic/media/vout/lcd/lcd_debug.c
Normal file
File diff suppressed because it is too large
Load Diff
77
drivers/amlogic/media/vout/lcd/lcd_extern/Kconfig
Normal file
77
drivers/amlogic/media/vout/lcd/lcd_extern/Kconfig
Normal file
@@ -0,0 +1,77 @@
|
||||
|
||||
menuconfig AMLOGIC_LCD_EXTERN
|
||||
bool "LCD external driver support"
|
||||
default n
|
||||
help
|
||||
Amlogic LCD external driver support, such as i2c initial
|
||||
|
||||
config AMLOGIC_LCD_EXTERN_I2C_T5800Q
|
||||
bool "lcd external i2c T5800Q init driver"
|
||||
default n
|
||||
depends on AMLOGIC_LCD_EXTERN
|
||||
help
|
||||
Amlogic LCD external i2c_T5800Q init driver support
|
||||
Once the power on, according to the timing requirements,
|
||||
through the i2c interface to write data to the LCD,
|
||||
make its initialization
|
||||
|
||||
config AMLOGIC_LCD_EXTERN_I2C_DLPC3439
|
||||
bool "lcd external i2c DLPC3439 init driver"
|
||||
default n
|
||||
depends on AMLOGIC_LCD_EXTERN
|
||||
help
|
||||
Amlogic LCD external i2c_DLPC3439 init driver support
|
||||
Once the power on, according to the timing requirements,
|
||||
through the i2c interface to write data to the LCD,
|
||||
make its initialization
|
||||
|
||||
config AMLOGIC_LCD_EXTERN_I2C_ANX6345
|
||||
bool "lcd external i2c ANX6345 init driver"
|
||||
default n
|
||||
depends on AMLOGIC_LCD_EXTERN
|
||||
help
|
||||
Amlogic LCD external i2c_ANX6345 init driver support
|
||||
Once the power on, according to the timing requirements,
|
||||
through the i2c interface to write data to the LCD,
|
||||
make its initialization
|
||||
|
||||
config AMLOGIC_LCD_EXTERN_I2C_TC101
|
||||
bool "lcd external i2c TC101 init driver"
|
||||
default n
|
||||
depends on AMLOGIC_LCD_EXTERN
|
||||
help
|
||||
Amlogic LCD external i2c_TC101 init driver support
|
||||
Once the power on, according to the timing requirements,
|
||||
through the i2c interface to write data to the LCD,
|
||||
make its initialization
|
||||
|
||||
config AMLOGIC_LCD_EXTERN_SPI_LD070WS2
|
||||
bool "lcd external spi LD070WS2 init driver"
|
||||
default n
|
||||
depends on AMLOGIC_LCD_EXTERN
|
||||
help
|
||||
Amlogic LCD external spi_LD070WS2 init driver support
|
||||
Once the power on, according to the timing requirements,
|
||||
through the spi interface to write data to the LCD,
|
||||
make its initialization
|
||||
|
||||
config AMLOGIC_LCD_EXTERN_MIPI_KD080D13
|
||||
bool "lcd external mipi KD080D13 init driver"
|
||||
default n
|
||||
depends on AMLOGIC_LCD_EXTERN
|
||||
help
|
||||
Amlogic LCD external mipi_KD080D13 init driver support
|
||||
Once the power on, according to the timing requirements,
|
||||
through the mipi interface to write data to the LCD,
|
||||
make its initialization
|
||||
|
||||
config AMLOGIC_LCD_EXTERN_MIPI_N070ICN
|
||||
bool "lcd external mipi N070ICN init driver"
|
||||
default n
|
||||
depends on AMLOGIC_LCD_EXTERN
|
||||
help
|
||||
Amlogic LCD external mipi_N070ICN init driver support
|
||||
Once the power on, according to the timing requirements,
|
||||
through the mipi interface to write data to the LCD,
|
||||
make its initialization
|
||||
|
||||
6
drivers/amlogic/media/vout/lcd/lcd_extern/Makefile
Normal file
6
drivers/amlogic/media/vout/lcd/lcd_extern/Makefile
Normal file
@@ -0,0 +1,6 @@
|
||||
obj-$(CONFIG_AMLOGIC_LCD_EXTERN) += lcd_extern.o ext_default.o
|
||||
obj-$(CONFIG_AMLOGIC_LCD_EXTERN_I2C_T5800Q) += i2c_T5800Q.o
|
||||
obj-$(CONFIG_AMLOGIC_LCD_EXTERN_SPI_LD070WS2) += spi_LD070WS2.o
|
||||
obj-$(CONFIG_AMLOGIC_LCD_EXTERN_I2C_DLPC3439) += i2c_DLPC3439.o
|
||||
obj-$(CONFIG_AMLOGIC_LCD_EXTERN_MIPI_KD080D13) += mipi_KD080D13.o
|
||||
|
||||
453
drivers/amlogic/media/vout/lcd/lcd_extern/ext_default.c
Normal file
453
drivers/amlogic/media/vout/lcd/lcd_extern/ext_default.c
Normal file
@@ -0,0 +1,453 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_extern/ext_default.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/amlogic/i2c-amlogic.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_extern.h>
|
||||
#include "lcd_extern.h"
|
||||
|
||||
#define LCD_EXTERN_INDEX 0
|
||||
#define LCD_EXTERN_NAME "ext_default"
|
||||
|
||||
#define LCD_EXTERN_TYPE LCD_EXTERN_I2C
|
||||
|
||||
#define LCD_EXTERN_I2C_ADDR (0x1c) /* 7bit address */
|
||||
#define LCD_EXTERN_I2C_ADDR2 (0xff) /* 7bit address */
|
||||
#define LCD_EXTERN_I2C_BUS AML_I2C_MASTER_A
|
||||
|
||||
#define SPI_GPIO_CS 0 /* index */
|
||||
#define SPI_GPIO_CLK 1 /* index */
|
||||
#define SPI_GPIO_DATA 2 /* index */
|
||||
#define SPI_CLK_FREQ 10000 /* Hz */
|
||||
#define SPI_CLK_POL 1
|
||||
|
||||
static struct i2c_client *aml_default_i2c_client;
|
||||
static struct i2c_client *aml_default_i2c2_client;
|
||||
static struct lcd_extern_config_s *ext_config;
|
||||
|
||||
#define LCD_EXTERN_CMD_SIZE 9
|
||||
static unsigned char init_on_table[] = {
|
||||
0x00, 0x20, 0x01, 0x02, 0x00, 0x40, 0xFF, 0x00, 0x00,
|
||||
0x00, 0x80, 0x02, 0x00, 0x40, 0x62, 0x51, 0x73, 0x00,
|
||||
0x00, 0x61, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xC1, 0x05, 0x0F, 0x00, 0x08, 0x70, 0x00, 0x00,
|
||||
0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x3D, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xED, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x23, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, /* delay 10ms */
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ending */
|
||||
};
|
||||
|
||||
static unsigned char init_off_table[] = {
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ending */
|
||||
};
|
||||
|
||||
static int lcd_extern_i2c_write(struct i2c_client *i2client,
|
||||
unsigned char *buff, unsigned int len)
|
||||
{
|
||||
int ret = 0;
|
||||
struct i2c_msg msg[] = {
|
||||
{
|
||||
.addr = i2client->addr,
|
||||
.flags = 0,
|
||||
.len = len,
|
||||
.buf = buff,
|
||||
}
|
||||
};
|
||||
|
||||
ret = i2c_transfer(i2client->adapter, msg, 1);
|
||||
if (ret < 0)
|
||||
EXTERR("i2c write failed [addr 0x%02x]\n", i2client->addr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_reg_read(unsigned char reg, unsigned char *buf)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_reg_write(unsigned char reg, unsigned char value)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_spi_write(unsigned char *buf, int len)
|
||||
{
|
||||
EXTPR("to do\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lcd_extern_power_cmd(unsigned char *init_table)
|
||||
{
|
||||
int i = 0, len;
|
||||
int ret = 0;
|
||||
|
||||
len = ext_config->cmd_size;
|
||||
if (len < 1) {
|
||||
EXTERR("%s: cmd_size %d is invalid\n", __func__, len);
|
||||
return -1;
|
||||
}
|
||||
if (len == LCD_EXTERN_DYNAMIC_LEN) {
|
||||
switch (ext_config->type) {
|
||||
case LCD_EXTERN_I2C:
|
||||
while (i <= LCD_EXTERN_INIT_TABLE_MAX) {
|
||||
if (init_table[i] == LCD_EXTERN_INIT_END) {
|
||||
break;
|
||||
} else if (init_table[i] ==
|
||||
LCD_EXTERN_INIT_NONE) {
|
||||
/* do nothing, only for delay */
|
||||
if (init_table[i+1] > 0)
|
||||
mdelay(init_table[i+1]);
|
||||
i += 2;
|
||||
} else if (init_table[i] ==
|
||||
LCD_EXTERN_INIT_GPIO) {
|
||||
if (init_table[i+1] < LCD_GPIO_MAX) {
|
||||
lcd_extern_gpio_set(
|
||||
init_table[i+1],
|
||||
init_table[i+2]);
|
||||
}
|
||||
if (init_table[i+3] > 0)
|
||||
mdelay(init_table[i+3]);
|
||||
i += 4;
|
||||
} else if (init_table[i] ==
|
||||
LCD_EXTERN_INIT_CMD) {
|
||||
ret = lcd_extern_i2c_write(
|
||||
aml_default_i2c_client,
|
||||
&init_table[i+2],
|
||||
init_table[i+1]-1);
|
||||
if (init_table[i+init_table[i+1]+1] > 0)
|
||||
mdelay(init_table[i+
|
||||
init_table[i+1]+1]);
|
||||
i += (init_table[i+1] + 2);
|
||||
} else if (init_table[i] ==
|
||||
LCD_EXTERN_INIT_CMD2) {
|
||||
ret = lcd_extern_i2c_write(
|
||||
aml_default_i2c2_client,
|
||||
&init_table[i+2],
|
||||
init_table[i+1]-1);
|
||||
if (init_table[i+init_table[i+1]+1] > 0)
|
||||
mdelay(init_table[i+
|
||||
init_table[i+1]+1]);
|
||||
i += (init_table[i+1] + 2);
|
||||
} else {
|
||||
EXTERR("%s(%d: %s): type %d invalid\n",
|
||||
__func__, ext_config->index,
|
||||
ext_config->name,
|
||||
ext_config->type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LCD_EXTERN_SPI:
|
||||
while (i <= LCD_EXTERN_INIT_TABLE_MAX) {
|
||||
if (init_table[i] == LCD_EXTERN_INIT_END) {
|
||||
break;
|
||||
} else if (init_table[i] ==
|
||||
LCD_EXTERN_INIT_NONE) {
|
||||
/* do nothing, only for delay */
|
||||
if (init_table[i+1] > 0)
|
||||
mdelay(init_table[i+1]);
|
||||
i += 2;
|
||||
} else if (init_table[i] ==
|
||||
LCD_EXTERN_INIT_GPIO) {
|
||||
if (init_table[i+1] < LCD_GPIO_MAX) {
|
||||
lcd_extern_gpio_set(
|
||||
init_table[i+1],
|
||||
init_table[i+2]);
|
||||
}
|
||||
if (init_table[i+3] > 0)
|
||||
mdelay(init_table[i+3]);
|
||||
i += 4;
|
||||
} else if (init_table[i] ==
|
||||
LCD_EXTERN_INIT_CMD) {
|
||||
ret = lcd_extern_spi_write(
|
||||
&init_table[i+2],
|
||||
init_table[i+1]-1);
|
||||
if (init_table[i+init_table[i+1]+1] > 0)
|
||||
mdelay(init_table[i+
|
||||
init_table[i+1]+1]);
|
||||
i += (init_table[i+1] + 2);
|
||||
} else {
|
||||
EXTERR("%s(%d: %s): type %d invalid\n",
|
||||
__func__, ext_config->index,
|
||||
ext_config->name,
|
||||
ext_config->type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
EXTERR("%s(%d: %s): extern_type %d is not support\n",
|
||||
__func__, ext_config->index,
|
||||
ext_config->name, ext_config->type);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (ext_config->type) {
|
||||
case LCD_EXTERN_I2C:
|
||||
while (i <= LCD_EXTERN_INIT_TABLE_MAX) {
|
||||
if (init_table[i] == LCD_EXTERN_INIT_END) {
|
||||
break;
|
||||
} else if (init_table[i] ==
|
||||
LCD_EXTERN_INIT_NONE) {
|
||||
/* do nothing, only for delay */
|
||||
} else if (init_table[i] ==
|
||||
LCD_EXTERN_INIT_GPIO) {
|
||||
if (init_table[i+1] < LCD_GPIO_MAX) {
|
||||
lcd_extern_gpio_set(
|
||||
init_table[i+1],
|
||||
init_table[i+2]);
|
||||
}
|
||||
} else if (init_table[i] ==
|
||||
LCD_EXTERN_INIT_CMD) {
|
||||
ret = lcd_extern_i2c_write(
|
||||
aml_default_i2c_client,
|
||||
&init_table[i+1], (len-2));
|
||||
} else if (init_table[i] ==
|
||||
LCD_EXTERN_INIT_CMD2) {
|
||||
ret = lcd_extern_i2c_write(
|
||||
aml_default_i2c2_client,
|
||||
&init_table[i+1], (len-2));
|
||||
} else {
|
||||
EXTERR("%s(%d: %s): type %d invalid\n",
|
||||
__func__, ext_config->index,
|
||||
ext_config->name,
|
||||
ext_config->type);
|
||||
}
|
||||
if (init_table[i+len-1] > 0)
|
||||
mdelay(init_table[i+len-1]);
|
||||
i += len;
|
||||
}
|
||||
break;
|
||||
case LCD_EXTERN_SPI:
|
||||
while (i <= LCD_EXTERN_INIT_TABLE_MAX) {
|
||||
if (init_table[i] == LCD_EXTERN_INIT_END) {
|
||||
break;
|
||||
} else if (init_table[i] ==
|
||||
LCD_EXTERN_INIT_NONE) {
|
||||
/* do nothing, only for delay */
|
||||
} else if (init_table[i] ==
|
||||
LCD_EXTERN_INIT_GPIO) {
|
||||
if (init_table[i+1] < LCD_GPIO_MAX) {
|
||||
lcd_extern_gpio_set(
|
||||
init_table[i+1],
|
||||
init_table[i+2]);
|
||||
}
|
||||
} else if (init_table[i] ==
|
||||
LCD_EXTERN_INIT_CMD) {
|
||||
ret = lcd_extern_spi_write(
|
||||
&init_table[i+1], (len-1));
|
||||
} else {
|
||||
EXTERR("%s(%d: %s): type %d invalid\n",
|
||||
__func__, ext_config->index,
|
||||
ext_config->name,
|
||||
ext_config->type);
|
||||
}
|
||||
if (init_table[i+len-1] > 0)
|
||||
mdelay(init_table[i+len-1]);
|
||||
i += len;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
EXTERR("%s(%d: %s): extern_type %d is not support\n",
|
||||
__func__, ext_config->index,
|
||||
ext_config->name, ext_config->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_power_ctrl(int flag)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (flag)
|
||||
ret = lcd_extern_power_cmd(ext_config->table_init_on);
|
||||
else
|
||||
ret = lcd_extern_power_cmd(ext_config->table_init_off);
|
||||
|
||||
EXTPR("%s(%d: %s): %d\n",
|
||||
__func__, ext_config->index, ext_config->name, flag);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_power_on(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = lcd_extern_power_ctrl(1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_power_off(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = lcd_extern_power_ctrl(0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
|
||||
{
|
||||
if (ext_drv == NULL) {
|
||||
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ext_drv->config.type == LCD_EXTERN_MAX) { /* default for no dts */
|
||||
ext_drv->config.index = LCD_EXTERN_INDEX;
|
||||
ext_drv->config.type = LCD_EXTERN_TYPE;
|
||||
strcpy(ext_drv->config.name, LCD_EXTERN_NAME);
|
||||
ext_drv->config.cmd_size = LCD_EXTERN_CMD_SIZE;
|
||||
switch (ext_drv->config.type) {
|
||||
case LCD_EXTERN_I2C:
|
||||
ext_drv->config.i2c_addr = LCD_EXTERN_I2C_ADDR;
|
||||
ext_drv->config.i2c_addr2 = LCD_EXTERN_I2C_ADDR2;
|
||||
ext_drv->config.i2c_bus = LCD_EXTERN_I2C_BUS;
|
||||
break;
|
||||
case LCD_EXTERN_SPI:
|
||||
ext_drv->config.spi_gpio_cs = SPI_GPIO_CS;
|
||||
ext_drv->config.spi_gpio_clk = SPI_GPIO_CLK;
|
||||
ext_drv->config.spi_gpio_data = SPI_GPIO_DATA;
|
||||
ext_drv->config.spi_clk_freq = SPI_CLK_FREQ;
|
||||
ext_drv->config.spi_clk_pol = SPI_CLK_POL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ext_drv->config.table_init_loaded == 0) {
|
||||
ext_drv->config.table_init_on = init_on_table;
|
||||
ext_drv->config.table_init_off = init_off_table;
|
||||
}
|
||||
ext_drv->reg_read = lcd_extern_reg_read;
|
||||
ext_drv->reg_write = lcd_extern_reg_write;
|
||||
ext_drv->power_on = lcd_extern_power_on;
|
||||
ext_drv->power_off = lcd_extern_power_off;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aml_default_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
|
||||
EXTERR("%s: functionality check failed\n", __func__);
|
||||
else
|
||||
aml_default_i2c_client = client;
|
||||
|
||||
EXTPR("%s OK\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aml_default_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id aml_default_i2c_id[] = {
|
||||
{LCD_EXTERN_NAME, 0},
|
||||
{ }
|
||||
};
|
||||
/* MODULE_DEVICE_TABLE(i2c, aml_T5800Q_id); */
|
||||
|
||||
static struct i2c_driver aml_default_i2c_driver = {
|
||||
.probe = aml_default_i2c_probe,
|
||||
.remove = aml_default_i2c_remove,
|
||||
.id_table = aml_default_i2c_id,
|
||||
.driver = {
|
||||
.name = LCD_EXTERN_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
int aml_lcd_extern_default_probe(struct aml_lcd_extern_driver_s *ext_drv)
|
||||
{
|
||||
struct i2c_board_info i2c_info;
|
||||
struct i2c_adapter *adapter;
|
||||
struct i2c_client *i2c_client;
|
||||
int ret = 0;
|
||||
|
||||
ext_config = &ext_drv->config;
|
||||
|
||||
switch (ext_drv->config.type) {
|
||||
case LCD_EXTERN_I2C:
|
||||
aml_default_i2c_client = NULL;
|
||||
aml_default_i2c2_client = NULL;
|
||||
memset(&i2c_info, 0, sizeof(i2c_info));
|
||||
adapter = i2c_get_adapter(ext_drv->config.i2c_bus);
|
||||
if (!adapter) {
|
||||
EXTERR("%s failed to get i2c adapter\n",
|
||||
ext_drv->config.name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(i2c_info.type, ext_drv->config.name, I2C_NAME_SIZE);
|
||||
i2c_info.addr = ext_drv->config.i2c_addr;
|
||||
i2c_info.platform_data = &ext_drv->config;
|
||||
i2c_info.flags = 0;
|
||||
if (i2c_info.addr > 0x7f) {
|
||||
EXTERR("%s invalid i2c address: 0x%02x\n",
|
||||
ext_drv->config.name, ext_drv->config.i2c_addr);
|
||||
return -1;
|
||||
}
|
||||
i2c_client = i2c_new_device(adapter, &i2c_info);
|
||||
if (!i2c_client) {
|
||||
EXTERR("%s failed to new i2c device\n",
|
||||
ext_drv->config.name);
|
||||
} else {
|
||||
if (lcd_debug_print_flag) {
|
||||
EXTPR("%s new i2c device succeed\n",
|
||||
ext_drv->config.name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!aml_default_i2c_client) {
|
||||
ret = i2c_add_driver(&aml_default_i2c_driver);
|
||||
if (ret) {
|
||||
EXTERR("%s add i2c_driver failed\n",
|
||||
ext_drv->config.name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LCD_EXTERN_SPI:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ret = lcd_extern_driver_update(ext_drv);
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
EXTPR("%s: %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
198
drivers/amlogic/media/vout/lcd/lcd_extern/i2c_DLPC3439.c
Normal file
198
drivers/amlogic/media/vout/lcd/lcd_extern/i2c_DLPC3439.c
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_extern/i2c_DLPC3439.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/amlogic/i2c-amlogic.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_extern.h>
|
||||
#include "lcd_extern.h"
|
||||
|
||||
#define LCD_EXTERN_NAME "i2c_DLPC3439"
|
||||
|
||||
static struct i2c_client *aml_DLPC3439_i2c_client;
|
||||
static struct lcd_extern_config_s *ext_config;
|
||||
|
||||
|
||||
/* Write: ImageCrop: 1920x1080
|
||||
* W 36 10 00 00 00 00 80 07 38 04
|
||||
*/
|
||||
static unsigned char data_1[] = {0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x07, 0x38, 0x04};
|
||||
/* Write: DisplaySize: 1920x1080
|
||||
* W 36 12 80 07 38 04
|
||||
*/
|
||||
static unsigned char data_2[] = {0x12, 0x80, 0x07, 0x38, 0x04};
|
||||
/* Write: InputImageSize: 1920x1080
|
||||
* W 36 2e 80 07 38 04
|
||||
*/
|
||||
static unsigned char data_3[] = {0x2e, 0x80, 0x07, 0x38, 0x04};
|
||||
/* Write: InputSourceSelect; 0 = External Video Port
|
||||
* W 36 05 00
|
||||
*/
|
||||
static unsigned char data_4[] = {0x05, 0x00};
|
||||
/* Write: VideoSourceFormatSelect: 0x43=RGB888
|
||||
* W 36 07 43
|
||||
*/
|
||||
static unsigned char data_5[] = {0x07, 0x43};
|
||||
|
||||
static int lcd_extern_i2c_write(struct i2c_client *i2client,
|
||||
unsigned char *buff, unsigned int len)
|
||||
{
|
||||
int ret = 0;
|
||||
struct i2c_msg msg[] = {
|
||||
{
|
||||
.addr = i2client->addr,
|
||||
.flags = 0,
|
||||
.len = len,
|
||||
.buf = buff,
|
||||
}
|
||||
};
|
||||
|
||||
ret = i2c_transfer(i2client->adapter, msg, 1);
|
||||
if (ret < 0)
|
||||
EXTERR("i2c write failed [addr 0x%02x]\n", i2client->addr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_power_on(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
lcd_extern_i2c_write(aml_DLPC3439_i2c_client, data_1, 9);
|
||||
lcd_extern_i2c_write(aml_DLPC3439_i2c_client, data_2, 5);
|
||||
lcd_extern_i2c_write(aml_DLPC3439_i2c_client, data_3, 5);
|
||||
lcd_extern_i2c_write(aml_DLPC3439_i2c_client, data_4, 2);
|
||||
lcd_extern_i2c_write(aml_DLPC3439_i2c_client, data_5, 2);
|
||||
|
||||
EXTPR("%s\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_power_off(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (ext_drv) {
|
||||
ext_drv->power_on = lcd_extern_power_on;
|
||||
ext_drv->power_off = lcd_extern_power_off;
|
||||
} else {
|
||||
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aml_DLPC3439_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
|
||||
EXTERR("%s: functionality check failed\n", __func__);
|
||||
else
|
||||
aml_DLPC3439_i2c_client = client;
|
||||
|
||||
EXTPR("%s OK\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aml_DLPC3439_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id aml_DLPC3439_i2c_id[] = {
|
||||
{LCD_EXTERN_NAME, 0},
|
||||
{ }
|
||||
};
|
||||
/* MODULE_DEVICE_TABLE(i2c, aml_DLPC3439_id); */
|
||||
|
||||
static struct i2c_driver aml_DLPC3439_i2c_driver = {
|
||||
.probe = aml_DLPC3439_i2c_probe,
|
||||
.remove = aml_DLPC3439_i2c_remove,
|
||||
.id_table = aml_DLPC3439_i2c_id,
|
||||
.driver = {
|
||||
.name = LCD_EXTERN_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
int aml_lcd_extern_i2c_DLPC3439_probe(struct aml_lcd_extern_driver_s *ext_drv)
|
||||
{
|
||||
struct i2c_board_info i2c_info;
|
||||
struct i2c_adapter *adapter;
|
||||
struct i2c_client *i2c_client;
|
||||
int ret = 0;
|
||||
|
||||
ext_config = &ext_drv->config;
|
||||
memset(&i2c_info, 0, sizeof(i2c_info));
|
||||
|
||||
adapter = i2c_get_adapter(ext_drv->config.i2c_bus);
|
||||
if (!adapter) {
|
||||
EXTERR("%s failed to get i2c adapter\n", ext_drv->config.name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(i2c_info.type, ext_drv->config.name, I2C_NAME_SIZE);
|
||||
i2c_info.addr = ext_drv->config.i2c_addr;
|
||||
i2c_info.platform_data = &ext_drv->config;
|
||||
i2c_info.flags = 0;
|
||||
if (i2c_info.addr > 0x7f) {
|
||||
EXTERR("%s invalid i2c address: 0x%02x\n",
|
||||
ext_drv->config.name, ext_drv->config.i2c_addr);
|
||||
return -1;
|
||||
}
|
||||
i2c_client = i2c_new_device(adapter, &i2c_info);
|
||||
if (!i2c_client) {
|
||||
EXTERR("%s failed to new i2c device\n", ext_drv->config.name);
|
||||
} else {
|
||||
if (lcd_debug_print_flag) {
|
||||
EXTPR("%s new i2c device succeed\n",
|
||||
ext_drv->config.name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!aml_DLPC3439_i2c_client) {
|
||||
ret = i2c_add_driver(&aml_DLPC3439_i2c_driver);
|
||||
if (ret) {
|
||||
EXTERR("%s add i2c_driver failed\n",
|
||||
ext_drv->config.name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ret = lcd_extern_driver_update(ext_drv);
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
EXTPR("%s: %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
365
drivers/amlogic/media/vout/lcd/lcd_extern/i2c_T5800Q.c
Normal file
365
drivers/amlogic/media/vout/lcd/lcd_extern/i2c_T5800Q.c
Normal file
@@ -0,0 +1,365 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_extern/i2c_T5800Q.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/amlogic/i2c-amlogic.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_extern.h>
|
||||
#include "lcd_extern.h"
|
||||
|
||||
#define LCD_EXTERN_NAME "i2c_T5800Q"
|
||||
|
||||
static struct i2c_client *aml_T5800Q_i2c_client;
|
||||
static struct lcd_extern_config_s *ext_config;
|
||||
|
||||
#define LCD_EXTERN_CMD_SIZE 9
|
||||
static unsigned char init_on_table[] = {
|
||||
0x00, 0x20, 0x01, 0x02, 0x00, 0x40, 0xFF, 0x00, 0x00,
|
||||
0x00, 0x80, 0x02, 0x00, 0x40, 0x62, 0x51, 0x73, 0x00,
|
||||
0x00, 0x61, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xC1, 0x05, 0x0F, 0x00, 0x08, 0x70, 0x00, 0x00,
|
||||
0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x3D, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xED, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x23, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, /* delay 10ms */
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ending */
|
||||
};
|
||||
|
||||
static unsigned char init_off_table[] = {
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ending */
|
||||
};
|
||||
|
||||
static int lcd_extern_i2c_write(struct i2c_client *i2client,
|
||||
unsigned char *buff, unsigned int len)
|
||||
{
|
||||
int ret = 0;
|
||||
struct i2c_msg msg[] = {
|
||||
{
|
||||
.addr = i2client->addr,
|
||||
.flags = 0,
|
||||
.len = len,
|
||||
.buf = buff,
|
||||
}
|
||||
};
|
||||
|
||||
ret = i2c_transfer(i2client->adapter, msg, 1);
|
||||
if (ret < 0)
|
||||
EXTERR("i2c write failed [addr 0x%02x]\n", i2client->addr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#if 0
|
||||
static int lcd_extern_i2c_read(struct i2c_client *i2client,
|
||||
unsigned char *buff, unsigned int len)
|
||||
{
|
||||
int ret = 0;
|
||||
struct i2c_msg msgs[] = {
|
||||
{
|
||||
.addr = i2client->addr,
|
||||
.flags = 0,
|
||||
.len = 1,
|
||||
.buf = buff,
|
||||
},
|
||||
{
|
||||
.addr = i2client->addr,
|
||||
.flags = I2C_M_RD,
|
||||
.len = len,
|
||||
.buf = buff,
|
||||
}
|
||||
};
|
||||
|
||||
ret = i2c_transfer(i2client->adapter, msgs, 2);
|
||||
if (ret < 0)
|
||||
EXTERR("i2c read failed [addr 0x%02x]\n", i2client->addr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int lcd_extern_reg_read(unsigned char reg, unsigned char *buf)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_reg_write(unsigned char reg, unsigned char value)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_power_cmd(unsigned char *init_table)
|
||||
{
|
||||
int i = 0, len;
|
||||
int ret = 0;
|
||||
|
||||
len = ext_config->cmd_size;
|
||||
if (len < 1) {
|
||||
EXTERR("%s: cmd_size %d is invalid\n", __func__, len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (i <= LCD_EXTERN_INIT_TABLE_MAX) {
|
||||
if (init_table[i] == LCD_EXTERN_INIT_END) {
|
||||
break;
|
||||
} else if (init_table[i] == LCD_EXTERN_INIT_NONE) {
|
||||
/* do nothing, only for delay */
|
||||
} else if (init_table[i] == LCD_EXTERN_INIT_GPIO) {
|
||||
if (init_table[i+1] < LCD_GPIO_MAX) {
|
||||
lcd_extern_gpio_set(init_table[i+1],
|
||||
init_table[i+2]);
|
||||
}
|
||||
} else if (init_table[i] == LCD_EXTERN_INIT_CMD) {
|
||||
ret = lcd_extern_i2c_write(aml_T5800Q_i2c_client,
|
||||
&init_table[i+1], (len-2));
|
||||
} else {
|
||||
EXTERR("%s(%d: %s): power_type %d is invalid\n",
|
||||
__func__, ext_config->index,
|
||||
ext_config->name, ext_config->type);
|
||||
}
|
||||
if (init_table[i+len-1] > 0)
|
||||
mdelay(init_table[i+len-1]);
|
||||
i += len;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_power_ctrl(int flag)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (flag)
|
||||
ret = lcd_extern_power_cmd(ext_config->table_init_on);
|
||||
else
|
||||
ret = lcd_extern_power_cmd(ext_config->table_init_off);
|
||||
|
||||
EXTPR("%s(%d: %s): %d\n",
|
||||
__func__, ext_config->index, ext_config->name, flag);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_power_on(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = lcd_extern_power_ctrl(1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_power_off(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = lcd_extern_power_ctrl(0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
|
||||
{
|
||||
if (ext_drv == NULL) {
|
||||
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ext_drv->config.table_init_loaded == 0) {
|
||||
ext_drv->config.table_init_on = init_on_table;
|
||||
ext_drv->config.table_init_off = init_off_table;
|
||||
}
|
||||
ext_drv->reg_read = lcd_extern_reg_read;
|
||||
ext_drv->reg_write = lcd_extern_reg_write;
|
||||
ext_drv->power_on = lcd_extern_power_on;
|
||||
ext_drv->power_off = lcd_extern_power_off;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* debug function */
|
||||
static const char *lcd_extern_debug_usage_str = {
|
||||
"Usage:\n"
|
||||
" echo <reg> <> ... <> > write ; T5800Q i2c command write, 7 parameters without address\n"
|
||||
};
|
||||
|
||||
static ssize_t lcd_extern_debug_help(struct class *class,
|
||||
struct class_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%s\n", lcd_extern_debug_usage_str);
|
||||
}
|
||||
|
||||
static ssize_t lcd_extern_debug_write(struct class *class,
|
||||
struct class_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
unsigned int ret;
|
||||
unsigned int temp[8];
|
||||
unsigned char data[8];
|
||||
int i;
|
||||
|
||||
memset(temp, 0, (sizeof(unsigned int) * 8));
|
||||
ret = sscanf(buf, "%x %x %x %x %x %x %x",
|
||||
&temp[0], &temp[1], &temp[2], &temp[3],
|
||||
&temp[4], &temp[5], &temp[6]);
|
||||
EXTPR("T5800Q i2c write:\n");
|
||||
for (i = 0; i < 7; i++) {
|
||||
data[i] = (unsigned char)temp[i];
|
||||
pr_info("0x%02x ", data[i]);
|
||||
}
|
||||
pr_info("\n");
|
||||
lcd_extern_i2c_write(aml_T5800Q_i2c_client, data, 7);
|
||||
|
||||
if (ret != 1 || ret != 2)
|
||||
return -EINVAL;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct class_attribute lcd_extern_class_attrs[] = {
|
||||
__ATTR(write, 0644,
|
||||
lcd_extern_debug_help, lcd_extern_debug_write),
|
||||
};
|
||||
|
||||
static struct class *debug_class;
|
||||
static int creat_lcd_extern_class(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
debug_class = class_create(THIS_MODULE, LCD_EXTERN_NAME);
|
||||
if (IS_ERR(debug_class)) {
|
||||
EXTERR("create debug class failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(lcd_extern_class_attrs); i++) {
|
||||
if (class_create_file(debug_class,
|
||||
&lcd_extern_class_attrs[i])) {
|
||||
EXTERR("create debug attribute %s failed\n",
|
||||
lcd_extern_class_attrs[i].attr.name);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int remove_lcd_extern_class(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(lcd_extern_class_attrs); i++)
|
||||
class_remove_file(debug_class, &lcd_extern_class_attrs[i]);
|
||||
|
||||
class_destroy(debug_class);
|
||||
debug_class = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
/* ********************************************************* */
|
||||
|
||||
static int aml_T5800Q_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
|
||||
EXTERR("%s: functionality check failed\n", __func__);
|
||||
else
|
||||
aml_T5800Q_i2c_client = client;
|
||||
|
||||
EXTPR("%s OK\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aml_T5800Q_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id aml_T5800Q_i2c_id[] = {
|
||||
{LCD_EXTERN_NAME, 0},
|
||||
{ }
|
||||
};
|
||||
/* MODULE_DEVICE_TABLE(i2c, aml_T5800Q_id); */
|
||||
|
||||
static struct i2c_driver aml_T5800Q_i2c_driver = {
|
||||
.probe = aml_T5800Q_i2c_probe,
|
||||
.remove = aml_T5800Q_i2c_remove,
|
||||
.id_table = aml_T5800Q_i2c_id,
|
||||
.driver = {
|
||||
.name = LCD_EXTERN_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
int aml_lcd_extern_i2c_T5800Q_probe(struct aml_lcd_extern_driver_s *ext_drv)
|
||||
{
|
||||
struct i2c_board_info i2c_info;
|
||||
struct i2c_adapter *adapter;
|
||||
struct i2c_client *i2c_client;
|
||||
int ret = 0;
|
||||
|
||||
ext_config = &ext_drv->config;
|
||||
memset(&i2c_info, 0, sizeof(i2c_info));
|
||||
|
||||
adapter = i2c_get_adapter(ext_drv->config.i2c_bus);
|
||||
if (!adapter) {
|
||||
EXTERR("%s failed to get i2c adapter\n", ext_drv->config.name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(i2c_info.type, ext_drv->config.name, I2C_NAME_SIZE);
|
||||
i2c_info.addr = ext_drv->config.i2c_addr;
|
||||
i2c_info.platform_data = &ext_drv->config;
|
||||
i2c_info.flags = 0;
|
||||
if (i2c_info.addr > 0x7f) {
|
||||
EXTERR("%s invalid i2c address: 0x%02x\n",
|
||||
ext_drv->config.name, ext_drv->config.i2c_addr);
|
||||
return -1;
|
||||
}
|
||||
i2c_client = i2c_new_device(adapter, &i2c_info);
|
||||
if (!i2c_client) {
|
||||
EXTERR("%s failed to new i2c device\n", ext_drv->config.name);
|
||||
} else {
|
||||
if (lcd_debug_print_flag) {
|
||||
EXTPR("%s new i2c device succeed\n",
|
||||
ext_drv->config.name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!aml_T5800Q_i2c_client) {
|
||||
ret = i2c_add_driver(&aml_T5800Q_i2c_driver);
|
||||
if (ret) {
|
||||
EXTERR("%s add i2c_driver failed\n",
|
||||
ext_drv->config.name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ret = lcd_extern_driver_update(ext_drv);
|
||||
creat_lcd_extern_class();
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
EXTPR("%s: %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
497
drivers/amlogic/media/vout/lcd/lcd_extern/i2c_anx6345.c
Normal file
497
drivers/amlogic/media/vout/lcd/lcd_extern/i2c_anx6345.c
Normal file
@@ -0,0 +1,497 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_extern/i2c_anx6345.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/amlogic/i2c-amlogic.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_extern.h>
|
||||
#include "lcd_extern.h"
|
||||
#include "i2c_anx6345.h"
|
||||
|
||||
static struct lcd_extern_config_s *ext_config;
|
||||
static struct i2c_client *aml_anx6345_70_client;
|
||||
static struct i2c_client *aml_anx6345_72_client;
|
||||
|
||||
const char *anx_addr_name[2] = {"anx6345_70", "anx6345_72"};
|
||||
static unsigned int edp_tx_lane = 1;
|
||||
|
||||
#define LCD_EXTERN_NAME "lcd_anx6345"
|
||||
|
||||
static int aml_i2c_write(struct i2c_client *i2client, unsigned char *buff,
|
||||
unsigned int len)
|
||||
{
|
||||
int ret = 0;
|
||||
struct i2c_msg msg[] = {
|
||||
{
|
||||
.addr = i2client->addr,
|
||||
.flags = 0,
|
||||
.len = len,
|
||||
.buf = buff,
|
||||
},
|
||||
};
|
||||
|
||||
ret = i2c_transfer(i2client->adapter, msg, 1);
|
||||
if (ret < 0) {
|
||||
EXTERR("%s: i2c transfer failed [addr 0x%02x]\n",
|
||||
__func__, i2client->addr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aml_i2c_read(struct i2c_client *i2client, unsigned char *buff,
|
||||
unsigned int len)
|
||||
{
|
||||
int ret = 0;
|
||||
struct i2c_msg msgs[] = {
|
||||
{
|
||||
.addr = i2client->addr,
|
||||
.flags = 0,
|
||||
.len = 1,
|
||||
.buf = buff,
|
||||
},
|
||||
{
|
||||
.addr = i2client->addr,
|
||||
.flags = I2C_M_RD,
|
||||
.len = len,
|
||||
.buf = buff,
|
||||
},
|
||||
};
|
||||
|
||||
ret = i2c_transfer(i2client->adapter, msgs, 2);
|
||||
if (ret < 0) {
|
||||
EXTERR("%s: i2c transfer failed [addr 0x%02x]\n",
|
||||
__func__, i2client->addr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int i2c_reg_read(unsigned char reg, unsigned char *buf)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int i2c_reg_write(unsigned char reg, unsigned char value)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int SP_TX_Write_Reg(unsigned char addr, unsigned char reg,
|
||||
unsigned char data)
|
||||
{
|
||||
struct i2c_client *client = aml_anx6345_70_client;
|
||||
unsigned char buff[2];
|
||||
int ret;
|
||||
|
||||
buff[0] = reg;
|
||||
buff[1] = data;
|
||||
if (addr == 0x70)
|
||||
client = aml_anx6345_70_client;
|
||||
else if (addr == 0x72)
|
||||
client = aml_anx6345_72_client;
|
||||
|
||||
ret = aml_i2c_write(client, buff, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int SP_TX_Read_Reg(unsigned char addr, unsigned char reg,
|
||||
unsigned char *data)
|
||||
{
|
||||
struct i2c_client *client = aml_anx6345_70_client;
|
||||
int ret;
|
||||
|
||||
*data = reg;
|
||||
if (addr == 0x70)
|
||||
client = aml_anx6345_70_client;
|
||||
else if (addr == 0x72)
|
||||
client = aml_anx6345_72_client;
|
||||
|
||||
ret = aml_i2c_read(client, data, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int SP_TX_Wait_AUX_Finished(void)
|
||||
{
|
||||
unsigned char c;
|
||||
unsigned char cCnt;
|
||||
|
||||
cCnt = 0;
|
||||
SP_TX_Read_Reg(0x70, SP_TX_AUX_STATUS, &c);
|
||||
while (c & 0x10) {/* aux busy */
|
||||
cCnt++;
|
||||
SP_TX_Read_Reg(0x70, SP_TX_AUX_STATUS, &c);
|
||||
if (cCnt > 100)
|
||||
return -1; /* aux fail */
|
||||
}
|
||||
|
||||
return 0; /* aux ok */
|
||||
}
|
||||
|
||||
static int SP_TX_AUX_DPCDRead_Bytes(unsigned char addrh, unsigned char addrm,
|
||||
unsigned char addrl, unsigned char cCount, unsigned char *pBuf)
|
||||
{
|
||||
unsigned char c, i;
|
||||
|
||||
/* clr buffer */
|
||||
SP_TX_Write_Reg(0x70, SP_TX_BUF_DATA_COUNT_REG, 0x80);
|
||||
|
||||
/* set read cmd and count */
|
||||
SP_TX_Write_Reg(0x70, SP_TX_AUX_CTRL_REG, (((cCount-1) << 4) | 0x09));
|
||||
|
||||
/* set aux address15:0 */
|
||||
SP_TX_Write_Reg(0x70, SP_TX_AUX_ADDR_7_0_REG, addrl);
|
||||
SP_TX_Write_Reg(0x70, SP_TX_AUX_ADDR_15_8_REG, addrm);
|
||||
|
||||
/* set address19:16 and enable aux */
|
||||
SP_TX_Read_Reg(0x70, SP_TX_AUX_ADDR_19_16_REG, &c);
|
||||
SP_TX_Write_Reg(0x70, SP_TX_AUX_ADDR_19_16_REG, ((c & 0xf0) | addrh));
|
||||
|
||||
/* Enable Aux */
|
||||
SP_TX_Read_Reg(0x70, SP_TX_AUX_CTRL_REG2, &c);
|
||||
SP_TX_Write_Reg(0x70, SP_TX_AUX_CTRL_REG2, (c | 0x01));
|
||||
|
||||
mdelay(5);
|
||||
if (SP_TX_Wait_AUX_Finished())
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < cCount; i++) {
|
||||
SP_TX_Read_Reg(0x70, SP_TX_BUF_DATA_0_REG+i, &c);
|
||||
*(pBuf+i) = c;
|
||||
if (i >= MAX_BUF_CNT)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0; /* aux ok */
|
||||
}
|
||||
|
||||
static int lcd_extern_power_on(void)
|
||||
{
|
||||
unsigned int lane_num;
|
||||
unsigned int link_rate;
|
||||
unsigned char bits;
|
||||
unsigned char device_id;
|
||||
unsigned char temp;
|
||||
unsigned char temp1;
|
||||
unsigned int count = 0;
|
||||
unsigned int count1 = 0;
|
||||
|
||||
lane_num = edp_tx_lane; /* 1 lane */
|
||||
link_rate = VAL_EDP_TX_LINK_BW_SET_270; /* 2.7G */
|
||||
bits = 0; /* 0x00: 6bit; 0x10:8bit */
|
||||
SP_TX_Write_Reg(0x72, 0x05, 0x00);
|
||||
|
||||
SP_TX_Read_Reg(0x72, 0x01, &device_id);
|
||||
if (device_id == 0xaa) {
|
||||
EXTPR("ANX6345 Chip found\n\n");
|
||||
} else {
|
||||
EXTERR("ANX6345 Chip not found\n\n");
|
||||
return -1;
|
||||
}
|
||||
temp = device_id;
|
||||
/* if aux read fail, do h/w reset */
|
||||
while (SP_TX_AUX_DPCDRead_Bytes(0x00, 0x00, 0x00, 1, &temp1) &&
|
||||
(count < 200)) {
|
||||
/* read fail, h/w reset */
|
||||
SP_TX_Write_Reg(0x72, 0x06, 0x01);
|
||||
SP_TX_Write_Reg(0x72, 0x06, 0x00);
|
||||
SP_TX_Write_Reg(0x72, 0x05, 0x00);
|
||||
mdelay(10);
|
||||
count++;
|
||||
}
|
||||
|
||||
/* software reset */
|
||||
SP_TX_Read_Reg(0x72, SP_TX_RST_CTRL_REG, &temp);
|
||||
SP_TX_Write_Reg(0x72, SP_TX_RST_CTRL_REG, (temp | SP_TX_RST_SW_RST));
|
||||
SP_TX_Write_Reg(0x72, SP_TX_RST_CTRL_REG, (temp & ~SP_TX_RST_SW_RST));
|
||||
|
||||
/* EDID address for AUX access */
|
||||
SP_TX_Write_Reg(0x70, SP_TX_EXTRA_ADDR_REG, 0x50);
|
||||
/* disable HDCP polling mode. */
|
||||
SP_TX_Write_Reg(0x70, SP_TX_HDCP_CTRL, 0x00);
|
||||
/* Enable HDCP polling mode. */
|
||||
/* SP_TX_Write_Reg(0x70, SP_TX_HDCP_CTRL, 0x02); */
|
||||
/* enable M value read out */
|
||||
SP_TX_Write_Reg(0x70, SP_TX_LINK_DEBUG_REG, 0x30);
|
||||
|
||||
/* SP_TX_Read_Reg(0x70, SP_TX_DEBUG_REG1, &temp); */
|
||||
SP_TX_Write_Reg(0x70, SP_TX_DEBUG_REG1, 0x00); /*disable polling HPD */
|
||||
|
||||
SP_TX_Read_Reg(0x70, SP_TX_HDCP_CONTROL_0_REG, &temp);
|
||||
/* set KSV valid */
|
||||
SP_TX_Write_Reg(0x70, SP_TX_HDCP_CONTROL_0_REG, (temp | 0x03));
|
||||
|
||||
SP_TX_Read_Reg(0x70, SP_TX_AUX_CTRL_REG2, &temp);
|
||||
/* set double AUX output */
|
||||
SP_TX_Write_Reg(0x70, SP_TX_AUX_CTRL_REG2, (temp | 0x08));
|
||||
|
||||
/* unmask pll change int */
|
||||
SP_TX_Write_Reg(0x72, SP_COMMON_INT_MASK1, 0xbf);
|
||||
SP_TX_Write_Reg(0x72, SP_COMMON_INT_MASK2, 0xff);/* mask all int */
|
||||
SP_TX_Write_Reg(0x72, SP_COMMON_INT_MASK3, 0xff);/* mask all int */
|
||||
SP_TX_Write_Reg(0x72, SP_COMMON_INT_MASK4, 0xff);/* mask all int */
|
||||
|
||||
/* reset AUX */
|
||||
SP_TX_Read_Reg(0x72, SP_TX_RST_CTRL2_REG, &temp);
|
||||
SP_TX_Write_Reg(0x72, SP_TX_RST_CTRL2_REG, temp | SP_TX_AUX_RST);
|
||||
SP_TX_Write_Reg(0x72, SP_TX_RST_CTRL2_REG, temp & (~SP_TX_AUX_RST));
|
||||
|
||||
/* Chip initialization */
|
||||
SP_TX_Write_Reg(0x70, SP_TX_SYS_CTRL1_REG, 0x00);
|
||||
mdelay(10);
|
||||
|
||||
SP_TX_Write_Reg(0x72, SP_TX_VID_CTRL2_REG, bits);
|
||||
|
||||
/* ANX6345 chip analog setting */
|
||||
SP_TX_Write_Reg(0x70, SP_TX_PLL_CTRL_REG, 0x00);/* UPDATE: 0x07->0x00 */
|
||||
|
||||
/* ANX chip analog setting */
|
||||
/* UPDATE: 0xF0->0X70 */
|
||||
/* SP_TX_Write_Reg(0x72, ANALOG_DEBUG_REG1, 0x70); */
|
||||
SP_TX_Write_Reg(0x70, SP_TX_LINK_DEBUG_REG, 0x30);
|
||||
|
||||
/* force HPD */
|
||||
SP_TX_Write_Reg(0x70, SP_TX_SYS_CTRL3_REG, 0x30);
|
||||
|
||||
/* enable ssc function */
|
||||
SP_TX_Write_Reg(0x70, 0xA7, 0x00); /* disable SSC first */
|
||||
SP_TX_Write_Reg(0x70, 0xD0, 0x5f); /* ssc d 0.4%, f0/4 mode */
|
||||
SP_TX_Write_Reg(0x70, 0xD1, 0x00);
|
||||
SP_TX_Write_Reg(0x70, 0xD2, 0x75); /* ctrl_th */
|
||||
SP_TX_Read_Reg(0x70, 0xA7, &temp);
|
||||
SP_TX_Write_Reg(0x70, 0xA7, (temp | 0x10)); /* enable SSC */
|
||||
SP_TX_Read_Reg(0x72, 0x07, &temp); /* reset SSC */
|
||||
SP_TX_Write_Reg(0x72, 0x07, (temp | 0x80));
|
||||
SP_TX_Write_Reg(0x72, 0x07, (temp & (~0x80)));
|
||||
|
||||
/* Select 2.7G */
|
||||
/* 2.7g:0x0a; 1.62g:0x06 */
|
||||
SP_TX_Write_Reg(0x70, SP_TX_LINK_BW_SET_REG, link_rate);
|
||||
/* Select 2 lanes */
|
||||
SP_TX_Write_Reg(0x70, 0xa1, lane_num);
|
||||
|
||||
SP_TX_Write_Reg(0x70, SP_TX_LINK_TRAINING_CTRL_REG,
|
||||
SP_TX_LINK_TRAINING_CTRL_EN);
|
||||
mdelay(5);
|
||||
SP_TX_Read_Reg(0x70, SP_TX_LINK_TRAINING_CTRL_REG, &temp);
|
||||
/* UPDATE: FROM 0X01 TO 0X80 */
|
||||
while ((temp & 0x80) != 0) {
|
||||
/* debug_puts("Waiting...\n"); */
|
||||
mdelay(5);
|
||||
count1++;
|
||||
if (count1 > 100) {
|
||||
EXTERR("ANX6345 Link training fail\n");
|
||||
break;
|
||||
}
|
||||
SP_TX_Read_Reg(0x70, SP_TX_LINK_TRAINING_CTRL_REG, &temp);
|
||||
}
|
||||
|
||||
SP_TX_Write_Reg(0x72, 0x12, 0x2c);
|
||||
SP_TX_Write_Reg(0x72, 0x13, 0x06);
|
||||
SP_TX_Write_Reg(0x72, 0x14, 0x00);
|
||||
SP_TX_Write_Reg(0x72, 0x15, 0x06);
|
||||
SP_TX_Write_Reg(0x72, 0x16, 0x02);
|
||||
SP_TX_Write_Reg(0x72, 0x17, 0x04);
|
||||
SP_TX_Write_Reg(0x72, 0x18, 0x26);
|
||||
SP_TX_Write_Reg(0x72, 0x19, 0x50);
|
||||
SP_TX_Write_Reg(0x72, 0x1a, 0x04);
|
||||
SP_TX_Write_Reg(0x72, 0x1b, 0x00);
|
||||
SP_TX_Write_Reg(0x72, 0x1c, 0x04);
|
||||
SP_TX_Write_Reg(0x72, 0x1d, 0x18);
|
||||
SP_TX_Write_Reg(0x72, 0x1e, 0x00);
|
||||
SP_TX_Write_Reg(0x72, 0x1f, 0x10);
|
||||
SP_TX_Write_Reg(0x72, 0x20, 0x00);
|
||||
SP_TX_Write_Reg(0x72, 0x21, 0x28);
|
||||
|
||||
SP_TX_Write_Reg(0x72, 0x11, 0x03);
|
||||
/* enable BIST. In normal mode, don't need to config this reg
|
||||
* if want to open BIST, must setting
|
||||
* right dat 0x11-0x21 base lcd timing.
|
||||
*/
|
||||
/* SP_TX_Write_Reg(0x72, 0x0b, 0x09); //colorbar:08,graystep:09 */
|
||||
SP_TX_Write_Reg(0x72, 0x08, 0x81); /* SDR:0x81;DDR:0x8f */
|
||||
|
||||
/* force HPD and stream valid */
|
||||
SP_TX_Write_Reg(0x70, 0x82, 0x33);
|
||||
EXTPR("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lcd_extern_power_off(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (ext_drv) {
|
||||
ext_drv->power_on = lcd_extern_power_on;
|
||||
ext_drv->power_off = lcd_extern_power_off;
|
||||
} else {
|
||||
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aml_anx6345_70_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
|
||||
EXTERR("%s: functionality check failed\n", __func__);
|
||||
else
|
||||
aml_anx6345_70_client = client;
|
||||
|
||||
EXTPR("%s OK\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aml_anx6345_72_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
|
||||
EXTERR("%s: functionality check failed\n", __func__);
|
||||
else
|
||||
aml_anx6345_72_client = client;
|
||||
|
||||
EXTPR("%s OK\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aml_anx6345_70_remove(struct i2c_client *client)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static int aml_anx6345_72_remove(struct i2c_client *client)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id aml_anx6345_70_id[] = {
|
||||
{"anx6345_70", 0},
|
||||
{ }
|
||||
};
|
||||
static const struct i2c_device_id aml_anx6345_72_id[] = {
|
||||
{"anx6345_72", 0},
|
||||
{ }
|
||||
};
|
||||
|
||||
/* MODULE_DEVICE_TABLE(i2c, aml_tc101_id); */
|
||||
|
||||
static struct i2c_driver aml_anx6345_70_driver = {
|
||||
.probe = aml_anx6345_70_probe,
|
||||
.remove = aml_anx6345_70_remove,
|
||||
.id_table = aml_anx6345_70_id,
|
||||
.driver = {
|
||||
.name = "anx6345_70",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct i2c_driver aml_anx6345_72_driver = {
|
||||
.probe = aml_anx6345_72_probe,
|
||||
.remove = aml_anx6345_72_remove,
|
||||
.id_table = aml_anx6345_72_id,
|
||||
.driver = {
|
||||
.name = "anx6345_72",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
int aml_lcd_extern_i2c_anx6345_probe(struct aml_lcd_extern_driver_s *ext_drv)
|
||||
{
|
||||
struct i2c_board_info i2c_info[2];
|
||||
struct i2c_adapter *adapter;
|
||||
struct i2c_client *i2c_client;
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
|
||||
ext_config = &ext_drv->config;
|
||||
for (i = 0; i < 2; i++)
|
||||
memset(&i2c_info[i], 0, sizeof(i2c_info[i]));
|
||||
|
||||
adapter = i2c_get_adapter(ext_config->i2c_bus);
|
||||
if (!adapter) {
|
||||
EXTERR("%s failed to get i2c adapter\n", ext_drv->config.name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
i2c_info[0].addr = 0x38; /* 0x70 >> 1; */
|
||||
i2c_info[1].addr = 0x39; /* 0x72 >> 1; */
|
||||
for (i = 0; i < 2; i++) {
|
||||
strncpy(i2c_info[i].type, anx_addr_name[i], I2C_NAME_SIZE);
|
||||
/* i2c_info[i].platform_data = &ext_drv->config; */
|
||||
i2c_info[i].flags = 0;
|
||||
if (i2c_info[i].addr > 0x7f) {
|
||||
EXTERR("%s invalid i2c address: 0x%02x\n",
|
||||
ext_drv->config.name, i2c_info[i].addr);
|
||||
return -1;
|
||||
}
|
||||
i2c_client = i2c_new_device(adapter, &i2c_info[i]);
|
||||
if (!i2c_client) {
|
||||
EXTERR("%s failed to new i2c device\n",
|
||||
ext_drv->config.name);
|
||||
} else {
|
||||
if (lcd_debug_print_flag) {
|
||||
EXTPR("%s new i2c device succeed\n",
|
||||
ext_drv->config.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!aml_anx6345_70_client) {
|
||||
ret = i2c_add_driver(&aml_anx6345_70_driver);
|
||||
if (ret) {
|
||||
EXTERR("%s add i2c_driver failed\n",
|
||||
ext_drv->config.name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (!aml_anx6345_72_client) {
|
||||
ret = i2c_add_driver(&aml_anx6345_72_driver);
|
||||
if (ret) {
|
||||
EXTERR("%s add i2c_driver failed\n",
|
||||
ext_drv->config.name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ret = lcd_extern_driver_update(ext_drv);
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
EXTPR("%s: %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
716
drivers/amlogic/media/vout/lcd/lcd_extern/i2c_anx6345.h
Normal file
716
drivers/amlogic/media/vout/lcd/lcd_extern/i2c_anx6345.h
Normal file
@@ -0,0 +1,716 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_extern/i2c_anx6345.h
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EDP_ANX6345_H
|
||||
#define EDP_ANX6345_H
|
||||
|
||||
/* ************************************************************* */
|
||||
#define SP_TX_PORT0_ADDR 0x70
|
||||
#define SP_TX_PORT1_ADDR 0x74
|
||||
#define SP_TX_PORT2_ADDR 0x72
|
||||
#define MIPI_RX_PORT1_ADDR 0x7A
|
||||
|
||||
#define MAX_BUF_CNT 6
|
||||
|
||||
#define CR_LOOP_TIME 5
|
||||
#define EQ_LOOP_TIME 5
|
||||
|
||||
#define SP_TX_AVI_SEL 0x01
|
||||
#define SP_TX_SPD_SEL 0x02
|
||||
#define SP_TX_MPEG_SEL 0x04
|
||||
|
||||
#define VAL_EDP_TX_LINK_BW_SET_162 0x06
|
||||
#define VAL_EDP_TX_LINK_BW_SET_270 0x0a
|
||||
#define VAL_EDP_TX_LINK_BW_SET_540 0x14
|
||||
|
||||
/* End for DEV_addr 0x7A/0x7E */
|
||||
|
||||
/* ************************************************************* */
|
||||
/* DEV_ADDR = 0x70 or 0x78 , Displayport mode and HDCP registers */
|
||||
#define SP_TX_HDCP_STATUS 0x00
|
||||
/* bit position */
|
||||
#define SP_TX_HDCP_AUTH_PASS 0x02
|
||||
|
||||
#define SP_TX_HDCP_CONTROL_0_REG 0x01
|
||||
/* bit position */
|
||||
#define SP_TX_HDCP_CONTROL_0_STORE_AN 0x80
|
||||
#define SP_TX_HDCP_CONTROL_0_RX_REPEATER 0x40
|
||||
#define SP_TX_HDCP_CONTROL_0_RE_AUTH 0x20
|
||||
#define SP_TX_HDCP_CONTROL_0_SW_AUTH_OK 0x10
|
||||
#define SP_TX_HDCP_CONTROL_0_HARD_AUTH_EN 0x08
|
||||
#define SP_TX_HDCP_CONTROL_0_HDCP_ENC_EN 0x04
|
||||
#define SP_TX_HDCP_CONTROL_0_BKSV_SRM_PASS 0x02
|
||||
#define SP_TX_HDCP_CONTROL_0_KSVLIST_VLD 0x01
|
||||
|
||||
#define SP_TX_HDCP_CONTROL_1_REG 0x02
|
||||
/* bit position */
|
||||
#define SP_TX_HDCP_CONTROL_1_DDC_NO_STOP 0x20
|
||||
#define SP_TX_HDCP_CONTROL_1_DDC_NO_ACK 0x10
|
||||
#define SP_TX_HDCP_CONTROL_1_EDDC_NO_ACK 0x08
|
||||
/* #define SP_TX_HDCP_CONTROL_1_HDCP_EMB_SCREEN_EN 0x04 */
|
||||
#define SP_TX_HDCP_CONTROL_1_RCV_11_EN 0x02
|
||||
#define SP_TX_HDCP_CONTROL_1_HDCP_11_EN 0x01
|
||||
|
||||
#define SP_TX_HDCP_LINK_CHK_FRAME_NUM 0x03
|
||||
#define SP_TX_HDCP_CONTROL_2_REG 0x04
|
||||
|
||||
#define SP_TX_HDCP_AKSV0 0x05
|
||||
#define SP_TX_HDCP_AKSV1 0x06
|
||||
#define SP_TX_HDCP_AKSV2 0x07
|
||||
#define SP_TX_HDCP_AKSV3 0x08
|
||||
#define SP_TX_HDCP_AKSV4 0x09
|
||||
|
||||
/* AKSV */
|
||||
#define SP_TX_HDCP_AN0 0x0A
|
||||
#define SP_TX_HDCP_AN1 0x0B
|
||||
#define SP_TX_HDCP_AN2 0x0C
|
||||
#define SP_TX_HDCP_AN3 0x0D
|
||||
#define SP_TX_HDCP_AN4 0x0E
|
||||
#define SP_TX_HDCP_AN5 0x0F
|
||||
#define SP_TX_HDCP_AN6 0x10
|
||||
#define SP_TX_HDCP_AN7 0x11
|
||||
|
||||
/* BKSV */
|
||||
#define SP_TX_HDCP_BKSV0 0x12
|
||||
#define SP_TX_HDCP_BKSV1 0x13
|
||||
#define SP_TX_HDCP_BKSV2 0x14
|
||||
#define SP_TX_HDCP_BKSV3 0x15
|
||||
#define SP_TX_HDCP_BKSV4 0x16
|
||||
|
||||
#define SP_TX_HDCP_R0_L 0x17
|
||||
#define SP_TX_HDCP_R0_H 0x18
|
||||
|
||||
#ifndef M_VID_0
|
||||
#define M_VID_0 0xC0
|
||||
#define M_VID_1 0xC1
|
||||
#define M_VID_2 0xC2
|
||||
#define N_VID_0 0xC3
|
||||
#define N_VID_1 0xC4
|
||||
#define N_VID_2 0xC5
|
||||
#endif
|
||||
|
||||
#define SP_TX_HDCP_R0_WAIT_Timer 0x40
|
||||
|
||||
#define SP_TX_SYS_CTRL1_REG 0x80
|
||||
/* bit position */
|
||||
/* #define SP_TX_SYS_CTRL1_PD_IO 0x80 */
|
||||
/* #define SP_TX_SYS_CTRL1_PD_VID 0x40 */
|
||||
/* #define SP_TX_SYS_CTRL1_PD_LINK 0x20 */
|
||||
/* #define SP_TX_SYS_CTRL1_PD_TOTAL 0x10 */
|
||||
/* #define SP_TX_SYS_CTRL1_MODE_SEL 0x08 */
|
||||
#define SP_TX_SYS_CTRL1_DET_STA 0x04
|
||||
#define SP_TX_SYS_CTRL1_FORCE_DET 0x02
|
||||
#define SP_TX_SYS_CTRL1_DET_CTRL 0x01
|
||||
|
||||
#define SP_TX_SYS_CTRL2_REG 0x81
|
||||
/* bit position */
|
||||
/* #define SP_TX_SYS_CTRL2_ENHANCED 0x08 */
|
||||
#define SP_TX_SYS_CTRL2_CHA_STA 0x04
|
||||
#define SP_TX_SYS_CTRL2_FORCE_CHA 0x02
|
||||
#define SP_TX_SYS_CTRL2_CHA_CTRL 0x01
|
||||
|
||||
#define SP_TX_SYS_CTRL3_REG 0x82
|
||||
/* bit position */
|
||||
#define SP_TX_SYS_CTRL3_HPD_STATUS 0x40
|
||||
#define SP_TX_SYS_CTRL3_F_HPD 0x20
|
||||
#define SP_TX_SYS_CTRL3_HPD_CTRL 0x10
|
||||
#define SP_TX_SYS_CTRL3_STRM_VALID 0x04
|
||||
#define SP_TX_SYS_CTRL3_F_VALID 0x02
|
||||
#define SP_TX_SYS_CTRL3_VALID_CTRL 0x01
|
||||
|
||||
#define SP_TX_SYS_CTRL4_REG 0x83
|
||||
/* bit position */
|
||||
#define SP_TX_SYS_CTRL4_ENHANCED 0x08
|
||||
|
||||
#define SP_TX_VID_CTRL 0x84
|
||||
|
||||
#define SP_TX_AUD_CTRL 0x87
|
||||
/* bit position */
|
||||
#define SP_TX_AUD_CTRL_AUD_EN 0x01
|
||||
|
||||
#define SP_TX_PKT_EN_REG 0x90
|
||||
/* bit position */
|
||||
#define SP_TX_PKT_AUD_UP 0x80
|
||||
#define SP_TX_PKT_AVI_UD 0x40
|
||||
#define SP_TX_PKT_MPEG_UD 0x20
|
||||
#define SP_TX_PKT_SPD_UD 0x10
|
||||
#define SP_TX_PKT_AUD_EN 0x08
|
||||
#define SP_TX_PKT_AVI_EN 0x04
|
||||
#define SP_TX_PKT_MPEG_EN 0x02
|
||||
#define SP_TX_PKT_SPD_EN 0x01
|
||||
|
||||
#define SP_TX_HDCP_CTRL 0x92
|
||||
|
||||
#define SP_TX_LINK_BW_SET_REG 0xA0
|
||||
#define SP_TX_LANE_COUNT_SET_REG 0xA1
|
||||
|
||||
#define SP_TX_TRAINING_PTN_SET_REG 0xA2
|
||||
/* bit position */
|
||||
#define SP_TX_SCRAMBLE_DISABLE 0x20
|
||||
|
||||
#define SP_TX_TRAINING_LANE0_SET_REG 0xA3
|
||||
/* bit position */
|
||||
#define SP_TX_TRAINING_LANE0_SET_MAX_PRE_REACH 0x20
|
||||
#define SP_TX_TRAINING_LANE0_SET_MAX_DRIVE_REACH 0x04
|
||||
|
||||
#define SP_TX_TRAINING_LANE1_SET_REG 0xA4
|
||||
|
||||
#define SSC_CTRL_REG1 0xA7
|
||||
/* bit position */
|
||||
#define SPREAD_AMP 0x10
|
||||
#define MODULATION_FREQ 0x01
|
||||
|
||||
|
||||
#define SP_TX_LINK_TRAINING_CTRL_REG 0xA8
|
||||
/* bit position */
|
||||
#define SP_TX_LINK_TRAINING_CTRL_EN 0x01
|
||||
|
||||
#define SP_TX_DEBUG_REG1 0xB0
|
||||
/* bit position */
|
||||
#define SP_TX_DEBUG_HPD_POLLING_DET 0x40
|
||||
#define SP_TX_DEBUG_HPD_POLLING_EN 0x20
|
||||
#define SP_TX_DEBUG_PLL_LOCK 0x10
|
||||
|
||||
#define SP_TX_LINK_DEBUG_REG 0xB8
|
||||
/* bit position */
|
||||
#define SP_TX_LINK_DEBUG_INSERT_ER 0x02
|
||||
#define SP_TX_LINK_DEBUG_PRBS31_EN 0x01
|
||||
|
||||
#define SP_TX_SINK_COUNT_REG 0xB9
|
||||
|
||||
#define SP_TX_LINK_STATUS_REG1 0xBB
|
||||
|
||||
#define SP_TX_SINK_STATUS_REG 0xBE
|
||||
/* bit position */
|
||||
#define SP_TX_SINK_STATUS_SINK_STATUS_1 0x02
|
||||
#define SP_TX_SINK_STATUS_SINK_STATUS_0 0x01
|
||||
|
||||
|
||||
/* #define SP_TX_LINK_TEST_COUNT 0xC0 */
|
||||
|
||||
|
||||
#define SP_TX_PLL_CTRL_REG 0xC7
|
||||
/* bit position */
|
||||
#define SP_TX_PLL_CTRL_PLL_PD 0x80
|
||||
#define SP_TX_PLL_CTRL_PLL_RESET 0x40
|
||||
/* #define SP_TX_PLL_CTRL_CPREG_BLEED 0x08 */
|
||||
|
||||
#define SP_TX_ANALOG_POWER_DOWN_REG 0xC8
|
||||
/* bit position */
|
||||
#define SP_TX_ANALOG_POWER_DOWN_MACRO_PD 0x20
|
||||
#define SP_TX_ANALOG_POWER_DOWN_AUX_PD 0x10
|
||||
/* #define SP_TX_ANALOG_POWER_DOWN_CH3_PD 0x08 */
|
||||
/* #define SP_TX_ANALOG_POWER_DOWN_CH2_PD 0x04 */
|
||||
#define SP_TX_ANALOG_POWER_DOWN_CH1_PD 0x02
|
||||
#define SP_TX_ANALOG_POWER_DOWN_CH0_PD 0x01
|
||||
|
||||
|
||||
#define SP_TX_ANALOG_TEST_REG 0xC9
|
||||
/* bit position */
|
||||
#define SP_TX_ANALOG_TEST_MACRO_RST 0x20
|
||||
#define SP_TX_ANALOG_TEST_PLL_TEST 0x10
|
||||
#define SP_TX_ANALOG_TEST_CH3_TEST 0x08
|
||||
#define SP_TX_ANALOG_TEST_CH2_TEST 0x04
|
||||
#define SP_TX_ANALOG_TEST_CH1_TEST 0x02
|
||||
#define SP_TX_ANALOG_TEST_CH0_TEST 0x01
|
||||
|
||||
#define SP_TX_GNS_CTRL_REG 0xCD
|
||||
/* bit position */
|
||||
#define SP_EQ_LOOP_CNT 0x40
|
||||
#define SP_TX_VIDEO_MAP_CTRL 0x02
|
||||
#define SP_TX_RS_CTRL 0x01
|
||||
|
||||
#define SP_TX_DOWN_SPREADING_CTRL1 0xD0
|
||||
#define SP_TX_DOWN_SPREADING_CTRL2 0xD1
|
||||
#define SP_TX_DOWN_SPREADING_CTRL3 0xD2
|
||||
/* bit position */
|
||||
#define SP_TX_SSC_D_CTRL 0x40
|
||||
#define SP_TX_FS_CTRL_TH_CTRL 0x20
|
||||
|
||||
#define SP_TX_M_CALCU_CTRL 0xD9
|
||||
/* bit position */
|
||||
#define M_GEN_CLK_SEL 0x01
|
||||
|
||||
|
||||
#define SP_TX_EXTRA_ADDR_REG 0xCE
|
||||
#define SP_TX_I2C_STRETCH_CTRL_REG 0xDB
|
||||
#define SP_TX_AUX_STATUS 0xE0
|
||||
#define SP_TX_DEFER_CTRL_REG 0xE2
|
||||
/* bit position */
|
||||
#define SP_TXL_DEFER_CTRL_EN 0x80
|
||||
|
||||
#define SP_TX_BUF_DATA_COUNT_REG 0xE4
|
||||
#define SP_TX_AUX_CTRL_REG 0xE5
|
||||
/* bit position */
|
||||
#define SP_TX_MOT_BIT 0x04
|
||||
|
||||
#define SP_TX_AUX_ADDR_7_0_REG 0xE6
|
||||
#define SP_TX_AUX_ADDR_15_8_REG 0xE7
|
||||
#define SP_TX_AUX_ADDR_19_16_REG 0xE8
|
||||
|
||||
#define SP_TX_AUX_CTRL_REG2 0xE9
|
||||
/* bit position */
|
||||
#define SP_TX_ADDR_ONLY_BIT 0x02
|
||||
|
||||
#define SP_TX_BUF_DATA_0_REG 0xf0
|
||||
#define SP_TX_BUF_DATA_1_REG 0xf1
|
||||
#define SP_TX_BUF_DATA_2_REG 0xf2
|
||||
#define SP_TX_BUF_DATA_3_REG 0xf3
|
||||
#define SP_TX_BUF_DATA_4_REG 0xf4
|
||||
#define SP_TX_BUF_DATA_5_REG 0xf5
|
||||
#define SP_TX_BUF_DATA_6_REG 0xf6
|
||||
#define SP_TX_BUF_DATA_7_REG 0xf7
|
||||
#define SP_TX_BUF_DATA_8_REG 0xf8
|
||||
#define SP_TX_BUF_DATA_9_REG 0xf9
|
||||
#define SP_TX_BUF_DATA_10_REG 0xfa
|
||||
#define SP_TX_BUF_DATA_11_REG 0xfb
|
||||
#define SP_TX_BUF_DATA_12_REG 0xfc
|
||||
#define SP_TX_BUF_DATA_13_REG 0xfd
|
||||
#define SP_TX_BUF_DATA_14_REG 0xfe
|
||||
#define SP_TX_BUF_DATA_15_REG 0xff
|
||||
|
||||
/* End for Address 0x70 or 0x78 */
|
||||
|
||||
/* ************************************************************* */
|
||||
/* DEV_ADDR = 0x72 or 0x76, System control registers */
|
||||
#define SP_TX_VND_IDL_REG 0x00
|
||||
#define SP_TX_VND_IDH_REG 0x01
|
||||
#define SP_TX_DEV_IDL_REG 0x02
|
||||
#define SP_TX_DEV_IDH_REG 0x03
|
||||
#define SP_TX_DEV_REV_REG 0x04
|
||||
|
||||
#define SP_POWERD_CTRL_REG 0x05
|
||||
/* bit position */
|
||||
#define SP_POWERD_REGISTER_REG 0x80
|
||||
/* #define SP_POWERD_MISC_REG 0x40 */
|
||||
#define SP_POWERD_IO_REG 0x20
|
||||
#define SP_POWERD_AUDIO_REG 0x10
|
||||
#define SP_POWERD_VIDEO_REG 0x08
|
||||
#define SP_POWERD_LINK_REG 0x04
|
||||
#define SP_POWERD_TOTAL_REG 0x02
|
||||
#define SP_MODE_SEL_REG 0x01
|
||||
|
||||
#define SP_TX_RST_CTRL_REG 0x06
|
||||
#define SP_TX_RST_MISC_REG 0x80
|
||||
#define SP_TX_RST_VIDCAP_REG 0x40
|
||||
#define SP_TX_RST_VIDFIF_REG 0x20
|
||||
#define SP_TX_RST_AUDFIF_REG 0x10
|
||||
#define SP_TX_RST_AUDCAP_REG 0x08
|
||||
#define SP_TX_RST_HDCP_REG 0x04
|
||||
#define SP_TX_RST_SW_RST 0x02
|
||||
#define SP_TX_RST_HW_RST 0x01
|
||||
|
||||
#define SP_TX_RST_CTRL2_REG 0x07
|
||||
#define SP_TX_RST_SSC 0x80
|
||||
#define SP_TX_AC_MODE 0x40
|
||||
/* #define SP_TX_DDC_RST 0x10 */
|
||||
/* #define SP_TX_TMDS_BIST_RST 0x08 */
|
||||
#define SP_TX_AUX_RST 0x04
|
||||
#define SP_TX_SERDES_FIFO_RST 0x02
|
||||
#define SP_TX_I2C_REG_RST 0x01
|
||||
|
||||
|
||||
#define SP_TX_VID_CTRL1_REG 0x08
|
||||
/* bit position */
|
||||
#define SP_TX_VID_CTRL1_VID_EN 0x80
|
||||
#define SP_TX_VID_CTRL1_VID_MUTE 0x40
|
||||
#define SP_TX_VID_CTRL1_DE_GEN 0x20
|
||||
#define SP_TX_VID_CTRL1_DEMUX 0x10
|
||||
#define SP_TX_VID_CTRL1_IN_BIT 0x04
|
||||
#define SP_TX_VID_CTRL1_DDRCTRL 0x02
|
||||
#define SP_TX_VID_CTRL1_EDGE 0x01
|
||||
|
||||
#define SP_TX_VID_CTRL2_REG 0x09
|
||||
/* bit position */
|
||||
#define SP_TX_VID_CTRL1_YCBIT_SEL 0x04
|
||||
|
||||
#define SP_TX_VID_CTRL3_REG 0x0A
|
||||
|
||||
#define SP_TX_VID_CTRL4_REG 0x0B
|
||||
/* bit position */
|
||||
#define SP_TX_VID_CTRL4_E_SYNC_EN 0x80
|
||||
#define SP_TX_VID_CTRL4_EX_E_SYNC 0x40
|
||||
#define SP_TX_VID_CTRL4_BIST 0x08
|
||||
#define SP_TX_VID_CTRL4_BIST_WIDTH 0x04
|
||||
|
||||
#define SP_TX_VID_CTRL5_REG 0x0C
|
||||
|
||||
#define SP_TX_VID_CTRL6_REG 0x0D
|
||||
/* bit position */
|
||||
#define SP_TX_VID_UPSAMPLE 0x02
|
||||
|
||||
#define SP_TX_VID_CTRL7_REG 0x0E
|
||||
#define SP_TX_VID_CTRL8_REG 0x0F
|
||||
#define SP_TX_VID_CTRL9_REG 0x10
|
||||
|
||||
#define SP_TX_VID_CTRL10_REG 0x11
|
||||
/* bit position */
|
||||
#define SP_TX_VID_CTRL10_INV_F 0x08
|
||||
#define SP_TX_VID_CTRL10_I_SCAN 0x04
|
||||
#define SP_TX_VID_CTRL10_VSYNC_POL 0x02
|
||||
#define SP_TX_VID_CTRL10_HSYNC_POL 0x01
|
||||
|
||||
#define SP_TX_TOTAL_LINEL_REG 0x12
|
||||
#define SP_TX_TOTAL_LINEH_REG 0x13
|
||||
#define SP_TX_ACT_LINEL_REG 0x14
|
||||
#define SP_TX_ACT_LINEH_REG 0x15
|
||||
#define SP_TX_VF_PORCH_REG 0x16
|
||||
#define SP_TX_VSYNC_CFG_REG 0x17
|
||||
#define SP_TX_VB_PORCH_REG 0x18
|
||||
#define SP_TX_TOTAL_PIXELL_REG 0x19
|
||||
#define SP_TX_TOTAL_PIXELH_REG 0x1A
|
||||
#define SP_TX_ACT_PIXELL_REG 0x1B
|
||||
#define SP_TX_ACT_PIXELH_REG 0x1C
|
||||
#define SP_TX_HF_PORCHL_REG 0x1D
|
||||
#define SP_TX_HF_PORCHH_REG 0x1E
|
||||
#define SP_TX_HSYNC_CFGL_REG 0x1F
|
||||
#define SP_TX_HSYNC_CFGH_REG 0x20
|
||||
#define SP_TX_HB_PORCHL_REG 0x21
|
||||
#define SP_TX_HB_PORCHH_REG 0x22
|
||||
|
||||
#define SP_TX_VID_STATUS 0x23
|
||||
|
||||
#define SP_TX_TOTAL_LINE_STA_L 0x24
|
||||
#define SP_TX_TOTAL_LINE_STA_H 0x25
|
||||
#define SP_TX_ACT_LINE_STA_L 0x26
|
||||
#define SP_TX_ACT_LINE_STA_H 0x27
|
||||
#define SP_TX_V_F_PORCH_STA 0x28
|
||||
#define SP_TX_V_SYNC_STA 0x29
|
||||
#define SP_TX_V_B_PORCH_STA 0x2A
|
||||
#define SP_TX_TOTAL_PIXEL_STA_L 0x2B
|
||||
#define SP_TX_TOTAL_PIXEL_STA_H 0x2C
|
||||
#define SP_TX_ACT_PIXEL_STA_L 0x2D
|
||||
#define SP_TX_ACT_PIXEL_STA_H 0x2E
|
||||
#define SP_TX_H_F_PORCH_STA_L 0x2F
|
||||
#define SP_TX_H_F_PORCH_STA_H 0x30
|
||||
#define SP_TX_H_SYNC_STA_L 0x31
|
||||
#define SP_TX_H_SYNC_STA_H 0x32
|
||||
#define SP_TX_H_B_PORCH_STA_L 0x33
|
||||
#define SP_TX_H_B_PORCH_STA_H 0x34
|
||||
|
||||
#define SP_TX_Video_Interface_BIST 0x35
|
||||
|
||||
#define SPDIF_AUDIO_CTRL0 0x36
|
||||
/* bit position */
|
||||
#define SPDIF_AUDIO_CTRL0_SPDIF_IN 0x80
|
||||
|
||||
#define SPDIF_AUDIO_STATUS0 0x38
|
||||
#define SPDIF_AUDIO_STATUS0_CLK_DET 0x80
|
||||
#define SPDIF_AUDIO_STATUS0_AUD_DET 0x01
|
||||
|
||||
#define SPDIF_AUDIO_STATUS1 0x39
|
||||
|
||||
#define AUDIO_BIST_CTRL 0x3c
|
||||
#define AUDIO_BIST_EN 0x01
|
||||
|
||||
/* #define AUDIO_BIST_CHANNEL_STATUS1 0xd0 */
|
||||
/* #define AUDIO_BIST_CHANNEL_STATUS2 0xd1 */
|
||||
/* #define AUDIO_BIST_CHANNEL_STATUS3 0xd2 */
|
||||
/* #define AUDIO_BIST_CHANNEL_STATUS4 0xd3 */
|
||||
/* #define AUDIO_BIST_CHANNEL_STATUS5 0xd4 */
|
||||
|
||||
#define SP_TX_VIDEO_BIT_CTRL_0_REG 0x40
|
||||
#define SP_TX_VIDEO_BIT_CTRL_1_REG 0x41
|
||||
#define SP_TX_VIDEO_BIT_CTRL_2_REG 0x42
|
||||
#define SP_TX_VIDEO_BIT_CTRL_3_REG 0x43
|
||||
#define SP_TX_VIDEO_BIT_CTRL_4_REG 0x44
|
||||
#define SP_TX_VIDEO_BIT_CTRL_5_REG 0x45
|
||||
#define SP_TX_VIDEO_BIT_CTRL_6_REG 0x46
|
||||
#define SP_TX_VIDEO_BIT_CTRL_7_REG 0x47
|
||||
#define SP_TX_VIDEO_BIT_CTRL_8_REG 0x48
|
||||
#define SP_TX_VIDEO_BIT_CTRL_9_REG 0x49
|
||||
#define SP_TX_VIDEO_BIT_CTRL_10_REG 0x4a
|
||||
#define SP_TX_VIDEO_BIT_CTRL_11_REG 0x4b
|
||||
#define SP_TX_VIDEO_BIT_CTRL_12_REG 0x4c
|
||||
#define SP_TX_VIDEO_BIT_CTRL_13_REG 0x4d
|
||||
#define SP_TX_VIDEO_BIT_CTRL_14_REG 0x4e
|
||||
#define SP_TX_VIDEO_BIT_CTRL_15_REG 0x4f
|
||||
#define SP_TX_VIDEO_BIT_CTRL_16_REG 0x50
|
||||
#define SP_TX_VIDEO_BIT_CTRL_17_REG 0x51
|
||||
#define SP_TX_VIDEO_BIT_CTRL_18_REG 0x52
|
||||
#define SP_TX_VIDEO_BIT_CTRL_19_REG 0x53
|
||||
#define SP_TX_VIDEO_BIT_CTRL_20_REG 0x54
|
||||
#define SP_TX_VIDEO_BIT_CTRL_21_REG 0x55
|
||||
#define SP_TX_VIDEO_BIT_CTRL_22_REG 0x56
|
||||
#define SP_TX_VIDEO_BIT_CTRL_23_REG 0x57
|
||||
#define SP_TX_VIDEO_BIT_CTRL_24_REG 0x58
|
||||
#define SP_TX_VIDEO_BIT_CTRL_25_REG 0x59
|
||||
#define SP_TX_VIDEO_BIT_CTRL_26_REG 0x5a
|
||||
#define SP_TX_VIDEO_BIT_CTRL_27_REG 0x5b
|
||||
#define SP_TX_VIDEO_BIT_CTRL_28_REG 0x5c
|
||||
#define SP_TX_VIDEO_BIT_CTRL_29_REG 0x5d
|
||||
#define SP_TX_VIDEO_BIT_CTRL_30_REG 0x5e
|
||||
#define SP_TX_VIDEO_BIT_CTRL_31_REG 0x5f
|
||||
#define SP_TX_VIDEO_BIT_CTRL_32_REG 0x60
|
||||
#define SP_TX_VIDEO_BIT_CTRL_33_REG 0x61
|
||||
#define SP_TX_VIDEO_BIT_CTRL_34_REG 0x62
|
||||
#define SP_TX_VIDEO_BIT_CTRL_35_REG 0x63
|
||||
#define SP_TX_VIDEO_BIT_CTRL_36_REG 0x64
|
||||
#define SP_TX_VIDEO_BIT_CTRL_37_REG 0x65
|
||||
#define SP_TX_VIDEO_BIT_CTRL_38_REG 0x66
|
||||
#define SP_TX_VIDEO_BIT_CTRL_39_REG 0x67
|
||||
#define SP_TX_VIDEO_BIT_CTRL_40_REG 0x68
|
||||
#define SP_TX_VIDEO_BIT_CTRL_41_REG 0x69
|
||||
#define SP_TX_VIDEO_BIT_CTRL_42_REG 0x6a
|
||||
#define SP_TX_VIDEO_BIT_CTRL_43_REG 0x6b
|
||||
#define SP_TX_VIDEO_BIT_CTRL_44_REG 0x6c
|
||||
#define SP_TX_VIDEO_BIT_CTRL_45_REG 0x6d
|
||||
#define SP_TX_VIDEO_BIT_CTRL_46_REG 0x6e
|
||||
#define SP_TX_VIDEO_BIT_CTRL_47_REG 0x6f
|
||||
|
||||
/* AVI info frame */
|
||||
#define SP_TX_AVI_TYPE 0x70
|
||||
#define SP_TX_AVI_VER 0x71
|
||||
#define SP_TX_AVI_LEN 0x72
|
||||
#define SP_TX_AVI_DB0 0x73
|
||||
#define SP_TX_AVI_DB1 0x74
|
||||
#define SP_TX_AVI_DB2 0x75
|
||||
#define SP_TX_AVI_DB3 0x76
|
||||
#define SP_TX_AVI_DB4 0x77
|
||||
#define SP_TX_AVI_DB5 0x78
|
||||
#define SP_TX_AVI_DB6 0x79
|
||||
#define SP_TX_AVI_DB7 0x7A
|
||||
#define SP_TX_AVI_DB8 0x7B
|
||||
#define SP_TX_AVI_DB9 0x7C
|
||||
#define SP_TX_AVI_DB10 0x7D
|
||||
#define SP_TX_AVI_DB11 0x7E
|
||||
#define SP_TX_AVI_DB12 0x7F
|
||||
#define SP_TX_AVI_DB13 0x80
|
||||
#define SP_TX_AVI_DB14 0x81
|
||||
#define SP_TX_AVI_DB15 0x82
|
||||
|
||||
/* Audio info frame */
|
||||
#define SP_TX_AUD_TYPE 0x83
|
||||
#define SP_TX_AUD_VER 0x84
|
||||
#define SP_TX_AUD_LEN 0x85
|
||||
#define SP_TX_AUD_DB0 0x86
|
||||
#define SP_TX_AUD_DB1 0x87
|
||||
#define SP_TX_AUD_DB2 0x88
|
||||
#define SP_TX_AUD_DB3 0x89
|
||||
#define SP_TX_AUD_DB4 0x8A
|
||||
#define SP_TX_AUD_DB5 0x8B
|
||||
#define SP_TX_AUD_DB6 0x8C
|
||||
#define SP_TX_AUD_DB7 0x8D
|
||||
#define SP_TX_AUD_DB8 0x8E
|
||||
#define SP_TX_AUD_DB9 0x8F
|
||||
#define SP_TX_AUD_DB10 0x90
|
||||
|
||||
/* SPD info frame */
|
||||
#define SP_TX_SPD_TYPE 0x91
|
||||
#define SP_TX_SPD_VER 0x92
|
||||
#define SP_TX_SPD_LEN 0x93
|
||||
#define SP_TX_SPD_DATA0 0x94
|
||||
#define SP_TX_SPD_DATA1 0x95
|
||||
#define SP_TX_SPD_DATA2 0x96
|
||||
#define SP_TX_SPD_DATA3 0x97
|
||||
#define SP_TX_SPD_DATA4 0x98
|
||||
#define SP_TX_SPD_DATA5 0x99
|
||||
#define SP_TX_SPD_DATA6 0x9A
|
||||
#define SP_TX_SPD_DATA7 0x9B
|
||||
#define SP_TX_SPD_DATA8 0x9C
|
||||
#define SP_TX_SPD_DATA9 0x9D
|
||||
#define SP_TX_SPD_DATA10 0x9E
|
||||
#define SP_TX_SPD_DATA11 0x9F
|
||||
#define SP_TX_SPD_DATA12 0xA0
|
||||
#define SP_TX_SPD_DATA13 0xA1
|
||||
#define SP_TX_SPD_DATA14 0xA2
|
||||
#define SP_TX_SPD_DATA15 0xA3
|
||||
#define SP_TX_SPD_DATA16 0xA4
|
||||
#define SP_TX_SPD_DATA17 0xA5
|
||||
#define SP_TX_SPD_DATA18 0xA6
|
||||
#define SP_TX_SPD_DATA19 0xA7
|
||||
#define SP_TX_SPD_DATA20 0xA8
|
||||
#define SP_TX_SPD_DATA21 0xA9
|
||||
#define SP_TX_SPD_DATA22 0xAA
|
||||
#define SP_TX_SPD_DATA23 0xAB
|
||||
#define SP_TX_SPD_DATA24 0xAC
|
||||
#define SP_TX_SPD_DATA25 0xAD
|
||||
#define SP_TX_SPD_DATA26 0xAE
|
||||
#define SP_TX_SPD_DATA27 0xAF
|
||||
|
||||
/* Mpeg source info frame */
|
||||
#define SP_TX_MPEG_TYPE 0xB0
|
||||
#define SP_TX_MPEG_VER 0xB1
|
||||
#define SP_TX_MPEG_LEN 0xB2
|
||||
#define SP_TX_MPEG_DATA0 0xB3
|
||||
#define SP_TX_MPEG_DATA1 0xB4
|
||||
#define SP_TX_MPEG_DATA2 0xB5
|
||||
#define SP_TX_MPEG_DATA3 0xB6
|
||||
#define SP_TX_MPEG_DATA4 0xB7
|
||||
#define SP_TX_MPEG_DATA5 0xB8
|
||||
#define SP_TX_MPEG_DATA6 0xB9
|
||||
#define SP_TX_MPEG_DATA7 0xBA
|
||||
#define SP_TX_MPEG_DATA8 0xBB
|
||||
#define SP_TX_MPEG_DATA9 0xBC
|
||||
#define SP_TX_MPEG_DATA10 0xBD
|
||||
#define SP_TX_MPEG_DATA11 0xBE
|
||||
#define SP_TX_MPEG_DATA12 0xBF
|
||||
#define SP_TX_MPEG_DATA13 0xC0
|
||||
#define SP_TX_MPEG_DATA14 0xC1
|
||||
#define SP_TX_MPEG_DATA15 0xC2
|
||||
#define SP_TX_MPEG_DATA16 0xC3
|
||||
#define SP_TX_MPEG_DATA17 0xC4
|
||||
#define SP_TX_MPEG_DATA18 0xC5
|
||||
#define SP_TX_MPEG_DATA19 0xC6
|
||||
#define SP_TX_MPEG_DATA20 0xC7
|
||||
#define SP_TX_MPEG_DATA21 0xC8
|
||||
#define SP_TX_MPEG_DATA22 0xC9
|
||||
#define SP_TX_MPEG_DATA23 0xCA
|
||||
#define SP_TX_MPEG_DATA24 0xCB
|
||||
#define SP_TX_MPEG_DATA25 0xCC
|
||||
#define SP_TX_MPEG_DATA26 0xCD
|
||||
#define SP_TX_MPEG_DATA27 0xCE
|
||||
|
||||
/* #define GNSS_CTRL_REG 0xCD */
|
||||
/* bit position */
|
||||
/* #define ENABLE_SSC_FILTER 0x80 */
|
||||
|
||||
/* #define SSC_D_VALUE 0xD0 */
|
||||
/* #define SSC_CTRL_REG2 0xD1 */
|
||||
|
||||
#define ANALOG_DEBUG_REG1 0xDC
|
||||
/* bit position */
|
||||
#define ANALOG_SEL_BG 0x40
|
||||
#define ANALOG_SWING_A_30PER 0x08
|
||||
|
||||
#define ANALOG_DEBUG_REG2 0xDD
|
||||
/* bit position */
|
||||
#define ANALOG_24M_SEL 0x08
|
||||
/* #define ANALOG_FILTER_ENABLED 0x10 */
|
||||
|
||||
|
||||
#define ANALOG_DEBUG_REG3 0xDE
|
||||
|
||||
#define PLL_FILTER_CTRL1 0xDF
|
||||
/* bit position */
|
||||
#define PD_RING_OSC 0x40
|
||||
|
||||
#define PLL_FILTER_CTRL2 0xE0
|
||||
#define PLL_FILTER_CTRL3 0xE1
|
||||
#define PLL_FILTER_CTRL4 0xE2
|
||||
#define PLL_FILTER_CTRL5 0xE3
|
||||
#define PLL_FILTER_CTRL6 0xE4
|
||||
|
||||
#define SP_TX_I2S_CTRL 0xE6
|
||||
#define SP_TX_I2S_FMT 0xE7
|
||||
#define SP_TX_I2S_CH_Status1 0xD0
|
||||
#define SP_TX_I2S_CH_Status2 0xD1
|
||||
#define SP_TX_I2S_CH_Status3 0xD2
|
||||
#define SP_TX_I2S_CH_Status4 0xD3
|
||||
#define SP_TX_I2S_CH_Status5 0xD4
|
||||
|
||||
/* interrupt */
|
||||
#define SP_COMMON_INT_STATUS1 0xF1
|
||||
/* bit position */
|
||||
#define SP_COMMON_INT1_PLL_LOCK_CHG 0x40
|
||||
#define SP_COMMON_INT1_VIDEO_FORMAT_CHG 0x08
|
||||
#define SP_COMMON_INT1_AUDIO_CLK_CHG 0x04
|
||||
#define SP_COMMON_INT1_VIDEO_CLOCK_CHG 0x02
|
||||
|
||||
|
||||
#define SP_COMMON_INT_STATUS2 0xF2
|
||||
/* bit position */
|
||||
#define SP_COMMON_INT2_AUTHCHG 0x02
|
||||
#define SP_COMMON_INT2_AUTHDONE 0x01
|
||||
|
||||
#define SP_COMMON_INT_STATUS3 0xF3
|
||||
/* bit position */
|
||||
#define SP_COMMON_INT3_AFIFO_UNDER 0x80
|
||||
#define SP_COMMON_INT3_AFIFO_OVER 0x40
|
||||
|
||||
#define SP_COMMON_INT_STATUS4 0xF4
|
||||
/* bit position */
|
||||
#define SP_COMMON_INT4_PLUG 0x01
|
||||
#define SP_COMMON_INT4_ESYNC_ERR 0x10
|
||||
#define SP_COMMON_INT4_HPDLOST 0x02
|
||||
#define SP_COMMON_INT4_HPD_CHANGE 0x04
|
||||
|
||||
|
||||
#define SP_TX_INT_STATUS1 0xF7
|
||||
/* bit position */
|
||||
#define SP_TX_INT_STATUS1_HPD 0x40
|
||||
#define SP_TX_INT_STATUS1_TRAINING_Finish 0x20
|
||||
#define SP_TX_INT_STATUS1_POLLING_ERR 0x10
|
||||
#define SP_TX_INT_SINK_CHG 0x08
|
||||
|
||||
/* interrupt mask */
|
||||
#define SP_COMMON_INT_MASK1 0xF8
|
||||
#define SP_COMMON_INT_MASK2 0xF9
|
||||
#define SP_COMMON_INT_MASK3 0xFA
|
||||
#define SP_COMMON_INT_MASK4 0xFB
|
||||
#define SP_INT_MASK 0xFE
|
||||
#define SP_TX_INT_CTRL_REG 0xFF
|
||||
/* End for dev_addr 0x72 or 0x76 */
|
||||
|
||||
/***************************************************************/
|
||||
/***************************************************************/
|
||||
|
||||
/* DPCD regs */
|
||||
#define DPCD_DPCD_REV 0x00
|
||||
#define DPCD_MAX_LINK_RATE 0x01
|
||||
#define DPCD_MAX_LANE_COUNT 0x02
|
||||
#define DPCD_MAX_DOWNSPREAD 0x03
|
||||
#define DPCD_NORP 0x04
|
||||
#define DPCD_DOWNSTREAMPORT_PRESENT 0x05
|
||||
|
||||
#define DPCD_RECEIVE_PORT0_CAP_0 0x08
|
||||
#define DPCD_RECEIVE_PORT0_CAP_1 0x09
|
||||
#define DPCD_RECEIVE_PORT0_CAP_2 0x0a
|
||||
#define DPCD_RECEIVE_PORT0_CAP_3 0x0b
|
||||
|
||||
#define DPCD_LINK_BW_SET 0x00
|
||||
#define DPCD_LANE_COUNT_SET 0x01
|
||||
#define DPCD_TRAINING_PATTERN_SET 0x02
|
||||
#define DPCD_TRAINNIG_LANE0_SET 0x03
|
||||
#define DPCD_TRAINNIG_LANE1_SET 0x04
|
||||
#define DPCD_TRAINNIG_LANE2_SET 0x05
|
||||
#define DPCD_TRAINNIG_LANE3_SET 0x06
|
||||
#define DPCD_DOWNSPREAD_CTRL 0x07
|
||||
|
||||
#define DPCD_SINK_COUNT 0x00
|
||||
#define DPCD_DEVICE_SERVICE_IRQ_VECTOR 0x01
|
||||
#define DPCD_LANE0_1_STATUS 0x02
|
||||
#define DPCD_LANE2_3_STATUS 0x03
|
||||
#define DPCD_LANE_ALIGN_STATUS_UPDATED 0x04
|
||||
#define DPCD_SINK_STATUS 0x05
|
||||
#define DPCD_ADJUST_REQUEST_LANE0_1 0x06
|
||||
#define DPCD_ADJUST_REQUEST_LANE2_3 0x07
|
||||
#define DPCD_TRAINING_SCORE_LANE0 0x08
|
||||
#define DPCD_TRAINING_SCORE_LANE1 0x09
|
||||
#define DPCD_TRAINING_SCORE_LANE2 0x0a
|
||||
#define DPCD_TRAINING_SCORE_LANE3 0x0b
|
||||
|
||||
#define DPCD_TEST_REQUEST 0x18
|
||||
#define DPCD_TEST_LINK_RATE 0x19
|
||||
|
||||
#define DPCD_TEST_LANE_COUNT 0x20
|
||||
|
||||
#define DPCD_TEST_Response 0x60
|
||||
#define TEST_ACK 0x01
|
||||
/* bit position */
|
||||
#define DPCD_TEST_EDID_Checksum_Write 0x04
|
||||
|
||||
#define DPCD_TEST_EDID_Checksum 0x61
|
||||
|
||||
|
||||
#define DPCD_SPECIFIC_INTERRUPT 0x10
|
||||
/* define for downstream HDMI Rx sense detection */
|
||||
#define DPCD_USER_COMM1 0x22
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
242
drivers/amlogic/media/vout/lcd/lcd_extern/i2c_tc101.c
Normal file
242
drivers/amlogic/media/vout/lcd/lcd_extern/i2c_tc101.c
Normal file
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_extern/i2c_tc101.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/amlogic/i2c-amlogic.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_extern.h>
|
||||
#include "lcd_extern.h"
|
||||
|
||||
static struct lcd_extern_config_s *ext_config;
|
||||
static struct i2c_client *aml_tc101_i2c_client;
|
||||
|
||||
#define LCD_EXTERN_NAME "lcd_i2c_tc101"
|
||||
|
||||
static unsigned char i2c_init_table[][3] = {
|
||||
/* {0xff, 0xff, 20},//delay mark(20ms) */
|
||||
{0xf8, 0x30, 0xb2},
|
||||
{0xf8, 0x33, 0xc2},
|
||||
{0xf8, 0x31, 0xf0},
|
||||
{0xf8, 0x40, 0x80},
|
||||
{0xf8, 0x81, 0xec},
|
||||
{0xff, 0xff, 0xff},/* end mark */
|
||||
};
|
||||
|
||||
static int aml_i2c_write(struct i2c_client *i2client, unsigned char *buff,
|
||||
unsigned int len)
|
||||
{
|
||||
int ret = 0;
|
||||
struct i2c_msg msg[] = {
|
||||
{
|
||||
.addr = i2client->addr,
|
||||
.flags = 0,
|
||||
.len = len,
|
||||
.buf = buff,
|
||||
},
|
||||
};
|
||||
|
||||
ret = i2c_transfer(i2client->adapter, msg, 1);
|
||||
if (ret < 0) {
|
||||
EXTERR("%s: i2c transfer failed [addr 0x%02x]\n",
|
||||
__func__, i2client->addr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#if 0
|
||||
static int aml_i2c_read(struct i2c_client *i2client, unsigned char *buff,
|
||||
unsigned int len)
|
||||
{
|
||||
int ret = 0;
|
||||
struct i2c_msg msgs[] = {
|
||||
{
|
||||
.addr = i2client->addr,
|
||||
.flags = 0,
|
||||
.len = 1,
|
||||
.buf = buff,
|
||||
},
|
||||
{
|
||||
.addr = i2client->addr,
|
||||
.flags = I2C_M_RD,
|
||||
.len = len,
|
||||
.buf = buff,
|
||||
},
|
||||
};
|
||||
|
||||
ret = i2c_transfer(i2client->adapter, msgs, 2);
|
||||
if (ret < 0) {
|
||||
EXTERR("%s: i2c transfer failed [addr 0x%02x]\n",
|
||||
__func__, i2client->addr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int i2c_reg_read(unsigned char reg, unsigned char *buf)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int i2c_reg_write(unsigned char reg, unsigned char value)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int lcd_extern_power_on(void)
|
||||
{
|
||||
unsigned char tData[4];
|
||||
int i = 0, ending_flag = 0;
|
||||
int ret = 0;
|
||||
|
||||
while (ending_flag == 0) {
|
||||
if ((i2c_init_table[i][0] == 0xff) &&
|
||||
(i2c_init_table[i][1] == 0xff)) { /* special mark */
|
||||
if (i2c_init_table[i][2] == 0xff) /* ending flag */
|
||||
ending_flag = 1;
|
||||
else /* delay flag */
|
||||
mdelay(i2c_init_table[i][2]);
|
||||
} else {
|
||||
tData[0] = i2c_init_table[i][0];
|
||||
tData[1] = i2c_init_table[i][1];
|
||||
tData[2] = i2c_init_table[i][2];
|
||||
aml_i2c_write(aml_tc101_i2c_client, tData, 3);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
EXTPR("%s\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_power_off(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (ext_drv) {
|
||||
ext_drv->power_on = lcd_extern_power_on;
|
||||
ext_drv->power_off = lcd_extern_power_off;
|
||||
} else {
|
||||
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aml_tc101_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
|
||||
EXTERR("%s: functionality check failed\n", __func__);
|
||||
else
|
||||
aml_tc101_i2c_client = client;
|
||||
|
||||
EXTPR("%s OK\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aml_tc101_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id aml_tc101_i2c_id[] = {
|
||||
{LCD_EXTERN_NAME, 0},
|
||||
{ }
|
||||
};
|
||||
/* MODULE_DEVICE_TABLE(i2c, aml_tc101_id); */
|
||||
|
||||
static struct i2c_driver aml_tc101_i2c_driver = {
|
||||
.probe = aml_tc101_i2c_probe,
|
||||
.remove = aml_tc101_i2c_remove,
|
||||
.id_table = aml_tc101_i2c_id,
|
||||
.driver = {
|
||||
.name = LCD_EXTERN_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
int aml_lcd_extern_i2c_tc101_probe(struct aml_lcd_extern_driver_s *ext_drv)
|
||||
{
|
||||
struct i2c_board_info i2c_info;
|
||||
struct i2c_adapter *adapter;
|
||||
struct i2c_client *i2c_client;
|
||||
int ret = 0;
|
||||
|
||||
ext_config = &ext_drv->config;
|
||||
memset(&i2c_info, 0, sizeof(i2c_info));
|
||||
|
||||
adapter = i2c_get_adapter(ext_drv->config.i2c_bus);
|
||||
if (!adapter) {
|
||||
EXTERR("%s failed to get i2c adapter\n", ext_drv->config.name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(i2c_info.type, ext_drv->config.name, I2C_NAME_SIZE);
|
||||
i2c_info.addr = ext_drv->config.i2c_addr;
|
||||
i2c_info.platform_data = &ext_drv->config;
|
||||
i2c_info.flags = 0;
|
||||
if (i2c_info.addr > 0x7f) {
|
||||
EXTERR("%s invalid i2c address: 0x%02x\n",
|
||||
ext_drv->config.name, ext_drv->config.i2c_addr);
|
||||
return -1;
|
||||
}
|
||||
i2c_client = i2c_new_device(adapter, &i2c_info);
|
||||
if (!i2c_client) {
|
||||
EXTERR("%s failed to new i2c device\n", ext_drv->config.name);
|
||||
} else {
|
||||
if (lcd_debug_print_flag) {
|
||||
EXTPR("%s new i2c device succeed\n",
|
||||
ext_drv->config.name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!aml_tc101_i2c_client) {
|
||||
ret = i2c_add_driver(&aml_tc101_i2c_driver);
|
||||
if (ret) {
|
||||
EXTERR("%s add i2c_driver failed\n",
|
||||
ext_drv->config.name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ret = lcd_extern_driver_update(ext_drv);
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
EXTPR("%s: %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
1315
drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.c
Normal file
1315
drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.c
Normal file
File diff suppressed because it is too large
Load Diff
99
drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.dts
Normal file
99
drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.dts
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.dts
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
lcd_extern{
|
||||
compatible = "amlogic, lcd_extern";
|
||||
dev_name = "lcd_extern";
|
||||
status = "okay";
|
||||
|
||||
extern-gpios = <&gpio GPIODV_1 GPIO_ACTIVE_HIGH
|
||||
&gpio GPIODV_16 GPIO_ACTIVE_HIGH
|
||||
&gpio GPIODV_17 GPIO_ACTIVE_HIGH>;
|
||||
extern_gpio_names = "GPIODV_1","GPIODV_16","GPIODV_17";
|
||||
|
||||
extern_0{
|
||||
index = <0>;
|
||||
extern_name = "i2c_T5800Q";
|
||||
status = "disabled";
|
||||
|
||||
type = <0>; /** lcd_extern_driver type: 0=i2c, 1=spi, 2=mipi */
|
||||
i2c_address = <0x1c>; /** 7bit i2c address */
|
||||
i2c_bus = "i2c_bus_d";
|
||||
};
|
||||
|
||||
extern_1{
|
||||
index = <1>;
|
||||
extern_name = "i2c_tc101";
|
||||
status = "disabled";
|
||||
|
||||
type = <0>; /** lcd_extern_driver type: 0=i2c, 1=spi, 2=mipi */
|
||||
i2c_address = <0x7e>; /** 7bit i2c address */
|
||||
i2c_bus = "i2c_bus_a";
|
||||
};
|
||||
|
||||
extern_2{
|
||||
index = <2>;
|
||||
extern_name = "i2c_anx6345";
|
||||
status = "disabled";
|
||||
|
||||
type = <0>; /** lcd_extern_driver type: 0=i2c, 1=spi, 2=mipi */
|
||||
i2c_address = <0x38>; /** 7bit i2c address */
|
||||
i2c_bus = "i2c_bus_b";
|
||||
lane_num = <1>; /** edp lane_num: 1/2/4 */
|
||||
bits = <0>; /** lcd_bits(0=6bit, 1=8bit) */
|
||||
link_rate = <1>; /** edp link rate: (0=1.62G, 1=27G, 2=5.4G) */
|
||||
};
|
||||
|
||||
extern_3{
|
||||
index = <3>;
|
||||
extern_name = "spi_LD070WS2";
|
||||
status = "disabled";
|
||||
|
||||
type = <1>; /** lcd_extern_driver type: 0=i2c, 1=spi, 2=mipi */
|
||||
|
||||
gpio_spi_cs = <0>; /* index in extern-gpios */
|
||||
gpio_spi_clk = <1>; /* index in extern-gpios */
|
||||
gpio_spi_data = <2>; /* index in extern-gpios */
|
||||
};
|
||||
|
||||
extern_4{
|
||||
index = <4>;
|
||||
extern_name = "mipi_N070ICN";
|
||||
status = "disabled";
|
||||
|
||||
type = <2>; /** lcd_extern_driver type: 0=i2c, 1=spi, 2=mipi */
|
||||
};
|
||||
|
||||
extern_5{
|
||||
index = <5>;
|
||||
extern_name = "mipi_KD080D13";
|
||||
status = "disabled";
|
||||
|
||||
type = <2>; /** lcd_extern_driver type: 0=i2c, 1=spi, 2=mipi */
|
||||
};
|
||||
|
||||
extern_6{
|
||||
index = <6>;
|
||||
extern_name = "i2c_DLPC3439";
|
||||
status = "disabled";
|
||||
|
||||
type = <0>; /** lcd_extern_driver type: 0=i2c, 1=spi, 2=mipi */
|
||||
i2c_address = <0x1b>; /** 7bit i2c address */
|
||||
i2c_bus = "i2c_bus_a";
|
||||
};
|
||||
};
|
||||
|
||||
74
drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.h
Normal file
74
drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.h
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LCD_EXTERN_H_
|
||||
#define _LCD_EXTERN_H_
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/amlogic/aml_gpio_consumer.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_vout.h>
|
||||
|
||||
#define EXTPR(fmt, args...) pr_info("lcd extern: "fmt"", ## args)
|
||||
#define EXTERR(fmt, args...) pr_info("lcd extern: error: "fmt"", ## args)
|
||||
|
||||
#define LCD_EXTERN_DRIVER "lcd_extern"
|
||||
|
||||
#ifdef CONFIG_USE_OF
|
||||
extern struct device_node *aml_lcd_extern_get_dts_child(int index);
|
||||
#endif
|
||||
extern void lcd_extern_gpio_register(unsigned char index);
|
||||
extern void lcd_extern_gpio_set(unsigned char index, int value);
|
||||
extern unsigned int lcd_extern_gpio_get(unsigned char index);
|
||||
|
||||
#define LCD_EXTERN_DEFAULT_ENABLE
|
||||
|
||||
#ifdef LCD_EXTERN_DEFAULT_ENABLE
|
||||
extern int aml_lcd_extern_default_probe(
|
||||
struct aml_lcd_extern_driver_s *ext_drv);
|
||||
#endif
|
||||
#ifdef CONFIG_AMLOGIC_LCD_EXTERN_I2C_T5800Q
|
||||
extern int aml_lcd_extern_i2c_T5800Q_probe(
|
||||
struct aml_lcd_extern_driver_s *ext_drv);
|
||||
#endif
|
||||
#ifdef CONFIG_AMLOGIC_LCD_EXTERN_I2C_DLPC3439
|
||||
extern int aml_lcd_extern_i2c_DLPC3439_probe(
|
||||
struct aml_lcd_extern_driver_s *ext_drv);
|
||||
#endif
|
||||
#ifdef CONFIG_AMLOGIC_LCD_EXTERN_I2C_TC101
|
||||
extern int aml_lcd_extern_i2c_tc101_probe(
|
||||
struct aml_lcd_extern_driver_s *ext_drv);
|
||||
#endif
|
||||
#ifdef CONFIG_AMLOGIC_LCD_EXTERN_I2C_ANX6345
|
||||
extern int aml_lcd_extern_i2c_anx6345_probe(
|
||||
struct aml_lcd_extern_driver_s *ext_drv);
|
||||
#endif
|
||||
#ifdef CONFIG_AMLOGIC_LCD_EXTERN_SPI_LD070WS2
|
||||
extern int aml_lcd_extern_spi_LD070WS2_probe(
|
||||
struct aml_lcd_extern_driver_s *ext_drv);
|
||||
#endif
|
||||
#ifdef CONFIG_AMLOGIC_LCD_EXTERN_MIPI_N070ICN
|
||||
extern int aml_lcd_extern_mipi_N070ICN_probe(
|
||||
struct aml_lcd_extern_driver_s *ext_drv);
|
||||
#endif
|
||||
#ifdef CONFIG_AMLOGIC_LCD_EXTERN_MIPI_KD080D13
|
||||
extern int aml_lcd_extern_mipi_KD080D13_probe(
|
||||
struct aml_lcd_extern_driver_s *ext_drv);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
129
drivers/amlogic/media/vout/lcd/lcd_extern/mipi_KD080D13.c
Normal file
129
drivers/amlogic/media/vout/lcd/lcd_extern/mipi_KD080D13.c
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_extern/mipi_KD080D13.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/amlogic/i2c-amlogic.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_extern.h>
|
||||
#include "lcd_extern.h"
|
||||
|
||||
#define LCD_EXTERN_NAME "lcd_mipi_KD080D13"
|
||||
|
||||
/* ******************** mipi command ********************
|
||||
* format: data_type, num, data....
|
||||
* special: data_type=0xff, num<0xff means delay ms, num=0xff means ending.
|
||||
*/
|
||||
static unsigned char mipi_init_on_table[] = {
|
||||
0x39, 3, 0xf0, 0x5a, 0x5a,
|
||||
0x39, 3, 0xf1, 0x5a, 0x5a,
|
||||
0x39, 3, 0xfc, 0xa5, 0xa5,
|
||||
0x39, 3, 0xd0, 0x00, 0x10,
|
||||
0x15, 2, 0xb1, 0x10,
|
||||
0x39, 5, 0xb2, 0x14, 0x22, 0x2f, 0x04,
|
||||
0x39, 6, 0xf2, 0x02, 0x08, 0x08, 0x40, 0x10,
|
||||
0x15, 2, 0xb0, 0x03,
|
||||
0x39, 3, 0xfd, 0x23, 0x09,
|
||||
0x39, 11, 0xf3, 0x01, 0x93, 0x20, 0x22, 0x80, 0x05, 0x25, 0x3c, 0x26,
|
||||
0x00,
|
||||
0x39, 46, 0xf4, 0x00, 0x02, 0x03, 0x26, 0x03, 0x02, 0x09, 0x00, 0x07,
|
||||
0x16, 0x16, 0x03, 0x00, 0x08, 0x08, 0x03, 0x0E, 0x0F, 0x12,
|
||||
0x1C, 0x1D, 0x1E, 0x0C, 0x09, 0x01, 0x04, 0x02, 0x61, 0x74,
|
||||
0x75, 0x72, 0x83, 0x80, 0x80, 0xB0, 0x00, 0x01, 0x01, 0x28,
|
||||
0x04, 0x03, 0x28, 0x01, 0xD1, 0x32,
|
||||
0x39, 27, 0xf5, 0x84, 0x2F, 0x2F, 0x5F, 0xAB, 0x98, 0x52, 0x0F, 0x33,
|
||||
0x43, 0x04, 0x59, 0x54, 0x52, 0x05, 0x40, 0x60, 0x4E, 0x60,
|
||||
0x40, 0x27, 0x26, 0x52, 0x25, 0x6D, 0x18,
|
||||
0x39, 9, 0xee, 0x25, 0x00, 0x25, 0x00, 0x25, 0x00, 0x25, 0x00,
|
||||
0x39, 9, 0xef, 0x34, 0x12, 0x98, 0xBA, 0x20, 0x00, 0x24, 0x80,
|
||||
0x39, 33, 0xf7, 0x0E, 0x0E, 0x0A, 0x0A, 0x0F, 0x0F, 0x0B, 0x0B, 0x05,
|
||||
0x07, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0C, 0x0C, 0x08,
|
||||
0x08, 0x0D, 0x0D, 0x09, 0x09, 0x04, 0x06, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01,
|
||||
0x39, 4, 0xbc, 0x01, 0x4e, 0x0a,
|
||||
0x39, 6, 0xe1, 0x03, 0x10, 0x1c, 0xa0, 0x10,
|
||||
0x39, 7, 0xf6, 0x60, 0x21, 0xA6, 0x00, 0x00, 0x00,
|
||||
0x39, 7, 0xfe, 0x00, 0x0D, 0x03, 0x21, 0x80, 0x48,
|
||||
0x15, 2, 0xb0, 0x22,
|
||||
0x39, 18, 0xfa, 0x02, 0x34, 0x09, 0x13, 0x0B, 0x0F, 0x16, 0x16, 0x17,
|
||||
0x1E, 0x1D, 0x1C, 0x1E, 0x1D, 0x1D, 0x1F, 0x24,
|
||||
0x15, 2, 0xb0, 0x22,
|
||||
0x39, 18, 0xfb, 0x00, 0x34, 0x07, 0x11, 0x09, 0x0D, 0x14, 0x14, 0x15,
|
||||
0x1C, 0x1F, 0x1C, 0x1D, 0x1D, 0x1D, 0x20, 0x26,
|
||||
0x15, 2, 0xb0, 0x11,
|
||||
0x39, 18, 0xfa, 0x20, 0x34, 0x24, 0x27, 0x19, 0x1B, 0x1F, 0x1E, 0x1B,
|
||||
0x1F, 0x21, 0x1F, 0x1E, 0x20, 0x1E, 0x1E, 0x21,
|
||||
0x15, 2, 0xb0, 0x11,
|
||||
0x39, 18, 0xfb, 0x1E, 0x34, 0x22, 0x25, 0x17, 0x19, 0x1D, 0x1A, 0x19,
|
||||
0x20, 0x1F, 0x1E, 0x20, 0x1E, 0x1E, 0x1F, 0x22,
|
||||
0x39, 18, 0xfa, 0x1C, 0x34, 0x1C, 0x1F, 0x13, 0x17, 0x1A, 0x18, 0x18,
|
||||
0x1E, 0x20, 0x21, 0x21, 0x21, 0x23, 0x22, 0x2A,
|
||||
0x39, 18, 0xfb, 0x1A, 0x34, 0x1A, 0x1D, 0x11, 0x15, 0x18, 0x16, 0x16,
|
||||
0x1C, 0x20, 0x20, 0x20, 0x1F, 0x23, 0x23, 0x2B,
|
||||
|
||||
0x05, 1, 0x11,
|
||||
0xff, 20,
|
||||
0x39, 4, 0xc3, 0x40, 0x00, 0x28,
|
||||
0xff, 200,
|
||||
0x15, 2, 0x35, 0x00,
|
||||
0x05, 1, 0x29,
|
||||
0xff, 30, /* delay 30ms */
|
||||
0xff, 0xff, /* ending flag */
|
||||
};
|
||||
|
||||
static unsigned char mipi_init_off_table[] = {
|
||||
0x05, 1, 0x28, /* display off */
|
||||
0xff, 30, /* delay 30ms */
|
||||
0x05, 1, 0x10, /* sleep in */
|
||||
0xff, 30, /* delay 30ms */
|
||||
0x39, 4, 0xc3, 0x40, 0x00, 0x20,
|
||||
0xff, 10,
|
||||
0xff, 0xff, /* ending flag */
|
||||
};
|
||||
|
||||
static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (ext_drv) {
|
||||
ext_drv->config.table_init_on = &mipi_init_on_table[0];
|
||||
ext_drv->config.table_init_off = &mipi_init_off_table[0];
|
||||
} else {
|
||||
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int aml_lcd_extern_mipi_KD080D13_probe(struct aml_lcd_extern_driver_s *ext_drv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = lcd_extern_driver_update(ext_drv);
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
EXTPR("%s: %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
246
drivers/amlogic/media/vout/lcd/lcd_extern/mipi_N070ICN.c
Normal file
246
drivers/amlogic/media/vout/lcd/lcd_extern/mipi_N070ICN.c
Normal file
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_extern/mipi_N070ICN.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/amlogic/i2c-amlogic.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_extern.h>
|
||||
#include "lcd_extern.h"
|
||||
|
||||
#define LCD_EXTERN_NAME "lcd_mipi_N070ICN"
|
||||
|
||||
/* ******************** mipi command ********************
|
||||
* format: data_type, num, data....
|
||||
* special: data_type=0xff, num<0xff means delay ms, num=0xff means ending.
|
||||
*/
|
||||
static unsigned char mipi_init_on_table[] = {
|
||||
/* ========== Internal setting ========== */
|
||||
0x39, 5, 0xFF, 0xAA, 0x55, 0xA5, 0x80,
|
||||
|
||||
0x39, 3, 0x6F, 0x11, 0x00, /* MIPI related Timing Setting */
|
||||
0x39, 3, 0xF7, 0x20, 0x00,
|
||||
|
||||
0x15, 2, 0x6F, 0x06, /* Improve ESD option */
|
||||
0x15, 2, 0xF7, 0xA0,
|
||||
0x15, 2, 0x6F, 0x19,
|
||||
0x15, 2, 0xF7, 0x12,
|
||||
|
||||
0x15, 2, 0x6F, 0x08, /* Vcom floating */
|
||||
0x15, 2, 0xFA, 0x40,
|
||||
0x15, 2, 0x6F, 0x11,
|
||||
0x15, 2, 0xF3, 0x01,
|
||||
|
||||
/* ========== page0 relative ========== */
|
||||
0x39, 6, 0xF0, 0x55, 0xAA, 0x52, 0x08, 0x00,
|
||||
0x15, 2, 0xC8, 0x80,
|
||||
|
||||
0x39, 3, 0xB1, 0x6C, 0x01, /* Set WXGA resolution */
|
||||
|
||||
0x15, 2, 0xB6, 0x08, /* Set source output hold time */
|
||||
|
||||
0x15, 2, 0x6F, 0x02, /* EQ control function */
|
||||
0x15, 2, 0xB8, 0x08,
|
||||
|
||||
0x39, 3, 0xBB, 0x54, 0x54, /* Set bias current for GOP and SOP */
|
||||
|
||||
0x39, 3, 0xBC, 0x05, 0x05, /* Inversion setting */
|
||||
|
||||
0x15, 2, 0xC7, 0x01, /* zigzag setting */
|
||||
|
||||
/* DSP Timing Settings update for BIST */
|
||||
0x39, 6, 0xBD, 0x02, 0xB0, 0x0C, 0x0A, 0x00,
|
||||
|
||||
/* ========== page1 relative ========== */
|
||||
0x39, 6, 0xF0, 0x55, 0xAA, 0x52, 0x08, 0x01,
|
||||
|
||||
0x39, 3, 0xB0, 0x05, 0x05, /* Setting AVDD, AVEE clamp */
|
||||
0x39, 3, 0xB1, 0x05, 0x05,
|
||||
|
||||
0x39, 3, 0xBC, 0x3A, 0x01, /* VGMP, VGMN, VGSP, VGSN setting */
|
||||
0x39, 3, 0xBD, 0x3E, 0x01,
|
||||
|
||||
0x15, 2, 0xCA, 0x00, /* gate signal control */
|
||||
|
||||
0x15, 2, 0xC0, 0x04, /* power IC control */
|
||||
0x15, 2, 0xB2, 0x00,
|
||||
0x15, 2, 0xBE, 0x80, /*vcom -1.88V */
|
||||
|
||||
0x39, 3, 0xB3, 0x19, 0x19, /* Setting VGH=15V, VGL=-11V */
|
||||
0x39, 3, 0xB4, 0x12, 0x12,
|
||||
|
||||
0x39, 3, 0xB9, 0x24, 0x24, /* power control for VGH, VGL */
|
||||
0x39, 3, 0xBA, 0x14, 0x14,
|
||||
|
||||
/* ========== page2 relative ========== */
|
||||
0x39, 6, 0xF0, 0x55, 0xAA, 0x52, 0x08, 0x02,
|
||||
|
||||
0x15, 2, 0xEE, 0x01, /* Gamma setting */
|
||||
/* Gradient Control for Gamma Voltage */
|
||||
0x39, 5, 0xEF, 0x09, 0x06, 0x15, 0x18,
|
||||
|
||||
/* ========== GOA relative ========== */
|
||||
0x39, 7, 0xB0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x17,
|
||||
0x15, 2, 0x6F, 0x06,
|
||||
0x39, 7, 0xB0, 0x00, 0x25, 0x00, 0x30, 0x00, 0x45,
|
||||
0x15, 2, 0x6F, 0x0C,
|
||||
0x39, 5, 0xB0, 0x00, 0x56, 0x00, 0x7A,
|
||||
0x39, 7, 0xB1, 0x00, 0xA3, 0x00, 0xE7, 0x01, 0x20,
|
||||
0x15, 2, 0x6F, 0x06,
|
||||
0x39, 7, 0xB1, 0x01, 0x7A, 0x01, 0xC2, 0x01, 0xC5,
|
||||
0x15, 2, 0x6F, 0x0C,
|
||||
0x39, 5, 0xB1, 0x02, 0x06, 0x02, 0x5F,
|
||||
0x39, 7, 0xB2, 0x02, 0x92, 0x02, 0xD0, 0x02, 0xFC,
|
||||
0x15, 2, 0x6F, 0x06,
|
||||
0x39, 7, 0xB2, 0x03, 0x35, 0x03, 0x5D, 0x03, 0x8B,
|
||||
0x15, 2, 0x6F, 0x0C,
|
||||
0x39, 5, 0xB2, 0x03, 0xA2, 0x03, 0xBF,
|
||||
0x39, 5, 0xB3, 0x03, 0xD2, 0x03, 0xFF,
|
||||
|
||||
/* PAGE6 : GOUT Mapping, VGLO select */
|
||||
0x39, 6, 0xF0, 0x55, 0xAA, 0x52, 0x08, 0x06,
|
||||
0x39, 3, 0xB0, 0x00, 0x17,
|
||||
0x39, 3, 0xB1, 0x16, 0x15,
|
||||
0x39, 3, 0xB2, 0x14, 0x13,
|
||||
0x39, 3, 0xB3, 0x12, 0x11,
|
||||
0x39, 3, 0xB4, 0x10, 0x2D,
|
||||
0x39, 3, 0xB5, 0x01, 0x08,
|
||||
0x39, 3, 0xB6, 0x09, 0x31,
|
||||
0x39, 3, 0xB7, 0x31, 0x31,
|
||||
0x39, 3, 0xB8, 0x31, 0x31,
|
||||
0x39, 3, 0xB9, 0x31, 0x31,
|
||||
0x39, 3, 0xBA, 0x31, 0x31,
|
||||
0x39, 3, 0xBB, 0x31, 0x31,
|
||||
0x39, 3, 0xBC, 0x31, 0x31,
|
||||
0x39, 3, 0xBD, 0x31, 0x09,
|
||||
0x39, 3, 0xBE, 0x08, 0x01,
|
||||
0x39, 3, 0xBF, 0x2D, 0x10,
|
||||
0x39, 3, 0xC0, 0x11, 0x12,
|
||||
0x39, 3, 0xC1, 0x13, 0x14,
|
||||
0x39, 3, 0xC2, 0x15, 0x16,
|
||||
0x39, 3, 0xC3, 0x17, 0x00,
|
||||
0x39, 3, 0xE5, 0x31, 0x31,
|
||||
0x39, 3, 0xC4, 0x00, 0x17,
|
||||
0x39, 3, 0xC5, 0x16, 0x15,
|
||||
0x39, 3, 0xC6, 0x14, 0x13,
|
||||
0x39, 3, 0xC7, 0x12, 0x11,
|
||||
0x39, 3, 0xC8, 0x10, 0x2D,
|
||||
0x39, 3, 0xC9, 0x01, 0x08,
|
||||
0x39, 3, 0xCA, 0x09, 0x31,
|
||||
0x39, 3, 0xCB, 0x31, 0x31,
|
||||
0x39, 3, 0xCC, 0x31, 0x31,
|
||||
0x39, 3, 0xCD, 0x31, 0x31,
|
||||
0x39, 3, 0xCE, 0x31, 0x31,
|
||||
0x39, 3, 0xCF, 0x31, 0x31,
|
||||
0x39, 3, 0xD0, 0x31, 0x31,
|
||||
0x39, 3, 0xD1, 0x31, 0x09,
|
||||
0x39, 3, 0xD2, 0x08, 0x01,
|
||||
0x39, 3, 0xD3, 0x2D, 0x10,
|
||||
0x39, 3, 0xD4, 0x11, 0x12,
|
||||
0x39, 3, 0xD5, 0x13, 0x14,
|
||||
0x39, 3, 0xD6, 0x15, 0x16,
|
||||
0x39, 3, 0xD7, 0x17, 0x00,
|
||||
0x39, 3, 0xE6, 0x31, 0x31,
|
||||
0x39, 6, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, /* VGL level select; */
|
||||
0x39, 6, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x15, 2, 0xE7, 0x00,
|
||||
|
||||
/* ===page 3====//gate timing control */
|
||||
0x39, 6, 0xF0, 0x55, 0xAA, 0x52, 0x08, 0x03,
|
||||
0x39, 3, 0xB0, 0x20, 0x00,
|
||||
0x39, 3, 0xB1, 0x20, 0x00,
|
||||
0x39, 6, 0xB2, 0x05, 0x00, 0x42, 0x00, 0x00,
|
||||
0x39, 6, 0xB6, 0x05, 0x00, 0x42, 0x00, 0x00,
|
||||
0x39, 6, 0xBA, 0x53, 0x00, 0x42, 0x00, 0x00,
|
||||
0x39, 6, 0xBB, 0x53, 0x00, 0x42, 0x00, 0x00,
|
||||
0x15, 2, 0xC4, 0x40,
|
||||
|
||||
/* ===page 5==== */
|
||||
0x39, 6, 0xF0, 0x55, 0xAA, 0x52, 0x08, 0x05,
|
||||
0x39, 3, 0xB0, 0x17, 0x06,
|
||||
0x15, 2, 0xB8, 0x00,
|
||||
0x39, 6, 0xBD, 0x03, 0x01, 0x01, 0x00, 0x01,
|
||||
0x39, 3, 0xB1, 0x17, 0x06,
|
||||
0x39, 3, 0xB9, 0x00, 0x01,
|
||||
0x39, 3, 0xB2, 0x17, 0x06,
|
||||
0x39, 3, 0xBA, 0x00, 0x01,
|
||||
0x39, 3, 0xB3, 0x17, 0x06,
|
||||
0x39, 3, 0xBB, 0x0A, 0x00,
|
||||
0x39, 3, 0xB4, 0x17, 0x06,
|
||||
0x39, 3, 0xB5, 0x17, 0x06,
|
||||
0x39, 3, 0xB6, 0x14, 0x03,
|
||||
0x39, 3, 0xB7, 0x00, 0x00,
|
||||
0x39, 3, 0xBC, 0x02, 0x01,
|
||||
0x15, 2, 0xC0, 0x05,
|
||||
0x15, 2, 0xC4, 0xA5,
|
||||
0x39, 3, 0xC8, 0x03, 0x30,
|
||||
0x39, 3, 0xC9, 0x03, 0x51,
|
||||
0x39, 6, 0xD1, 0x00, 0x05, 0x03, 0x00, 0x00,
|
||||
0x39, 6, 0xD2, 0x00, 0x05, 0x09, 0x00, 0x00,
|
||||
0x15, 2, 0xE5, 0x02,
|
||||
0x15, 2, 0xE6, 0x02,
|
||||
0x15, 2, 0xE7, 0x02,
|
||||
0x15, 2, 0xE9, 0x02,
|
||||
0x15, 2, 0xED, 0x33,
|
||||
|
||||
0x05, 1, 0x11, /* sleep out */
|
||||
0xff, 30, /* delay 30ms */
|
||||
0x05, 1, 0x29, /* display on */
|
||||
0xff, 30, /* delay 30ms */
|
||||
0xff, 0xff, /* ending flag */
|
||||
};
|
||||
|
||||
static unsigned char mipi_init_off_table[] = {
|
||||
0x05, 1, 0x28, /* display off */
|
||||
0xff, 10, /* delay 10ms */
|
||||
0x05, 1, 0x10, /* sleep in */
|
||||
0xff, 10, /* delay 10ms */
|
||||
0xff, 0xff, /* ending flag */
|
||||
};
|
||||
|
||||
static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (ext_drv) {
|
||||
ext_drv->config.table_init_on = &mipi_init_on_table[0];
|
||||
ext_drv->config.table_init_off = &mipi_init_off_table[0];
|
||||
} else {
|
||||
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int aml_lcd_extern_mipi_N070ICN_probe(struct aml_lcd_extern_driver_s *ext_drv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = lcd_extern_driver_update(ext_drv);
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
EXTPR("%s: %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
231
drivers/amlogic/media/vout/lcd/lcd_extern/spi_LD070WS2.c
Normal file
231
drivers/amlogic/media/vout/lcd/lcd_extern/spi_LD070WS2.c
Normal file
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_extern/spi_LD070WS2.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_extern.h>
|
||||
#include "lcd_extern.h"
|
||||
|
||||
static struct lcd_extern_config_s *ext_config;
|
||||
|
||||
#define LCD_EXTERN_NAME "lcd_spi_LD070WS2"
|
||||
|
||||
#define SPI_DELAY 30 /* unit: us */
|
||||
|
||||
#define LCD_EXTERN_CMD_SIZE 4
|
||||
static unsigned char init_on_table[] = {
|
||||
0x00, 0x00, 0x21, 0x00, /* reset */
|
||||
0x00, 0x00, 0xa5, 0x00, /* standby */
|
||||
0x00, 0x01, 0x30, 0x00, /* enable FRC/Dither */
|
||||
0x00, 0x02, 0x40, 0x00, /* enable normally black */
|
||||
0x00, 0x0e, 0x5f, 0x00, /* enable test mode1 */
|
||||
0x00, 0x0f, 0xa4, 0x00, /* enable test mode2 */
|
||||
0x00, 0x0d, 0x00, 0x00, /* enable SDRRS, enlarge OE width */
|
||||
0x00, 0x02, 0x43, 0x00, /* adjust charge sharing time */
|
||||
0x00, 0x0a, 0x28, 0x00, /* trigger bias reduction */
|
||||
0x00, 0x10, 0x41, 50, /* adopt 2 line/1 dot */ /* delay 50ms */
|
||||
0x00, 0x00, 0xad, 0x00, /* display on */
|
||||
0xff, 0x00, 0x00, 0x00, /* ending flag */
|
||||
};
|
||||
|
||||
static unsigned char init_off_table[] = {
|
||||
0x00, 0x00, 0xa5, 0x00, /* standby */
|
||||
0xff, 0x00, 0x00, 0x00, /* ending flag */
|
||||
};
|
||||
|
||||
static void set_lcd_csb(unsigned int v)
|
||||
{
|
||||
lcd_extern_gpio_set(ext_config->spi_cs, v);
|
||||
udelay(SPI_DELAY);
|
||||
}
|
||||
|
||||
static void set_lcd_scl(unsigned int v)
|
||||
{
|
||||
lcd_extern_gpio_set(ext_config->spi_clk, v);
|
||||
udelay(SPI_DELAY);
|
||||
}
|
||||
|
||||
static void set_lcd_sda(unsigned int v)
|
||||
{
|
||||
lcd_extern_gpio_set(ext_config->spi_data, v);
|
||||
udelay(SPI_DELAY);
|
||||
}
|
||||
|
||||
static void spi_gpio_init(void)
|
||||
{
|
||||
set_lcd_csb(1);
|
||||
set_lcd_scl(1);
|
||||
set_lcd_sda(1);
|
||||
}
|
||||
|
||||
static void spi_gpio_off(void)
|
||||
{
|
||||
set_lcd_sda(0);
|
||||
set_lcd_scl(0);
|
||||
set_lcd_csb(0);
|
||||
}
|
||||
|
||||
static void spi_write_8(unsigned char addr, unsigned char data)
|
||||
{
|
||||
int i;
|
||||
unsigned int sdata;
|
||||
|
||||
sdata = (unsigned int)(addr & 0x3f);
|
||||
sdata <<= 10;
|
||||
sdata |= (data & 0xff);
|
||||
sdata &= ~(1<<9); /* write flag */
|
||||
|
||||
set_lcd_csb(1);
|
||||
set_lcd_scl(1);
|
||||
set_lcd_sda(1);
|
||||
|
||||
set_lcd_csb(0);
|
||||
for (i = 0; i < 16; i++) {
|
||||
set_lcd_scl(0);
|
||||
if (sdata & 0x8000)
|
||||
set_lcd_sda(1);
|
||||
else
|
||||
set_lcd_sda(0);
|
||||
sdata <<= 1;
|
||||
set_lcd_scl(1);
|
||||
}
|
||||
|
||||
set_lcd_csb(1);
|
||||
set_lcd_scl(1);
|
||||
set_lcd_sda(1);
|
||||
udelay(SPI_DELAY);
|
||||
}
|
||||
|
||||
static int lcd_extern_spi_write(unsigned char *buf, int len)
|
||||
{
|
||||
if (len != 2) {
|
||||
EXTERR("%s: len %d error\n", __func__, len);
|
||||
return -1;
|
||||
}
|
||||
spi_write_8(buf[0], buf[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lcd_extern_power_cmd(unsigned char *init_table)
|
||||
{
|
||||
int i = 0, len;
|
||||
int ret = 0;
|
||||
|
||||
len = ext_config->cmd_size;
|
||||
if (len < 1) {
|
||||
EXTERR("%s: cmd_size %d is invalid\n", __func__, len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (i <= LCD_EXTERN_INIT_TABLE_MAX) {
|
||||
if (init_table[i] == LCD_EXTERN_INIT_END) {
|
||||
break;
|
||||
} else if (init_table[i] == LCD_EXTERN_INIT_NONE) {
|
||||
/* do nothing, only for delay */
|
||||
} else if (init_table[i] == LCD_EXTERN_INIT_GPIO) {
|
||||
if (init_table[i+1] < LCD_GPIO_MAX) {
|
||||
lcd_extern_gpio_set(init_table[i+1],
|
||||
init_table[i+2]);
|
||||
}
|
||||
} else if (init_table[i] == LCD_EXTERN_INIT_CMD) {
|
||||
ret = lcd_extern_spi_write(&init_table[i+1], (len-2));
|
||||
} else {
|
||||
EXTERR("%s(%d: %s): power_type %d is invalid\n",
|
||||
__func__, ext_config->index,
|
||||
ext_config->name, ext_config->type);
|
||||
}
|
||||
if (init_table[i+len-1] > 0)
|
||||
mdelay(init_table[i+len-1]);
|
||||
i += len;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_power_ctrl(int flag)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
spi_gpio_init();
|
||||
if (flag)
|
||||
ret = lcd_extern_power_cmd(ext_config->table_init_on);
|
||||
else
|
||||
ret = lcd_extern_power_cmd(ext_config->table_init_off);
|
||||
mdelay(10);
|
||||
spi_gpio_off();
|
||||
|
||||
EXTPR("%s(%d: %s): %d\n",
|
||||
__func__, ext_config->index, ext_config->name, flag);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_power_on(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = lcd_extern_power_ctrl(1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_power_off(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = lcd_extern_power_ctrl(0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
|
||||
{
|
||||
if (ext_drv == NULL) {
|
||||
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ext_drv->config.table_init_loaded == 0) {
|
||||
ext_drv->config.table_init_on = init_on_table;
|
||||
ext_drv->config.table_init_off = init_off_table;
|
||||
}
|
||||
ext_drv->power_on = lcd_extern_power_on;
|
||||
ext_drv->power_off = lcd_extern_power_off;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aml_lcd_extern_spi_LD070WS2_probe(struct aml_lcd_extern_driver_s *ext_drv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ext_config = &ext_drv->config;
|
||||
ret = lcd_extern_driver_update(ext_drv);
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
EXTPR("%s: %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
52
drivers/amlogic/media/vout/lcd/lcd_notify.c
Normal file
52
drivers/amlogic/media/vout/lcd/lcd_notify.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_notify.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_notify.h>
|
||||
|
||||
static BLOCKING_NOTIFIER_HEAD(lcd_notifier_list);
|
||||
|
||||
/**
|
||||
* aml_lcd_notifier_register - register a client notifier
|
||||
* @nb: notifier block to callback on events
|
||||
*/
|
||||
int aml_lcd_notifier_register(struct notifier_block *nb)
|
||||
{
|
||||
return blocking_notifier_chain_register(&lcd_notifier_list, nb);
|
||||
}
|
||||
EXPORT_SYMBOL(aml_lcd_notifier_register);
|
||||
|
||||
/**
|
||||
* aml_lcd_notifier_unregister - unregister a client notifier
|
||||
* @nb: notifier block to callback on events
|
||||
*/
|
||||
int aml_lcd_notifier_unregister(struct notifier_block *nb)
|
||||
{
|
||||
return blocking_notifier_chain_unregister(&lcd_notifier_list, nb);
|
||||
}
|
||||
EXPORT_SYMBOL(aml_lcd_notifier_unregister);
|
||||
|
||||
/**
|
||||
* aml_lcd_notifier_call_chain - notify clients of lcd events
|
||||
*
|
||||
*/
|
||||
int aml_lcd_notifier_call_chain(unsigned long event, void *v)
|
||||
{
|
||||
return blocking_notifier_call_chain(&lcd_notifier_list, event, v);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(aml_lcd_notifier_call_chain);
|
||||
631
drivers/amlogic/media/vout/lcd/lcd_reg.c
Normal file
631
drivers/amlogic/media/vout/lcd/lcd_reg.c
Normal file
@@ -0,0 +1,631 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_reg.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/amlogic/cpu_version.h>
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_vout.h>
|
||||
#include "lcd_common.h"
|
||||
#include "lcd_reg.h"
|
||||
|
||||
/* ********************************************* */
|
||||
#define LCD_REG_GLOBAL_API 0
|
||||
#define LCD_REG_IOREMAP 1
|
||||
#define LCD_REG_IF LCD_REG_IOREMAP
|
||||
/* ********************************************* */
|
||||
|
||||
#if (LCD_REG_IF == LCD_REG_IOREMAP)
|
||||
struct reg_map_s {
|
||||
unsigned int base_addr;
|
||||
unsigned int size;
|
||||
void __iomem *p;
|
||||
char flag;
|
||||
char dummy;
|
||||
};
|
||||
static struct reg_map_s *lcd_map;
|
||||
static int lcd_map_num;
|
||||
|
||||
#define LCD_MAP_HIUBUS 0
|
||||
#define LCD_MAP_VCBUS 1
|
||||
#define LCD_MAP_PERIPHS 2
|
||||
#define LCD_MAP_CBUS 3
|
||||
#define LCD_MAP_DSI_HOST 4
|
||||
#define LCD_MAP_DSI_PHY 5
|
||||
|
||||
static struct reg_map_s lcd_reg_maps_gxb[] = {
|
||||
{ /* HIU */
|
||||
.base_addr = 0xc883c000,
|
||||
.size = 0x400,
|
||||
.flag = 0,
|
||||
.dummy = 0,
|
||||
},
|
||||
{ /* VCBUS */
|
||||
.base_addr = 0xd0100000,
|
||||
.size = 0x10000,
|
||||
.flag = 0,
|
||||
.dummy = 0,
|
||||
},
|
||||
{ /* PERIPHS */
|
||||
.base_addr = 0xc8834400,
|
||||
.size = 0x100,
|
||||
.flag = 0,
|
||||
.dummy = 0,
|
||||
},
|
||||
{ /* CBUS */
|
||||
.base_addr = 0xc1100000,
|
||||
.size = 0x8000,
|
||||
.flag = 0,
|
||||
.dummy = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static struct reg_map_s lcd_reg_maps_txlx[] = {
|
||||
{ /* HIU */
|
||||
.base_addr = 0xff63c000,
|
||||
.size = 0x400,
|
||||
.flag = 0,
|
||||
.dummy = 0,
|
||||
},
|
||||
{ /* VCBUS */
|
||||
.base_addr = 0xff900000,
|
||||
.size = 0xa000,
|
||||
.flag = 0,
|
||||
.dummy = 0,
|
||||
},
|
||||
{ /* PERIPHS */
|
||||
.base_addr = 0xff634000,
|
||||
.size = 0x100,
|
||||
.flag = 0,
|
||||
.dummy = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static struct reg_map_s lcd_reg_maps_axg[] = {
|
||||
{ /* HIU */
|
||||
.base_addr = 0xff63c000,
|
||||
.size = 0x400,
|
||||
.flag = 0,
|
||||
.dummy = 0,
|
||||
},
|
||||
{ /* VCBUS */
|
||||
.base_addr = 0xff900000,
|
||||
.size = 0xa000,
|
||||
.flag = 0,
|
||||
.dummy = 0,
|
||||
},
|
||||
{ /* PERIPHS */
|
||||
.base_addr = 0xff634000,
|
||||
.size = 0x100,
|
||||
.flag = 0,
|
||||
.dummy = 0,
|
||||
},
|
||||
{ /* CBUS, dummy */
|
||||
.base_addr = 0xffd00000,
|
||||
.size = 0x10,
|
||||
.flag = 0,
|
||||
.dummy = 1,
|
||||
},
|
||||
{ /* mipi_dsi_host */
|
||||
.base_addr = 0xffd00000, /* 0xffd06000 */
|
||||
.size = 0x6400,
|
||||
.flag = 0,
|
||||
.dummy = 0,
|
||||
},
|
||||
{ /* mipi_dsi_phy */
|
||||
.base_addr = 0xff640000,
|
||||
.size = 0x100,
|
||||
.flag = 0,
|
||||
.dummy = 0,
|
||||
},
|
||||
};
|
||||
|
||||
int lcd_ioremap(void)
|
||||
{
|
||||
int i;
|
||||
int ret = 0;
|
||||
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
|
||||
|
||||
lcd_map = NULL;
|
||||
lcd_map_num = 0;
|
||||
|
||||
switch (lcd_drv->chip_type) {
|
||||
case LCD_CHIP_TXLX:
|
||||
lcd_map = lcd_reg_maps_txlx;
|
||||
lcd_map_num = ARRAY_SIZE(lcd_reg_maps_txlx);
|
||||
break;
|
||||
case LCD_CHIP_AXG:
|
||||
lcd_map = lcd_reg_maps_axg;
|
||||
lcd_map_num = ARRAY_SIZE(lcd_reg_maps_axg);
|
||||
break;
|
||||
default:
|
||||
lcd_map = lcd_reg_maps_gxb;
|
||||
lcd_map_num = ARRAY_SIZE(lcd_reg_maps_gxb);
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < lcd_map_num; i++) {
|
||||
if (lcd_map[i].dummy)
|
||||
continue;
|
||||
lcd_map[i].p = ioremap(lcd_map[i].base_addr,
|
||||
lcd_map[i].size);
|
||||
if (lcd_map[i].p == NULL) {
|
||||
lcd_map[i].flag = 0;
|
||||
LCDPR("reg map failed: 0x%x\n",
|
||||
lcd_map[i].base_addr);
|
||||
ret = -1;
|
||||
} else {
|
||||
lcd_map[i].flag = 1;
|
||||
if (lcd_debug_print_flag) {
|
||||
LCDPR("reg mapped: 0x%x -> %p\n",
|
||||
lcd_map[i].base_addr, lcd_map[i].p);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int check_lcd_ioremap(int n)
|
||||
{
|
||||
if (lcd_map == NULL)
|
||||
return -1;
|
||||
if (n >= lcd_map_num)
|
||||
return -1;
|
||||
|
||||
if (lcd_map[n].dummy) {
|
||||
LCDERR("reg 0x%x is invalid(dummy)\n", lcd_map[n].base_addr);
|
||||
return -1;
|
||||
}
|
||||
if (lcd_map[n].flag == 0) {
|
||||
LCDERR("reg 0x%x mapped error\n", lcd_map[n].base_addr);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int lcd_ioremap(void)
|
||||
{
|
||||
LCDPR("reg interface is global api\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* register mapping check */
|
||||
#if (LCD_REG_IF == LCD_REG_IOREMAP)
|
||||
static inline void __iomem *check_lcd_vcbus_reg(unsigned int _reg)
|
||||
{
|
||||
void __iomem *p;
|
||||
int reg_bus;
|
||||
unsigned int reg_offset;
|
||||
|
||||
reg_bus = LCD_MAP_VCBUS;
|
||||
if (check_lcd_ioremap(reg_bus))
|
||||
return NULL;
|
||||
|
||||
reg_offset = LCD_REG_OFFSET_VCBUS(_reg);
|
||||
if (reg_offset >= lcd_map[reg_bus].size) {
|
||||
LCDERR("invalid vcbus reg offset: 0x%04x\n", _reg);
|
||||
return NULL;
|
||||
}
|
||||
p = lcd_map[reg_bus].p + reg_offset;
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline void __iomem *check_lcd_hiu_reg(unsigned int _reg)
|
||||
{
|
||||
void __iomem *p;
|
||||
int reg_bus;
|
||||
unsigned int reg_offset;
|
||||
|
||||
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB)
|
||||
reg_bus = LCD_MAP_HIUBUS;
|
||||
else
|
||||
reg_bus = LCD_MAP_CBUS;
|
||||
if (check_lcd_ioremap(reg_bus))
|
||||
return NULL;
|
||||
|
||||
if (reg_bus == LCD_MAP_HIUBUS)
|
||||
reg_offset = LCD_REG_OFFSET_HIU(_reg);
|
||||
else
|
||||
reg_offset = LCD_REG_OFFSET_CBUS(_reg);
|
||||
if (reg_offset >= lcd_map[reg_bus].size) {
|
||||
LCDERR("invalid hiu reg offset: 0x%04x\n", _reg);
|
||||
return NULL;
|
||||
}
|
||||
p = lcd_map[reg_bus].p + reg_offset;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline void __iomem *check_lcd_cbus_reg(unsigned int _reg)
|
||||
{
|
||||
void __iomem *p;
|
||||
int reg_bus;
|
||||
unsigned int reg_offset;
|
||||
|
||||
reg_bus = LCD_MAP_CBUS;
|
||||
if (check_lcd_ioremap(reg_bus))
|
||||
return NULL;
|
||||
|
||||
reg_offset = LCD_REG_OFFSET_CBUS(_reg);
|
||||
if (reg_offset >= lcd_map[reg_bus].size) {
|
||||
LCDERR("invalid cbus reg offset: 0x%04x\n", _reg);
|
||||
return NULL;
|
||||
}
|
||||
p = lcd_map[reg_bus].p + reg_offset;
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline void __iomem *check_lcd_periphs_reg(unsigned int _reg)
|
||||
{
|
||||
void __iomem *p;
|
||||
int reg_bus;
|
||||
unsigned int reg_offset;
|
||||
|
||||
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB)
|
||||
reg_bus = LCD_MAP_PERIPHS;
|
||||
else
|
||||
reg_bus = LCD_MAP_CBUS;
|
||||
if (check_lcd_ioremap(reg_bus))
|
||||
return NULL;
|
||||
|
||||
if (reg_bus == LCD_MAP_PERIPHS)
|
||||
reg_offset = LCD_REG_OFFSET_PERIPHS(_reg);
|
||||
else
|
||||
reg_offset = LCD_REG_OFFSET_PERIPHS(_reg);
|
||||
if (reg_offset >= lcd_map[reg_bus].size) {
|
||||
LCDERR("invalid periphs reg offset: 0x%04x\n", _reg);
|
||||
return NULL;
|
||||
}
|
||||
p = lcd_map[reg_bus].p + reg_offset;
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline void __iomem *check_lcd_dsi_host_reg(unsigned int _reg)
|
||||
{
|
||||
void __iomem *p;
|
||||
int reg_bus;
|
||||
unsigned int reg_offset;
|
||||
|
||||
reg_bus = LCD_MAP_DSI_HOST;
|
||||
if (check_lcd_ioremap(reg_bus))
|
||||
return NULL;
|
||||
|
||||
reg_offset = LCD_REG_OFFSET_DSI_HOST(_reg);
|
||||
if (reg_offset >= lcd_map[reg_bus].size) {
|
||||
LCDERR("invalid dsi_host reg offset: 0x%04x\n", _reg);
|
||||
return NULL;
|
||||
}
|
||||
p = lcd_map[reg_bus].p + reg_offset;
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline void __iomem *check_lcd_dsi_phy_reg(unsigned int _reg)
|
||||
{
|
||||
void __iomem *p;
|
||||
int reg_bus;
|
||||
unsigned int reg_offset;
|
||||
|
||||
reg_bus = LCD_MAP_DSI_PHY;
|
||||
if (check_lcd_ioremap(reg_bus))
|
||||
return NULL;
|
||||
|
||||
reg_offset = LCD_REG_OFFSET_DSI_PHY(_reg);
|
||||
if (reg_offset >= lcd_map[reg_bus].size) {
|
||||
LCDERR("invalid dsi_phy reg offset: 0x%04x\n", _reg);
|
||||
return NULL;
|
||||
}
|
||||
p = lcd_map[reg_bus].p + reg_offset;
|
||||
return p;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* register access api */
|
||||
#if (LCD_REG_IF == LCD_REG_IOREMAP)
|
||||
unsigned int lcd_vcbus_read(unsigned int _reg)
|
||||
{
|
||||
void __iomem *p;
|
||||
|
||||
p = check_lcd_vcbus_reg(_reg);
|
||||
if (p)
|
||||
return readl(p);
|
||||
else
|
||||
return -1;
|
||||
};
|
||||
|
||||
void lcd_vcbus_write(unsigned int _reg, unsigned int _value)
|
||||
{
|
||||
void __iomem *p;
|
||||
|
||||
p = check_lcd_vcbus_reg(_reg);
|
||||
if (p)
|
||||
writel(_value, p);
|
||||
};
|
||||
#else
|
||||
unsigned int lcd_vcbus_read(unsigned int reg)
|
||||
{
|
||||
return aml_read_vcbus(reg);
|
||||
};
|
||||
|
||||
void lcd_vcbus_write(unsigned int reg, unsigned int value)
|
||||
{
|
||||
aml_write_vcbus(reg, value);
|
||||
};
|
||||
#endif
|
||||
|
||||
void lcd_vcbus_setb(unsigned int reg, unsigned int value,
|
||||
unsigned int _start, unsigned int _len)
|
||||
{
|
||||
lcd_vcbus_write(reg, ((lcd_vcbus_read(reg) &
|
||||
(~(((1L << _len)-1) << _start))) |
|
||||
((value & ((1L << _len)-1)) << _start)));
|
||||
}
|
||||
|
||||
unsigned int lcd_vcbus_getb(unsigned int reg,
|
||||
unsigned int _start, unsigned int _len)
|
||||
{
|
||||
return (lcd_vcbus_read(reg) >> _start) & ((1L << _len)-1);
|
||||
}
|
||||
|
||||
void lcd_vcbus_set_mask(unsigned int reg, unsigned int _mask)
|
||||
{
|
||||
lcd_vcbus_write(reg, (lcd_vcbus_read(reg) | (_mask)));
|
||||
}
|
||||
|
||||
void lcd_vcbus_clr_mask(unsigned int reg, unsigned int _mask)
|
||||
{
|
||||
lcd_vcbus_write(reg, (lcd_vcbus_read(reg) & (~(_mask))));
|
||||
}
|
||||
|
||||
#if (LCD_REG_IF == LCD_REG_IOREMAP)
|
||||
unsigned int lcd_hiu_read(unsigned int _reg)
|
||||
{
|
||||
void __iomem *p;
|
||||
|
||||
p = check_lcd_hiu_reg(_reg);
|
||||
if (p)
|
||||
return readl(p);
|
||||
else
|
||||
return -1;
|
||||
};
|
||||
|
||||
void lcd_hiu_write(unsigned int _reg, unsigned int _value)
|
||||
{
|
||||
void __iomem *p;
|
||||
|
||||
p = check_lcd_hiu_reg(_reg);
|
||||
if (p)
|
||||
writel(_value, p);
|
||||
};
|
||||
#else
|
||||
unsigned int lcd_hiu_read(unsigned int _reg)
|
||||
{
|
||||
return aml_read_cbus(_reg);
|
||||
};
|
||||
|
||||
void lcd_hiu_write(unsigned int _reg, unsigned int _value)
|
||||
{
|
||||
aml_write_cbus(_reg, _value);
|
||||
};
|
||||
#endif
|
||||
|
||||
void lcd_hiu_setb(unsigned int _reg, unsigned int _value,
|
||||
unsigned int _start, unsigned int _len)
|
||||
{
|
||||
lcd_hiu_write(_reg, ((lcd_hiu_read(_reg) &
|
||||
~(((1L << (_len))-1) << (_start))) |
|
||||
(((_value)&((1L<<(_len))-1)) << (_start))));
|
||||
}
|
||||
|
||||
unsigned int lcd_hiu_getb(unsigned int _reg,
|
||||
unsigned int _start, unsigned int _len)
|
||||
{
|
||||
return (lcd_hiu_read(_reg) >> (_start)) & ((1L << (_len)) - 1);
|
||||
}
|
||||
|
||||
void lcd_hiu_set_mask(unsigned int _reg, unsigned int _mask)
|
||||
{
|
||||
lcd_hiu_write(_reg, (lcd_hiu_read(_reg) | (_mask)));
|
||||
}
|
||||
|
||||
void lcd_hiu_clr_mask(unsigned int _reg, unsigned int _mask)
|
||||
{
|
||||
lcd_hiu_write(_reg, (lcd_hiu_read(_reg) & (~(_mask))));
|
||||
}
|
||||
|
||||
#if (LCD_REG_IF == LCD_REG_IOREMAP)
|
||||
unsigned int lcd_cbus_read(unsigned int _reg)
|
||||
{
|
||||
void __iomem *p;
|
||||
|
||||
p = check_lcd_cbus_reg(_reg);
|
||||
if (p)
|
||||
return readl(p);
|
||||
else
|
||||
return -1;
|
||||
};
|
||||
|
||||
void lcd_cbus_write(unsigned int _reg, unsigned int _value)
|
||||
{
|
||||
void __iomem *p;
|
||||
|
||||
p = check_lcd_cbus_reg(_reg);
|
||||
if (p)
|
||||
writel(_value, p);
|
||||
};
|
||||
#else
|
||||
unsigned int lcd_cbus_read(unsigned int _reg)
|
||||
{
|
||||
return aml_read_cbus(_reg);
|
||||
};
|
||||
|
||||
void lcd_cbus_write(unsigned int _reg, unsigned int _value)
|
||||
{
|
||||
aml_write_cbus(_reg, _value);
|
||||
};
|
||||
#endif
|
||||
|
||||
void lcd_cbus_setb(unsigned int _reg, unsigned int _value,
|
||||
unsigned int _start, unsigned int _len)
|
||||
{
|
||||
lcd_cbus_write(_reg, ((lcd_cbus_read(_reg) &
|
||||
~(((1L << (_len))-1) << (_start))) |
|
||||
(((_value)&((1L<<(_len))-1)) << (_start))));
|
||||
}
|
||||
|
||||
#if (LCD_REG_IF == LCD_REG_IOREMAP)
|
||||
unsigned int lcd_periphs_read(unsigned int _reg)
|
||||
{
|
||||
void __iomem *p;
|
||||
|
||||
p = check_lcd_periphs_reg(_reg);
|
||||
if (p)
|
||||
return readl(p);
|
||||
else
|
||||
return -1;
|
||||
};
|
||||
|
||||
void lcd_periphs_write(unsigned int _reg, unsigned int _value)
|
||||
{
|
||||
void __iomem *p;
|
||||
|
||||
p = check_lcd_periphs_reg(_reg);
|
||||
if (p)
|
||||
writel(_value, p);
|
||||
};
|
||||
#else
|
||||
unsigned int lcd_periphs_read(unsigned int _reg)
|
||||
{
|
||||
return aml_read_cbus(_reg);
|
||||
};
|
||||
|
||||
void lcd_periphs_write(unsigned int _reg, unsigned int _value)
|
||||
{
|
||||
aml_write_cbus(_reg, _value);
|
||||
};
|
||||
#endif
|
||||
|
||||
void lcd_pinmux_set_mask(unsigned int n, unsigned int _mask)
|
||||
{
|
||||
unsigned int _reg = PERIPHS_PIN_MUX_0;
|
||||
|
||||
_reg += n;
|
||||
lcd_periphs_write(_reg, (lcd_periphs_read(_reg) | (_mask)));
|
||||
}
|
||||
|
||||
void lcd_pinmux_clr_mask(unsigned int n, unsigned int _mask)
|
||||
{
|
||||
unsigned int _reg = PERIPHS_PIN_MUX_0;
|
||||
|
||||
_reg += n;
|
||||
lcd_periphs_write(_reg, (lcd_periphs_read(_reg) & (~(_mask))));
|
||||
}
|
||||
|
||||
#if (LCD_REG_IF == LCD_REG_IOREMAP)
|
||||
unsigned int dsi_host_read(unsigned int _reg)
|
||||
{
|
||||
void __iomem *p;
|
||||
|
||||
p = check_lcd_dsi_host_reg(_reg);
|
||||
if (p)
|
||||
return readl(p);
|
||||
else
|
||||
return -1;
|
||||
};
|
||||
|
||||
void dsi_host_write(unsigned int _reg, unsigned int _value)
|
||||
{
|
||||
void __iomem *p;
|
||||
|
||||
p = check_lcd_dsi_host_reg(_reg);
|
||||
if (p)
|
||||
writel(_value, p);
|
||||
};
|
||||
|
||||
void dsi_host_setb(unsigned int reg, unsigned int value,
|
||||
unsigned int _start, unsigned int _len)
|
||||
{
|
||||
dsi_host_write(reg, ((dsi_host_read(reg) &
|
||||
(~(((1L << _len)-1) << _start))) |
|
||||
((value & ((1L << _len)-1)) << _start)));
|
||||
}
|
||||
|
||||
unsigned int dsi_host_getb(unsigned int reg,
|
||||
unsigned int _start, unsigned int _len)
|
||||
{
|
||||
return (dsi_host_read(reg) >> _start) & ((1L << _len)-1);
|
||||
}
|
||||
|
||||
void dsi_host_set_mask(unsigned int reg, unsigned int _mask)
|
||||
{
|
||||
dsi_host_write(reg, (dsi_host_read(reg) | (_mask)));
|
||||
}
|
||||
|
||||
void dsi_host_clr_mask(unsigned int reg, unsigned int _mask)
|
||||
{
|
||||
dsi_host_write(reg, (dsi_host_read(reg) & (~(_mask))));
|
||||
}
|
||||
|
||||
|
||||
unsigned int dsi_phy_read(unsigned int _reg)
|
||||
{
|
||||
void __iomem *p;
|
||||
|
||||
p = check_lcd_dsi_phy_reg(_reg);
|
||||
if (p)
|
||||
return readl(p);
|
||||
else
|
||||
return -1;
|
||||
};
|
||||
|
||||
void dsi_phy_write(unsigned int _reg, unsigned int _value)
|
||||
{
|
||||
void __iomem *p;
|
||||
|
||||
p = check_lcd_dsi_phy_reg(_reg);
|
||||
if (p)
|
||||
writel(_value, p);
|
||||
};
|
||||
|
||||
void dsi_phy_setb(unsigned int reg, unsigned int value,
|
||||
unsigned int _start, unsigned int _len)
|
||||
{
|
||||
dsi_phy_write(reg, ((dsi_phy_read(reg) &
|
||||
(~(((1L << _len)-1) << _start))) |
|
||||
((value & ((1L << _len)-1)) << _start)));
|
||||
}
|
||||
|
||||
unsigned int dsi_phy_getb(unsigned int reg,
|
||||
unsigned int _start, unsigned int _len)
|
||||
{
|
||||
return (dsi_phy_read(reg) >> _start) & ((1L << _len)-1);
|
||||
}
|
||||
|
||||
void dsi_phy_set_mask(unsigned int reg, unsigned int _mask)
|
||||
{
|
||||
dsi_phy_write(reg, (dsi_phy_read(reg) | (_mask)));
|
||||
}
|
||||
|
||||
void dsi_phy_clr_mask(unsigned int reg, unsigned int _mask)
|
||||
{
|
||||
dsi_phy_write(reg, (dsi_phy_read(reg) & (~(_mask))));
|
||||
}
|
||||
#endif
|
||||
|
||||
1483
drivers/amlogic/media/vout/lcd/lcd_reg.h
Normal file
1483
drivers/amlogic/media/vout/lcd/lcd_reg.h
Normal file
File diff suppressed because it is too large
Load Diff
6
drivers/amlogic/media/vout/lcd/lcd_tablet/Kconfig
Normal file
6
drivers/amlogic/media/vout/lcd/lcd_tablet/Kconfig
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
config AMLOGIC_LCD_GAMMA_DEBUG
|
||||
bool "LCD Gamma debug support"
|
||||
default n
|
||||
help
|
||||
Amlogic LCD gamma debug
|
||||
1
drivers/amlogic/media/vout/lcd/lcd_tablet/Makefile
Normal file
1
drivers/amlogic/media/vout/lcd/lcd_tablet/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
obj-y += lcd_tablet.o lcd_drv.o mipi_dsi_util.o
|
||||
182
drivers/amlogic/media/vout/lcd/lcd_tablet/aml_lcd.dts
Normal file
182
drivers/amlogic/media/vout/lcd/lcd_tablet/aml_lcd.dts
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_tablet/aml_lcd.dts
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
lcd{
|
||||
compatible = "amlogic, lcd";
|
||||
dev_name = "lcd";
|
||||
mode = "tablet";
|
||||
status = "okay";
|
||||
resets = <&clock GCLK_IDX_VCLK2_ENCL &clock GCLK_IDX_VCLK2_VENCL>;
|
||||
reset-names = "encl","vencl";
|
||||
pinctrl-names = "ttl_6bit_hvsync_de_on","ttl_6bit_hvsync_on",
|
||||
"ttl_6bit_de_on","ttl_8bit_hvsync_de_on",
|
||||
"ttl_8bit_hvsync_on","ttl_8bit_de_on",
|
||||
"ttl_6bit_hvsync_de_off","ttl_8bit_hvsync_de_off";
|
||||
pinctrl-0 = <&lcd_ttl_rgb_6bit_pins_on &lcd_ttl_de_hvsync_on_pins>;
|
||||
pinctrl-1 = <&lcd_ttl_rgb_6bit_pins_on &lcd_ttl_hvsync_on_pins>;
|
||||
pinctrl-2 = <&lcd_ttl_rgb_6bit_pins_on &lcd_ttl_de_on_pins>;
|
||||
pinctrl-3 = <&lcd_ttl_rgb_8bit_pins_on &lcd_ttl_de_hvsync_on_pins>;
|
||||
pinctrl-4 = <&lcd_ttl_rgb_8bit_pins_on &lcd_ttl_hvsync_on_pins>;
|
||||
pinctrl-5 = <&lcd_ttl_rgb_8bit_pins_on &lcd_ttl_de_on_pins>;
|
||||
pinctrl-6 = <&lcd_ttl_rgb_6bit_pins_off &lcd_ttl_de_hvsync_off_pins>;
|
||||
pinctrl-7 = <&lcd_ttl_rgb_8bit_pins_off &lcd_ttl_de_hvsync_off_pins>;
|
||||
|
||||
/* power type:(0=cpu_gpio, 1=pmu_gpio,
|
||||
* 2=signal, 3=extern, 0xff=ending)
|
||||
*/
|
||||
/* power index:(point gpios_index, or extern_index, 0xff=invalid) */
|
||||
/* power value:(0=output low, 1=output high, 2=input) */
|
||||
/* power delay:(unit in ms) */
|
||||
lcd_cpu-gpios = <&gpio GPIOX_3 GPIO_ACTIVE_HIGH>;
|
||||
lcd_cpu_gpio_names = "GPIOX_3";
|
||||
|
||||
lcd_0{
|
||||
model_name = "LCD720P";
|
||||
interface = "ttl"; /* lcd_interface(ttl, lvds, mipi, edp) */
|
||||
basic_setting = <1280 720 1650 750 8 16 9>;
|
||||
/* h_active, v_active, h_period, v_period, lcd_bits,
|
||||
* screen_widht, screen_height
|
||||
*/
|
||||
lcd_timing = <40 220 1 5 20 1>;
|
||||
/* hs_width, hs_bp, hs_pol, vs_width, vs_bp, vs_pol */
|
||||
clk_attr = <0 0 1 74250000>;
|
||||
/* fr_adj_type(0=clock, 1=htotal, 2=vtotal),
|
||||
* clk_ss_level, clk_auto_generate,
|
||||
* pixel_clk(unit in Hz)
|
||||
*/
|
||||
ttl_attr = <0 1 1 0 0>;
|
||||
/* clk_pol, de_valid, hvsync_valid,
|
||||
* rb_swap, bit_swap
|
||||
*/
|
||||
power_on_step = <0 0 1 50
|
||||
2 0 0 0
|
||||
0xff 0 0 0>; /* type, index, value, delay */
|
||||
power_off_step = <2 0 0 50
|
||||
0 0 0 100
|
||||
0xff 0 0 0>; /* type, index, value, delay */
|
||||
backlight_index = <0>;
|
||||
};
|
||||
|
||||
lcd_1{
|
||||
model_name = "HJ080IA";
|
||||
interface = "lvds"; /* lcd_interface(ttl, lvds, mipi, edp) */
|
||||
basic_setting = <1024 768 1344 806 8 162 122>;
|
||||
/* h_active, v_active, h_period, v_period, lcd_bits,
|
||||
* screen_widht, screen_height
|
||||
*/
|
||||
lcd_timing = <10 60 0 2 18 0>;
|
||||
/* hs_width, hs_bp, hs_pol, vs_width, vs_bp, vs_pol */
|
||||
clk_attr = <0 0 1 65000000>;
|
||||
/* fr_adj_type(0=clock, 1=htotal, 2=vtotal),
|
||||
* clk_ss_level, clk_auto_generate,
|
||||
* pixel_clk(unit in Hz)
|
||||
*/
|
||||
lvds_attr = <1 0 0 0>;
|
||||
/* lvds_repack, dual_port, pn_swap, port_swap */
|
||||
power_on_step = <0 0 1 50
|
||||
2 0 0 0
|
||||
0xff 0 0 0>; /* type, index, value, delay */
|
||||
power_off_step = <2 0 0 50
|
||||
0 0 0 100
|
||||
0xff 0 0 0>; /* type, index, value, delay */
|
||||
backlight_index = <0>;
|
||||
};
|
||||
|
||||
/* operation_mode:(bit[0] for init, bit[1] for display.
|
||||
*0=video mode, 1=command mode)
|
||||
*/
|
||||
/* lp_clk_continuous:(0=disable, 1=enable) */
|
||||
/* transfer_switch:(0=auto, 1=standard, 2=slow) */
|
||||
/* clk_factor:(special adjust between pixel_clk
|
||||
* & lanebyte_clk, default 0)
|
||||
*/
|
||||
/* mipi-dsi command:(data_type, num, data....).
|
||||
* data_type=0xff, num=0xff means ending
|
||||
* num<0xff means delay num(unit: ms)
|
||||
*/
|
||||
lcd_2{
|
||||
model_name = "B080XAN01";
|
||||
interface = "mipi"; /* lcd_interface(ttl, lvds, mipi, edp) */
|
||||
basic_setting = <768 1024 948 1140 8 119 159>;
|
||||
/* h_active, v_active, h_period, v_period, lcd_bits,
|
||||
* screen_widht, screen_height
|
||||
*/
|
||||
lcd_timing = <64 56 0 50 30 0>;
|
||||
/* hs_width, hs_bp, hs_pol, vs_width, vs_bp, vs_pol */
|
||||
clk_attr = <0 0 1 64843200>;
|
||||
/* fr_adj_type(0=clock, 1=htotal, 2=vtotal),
|
||||
* clk_ss_level, clk_auto_generate,
|
||||
* pixel_clk(unit in Hz)
|
||||
*/
|
||||
mipi_attr = <4 0x1 1 0 1 1 550>;
|
||||
/* lane_count, operation_mode, lp_clk_continuous,
|
||||
* transfer_switch, factor_denominator,
|
||||
* factor_numerator, dsi_bit_rate_max (MHz)
|
||||
*/
|
||||
dsi_cmd_init_on = <0x05 1 0x11 /* sleep out */
|
||||
0xff 20 /* delay 20ms */
|
||||
0x05 1 0x29 /* display on */
|
||||
0xff 20 /* delay 20ms */
|
||||
0xff 0xff>; /* ending flag */
|
||||
dsi_cmd_init_off = <0x05 1 0x28 /* display off */
|
||||
0xff 10 /* delay 10ms */
|
||||
0x05 1 0x10 /* sleep in */
|
||||
0xff 10 /* delay 10ms */
|
||||
0xff 0xff>; /* ending flag */
|
||||
power_on_step = <0 0 1 50
|
||||
2 0 0 0
|
||||
0xff 0 0 0>; /* type, index, value, delay */
|
||||
power_off_step = <2 0 0 50
|
||||
0 0 0 100
|
||||
0xff 0 0 0>; /* type, index, value, delay */
|
||||
backlight_index = <0>;
|
||||
};
|
||||
|
||||
/* link_rate:(0=1.62G, 1=2.7G, 0xff=auto setting) */
|
||||
/* lane_count:(support 1,2,4, 0xff=auto setting) */
|
||||
/* link_vswing:(support level 0,1,2,3, 0xff=adaptive) */
|
||||
/* sync_clk_mode:(0=asyncronous clock,
|
||||
* 1=synchronous clock. default 1)
|
||||
*/
|
||||
/* edid_timing_used:(0=no use, 1=use) */
|
||||
lcd_3{
|
||||
model_name = "LP097QX1";
|
||||
interface = "edp"; /* lcd_interface(ttl, lvds, mipi, edp) */
|
||||
basic_setting = <2048 1536 2219 1560 8 197 147>;
|
||||
/* h_active, v_active, h_period, v_period, lcd_bits,
|
||||
* screen_widht, screen_height
|
||||
*/
|
||||
lcd_timing = <5 115 0 1 21 0>;
|
||||
/* hs_width, hs_bp, hs_pol, vs_width, vs_bp, vs_pol */
|
||||
clk_attr = <0 0 1 207700000>;
|
||||
/* fr_adj_type(0=clock, 1=htotal, 2=vtotal),
|
||||
* clk_ss_level, clk_auto_generate,
|
||||
* pixel_clk(unit in Hz)
|
||||
*/
|
||||
edp_attr = <4 1 2 0 1 0>;
|
||||
/* max_lane_count, link_rate, lane_count, link_vswing,
|
||||
* sync_clk_mode, edid_timing_used
|
||||
*/
|
||||
power_on_step = <0 0 1 50
|
||||
2 0 0 0
|
||||
0xff 0 0 0>; /* type, index, value, delay */
|
||||
power_off_step = <2 0 0 50
|
||||
0 0 0 100
|
||||
0xff 0 0 0>; /* type, index, value, delay */
|
||||
backlight_index = <0>;
|
||||
};
|
||||
};
|
||||
1043
drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_drv.c
Normal file
1043
drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_drv.c
Normal file
File diff suppressed because it is too large
Load Diff
1210
drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c
Normal file
1210
drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c
Normal file
File diff suppressed because it is too large
Load Diff
29
drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.h
Normal file
29
drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.h
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __AML_LCD_TABLET_H__
|
||||
#define __AML_LCD_TABLET_H__
|
||||
|
||||
extern void lcd_tablet_config_update(struct lcd_config_s *pconf);
|
||||
extern void lcd_tablet_config_post_update(struct lcd_config_s *pconf);
|
||||
extern void lcd_tablet_driver_init_pre(void);
|
||||
extern int lcd_tablet_driver_init(void);
|
||||
extern void lcd_tablet_driver_disable(void);
|
||||
extern void lcd_tablet_driver_tiny_enable(void);
|
||||
extern void lcd_tablet_driver_tiny_disable(void);
|
||||
|
||||
#endif
|
||||
1706
drivers/amlogic/media/vout/lcd/lcd_tablet/mipi_dsi_util.c
Normal file
1706
drivers/amlogic/media/vout/lcd/lcd_tablet/mipi_dsi_util.c
Normal file
File diff suppressed because it is too large
Load Diff
539
drivers/amlogic/media/vout/lcd/lcd_tablet/mipi_dsi_util.h
Normal file
539
drivers/amlogic/media/vout/lcd/lcd_tablet/mipi_dsi_util.h
Normal file
@@ -0,0 +1,539 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_tablet/mipi_dsi_util.h
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MIPI_DSI_UTIL_H
|
||||
#define MIPI_DSI_UTIL_H
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_vout.h>
|
||||
|
||||
|
||||
/* ********************************************************
|
||||
* MIPI DSI Data Type/ MIPI DCS Command Type Definitions
|
||||
* Pheripheral to Host
|
||||
*/
|
||||
enum mipi_dsi_data_type_host_e {
|
||||
DT_VSS = 0x01,
|
||||
DT_VSE = 0x11,
|
||||
DT_HSS = 0x21,
|
||||
DT_HSE = 0x31,
|
||||
DT_EOTP = 0x08,
|
||||
DT_CMOFF = 0x02,
|
||||
DT_CMON = 0x12,
|
||||
DT_SHUT_DOWN = 0x22,
|
||||
DT_TURN_ON = 0x32,
|
||||
DT_GEN_SHORT_WR_0 = 0x03,
|
||||
DT_GEN_SHORT_WR_1 = 0x13,
|
||||
DT_GEN_SHORT_WR_2 = 0x23,
|
||||
DT_GEN_RD_0 = 0x04,
|
||||
DT_GEN_RD_1 = 0x14,
|
||||
DT_GEN_RD_2 = 0x24,
|
||||
DT_DCS_SHORT_WR_0 = 0x05,
|
||||
DT_DCS_SHORT_WR_1 = 0x15,
|
||||
DT_DCS_RD_0 = 0x06,
|
||||
DT_SET_MAX_RET_PKT_SIZE = 0x37,
|
||||
DT_NULL_PKT = 0x09,
|
||||
DT_BLANK_PKT = 0x19,
|
||||
DT_GEN_LONG_WR = 0x29,
|
||||
DT_DCS_LONG_WR = 0x39,
|
||||
DT_20BIT_LOOSE_YCBCR = 0x0c,
|
||||
DT_24BIT_YCBCR = 0x1c,
|
||||
DT_16BIT_YCBCR = 0x2c,
|
||||
DT_30BIT_RGB_101010 = 0x0d,
|
||||
DT_36BIT_RGB_121212 = 0x1d,
|
||||
DT_12BIT_YCBCR = 0x3d,
|
||||
DT_16BIT_RGB_565 = 0x0e,
|
||||
DT_18BIT_RGB_666 = 0x1e,
|
||||
DT_18BIT_LOOSE_RGB_666 = 0x2e,
|
||||
DT_24BIT_RGB_888 = 0x3e
|
||||
};
|
||||
|
||||
/* DCS Command List */
|
||||
#define DCS_ENTER_IDLE_MODE 0x39
|
||||
#define DCS_ENTER_INVERT_MODE 0x21
|
||||
#define DCS_ENTER_NORMAL_MODE 0x13
|
||||
#define DCS_ENTER_PARTIAL_MODE 0x12
|
||||
#define DCS_ENTER_SLEEP_MODE 0x10
|
||||
#define DCS_EXIT_IDLE_MODE 0x38
|
||||
#define DCS_EXIT_INVERT_MODE 0x20
|
||||
#define DCS_EXIT_SLEEP_MODE 0x11
|
||||
#define DCS_GET_3D_CONTROL 0x3f
|
||||
#define DCS_GET_ADDRESS_MODE 0x0b
|
||||
#define DCS_GET_BLUE_CHANNEL 0x08
|
||||
#define DCS_GET_DIAGNOSTIC_RESULT 0x0f
|
||||
#define DCS_GET_DISPLAY_MODE 0x0d
|
||||
#define DCS_GET_GREEN_CHANNEL 0x07
|
||||
#define DCS_GET_PIXEL_FORMAT 0x0c
|
||||
#define DCS_GET_POWER_MODE 0x0a
|
||||
#define DCS_GET_RED_CHANNEL 0x06
|
||||
#define DCS_GET_SCANLINE 0x45
|
||||
#define DCS_GET_SIGNAL_MODE 0x0e
|
||||
#define DCS_NOP 0x00
|
||||
#define DCS_READ_DDB_CONTINUE 0xa8
|
||||
#define DCS_READ_DDB_START 0xa1
|
||||
#define DCS_READ_MEMORY_CONTINUE 0x3e
|
||||
#define DCS_READ_MEMORY_START 0x2e
|
||||
#define DCS_SET_3D_CONTROL 0x3d
|
||||
#define DCS_SET_ADDRESS_MODE 0x36
|
||||
#define DCS_SET_COLUMN_ADDRESS 0x2a
|
||||
#define DCS_SET_DISPLAY_OFF 0x28
|
||||
#define DCS_SET_DISPLAY_ON 0x29
|
||||
#define DCS_SET_GAMMA_CURVE 0x26
|
||||
#define DCS_SET_PAGE_ADDRESS 0x2b
|
||||
#define DCS_SET_PARTIAL_COLUMNS 0x31
|
||||
#define DCS_SET_PARTIAL_ROWS 0x30
|
||||
#define DCS_SET_PIXEL_FORMAT 0x3a
|
||||
#define DCS_SET_SCROLL_AREA 0x33
|
||||
#define DCS_SET_SCROLL_START 0x37
|
||||
#define DCS_SET_TEAR_OFF 0x34
|
||||
#define DCS_SET_TEAR_ON 0x35
|
||||
#define DCS_SET_TEAR_SCANLINE 0x44
|
||||
#define DCS_SET_VSYNC_TIMING 0x40
|
||||
#define DCS_SOFT_RESET 0x01
|
||||
#define DCS_WRITE_LUT 0x2d
|
||||
#define DCS_WRITE_MEMORY_CONTINUE 0x3c
|
||||
#define DCS_WRITE_MEMORY_START 0x2c
|
||||
|
||||
/* Pheripheral to Host
|
||||
* normal: 0x87(LPDT), data_type, 0, 0, ecc. (write or tearing-effect)
|
||||
* error: 0x87(LPDT), 0x02, error_code[15:0], ecc.
|
||||
* short read: 0x87, data_type, data0, data1, ecc
|
||||
* long read: 0x87, data_type, word_cnt[15:0], ecc, data0, ... data(N-1),
|
||||
* checksum(or 0)[15:0].
|
||||
*/
|
||||
enum mipi_dsi_data_type_peripheral_e {
|
||||
DT_RESP_TE = 0xba,
|
||||
DT_RESP_ACK = 0x84,
|
||||
DT_RESP_ACK_ERR = 0x02,
|
||||
DT_RESP_EOT = 0x08,
|
||||
DT_RESP_GEN_READ_1 = 0x11,
|
||||
DT_RESP_GEN_READ_2 = 0x12,
|
||||
DT_RESP_GEN_READ_LONG = 0x1a,
|
||||
DT_RESP_DCS_READ_LONG = 0x1c,
|
||||
DT_RESP_DCS_READ_1 = 0x21,
|
||||
DT_RESP_DCS_READ_2 = 0x22,
|
||||
};
|
||||
|
||||
struct dsi_cmd_request_s {
|
||||
unsigned char data_type;
|
||||
unsigned char vc_id;
|
||||
unsigned char *payload;
|
||||
unsigned short pld_count;
|
||||
unsigned int req_ack;
|
||||
};
|
||||
|
||||
/* MIPI DCS Pixel-to-Byte Format */
|
||||
#define DCS_PF_RSVD 0x0
|
||||
#define DCS_PF_3BIT 0x1
|
||||
#define DCS_PF_8BIT 0x2
|
||||
#define DCS_PF_12BIT 0x3
|
||||
#define DCS_PF_16BIT 0x5
|
||||
#define DCS_PF_18BIT 0x6
|
||||
#define DCS_PF_24BIT 0x7
|
||||
|
||||
/* MIPI DSI/VENC Color Format Definitions */
|
||||
#define MIPI_DSI_VENC_COLOR_30B 0x0
|
||||
#define MIPI_DSI_VENC_COLOR_24B 0x1
|
||||
#define MIPI_DSI_VENC_COLOR_18B 0x2
|
||||
#define MIPI_DSI_VENC_COLOR_16B 0x3
|
||||
|
||||
#define COLOR_16BIT_CFG_1 0x0
|
||||
#define COLOR_16BIT_CFG_2 0x1
|
||||
#define COLOR_16BIT_CFG_3 0x2
|
||||
#define COLOR_18BIT_CFG_1 0x3
|
||||
#define COLOR_18BIT_CFG_2 0x4
|
||||
#define COLOR_24BIT 0x5
|
||||
#define COLOR_20BIT_LOOSE 0x6
|
||||
#define COLOR_24_BIT_YCBCR 0x7
|
||||
#define COLOR_16BIT_YCBCR 0x8
|
||||
#define COLOR_30BIT 0x9
|
||||
#define COLOR_36BIT 0xa
|
||||
#define COLOR_12BIT 0xb
|
||||
#define COLOR_RGB_111 0xc
|
||||
#define COLOR_RGB_332 0xd
|
||||
#define COLOR_RGB_444 0xe
|
||||
|
||||
/* MIPI DSI Relative REGISTERs Definitions */
|
||||
/* For MIPI_DSI_TOP_CNTL */
|
||||
#define BIT_DPI_COLOR_MODE 20
|
||||
#define BIT_IN_COLOR_MODE 16
|
||||
#define BIT_CHROMA_SUBSAMPLE 14
|
||||
#define BIT_COMP2_SEL 12
|
||||
#define BIT_COMP1_SEL 10
|
||||
#define BIT_COMP0_SEL 8
|
||||
#define BIT_DE_POL 6
|
||||
#define BIT_HSYNC_POL 5
|
||||
#define BIT_VSYNC_POL 4
|
||||
#define BIT_DPICOLORM 3
|
||||
#define BIT_DPISHUTDN 2
|
||||
#define BIT_EDPITE_INTR_PULSE 1
|
||||
#define BIT_ERR_INTR_PULSE 0
|
||||
|
||||
/* For MIPI_DSI_DWC_CLKMGR_CFG_OS */
|
||||
#define BIT_TO_CLK_DIV 8
|
||||
#define BIT_TX_ESC_CLK_DIV 0
|
||||
|
||||
/* For MIPI_DSI_DWC_PCKHDL_CFG_OS */
|
||||
#define BIT_CRC_RX_EN 4
|
||||
#define BIT_ECC_RX_EN 3
|
||||
#define BIT_BTA_EN 2
|
||||
#define BIT_EOTP_RX_EN 1
|
||||
#define BIT_EOTP_TX_EN 0
|
||||
|
||||
/* For MIPI_DSI_DWC_VID_MODE_CFG_OS */
|
||||
#define BIT_LP_CMD_EN 15
|
||||
#define BIT_FRAME_BTA_ACK_EN 14
|
||||
#define BIT_LP_HFP_EN 13
|
||||
#define BIT_LP_HBP_EN 12
|
||||
#define BIT_LP_VCAT_EN 11
|
||||
#define BIT_LP_VFP_EN 10
|
||||
#define BIT_LP_VBP_EN 9
|
||||
#define BIT_LP_VSA_EN 8
|
||||
#define BIT_VID_MODE_TYPE 0
|
||||
|
||||
/* For MIPI_DSI_DWC_PHY_STATUS_OS */
|
||||
#define BIT_PHY_ULPSACTIVENOT3LANE 12
|
||||
#define BIT_PHY_STOPSTATE3LANE 11
|
||||
#define BIT_PHY_ULPSACTIVENOT2LANE 10
|
||||
#define BIT_PHY_STOPSTATE2LANE 9
|
||||
#define BIT_PHY_ULPSACTIVENOT1LANE 8
|
||||
#define BIT_PHY_STOPSTATE1LANE 7
|
||||
#define BIT_PHY_RXULPSESC0LANE 6
|
||||
#define BIT_PHY_ULPSACTIVENOT0LANE 5
|
||||
#define BIT_PHY_STOPSTATE0LANE 4
|
||||
#define BIT_PHY_ULPSACTIVENOTCLK 3
|
||||
#define BIT_PHY_STOPSTATECLKLANE 2
|
||||
#define BIT_PHY_DIRECTION 1
|
||||
#define BIT_PHY_LOCK 0
|
||||
|
||||
/* For MIPI_DSI_DWC_PHY_IF_CFG_OS */
|
||||
#define BIT_PHY_STOP_WAIT_TIME 8
|
||||
#define BIT_N_LANES 0
|
||||
|
||||
/* For MIPI_DSI_DWC_DPI_COLOR_CODING_OS */
|
||||
#define BIT_LOOSELY18_EN 8
|
||||
#define BIT_DPI_COLOR_CODING 0
|
||||
|
||||
/* For MIPI_DSI_DWC_GEN_HDR_OS */
|
||||
#define BIT_GEN_WC_MSBYTE 16
|
||||
#define BIT_GEN_WC_LSBYTE 8
|
||||
#define BIT_GEN_VC 6
|
||||
#define BIT_GEN_DT 0
|
||||
|
||||
/* For MIPI_DSI_DWC_LPCLK_CTRL_OS */
|
||||
#define BIT_AUTOCLKLANE_CTRL 1
|
||||
#define BIT_TXREQUESTCLKHS 0
|
||||
|
||||
/* For MIPI_DSI_DWC_DPI_CFG_POL_OS */
|
||||
#define BIT_COLORM_ACTIVE_LOW 4
|
||||
#define BIT_SHUTD_ACTIVE_LOW 3
|
||||
#define BIT_HSYNC_ACTIVE_LOW 2
|
||||
#define BIT_VSYNC_ACTIVE_LOW 1
|
||||
#define BIT_DATAEN_ACTIVE_LOW 0
|
||||
|
||||
/* For MIPI_DSI_DWC_CMD_MODE_CFG_OS */
|
||||
#define BIT_MAX_RD_PKT_SIZE 24
|
||||
#define BIT_DCS_LW_TX 19
|
||||
#define BIT_DCS_SR_0P_TX 18
|
||||
#define BIT_DCS_SW_1P_TX 17
|
||||
#define BIT_DCS_SW_0P_TX 16
|
||||
#define BIT_GEN_LW_TX 14
|
||||
#define BIT_GEN_SR_2P_TX 13
|
||||
#define BIT_GEN_SR_1P_TX 12
|
||||
#define BIT_GEN_SR_0P_TX 11
|
||||
#define BIT_GEN_SW_2P_TX 10
|
||||
#define BIT_GEN_SW_1P_TX 9
|
||||
#define BIT_GEN_SW_0P_TX 8
|
||||
#define BIT_ACK_RQST_EN 1
|
||||
#define BIT_TEAR_FX_EN 0
|
||||
|
||||
/* For MIPI_DSI_DWC_CMD_PKT_STATUS_OS */
|
||||
/* For DBI no use full */
|
||||
#define BIT_DBI_RD_CMD_BUSY 14
|
||||
#define BIT_DBI_PLD_R_FULL 13
|
||||
#define BIT_DBI_PLD_R_EMPTY 12
|
||||
#define BIT_DBI_PLD_W_FULL 11
|
||||
#define BIT_DBI_PLD_W_EMPTY 10
|
||||
#define BIT_DBI_CMD_FULL 9
|
||||
#define BIT_DBI_CMD_EMPTY 8
|
||||
/* For Generic interface */
|
||||
#define BIT_GEN_RD_CMD_BUSY 6
|
||||
#define BIT_GEN_PLD_R_FULL 5
|
||||
#define BIT_GEN_PLD_R_EMPTY 4
|
||||
#define BIT_GEN_PLD_W_FULL 3
|
||||
#define BIT_GEN_PLD_W_EMPTY 2
|
||||
#define BIT_GEN_CMD_FULL 1
|
||||
#define BIT_GEN_CMD_EMPTY 0
|
||||
|
||||
/* For MIPI_DSI_TOP_MEAS_CNTL */
|
||||
/* measure vsync control */
|
||||
#define BIT_CNTL_MEAS_VSYNC 10
|
||||
/* tear measure enable */
|
||||
#define BIT_EDPITE_MEAS_EN 9
|
||||
/* not clear the counter */
|
||||
#define BIT_EDPITE_ACCUM_MEAS_EN 8
|
||||
#define BIT_EDPITE_VSYNC_SPAN 0
|
||||
|
||||
/* For MIPI_DSI_TOP_STAT */
|
||||
/* signal from halt */
|
||||
#define BIT_STAT_EDPIHALT 31
|
||||
/* line number when edpite pulse */
|
||||
#define BIT_STAT_TE_LINE 16
|
||||
/* pixel number when edpite pulse */
|
||||
#define BIT_STAT_TE_PIXEL 0
|
||||
|
||||
/* For MIPI_DSI_TOP_INTR_CNTL_STAT */
|
||||
/* State/Clear for pic_eof */
|
||||
#define BIT_STAT_CLR_DWC_PIC_EOF 21
|
||||
/* State/Clear for de_fall */
|
||||
#define BIT_STAT_CLR_DWC_DE_FALL 20
|
||||
/* State/Clear for de_rise */
|
||||
#define BIT_STAT_CLR_DWC_DE_RISE 19
|
||||
/* State/Clear for vs_fall */
|
||||
#define BIT_STAT_CLR_DWC_VS_FALL 18
|
||||
/* State/Clear for vs_rise */
|
||||
#define BIT_STAT_CLR_DWC_VS_RISE 17
|
||||
/* State/Clear for edpite */
|
||||
#define BIT_STAT_CLR_DWC_EDPITE 16
|
||||
/* end of picture */
|
||||
#define BIT_PIC_EOF 5
|
||||
/* data enable fall */
|
||||
#define BIT_DE_FALL 4
|
||||
/* data enable rise */
|
||||
#define BIT_DE_RISE 3
|
||||
/* vsync fall */
|
||||
#define BIT_VS_FALL 2
|
||||
/* vsync rise */
|
||||
#define BIT_VS_RISE 1
|
||||
/* edpite int enable */
|
||||
#define BIT_EDPITE_INT_EN 0
|
||||
|
||||
/* For MIPI_DSI_TOP_MEAS_CNTL */
|
||||
/* vsync measure enable */
|
||||
#define BIT_VSYNC_MEAS_EN 19
|
||||
/* vsync accumulate measure */
|
||||
#define BIT_VSYNC_ACCUM_MEAS_EN 18
|
||||
/* vsync span */
|
||||
#define BIT_VSYNC_SPAN 10
|
||||
/* tearing measure enable */
|
||||
#define BIT_TE_MEAS_EN 9
|
||||
/* tearing accumulate measure */
|
||||
#define BIT_TE_ACCUM_MEAS_EN 8
|
||||
/* tearing span */
|
||||
#define BIT_TE_SPAN 0
|
||||
|
||||
/* For MIPI_DSI_DWC_INT_ST0_OS */
|
||||
/* LP1 contention error from lane0 */
|
||||
#define BIT_DPHY_ERR_4 20
|
||||
/* LP0 contention error from lane0 */
|
||||
#define BIT_DPHY_ERR_3 19
|
||||
/* ErrControl error from lane0 */
|
||||
#define BIT_DPHY_ERR_2 18
|
||||
/* ErrSyncEsc error from lane0 */
|
||||
#define BIT_DPHY_ERR_1 17
|
||||
/* ErrEsc escape error lane0 */
|
||||
#define BIT_DPHY_ERR_0 16
|
||||
#define BIT_ACK_ERR_15 15
|
||||
#define BIT_ACK_ERR_14 14
|
||||
#define BIT_ACK_ERR_13 13
|
||||
#define BIT_ACK_ERR_12 12
|
||||
#define BIT_ACK_ERR_11 11
|
||||
#define BIT_ACK_ERR_10 10
|
||||
#define BIT_ACK_ERR_9 9
|
||||
#define BIT_ACK_ERR_8 8
|
||||
#define BIT_ACK_ERR_7 7
|
||||
#define BIT_ACK_ERR_6 6
|
||||
#define BIT_ACK_ERR_5 5
|
||||
#define BIT_ACK_ERR_4 4
|
||||
#define BIT_ACK_ERR_3 3
|
||||
#define BIT_ACK_ERR_2 2
|
||||
#define BIT_ACK_ERR_1 1
|
||||
#define BIT_ACK_ERR_0 0
|
||||
|
||||
/* Command transfer type in command mode */
|
||||
#define DCS_TRANS_HS 0
|
||||
#define DCS_TRANS_LP 1
|
||||
|
||||
#define MIPI_DSI_DCS_NO_ACK 0
|
||||
#define MIPI_DSI_DCS_REQ_ACK 1
|
||||
|
||||
/* DSI Tear Defines */
|
||||
#define MIPI_DCS_SET_TEAR_ON_MODE_0 0
|
||||
#define MIPI_DCS_SET_TEAR_ON_MODE_1 1
|
||||
#define MIPI_DCS_ENABLE_TEAR 1
|
||||
#define MIPI_DCS_DISABLE_TEAR 0
|
||||
|
||||
/* Pixel FIFO Depth */
|
||||
#define PIXEL_FIFO_DEPTH 1440
|
||||
|
||||
#define BYTE_PER_PIXEL_COLOR_16BIT_CFG_1 2
|
||||
#define BYTE_PER_PIXEL_COLOR_16BIT_CFG_2 2
|
||||
#define BYTE_PER_PIXEL_COLOR_16BIT_CFG_3 2
|
||||
#define BYTE_PER_PIXEL_COLOR_18BIT_CFG_1 3
|
||||
#define BYTE_PER_PIXEL_COLOR_18BIT_CFG_2 3
|
||||
#define BYTE_PER_PIXEL_COLOR_24BIT 3
|
||||
#define BYTE_PER_PIXEL_COLOR_20BIT_LOOSE 3
|
||||
#define BYTE_PER_PIXEL_COLOR_24_BIT_YCBCR 3
|
||||
#define BYTE_PER_PIXEL_COLOR_16BIT_YCBCR 2
|
||||
#define BYTE_PER_PIXEL_COLOR_30BIT 4
|
||||
#define BYTE_PER_PIXEL_COLOR_36BIT 5
|
||||
/* in fact it should be 1.5(12bit) */
|
||||
#define BYTE_PER_PIXEL_COLOR_12BIT 3
|
||||
|
||||
/* Tearing Interrupt Bit */
|
||||
#define INT_TEARING 6
|
||||
|
||||
enum tv_enc_lcd_type_e {
|
||||
TV_ENC_LCD480x234 = 0,
|
||||
/* For MIPI_DSI 36-bit color: sample rate=2, 1 pixel per 2 cycle */
|
||||
TV_ENC_LCD480x234_dsi36b = 1,
|
||||
TV_ENC_LCD240x160 = 2,
|
||||
/* For MIPI_DSI 36-bit color: sample rate=2, 1 pixel per 2 cycle */
|
||||
TV_ENC_LCD240x160_dsi36b = 3,
|
||||
TV_ENC_LCD720x480 = 4,
|
||||
/* For MIPI_DSI 36-bit color: sample rate=2, 1 pixel per 2 cycle */
|
||||
TV_ENC_LCD720x480_dsi36b = 5,
|
||||
TV_ENC_LCD720x576 = 6,
|
||||
/* For MIPI_DSI 36-bit color: sample rate=2, 1 pixel per 2 cycle */
|
||||
TV_ENC_LCD720x576_dsi36b = 7,
|
||||
TV_ENC_LCD1280x720 = 8,
|
||||
/* For MIPI_DSI 36-bit color: sample rate=2, 1 pixel per 2 cycle */
|
||||
TV_ENC_LCD1280x720_dsi36b = 9,
|
||||
TV_ENC_LCD1920x1080 = 10,
|
||||
/* For MIPI_DSI 36-bit color: sample rate=2, 1 pixel per 2 cycle */
|
||||
TV_ENC_LCD1920x1080_dsi36b = 11,
|
||||
TV_ENC_LCD1920x2205 = 12,
|
||||
/* For MIPI_DSI 36-bit color: sample rate=2, 1 pixel per 2 cycle */
|
||||
TV_ENC_LCD1920x2205_dsi36b = 13,
|
||||
TV_ENC_LCD2560x1600 = 14,
|
||||
/* For MIPI_DSI 36-bit color: sample rate=2, 1 pixel per 2 cycle */
|
||||
TV_ENC_LCD2560x1600_dsi36b = 15,
|
||||
TV_ENC_LCD3840x2440 = 16,
|
||||
/* For MIPI_DSI 36-bit color: sample rate=2, 1 pixel per 2 cycle */
|
||||
TV_ENC_LCD3840x2440_dsi36b = 17,
|
||||
TV_ENC_LCD3840x2160p_vic03 = 18,
|
||||
TV_ENC_LCD4096x2160p_vic04 = 19,
|
||||
TV_ENC_LCD640x480 = 20,
|
||||
TV_ENC_LCD1920x1200p = 21,
|
||||
TV_ENC_LCD240x160_dsi = 22,
|
||||
TV_ENC_LCD240x160_slow = 23,
|
||||
TV_ENC_LCD3840x2160p_vic01 = 24,
|
||||
TV_ENC_LCD2048x1536 = 25,
|
||||
TV_ENC_LCD768x1024p = 26,
|
||||
TV_ENC_LCD_TYPE_MAX
|
||||
}; /* tv encoder output format */
|
||||
|
||||
/* DCS COMMAND LIST */
|
||||
#define DCS_CMD_CODE_ENTER_IDLE_MODE 0x0
|
||||
#define DCS_CMD_CODE_ENTER_INVERT_MODE 0x1
|
||||
#define DCS_CMD_CODE_ENTER_NORMAL_MODE 0x2
|
||||
#define DCS_CMD_CODE_ENTER_PARTIAL_MODE 0x3
|
||||
#define DCS_CMD_CODE_ENTER_SLEEP_MODE 0x4
|
||||
#define DCS_CMD_CODE_EXIT_IDLE_MODE 0x5
|
||||
#define DCS_CMD_CODE_EXIT_INVERT_MODE 0x6
|
||||
#define DCS_CMD_CODE_EXIT_SLEEP_MODE 0x7
|
||||
#define DCS_CMD_CODE_NOP 0x8
|
||||
#define DCS_CMD_CODE_SET_DISPLAY_OFF 0x9
|
||||
#define DCS_CMD_CODE_SET_DISPLAY_ON 0xa
|
||||
#define DCS_CMD_CODE_SET_TEAR_OFF 0xb
|
||||
#define DCS_CMD_CODE_SOFT_RESET 0xc
|
||||
|
||||
/* DPHY standard timing */
|
||||
/* unit: MHz */
|
||||
#define MIPI_PHY_CLK_MAX 1000
|
||||
|
||||
/* **** DPHY timing parameter Value (unit: 0.01ns) **** */
|
||||
/* >100ns (4M) */
|
||||
#define DPHY_TIME_LP_TESC(ui) (250 * 100)
|
||||
/* >50ns */
|
||||
#define DPHY_TIME_LP_LPX(ui) (100 * 100)
|
||||
/* (lpx, 2*lpx) */
|
||||
#define DPHY_TIME_LP_TA_SURE(ui) DPHY_TIME_LP_LPX(ui)
|
||||
/* 4*lpx */
|
||||
#define DPHY_TIME_LP_TA_GO(ui) (4 * DPHY_TIME_LP_LPX(ui))
|
||||
/* 5*lpx */
|
||||
#define DPHY_TIME_LP_TA_GETX(ui) (5 * DPHY_TIME_LP_LPX(ui))
|
||||
/* >100ns */
|
||||
#define DPHY_TIME_HS_EXIT(ui) (120 * 100)
|
||||
/* max(8*ui, 60+4*ui), (teot)<105+12*ui */
|
||||
#define DPHY_TIME_HS_TRAIL(ui) ((ui > (60 * 100 / 4)) ? \
|
||||
(8 * ui) : ((60 * 100) + 4 * ui))
|
||||
/* (40+4*ui, 85+6*ui) */
|
||||
#define DPHY_TIME_HS_PREPARE(ui) (50 * 100 + 4 * t_ui)
|
||||
/* hs_prepare+hs_zero >145+10*ui */
|
||||
#define DPHY_TIME_HS_ZERO(ui) (160 * 100 + 10 * ui - \
|
||||
DPHY_TIME_HS_PREPARE(ui))
|
||||
/* >60ns, (teot)<105+12*ui */
|
||||
#define DPHY_TIME_CLK_TRAIL(ui) (70 * 100)
|
||||
/* >60+52*ui */
|
||||
#define DPHY_TIME_CLK_POST(ui) (70 * 100 + 52 * ui)
|
||||
/* (38, 95) */
|
||||
#define DPHY_TIME_CLK_PREPARE(ui) (50 * 100)
|
||||
/* clk_prepare+clk_zero > 300 */
|
||||
#define DPHY_TIME_CLK_ZERO(ui) (320 * 100 - DPHY_TIME_CLK_PREPARE(ui))
|
||||
/* >8*ui */
|
||||
#define DPHY_TIME_CLK_PRE(ui) (10 * ui)
|
||||
/* >100us */
|
||||
#define DPHY_TIME_INIT(ui) (110 * 1000 * 100)
|
||||
/* >1ms */
|
||||
#define DPHY_TIME_WAKEUP(ui) (1020 * 1000 * 100)
|
||||
|
||||
|
||||
struct dsi_phy_s {
|
||||
unsigned int lp_tesc;
|
||||
unsigned int lp_lpx;
|
||||
unsigned int lp_ta_sure;
|
||||
unsigned int lp_ta_go;
|
||||
unsigned int lp_ta_get;
|
||||
unsigned int hs_exit;
|
||||
unsigned int hs_trail;
|
||||
unsigned int hs_zero;
|
||||
unsigned int hs_prepare;
|
||||
unsigned int clk_trail;
|
||||
unsigned int clk_post;
|
||||
unsigned int clk_zero;
|
||||
unsigned int clk_prepare;
|
||||
unsigned int clk_pre;
|
||||
unsigned int init;
|
||||
unsigned int wakeup;
|
||||
};
|
||||
|
||||
struct dsi_vid_s {
|
||||
unsigned int hline;
|
||||
unsigned int hsa;
|
||||
unsigned int hbp;
|
||||
unsigned int vsa;
|
||||
unsigned int vbp;
|
||||
unsigned int vfp;
|
||||
unsigned int vact;
|
||||
|
||||
/* for non-burst chunk overhead */
|
||||
unsigned int pixel_per_chunk;
|
||||
unsigned int num_of_chunk;
|
||||
unsigned int vid_null_size;
|
||||
};
|
||||
|
||||
#define DSI_CMD_SIZE_MAX 2000
|
||||
/* #define DSI_CMD_READ_VALID // DPHY don't support for M8 */
|
||||
|
||||
extern void mipi_dsi_print_info(struct lcd_config_s *pconf);
|
||||
extern int lcd_mipi_dsi_init_table_detect(struct device_node *m_node,
|
||||
struct dsi_config_s *dconf, int on_off);
|
||||
extern void lcd_mipi_dsi_config_set(struct lcd_config_s *pconf);
|
||||
extern void lcd_mipi_dsi_config_post(struct lcd_config_s *pconf);
|
||||
extern void mipi_dsi_link_off(struct lcd_config_s *pconf);
|
||||
extern void lcd_mipi_control_set(struct lcd_config_s *pconf, int status);
|
||||
|
||||
#endif
|
||||
1
drivers/amlogic/media/vout/lcd/lcd_tv/Makefile
Normal file
1
drivers/amlogic/media/vout/lcd/lcd_tv/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
obj-$(CONFIG_AMLOGIC_LCD_TV) += lcd_tv.o lcd_drv.o
|
||||
1435
drivers/amlogic/media/vout/lcd/lcd_tv/lcd_drv.c
Normal file
1435
drivers/amlogic/media/vout/lcd/lcd_tv/lcd_drv.c
Normal file
File diff suppressed because it is too large
Load Diff
1270
drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c
Normal file
1270
drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c
Normal file
File diff suppressed because it is too large
Load Diff
132
drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.dts
Normal file
132
drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.dts
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.dts
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
lcd{
|
||||
compatible = "amlogic, lcd";
|
||||
dev_name = "lcd";
|
||||
mode = "tv";
|
||||
status = "okay";
|
||||
resets = <&clock GCLK_IDX_VCLK2_ENCL &clock GCLK_IDX_VCLK2_VENCL>;
|
||||
reset-names = "encl","vencl";
|
||||
interrupts = <0 78 1 0 3 1>;
|
||||
interrupt-names = "vbyone","vbyone_vsync";
|
||||
pinctrl-names = "vbyone";
|
||||
pinctrl-0 = <&lcd_vbyone_pins>;
|
||||
|
||||
/* power type:(0=cpu, 1=pmu, 2=signal, 3=extern, 0xff=ending) */
|
||||
/* power index:(point gpios_index, or extern_index, 0xff=invalid) */
|
||||
/* power value:(0=output low, 1=output high, 2=input) */
|
||||
/* power delay:(unit in ms) */
|
||||
lcd_cpu-gpios = <&gpio GPIOX_3 GPIO_ACTIVE_HIGH>;
|
||||
lcd_cpu_gpio_names = "GPIOX_3";
|
||||
|
||||
lvds_0{
|
||||
model_name = "public";
|
||||
interface = "lvds"; /* lcd_interface(lvds, vbyone) */
|
||||
basic_setting = <1920 1080 2200 1125 8 16 9>;
|
||||
/* h_active, v_active, h_period, v_period, lcd_bits,
|
||||
* screen_widht, screen_height
|
||||
*/
|
||||
lcd_timing = <44 148 0 5 30 0>;
|
||||
/* hs_width, hs_bp, hs_pol, vs_width, vs_bp, vs_pol */
|
||||
clk_attr = <0 0 1>;
|
||||
/* fr_adj_type(0=clock, 1=htotal, 2=vtotal),
|
||||
* clk_ss_level, clk_auto_generate
|
||||
*/
|
||||
lvds_attr = <1 1 0 0>;
|
||||
/** lvds_repack, dual_port, pn_swap, port_swap */
|
||||
power_on_step = <0 0 1 50
|
||||
2 0 0 0
|
||||
0xff 0 0 0>; /* type, index, value, delay */
|
||||
power_off_step = <2 0 0 50
|
||||
0 0 0 100
|
||||
0xff 0 0 0>; /* type, index, value, delay */
|
||||
backlight_index = <0>;
|
||||
};
|
||||
|
||||
vbyone_0{
|
||||
model_name = "BOE_HV550QU2";
|
||||
interface = "vbyone"; /* lcd_interface(lvds, vbyone) */
|
||||
basic_setting = <3840 2160 4400 2250 10 16 9>;
|
||||
/* h_active, v_active, h_period, v_period, lcd_bits,
|
||||
* screen_widht, screen_height
|
||||
*/
|
||||
lcd_timing = <33 477 0 6 65 0>;
|
||||
/* hs_width, hs_bp, hs_pol, vs_width, vs_bp, vs_pol */
|
||||
clk_attr = <0 0 1>;
|
||||
/* fr_adj_type(0=clock, 1=htotal, 2=vtotal),
|
||||
* clk_ss_level, clk_auto_generate
|
||||
*/
|
||||
vbyone_attr = <8 2 4 4>;
|
||||
/** lane_count, region_num, byte_mode, color_fmt */
|
||||
power_on_step = <0 0 1 50
|
||||
2 0 0 0
|
||||
0xff 0 0 0>; /* type, index, value, delay */
|
||||
power_off_step = <2 0 0 50
|
||||
0 0 0 100
|
||||
0xff 0 0 0>; /* type, index, value, delay */
|
||||
backlight_index = <0>;
|
||||
};
|
||||
|
||||
vbyone_1{
|
||||
model_name = "LG_RDL550WY";
|
||||
interface = "vbyone"; /* lcd_interface(lvds, vbyone) */
|
||||
basic_setting = <3840 2160 4400 2250 10 16 9>;
|
||||
/* h_active, v_active, h_period, v_period, lcd_bits,
|
||||
* screen_widht, screen_height
|
||||
*/
|
||||
lcd_timing = <33 477 0 6 65 0>;
|
||||
/* hs_width, hs_bp, hs_pol, vs_width, vs_bp, vs_pol */
|
||||
clk_attr = <2 0 1>;
|
||||
/* fr_adj_type(0=clock, 1=htotal, 2=vtotal),
|
||||
* clk_ss_level, clk_auto_generate
|
||||
*/
|
||||
vbyone_attr = <8 2 4 4>;
|
||||
/** lane_count, region_num, byte_mode, color_fmt */
|
||||
power_on_step = <0 0 1 50
|
||||
2 0 0 0
|
||||
0xff 0 0 0>; /* type, index, value, delay */
|
||||
power_off_step = <2 0 0 50
|
||||
0 0 0 100
|
||||
0xff 0 0 0>; /* type, index, value, delay */
|
||||
backlight_index = <0>;
|
||||
};
|
||||
|
||||
vbyone_2{
|
||||
model_name = "INL_V580DJ2";
|
||||
interface = "vbyone"; /* lcd_interface(lvds, vbyone) */
|
||||
basic_setting = <3840 2160 4400 2250 10 16 9>;
|
||||
/* h_active, v_active, h_period, v_period, lcd_bits,
|
||||
* screen_widht, screen_height
|
||||
*/
|
||||
lcd_timing = <33 477 0 6 65 0>;
|
||||
/* hs_width, hs_bp, hs_pol, vs_width, vs_bp, vs_pol */
|
||||
clk_attr = <2 0 1>;
|
||||
/* fr_adj_type(0=clock, 1=htotal, 2=vtotal),
|
||||
* clk_ss_level, clk_auto_generate
|
||||
*/
|
||||
vbyone_attr = <8 1 4 4>;
|
||||
/** lane_count, region_num, byte_mode, color_fmt */
|
||||
power_on_step = <0 0 1 50
|
||||
2 0 0 0
|
||||
0xff 0 0 0>; /* type, index, value, delay */
|
||||
power_off_step = <2 0 0 50
|
||||
0 0 0 100
|
||||
0xff 0 0 0>; /* type, index, value, delay */
|
||||
backlight_index = <0>;
|
||||
};
|
||||
};
|
||||
34
drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.h
Normal file
34
drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.h
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __AML_LCD_TV_H__
|
||||
#define __AML_LCD_TV_H__
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_vout.h>
|
||||
|
||||
extern void lcd_tv_config_update(struct lcd_config_s *pconf);
|
||||
extern void lcd_tv_driver_init_pre(void);
|
||||
extern int lcd_tv_driver_init(void);
|
||||
extern void lcd_tv_driver_disable(void);
|
||||
extern int lcd_tv_driver_change(void);
|
||||
extern void lcd_tv_driver_tiny_enable(void);
|
||||
extern void lcd_tv_driver_tiny_disable(void);
|
||||
|
||||
extern void lcd_vbyone_wait_stable(void);
|
||||
extern void lcd_vbyone_interrupt_up(void);
|
||||
extern void lcd_vbyone_interrupt_down(void);
|
||||
|
||||
#endif
|
||||
301
drivers/amlogic/media/vout/lcd/lcd_unifykey.c
Normal file
301
drivers/amlogic/media/vout/lcd/lcd_unifykey.c
Normal file
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_unifykey.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_unifykey.h>
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_vout.h>
|
||||
|
||||
#define LCDUKEY(fmt, args...) pr_info("lcd ukey: "fmt"", ## args)
|
||||
#define LCDUKEYERR(fmt, args...) pr_info("lcd ukey err: error: "fmt"", ## args)
|
||||
|
||||
#ifdef CONFIG_KEY_MANAGE
|
||||
static unsigned int cal_crc32(unsigned int crc, const unsigned char *buf,
|
||||
int buf_len) {
|
||||
unsigned int s_crc32[16] = {
|
||||
0, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
|
||||
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
|
||||
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
|
||||
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c,
|
||||
};
|
||||
unsigned int crcu32 = crc;
|
||||
unsigned char b;
|
||||
|
||||
if (buf_len <= 0)
|
||||
return 0;
|
||||
if (!buf)
|
||||
return 0;
|
||||
|
||||
crcu32 = ~crcu32;
|
||||
while (buf_len--) {
|
||||
b = *buf++;
|
||||
crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)];
|
||||
crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)];
|
||||
}
|
||||
|
||||
return ~crcu32;
|
||||
}
|
||||
|
||||
int lcd_unifykey_len_check(int key_len, int len)
|
||||
{
|
||||
if (key_len < len) {
|
||||
LCDUKEYERR("invalid unifykey length %d, need %d\n",
|
||||
key_len, len);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lcd_unifykey_header_check(unsigned char *buf,
|
||||
struct aml_lcd_unifykey_header_s *header)
|
||||
{
|
||||
header->crc32 = (buf[0] | (buf[1] << 8) |
|
||||
(buf[2] << 16) | (buf[3] << 24));
|
||||
header->data_len = (buf[4] | (buf[5] << 8));
|
||||
header->version = (buf[6] | (buf[7] << 8));
|
||||
header->reserved = (buf[8] | (buf[9] << 8));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lcd_unifykey_check(char *key_name)
|
||||
{
|
||||
unsigned int key_exist, keypermit, key_len;
|
||||
unsigned char buf[550];
|
||||
struct aml_lcd_unifykey_header_s key_header;
|
||||
int retry_cnt = 0;
|
||||
unsigned int key_crc32;
|
||||
int ret;
|
||||
|
||||
key_exist = 0;
|
||||
key_len = 0;
|
||||
ret = key_unify_query(key_name, &key_exist, &keypermit);
|
||||
if (ret < 0) {
|
||||
if (lcd_debug_print_flag)
|
||||
LCDUKEYERR("%s query exist error\n", key_name);
|
||||
return -1;
|
||||
}
|
||||
if (key_exist == 0) {
|
||||
if (lcd_debug_print_flag)
|
||||
LCDUKEYERR("%s is not exist\n", key_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = key_unify_size(key_name, &key_len);
|
||||
if (ret < 0) {
|
||||
LCDUKEYERR("%s query size error\n", key_name);
|
||||
return -1;
|
||||
}
|
||||
if (key_len == 0) {
|
||||
if (lcd_debug_print_flag)
|
||||
LCDUKEY("%s size is zero\n", key_name);
|
||||
return -1;
|
||||
}
|
||||
if (lcd_debug_print_flag)
|
||||
LCDUKEY("%s size: %d\n", key_name, key_len);
|
||||
|
||||
lcd_unifykey_read:
|
||||
ret = key_unify_read(key_name, buf, key_len, &key_len);
|
||||
if (ret < 0) {
|
||||
LCDUKEYERR("%s unify read error\n", key_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* check header */
|
||||
if (key_len <= LCD_UKEY_HEAD_SIZE) {
|
||||
LCDUKEYERR("%s unify key_len %d error\n", key_name, key_len);
|
||||
return -1;
|
||||
}
|
||||
lcd_unifykey_header_check(buf, &key_header);
|
||||
if (key_len != key_header.data_len) { /* length check */
|
||||
if (lcd_debug_print_flag) {
|
||||
LCDUKEYERR("data_len %d is not match key_len %d\n",
|
||||
key_header.data_len, key_len);
|
||||
}
|
||||
if (retry_cnt < LCD_UKEY_RETRY_CNT_MAX) {
|
||||
retry_cnt++;
|
||||
goto lcd_unifykey_read;
|
||||
} else {
|
||||
LCDUKEYERR("%s: load unifykey failed\n", key_name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
key_crc32 = cal_crc32(0, &buf[4], (key_len - 4)); /* except crc32 */
|
||||
if (lcd_debug_print_flag) {
|
||||
LCDUKEY("crc32: 0x%08x, header_crc32: 0x%08x\n",
|
||||
key_crc32, key_header.crc32);
|
||||
}
|
||||
if (key_crc32 != key_header.crc32) { /* crc32 check */
|
||||
LCDUKEYERR("crc32 0x%08x is not match header_crc32 0x%08x\n",
|
||||
key_header.crc32, key_crc32);
|
||||
if (retry_cnt < LCD_UKEY_RETRY_CNT_MAX) {
|
||||
retry_cnt++;
|
||||
goto lcd_unifykey_read;
|
||||
} else {
|
||||
LCDUKEYERR("%s: load unifykey failed\n", key_name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lcd_unifykey_get(char *key_name, unsigned char *buf, int *len)
|
||||
{
|
||||
int key_len;
|
||||
int ret;
|
||||
|
||||
key_len = 0;
|
||||
ret = lcd_unifykey_check(key_name);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
ret = key_unify_size(key_name, &key_len);
|
||||
if (key_len > *len) {
|
||||
LCDUKEYERR("%s size(%d) is bigger than buf_size(%d)\n",
|
||||
key_name, key_len, *len);
|
||||
return -1;
|
||||
}
|
||||
*len = key_len;
|
||||
|
||||
ret = key_unify_read(key_name, buf, key_len, &key_len);
|
||||
if (ret < 0) {
|
||||
LCDUKEYERR("%s unify read error\n", key_name);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lcd_unifykey_print(void)
|
||||
{
|
||||
unsigned char buf[600];
|
||||
char *key_name;
|
||||
unsigned int key_len;
|
||||
int i, j;
|
||||
int ret;
|
||||
|
||||
key_name = "lcd";
|
||||
key_len = LCD_UKEY_LCD_SIZE;
|
||||
ret = lcd_unifykey_get(key_name, buf, &key_len);
|
||||
if (ret < 0)
|
||||
return;
|
||||
LCDUKEY("%s: %s: %d\n", __func__, key_name, key_len);
|
||||
i = 0;
|
||||
while (1) {
|
||||
pr_info("0x%08x: ", (i * 16));
|
||||
for (j = 0; j < 16; j++) {
|
||||
if ((i*16+j) < key_len) {
|
||||
pr_info("0x%02x ", buf[i*16+j]);
|
||||
} else {
|
||||
pr_info("\n");
|
||||
goto exit_print_lcd;
|
||||
}
|
||||
}
|
||||
pr_info("\n");
|
||||
i++;
|
||||
}
|
||||
|
||||
exit_print_lcd:
|
||||
key_name = "lcd_extern";
|
||||
key_len = LCD_UKEY_LCD_EXT_SIZE;
|
||||
ret = lcd_unifykey_get(key_name, buf, &key_len);
|
||||
if (ret < 0)
|
||||
return;
|
||||
LCDUKEY("%s: %s: %d\n", __func__, key_name, key_len);
|
||||
i = 0;
|
||||
while (1) {
|
||||
pr_info("0x%08x: ", (i * 16));
|
||||
for (j = 0; j < 16; j++) {
|
||||
if ((i*16+j) < key_len) {
|
||||
pr_info("0x%02x ", buf[i*16+j]);
|
||||
} else {
|
||||
pr_info("\n");
|
||||
goto exit_print_lcd_ext;
|
||||
}
|
||||
}
|
||||
pr_info("\n");
|
||||
i++;
|
||||
}
|
||||
|
||||
exit_print_lcd_ext:
|
||||
key_name = "backlight";
|
||||
key_len = LCD_UKEY_BL_SIZE;
|
||||
ret = lcd_unifykey_get(key_name, buf, &key_len);
|
||||
if (ret < 0)
|
||||
return;
|
||||
LCDUKEY("%s: %s: %d\n", __func__, key_name, key_len);
|
||||
i = 0;
|
||||
while (1) {
|
||||
pr_info("0x%08x: ", (i * 16));
|
||||
for (j = 0; j < 16; j++) {
|
||||
if ((i*16+j) < key_len) {
|
||||
pr_info("0x%02x ", buf[i*16+j]);
|
||||
} else {
|
||||
pr_info("\n");
|
||||
goto exit_print_backlight;
|
||||
}
|
||||
}
|
||||
pr_info("\n");
|
||||
i++;
|
||||
}
|
||||
|
||||
exit_print_backlight:
|
||||
return;
|
||||
}
|
||||
|
||||
#else
|
||||
/* dummy driver */
|
||||
int lcd_unifykey_len_check(int key_len, int len)
|
||||
{
|
||||
LCDUKEYERR("Don't support unifykey\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int lcd_unifykey_header_check(unsigned char *buf,
|
||||
struct aml_lcd_unifykey_header_s *header)
|
||||
{
|
||||
LCDUKEYERR("Don't support unifykey\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int lcd_unifykey_check(char *key_name)
|
||||
{
|
||||
LCDUKEYERR("Don't support unifykey\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int lcd_unifykey_get(char *key_name, unsigned char *buf, int *len)
|
||||
{
|
||||
LCDUKEYERR("Don't support unifykey\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void lcd_unifykey_print(void)
|
||||
{
|
||||
LCDUKEYERR("Don't support unifykey\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
998
drivers/amlogic/media/vout/lcd/lcd_vout.c
Normal file
998
drivers/amlogic/media/vout/lcd/lcd_vout.c
Normal file
@@ -0,0 +1,998 @@
|
||||
/*
|
||||
* drivers/amlogic/media/vout/lcd/lcd_vout.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/clk.h>
|
||||
#ifdef CONFIG_OF
|
||||
#include <linux/of.h>
|
||||
#endif
|
||||
#include <linux/reset.h>
|
||||
#include <linux/amlogic/cpu_version.h>
|
||||
#include <linux/amlogic/media/vout/vinfo.h>
|
||||
#include <linux/amlogic/media/vout/vout_notify.h>
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_vout.h>
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_notify.h>
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_unifykey.h>
|
||||
#ifdef CONFIG_AMLOGIC_LCD_EXTERN
|
||||
#include <linux/amlogic/media/vout/lcd/lcd_extern.h>
|
||||
#endif
|
||||
#include "lcd_reg.h"
|
||||
#include "lcd_common.h"
|
||||
|
||||
#define LCD_CDEV_NAME "lcd"
|
||||
|
||||
unsigned char lcd_debug_print_flag;
|
||||
unsigned char lcd_resume_flag;
|
||||
static struct aml_lcd_drv_s *lcd_driver;
|
||||
|
||||
struct mutex lcd_power_mutex;
|
||||
struct mutex lcd_vout_mutex;
|
||||
int lcd_vout_serve_bypass;
|
||||
|
||||
static char lcd_propname[20] = "lvds_0";
|
||||
|
||||
struct lcd_cdev_s {
|
||||
dev_t devno;
|
||||
struct cdev cdev;
|
||||
struct device *dev;
|
||||
};
|
||||
|
||||
static struct lcd_cdev_s *lcd_cdev;
|
||||
|
||||
/* lcd config define */
|
||||
static struct ttl_config_s lcd_ttl_config = {
|
||||
.clk_pol = 0,
|
||||
.sync_valid = ((1 << 1) | (1 << 0)),
|
||||
.swap_ctrl = ((0 << 1) | (0 << 0)),
|
||||
};
|
||||
|
||||
static struct lvds_config_s lcd_lvds_config = {
|
||||
.lvds_vswing = 1,
|
||||
.lvds_repack = 1,
|
||||
.dual_port = 0,
|
||||
.pn_swap = 0,
|
||||
.port_swap = 0,
|
||||
.lane_reverse = 0,
|
||||
.port_sel = 0,
|
||||
.phy_vswing = LVDS_PHY_VSWING_DFT,
|
||||
.phy_preem = LVDS_PHY_PREEM_DFT,
|
||||
};
|
||||
|
||||
static struct vbyone_config_s lcd_vbyone_config = {
|
||||
.lane_count = 8,
|
||||
.region_num = 2,
|
||||
.byte_mode = 4,
|
||||
.color_fmt = 4,
|
||||
.phy_div = 1,
|
||||
.bit_rate = 0,
|
||||
.phy_vswing = VX1_PHY_VSWING_DFT,
|
||||
.phy_preem = VX1_PHY_PREEM_DFT,
|
||||
.intr_en = 1,
|
||||
.vsync_intr_en = 1,
|
||||
};
|
||||
|
||||
static unsigned char dsi_init_on_table[DSI_INIT_ON_MAX] = {0xff, 0xff};
|
||||
static unsigned char dsi_init_off_table[DSI_INIT_OFF_MAX] = {0xff, 0xff};
|
||||
|
||||
static struct dsi_config_s lcd_mipi_config = {
|
||||
.lane_num = 4,
|
||||
.bit_rate_max = 550, /* MHz */
|
||||
.factor_numerator = 0,
|
||||
.factor_denominator = 100,
|
||||
.operation_mode_init = 1, /* 0=video mode, 1=command mode */
|
||||
.operation_mode_display = 0, /* 0=video mode, 1=command mode */
|
||||
.video_mode_type = 2, /* 0=sync_pulse, 1=sync_event, 2=burst */
|
||||
.clk_lp_continuous = 1, /* 0=stop, 1=continue */
|
||||
.phy_stop_wait = 0, /* 0=auto, 1=standard, 2=slow */
|
||||
|
||||
.dsi_init_on = &dsi_init_on_table[0],
|
||||
.dsi_init_off = &dsi_init_off_table[0],
|
||||
.extern_init = 0xff,
|
||||
/* ext_index if needed, must match ext_config index;
|
||||
* 0xff for invalid
|
||||
*/
|
||||
};
|
||||
|
||||
static struct lcd_power_ctrl_s lcd_power_config = {
|
||||
.cpu_gpio = {
|
||||
{.flag = 0,},
|
||||
{.flag = 0,},
|
||||
{.flag = 0,},
|
||||
{.flag = 0,},
|
||||
{.flag = 0,},
|
||||
{.flag = 0,},
|
||||
{.flag = 0,},
|
||||
{.flag = 0,},
|
||||
{.flag = 0,},
|
||||
{.flag = 0,},
|
||||
},
|
||||
.power_on_step = {
|
||||
{
|
||||
.type = LCD_POWER_TYPE_MAX,
|
||||
},
|
||||
},
|
||||
.power_off_step = {
|
||||
{
|
||||
.type = LCD_POWER_TYPE_MAX,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct lcd_config_s lcd_config_dft = {
|
||||
.lcd_propname = lcd_propname,
|
||||
.lcd_basic = {
|
||||
.lcd_type = LCD_TYPE_MAX,
|
||||
},
|
||||
.lcd_timing = {
|
||||
.lcd_clk = 0,
|
||||
.clk_auto = 1,
|
||||
.ss_level = 0,
|
||||
.fr_adjust_type = 0,
|
||||
},
|
||||
.hdr_info = {
|
||||
.hdr_support = 0,
|
||||
.features = 0,
|
||||
.primaries_r_x = 0,
|
||||
.primaries_r_y = 0,
|
||||
.primaries_g_x = 0,
|
||||
.primaries_g_y = 0,
|
||||
.primaries_b_x = 0,
|
||||
.primaries_b_y = 0,
|
||||
.white_point_x = 0,
|
||||
.white_point_y = 0,
|
||||
.luma_max = 0,
|
||||
.luma_min = 0,
|
||||
.luma_avg = 0,
|
||||
},
|
||||
.lcd_control = {
|
||||
.ttl_config = &lcd_ttl_config,
|
||||
.lvds_config = &lcd_lvds_config,
|
||||
.vbyone_config = &lcd_vbyone_config,
|
||||
.mipi_config = &lcd_mipi_config,
|
||||
},
|
||||
.lcd_power = &lcd_power_config,
|
||||
};
|
||||
|
||||
static struct vinfo_s lcd_vinfo = {
|
||||
.name = "panel",
|
||||
.mode = VMODE_LCD,
|
||||
.viu_color_fmt = COLOR_FMT_RGB444,
|
||||
};
|
||||
|
||||
struct aml_lcd_drv_s *aml_lcd_get_driver(void)
|
||||
{
|
||||
return lcd_driver;
|
||||
}
|
||||
/* ********************************************************* */
|
||||
|
||||
static void lcd_chip_detect(void)
|
||||
{
|
||||
unsigned int cpu_type;
|
||||
|
||||
cpu_type = get_cpu_type();
|
||||
switch (cpu_type) {
|
||||
case MESON_CPU_MAJOR_ID_GXTVBB:
|
||||
lcd_driver->chip_type = LCD_CHIP_GXTVBB;
|
||||
break;
|
||||
case MESON_CPU_MAJOR_ID_GXL:
|
||||
lcd_driver->chip_type = LCD_CHIP_GXL;
|
||||
break;
|
||||
case MESON_CPU_MAJOR_ID_GXM:
|
||||
lcd_driver->chip_type = LCD_CHIP_GXM;
|
||||
break;
|
||||
case MESON_CPU_MAJOR_ID_TXL:
|
||||
lcd_driver->chip_type = LCD_CHIP_TXL;
|
||||
break;
|
||||
case MESON_CPU_MAJOR_ID_TXLX:
|
||||
lcd_driver->chip_type = LCD_CHIP_TXLX;
|
||||
break;
|
||||
case MESON_CPU_MAJOR_ID_AXG:
|
||||
lcd_driver->chip_type = LCD_CHIP_AXG;
|
||||
break;
|
||||
default:
|
||||
lcd_driver->chip_type = LCD_CHIP_MAX;
|
||||
}
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("check chip: %d\n", lcd_driver->chip_type);
|
||||
}
|
||||
|
||||
static void lcd_power_tiny_ctrl(int status)
|
||||
{
|
||||
struct lcd_power_ctrl_s *lcd_power = lcd_driver->lcd_config->lcd_power;
|
||||
struct lcd_power_step_s *power_step;
|
||||
#ifdef CONFIG_AMLOGIC_LCD_EXTERN
|
||||
struct aml_lcd_extern_driver_s *ext_drv;
|
||||
#endif
|
||||
int i, index;
|
||||
|
||||
LCDPR("%s: %d\n", __func__, status);
|
||||
i = 0;
|
||||
while (i < LCD_PWR_STEP_MAX) {
|
||||
if (status)
|
||||
power_step = &lcd_power->power_on_step[i];
|
||||
else
|
||||
power_step = &lcd_power->power_off_step[i];
|
||||
|
||||
if (power_step->type >= LCD_POWER_TYPE_MAX)
|
||||
break;
|
||||
if (lcd_debug_print_flag) {
|
||||
LCDPR("power_tiny_ctrl: %d, step %d\n", status, i);
|
||||
LCDPR("type=%d, index=%d, value=%d, delay=%d\n",
|
||||
power_step->type, power_step->index,
|
||||
power_step->value, power_step->delay);
|
||||
}
|
||||
switch (power_step->type) {
|
||||
case LCD_POWER_TYPE_CPU:
|
||||
index = power_step->index;
|
||||
lcd_cpu_gpio_set(index, power_step->value);
|
||||
break;
|
||||
case LCD_POWER_TYPE_PMU:
|
||||
LCDPR("to do\n");
|
||||
break;
|
||||
case LCD_POWER_TYPE_SIGNAL:
|
||||
if (status)
|
||||
lcd_driver->driver_tiny_enable();
|
||||
else
|
||||
lcd_driver->driver_tiny_disable();
|
||||
break;
|
||||
#ifdef CONFIG_AMLOGIC_LCD_EXTERN
|
||||
case LCD_POWER_TYPE_EXTERN:
|
||||
index = power_step->index;
|
||||
ext_drv = aml_lcd_extern_get_driver(index);
|
||||
if (ext_drv) {
|
||||
if (status) {
|
||||
if (ext_drv->power_on)
|
||||
ext_drv->power_on();
|
||||
else
|
||||
LCDERR("no ext power on\n");
|
||||
} else {
|
||||
if (ext_drv->power_off)
|
||||
ext_drv->power_off();
|
||||
else
|
||||
LCDERR("no ext power off\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (power_step->delay)
|
||||
mdelay(power_step->delay);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s: %d finished\n", __func__, status);
|
||||
}
|
||||
|
||||
static void lcd_power_ctrl(int status)
|
||||
{
|
||||
struct lcd_power_ctrl_s *lcd_power = lcd_driver->lcd_config->lcd_power;
|
||||
struct lcd_power_step_s *power_step;
|
||||
#ifdef CONFIG_AMLOGIC_LCD_EXTERN
|
||||
struct aml_lcd_extern_driver_s *ext_drv;
|
||||
#endif
|
||||
int i, index;
|
||||
int ret = 0;
|
||||
|
||||
LCDPR("%s: %d\n", __func__, status);
|
||||
i = 0;
|
||||
while (i < LCD_PWR_STEP_MAX) {
|
||||
if (status)
|
||||
power_step = &lcd_power->power_on_step[i];
|
||||
else
|
||||
power_step = &lcd_power->power_off_step[i];
|
||||
|
||||
if (power_step->type >= LCD_POWER_TYPE_MAX)
|
||||
break;
|
||||
if (lcd_debug_print_flag) {
|
||||
LCDPR("power_ctrl: %d, step %d\n", status, i);
|
||||
LCDPR("type=%d, index=%d, value=%d, delay=%d\n",
|
||||
power_step->type, power_step->index,
|
||||
power_step->value, power_step->delay);
|
||||
}
|
||||
switch (power_step->type) {
|
||||
case LCD_POWER_TYPE_CPU:
|
||||
index = power_step->index;
|
||||
lcd_cpu_gpio_set(index, power_step->value);
|
||||
break;
|
||||
case LCD_POWER_TYPE_PMU:
|
||||
LCDPR("to do\n");
|
||||
break;
|
||||
case LCD_POWER_TYPE_SIGNAL:
|
||||
if (status)
|
||||
ret = lcd_driver->driver_init();
|
||||
else
|
||||
lcd_driver->driver_disable();
|
||||
break;
|
||||
#ifdef CONFIG_AMLOGIC_LCD_EXTERN
|
||||
case LCD_POWER_TYPE_EXTERN:
|
||||
index = power_step->index;
|
||||
ext_drv = aml_lcd_extern_get_driver(index);
|
||||
if (ext_drv) {
|
||||
if (status) {
|
||||
if (ext_drv->power_on)
|
||||
ext_drv->power_on();
|
||||
else
|
||||
LCDERR("no ext power on\n");
|
||||
} else {
|
||||
if (ext_drv->power_off)
|
||||
ext_drv->power_off();
|
||||
else
|
||||
LCDERR("no ext power off\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (power_step->delay)
|
||||
mdelay(power_step->delay);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s: %d finished\n", __func__, status);
|
||||
}
|
||||
|
||||
static void lcd_module_enable(void)
|
||||
{
|
||||
mutex_lock(&lcd_vout_mutex);
|
||||
|
||||
lcd_driver->driver_init_pre();
|
||||
lcd_driver->power_ctrl(1);
|
||||
lcd_driver->lcd_status = 1;
|
||||
|
||||
mutex_unlock(&lcd_vout_mutex);
|
||||
}
|
||||
|
||||
static void lcd_module_disable(void)
|
||||
{
|
||||
mutex_lock(&lcd_vout_mutex);
|
||||
|
||||
lcd_driver->lcd_status = 0;
|
||||
lcd_driver->power_ctrl(0);
|
||||
|
||||
mutex_unlock(&lcd_vout_mutex);
|
||||
}
|
||||
|
||||
static void lcd_module_reset(void)
|
||||
{
|
||||
mutex_lock(&lcd_vout_mutex);
|
||||
|
||||
lcd_driver->lcd_status = 0;
|
||||
lcd_driver->power_ctrl(0);
|
||||
|
||||
msleep(500);
|
||||
|
||||
lcd_driver->driver_init_pre();
|
||||
lcd_driver->power_ctrl(1);
|
||||
lcd_driver->lcd_status = 1;
|
||||
|
||||
mutex_unlock(&lcd_vout_mutex);
|
||||
}
|
||||
|
||||
static void lcd_module_tiny_reset(void)
|
||||
{
|
||||
mutex_lock(&lcd_vout_mutex);
|
||||
|
||||
lcd_driver->lcd_status = 0;
|
||||
lcd_power_tiny_ctrl(0);
|
||||
mdelay(500);
|
||||
lcd_power_tiny_ctrl(1);
|
||||
lcd_driver->lcd_status = 1;
|
||||
|
||||
mutex_unlock(&lcd_vout_mutex);
|
||||
}
|
||||
|
||||
/* lcd notify */
|
||||
static int lcd_power_notifier(struct notifier_block *nb,
|
||||
unsigned long event, void *data)
|
||||
{
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s: 0x%lx\n", __func__, event);
|
||||
|
||||
if (event & LCD_EVENT_LCD_ON)
|
||||
lcd_module_enable();
|
||||
else if (event & LCD_EVENT_LCD_OFF)
|
||||
lcd_module_disable();
|
||||
else
|
||||
return NOTIFY_DONE;
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block lcd_power_nb = {
|
||||
.notifier_call = lcd_power_notifier,
|
||||
.priority = LCD_PRIORITY_POWER_LCD,
|
||||
};
|
||||
|
||||
static int lcd_interface_notifier(struct notifier_block *nb,
|
||||
unsigned long event, void *data)
|
||||
{
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s: 0x%lx\n", __func__, event);
|
||||
|
||||
if (event & LCD_EVENT_IF_ON)
|
||||
lcd_driver->power_tiny_ctrl(1);
|
||||
else if (event & LCD_EVENT_IF_OFF)
|
||||
lcd_driver->power_tiny_ctrl(0);
|
||||
else
|
||||
return NOTIFY_DONE;
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block lcd_interface_nb = {
|
||||
.notifier_call = lcd_interface_notifier,
|
||||
.priority = LCD_PRIORITY_POWER_LCD,
|
||||
};
|
||||
|
||||
static int lcd_bl_select_notifier(struct notifier_block *nb,
|
||||
unsigned long event, void *data)
|
||||
{
|
||||
unsigned int *index;
|
||||
|
||||
/* LCDPR("%s: 0x%lx\n", __func__, event); */
|
||||
if ((event & LCD_EVENT_BACKLIGHT_SEL) == 0)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
index = (unsigned int *)data;
|
||||
*index = lcd_driver->lcd_config->backlight_index;
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block lcd_bl_select_nb = {
|
||||
.notifier_call = lcd_bl_select_notifier,
|
||||
};
|
||||
/* **************************************** */
|
||||
|
||||
/* ************************************************************* */
|
||||
/* lcd ioctl */
|
||||
/* ************************************************************* */
|
||||
static int lcd_io_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct lcd_cdev_s *lcd_cdev;
|
||||
|
||||
LCDPR("%s\n", __func__);
|
||||
lcd_cdev = container_of(inode->i_cdev, struct lcd_cdev_s, cdev);
|
||||
file->private_data = lcd_cdev;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lcd_io_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
LCDPR("%s\n", __func__);
|
||||
file->private_data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long lcd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int ret = 0;
|
||||
void __user *argp;
|
||||
int mcd_nr;
|
||||
struct lcd_hdr_info_s *hdr_info = &lcd_driver->lcd_config->hdr_info;
|
||||
|
||||
mcd_nr = _IOC_NR(cmd);
|
||||
LCDPR("%s: cmd_dir = 0x%x, cmd_nr = 0x%x\n",
|
||||
__func__, _IOC_DIR(cmd), mcd_nr);
|
||||
|
||||
argp = (void __user *)arg;
|
||||
switch (mcd_nr) {
|
||||
case LCD_IOC_NR_GET_HDR_INFO:
|
||||
if (copy_to_user(argp, hdr_info, sizeof(struct lcd_hdr_info_s)))
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
case LCD_IOC_NR_SET_HDR_INFO:
|
||||
if (copy_from_user(hdr_info, argp,
|
||||
sizeof(struct lcd_hdr_info_s))) {
|
||||
ret = -EFAULT;
|
||||
} else {
|
||||
lcd_hdr_vinfo_update();
|
||||
if (lcd_debug_print_flag) {
|
||||
LCDPR("set hdr_info:\n"
|
||||
"hdr_support %d\n"
|
||||
"features %d\n"
|
||||
"primaries_r_x %d\n"
|
||||
"primaries_r_y %d\n"
|
||||
"primaries_g_x %d\n"
|
||||
"primaries_g_y %d\n"
|
||||
"primaries_b_x %d\n"
|
||||
"primaries_b_y %d\n"
|
||||
"white_point_x %d\n"
|
||||
"white_point_y %d\n"
|
||||
"luma_max %d\n"
|
||||
"luma_min %d\n\n",
|
||||
hdr_info->hdr_support,
|
||||
hdr_info->features,
|
||||
hdr_info->primaries_r_x,
|
||||
hdr_info->primaries_r_y,
|
||||
hdr_info->primaries_g_x,
|
||||
hdr_info->primaries_g_y,
|
||||
hdr_info->primaries_b_x,
|
||||
hdr_info->primaries_b_y,
|
||||
hdr_info->white_point_x,
|
||||
hdr_info->white_point_y,
|
||||
hdr_info->luma_max,
|
||||
hdr_info->luma_min);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LCDERR("not support ioctl cmd_nr: 0x%x\n", mcd_nr);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static long lcd_compat_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
unsigned long ret;
|
||||
|
||||
arg = (unsigned long)compat_ptr(arg);
|
||||
ret = lcd_ioctl(file, cmd, arg);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct file_operations lcd_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = lcd_io_open,
|
||||
.release = lcd_io_release,
|
||||
.unlocked_ioctl = lcd_ioctl,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = lcd_compat_ioctl,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int lcd_fops_create(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
lcd_cdev = kmalloc(sizeof(struct lcd_cdev_s), GFP_KERNEL);
|
||||
if (!lcd_cdev) {
|
||||
LCDERR("%s: failed to allocate lcd_cdev\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = alloc_chrdev_region(&lcd_cdev->devno, 0, 1, LCD_CDEV_NAME);
|
||||
if (ret < 0) {
|
||||
LCDERR("%s: failed to alloc devno\n", __func__);
|
||||
kfree(lcd_cdev);
|
||||
lcd_cdev = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
cdev_init(&lcd_cdev->cdev, &lcd_fops);
|
||||
lcd_cdev->cdev.owner = THIS_MODULE;
|
||||
ret = cdev_add(&lcd_cdev->cdev, lcd_cdev->devno, 1);
|
||||
if (ret) {
|
||||
LCDERR("%s: failed to add cdev\n", __func__);
|
||||
unregister_chrdev_region(lcd_cdev->devno, 1);
|
||||
kfree(lcd_cdev);
|
||||
lcd_cdev = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
lcd_cdev->dev = device_create(lcd_driver->lcd_debug_class, NULL,
|
||||
lcd_cdev->devno, NULL, LCD_CDEV_NAME);
|
||||
if (IS_ERR(lcd_cdev->dev)) {
|
||||
LCDERR("%s: failed to add device\n", __func__);
|
||||
ret = PTR_ERR(lcd_cdev->dev);
|
||||
cdev_del(&lcd_cdev->cdev);
|
||||
unregister_chrdev_region(lcd_cdev->devno, 1);
|
||||
kfree(lcd_cdev);
|
||||
lcd_cdev = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
LCDPR("%s OK\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lcd_fops_remove(void)
|
||||
{
|
||||
cdev_del(&lcd_cdev->cdev);
|
||||
unregister_chrdev_region(lcd_cdev->devno, 1);
|
||||
kfree(lcd_cdev);
|
||||
lcd_cdev = NULL;
|
||||
}
|
||||
/* ************************************************************* */
|
||||
|
||||
static void lcd_init_vout(void)
|
||||
{
|
||||
switch (lcd_driver->lcd_mode) {
|
||||
#ifdef CONFIG_AMLOGIC_LCD_TV
|
||||
case LCD_MODE_TV:
|
||||
lcd_tv_vout_server_init();
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_AMLOGIC_LCD_TABLET
|
||||
case LCD_MODE_TABLET:
|
||||
lcd_tablet_vout_server_init();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
LCDERR("invalid lcd mode: %d\n", lcd_driver->lcd_mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int lcd_mode_probe(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (lcd_driver->lcd_mode) {
|
||||
#ifdef CONFIG_AMLOGIC_LCD_TV
|
||||
case LCD_MODE_TV:
|
||||
lcd_tv_probe(dev);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_AMLOGIC_LCD_TABLET
|
||||
case LCD_MODE_TABLET:
|
||||
lcd_tablet_probe(dev);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
LCDERR("invalid lcd mode: %d\n", lcd_driver->lcd_mode);
|
||||
break;
|
||||
}
|
||||
|
||||
lcd_class_creat();
|
||||
lcd_fops_create();
|
||||
|
||||
ret = aml_lcd_notifier_register(&lcd_interface_nb);
|
||||
if (ret)
|
||||
LCDERR("register aml_bl_select_notifier failed\n");
|
||||
ret = aml_lcd_notifier_register(&lcd_bl_select_nb);
|
||||
if (ret)
|
||||
LCDERR("register aml_bl_select_notifier failed\n");
|
||||
ret = aml_lcd_notifier_register(&lcd_power_nb);
|
||||
if (ret)
|
||||
LCDPR("register lcd_power_notifier failed\n");
|
||||
|
||||
/* add notifier for video sync_duration info refresh */
|
||||
vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE,
|
||||
&lcd_driver->lcd_info->mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lcd_mode_remove(struct device *dev)
|
||||
{
|
||||
switch (lcd_driver->lcd_mode) {
|
||||
#ifdef CONFIG_AMLOGIC_LCD_TV
|
||||
case LCD_MODE_TV:
|
||||
lcd_tv_remove(dev);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_AMLOGIC_LCD_TABLET
|
||||
case LCD_MODE_TABLET:
|
||||
lcd_tablet_remove(dev);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
LCDPR("invalid lcd mode\n");
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lcd_config_probe_delayed(struct work_struct *work)
|
||||
{
|
||||
int key_init_flag = 0;
|
||||
int i = 0;
|
||||
int ret;
|
||||
|
||||
if (lcd_driver->lcd_key_valid) {
|
||||
key_init_flag = key_unify_get_init_flag();
|
||||
while (key_init_flag == 0) {
|
||||
if (i++ >= LCD_UNIFYKEY_WAIT_TIMEOUT)
|
||||
break;
|
||||
msleep(20);
|
||||
key_init_flag = key_unify_get_init_flag();
|
||||
}
|
||||
LCDPR("key_init_flag=%d, i=%d\n", key_init_flag, i);
|
||||
}
|
||||
ret = lcd_mode_probe(lcd_driver->dev);
|
||||
if (ret) {
|
||||
kfree(lcd_driver);
|
||||
lcd_driver = NULL;
|
||||
LCDERR("probe exit\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void lcd_config_default(void)
|
||||
{
|
||||
struct lcd_config_s *pconf;
|
||||
|
||||
pconf = lcd_driver->lcd_config;
|
||||
pconf->lcd_basic.h_active = lcd_vcbus_read(ENCL_VIDEO_HAVON_END)
|
||||
- lcd_vcbus_read(ENCL_VIDEO_HAVON_BEGIN) + 1;
|
||||
pconf->lcd_basic.v_active = lcd_vcbus_read(ENCL_VIDEO_VAVON_ELINE)
|
||||
- lcd_vcbus_read(ENCL_VIDEO_VAVON_BLINE) + 1;
|
||||
if (lcd_vcbus_read(ENCL_VIDEO_EN)) {
|
||||
lcd_driver->lcd_status = 1;
|
||||
lcd_resume_flag = 1;
|
||||
} else {
|
||||
lcd_driver->lcd_status = 0;
|
||||
lcd_resume_flag = 0;
|
||||
}
|
||||
LCDPR("status: %d\n", lcd_driver->lcd_status);
|
||||
}
|
||||
|
||||
static int lcd_config_probe(void)
|
||||
{
|
||||
const char *str;
|
||||
unsigned int val;
|
||||
int ret = 0;
|
||||
|
||||
if (lcd_driver->dev->of_node == NULL) {
|
||||
LCDERR("dev of_node is null\n");
|
||||
lcd_driver->lcd_mode = LCD_MODE_MAX;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* lcd driver assign */
|
||||
ret = of_property_read_string(lcd_driver->dev->of_node, "mode", &str);
|
||||
if (ret) {
|
||||
str = "none";
|
||||
LCDERR("failed to get mode\n");
|
||||
return -1;
|
||||
}
|
||||
lcd_driver->lcd_mode = lcd_mode_str_to_mode(str);
|
||||
ret = of_property_read_u32(lcd_driver->dev->of_node,
|
||||
"fr_auto_policy", &val);
|
||||
if (ret) {
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("failed to get fr_auto_policy\n");
|
||||
lcd_driver->fr_auto_policy = 0;
|
||||
} else {
|
||||
lcd_driver->fr_auto_policy = (unsigned char)val;
|
||||
}
|
||||
ret = of_property_read_u32(lcd_driver->dev->of_node, "key_valid", &val);
|
||||
if (ret) {
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("failed to get key_valid\n");
|
||||
lcd_driver->lcd_key_valid = 0;
|
||||
} else {
|
||||
lcd_driver->lcd_key_valid = (unsigned char)val;
|
||||
}
|
||||
LCDPR("detect mode: %s, fr_auto_policy: %d, key_valid: %d\n",
|
||||
str, lcd_driver->fr_auto_policy, lcd_driver->lcd_key_valid);
|
||||
|
||||
lcd_clktree_probe();
|
||||
|
||||
lcd_driver->lcd_info = &lcd_vinfo;
|
||||
lcd_driver->lcd_config = &lcd_config_dft;
|
||||
lcd_driver->lcd_config->pinmux_flag = 0;
|
||||
lcd_driver->lcd_test_flag = 0;
|
||||
lcd_driver->power_ctrl = lcd_power_ctrl;
|
||||
lcd_driver->module_reset = lcd_module_reset;
|
||||
lcd_driver->power_tiny_ctrl = lcd_power_tiny_ctrl;
|
||||
lcd_driver->module_tiny_reset = lcd_module_tiny_reset;
|
||||
lcd_config_default();
|
||||
lcd_init_vout();
|
||||
|
||||
if (lcd_driver->lcd_key_valid) {
|
||||
if (lcd_driver->workqueue) {
|
||||
queue_delayed_work(lcd_driver->workqueue,
|
||||
&lcd_driver->lcd_probe_delayed_work,
|
||||
msecs_to_jiffies(2000));
|
||||
} else {
|
||||
LCDPR("Warning: no lcd_probe_delayed workqueue\n");
|
||||
ret = lcd_mode_probe(lcd_driver->dev);
|
||||
if (ret) {
|
||||
kfree(lcd_driver);
|
||||
lcd_driver = NULL;
|
||||
LCDERR("probe exit\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = lcd_mode_probe(lcd_driver->dev);
|
||||
if (ret) {
|
||||
kfree(lcd_driver);
|
||||
lcd_driver = NULL;
|
||||
LCDERR("probe exit\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lcd_resume_work(struct work_struct *p_work)
|
||||
{
|
||||
mutex_lock(&lcd_power_mutex);
|
||||
lcd_resume_flag = 1;
|
||||
aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL);
|
||||
LCDPR("%s finished\n", __func__);
|
||||
mutex_unlock(&lcd_power_mutex);
|
||||
}
|
||||
|
||||
static int lcd_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
#ifdef LCD_DEBUG_INFO
|
||||
lcd_debug_print_flag = 1;
|
||||
#else
|
||||
lcd_debug_print_flag = 0;
|
||||
#endif
|
||||
lcd_driver = kmalloc(sizeof(struct aml_lcd_drv_s), GFP_KERNEL);
|
||||
if (!lcd_driver) {
|
||||
LCDERR("%s: lcd driver no enough memory\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
lcd_driver->dev = &pdev->dev;
|
||||
|
||||
mutex_init(&lcd_vout_mutex);
|
||||
mutex_init(&lcd_power_mutex);
|
||||
lcd_vout_serve_bypass = 0;
|
||||
|
||||
/* init workqueue */
|
||||
INIT_DELAYED_WORK(&lcd_driver->lcd_probe_delayed_work,
|
||||
lcd_config_probe_delayed);
|
||||
lcd_driver->workqueue = create_singlethread_workqueue("lcd_work_queue");
|
||||
if (lcd_driver->workqueue == NULL)
|
||||
LCDERR("can't create lcd workqueue\n");
|
||||
|
||||
INIT_WORK(&(lcd_driver->lcd_resume_work), lcd_resume_work);
|
||||
|
||||
lcd_chip_detect();
|
||||
lcd_ioremap();
|
||||
lcd_clk_config_probe();
|
||||
ret = lcd_config_probe();
|
||||
|
||||
LCDPR("%s %s\n", __func__, (ret ? "failed" : "ok"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lcd_remove(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = cancel_delayed_work(&lcd_driver->lcd_probe_delayed_work);
|
||||
if (lcd_driver->workqueue)
|
||||
destroy_workqueue(lcd_driver->workqueue);
|
||||
|
||||
if (lcd_driver) {
|
||||
aml_lcd_notifier_unregister(&lcd_power_nb);
|
||||
aml_lcd_notifier_unregister(&lcd_bl_select_nb);
|
||||
aml_lcd_notifier_unregister(&lcd_interface_nb);
|
||||
|
||||
lcd_fops_remove();
|
||||
lcd_class_remove();
|
||||
if (!IS_ERR(lcd_driver->vencl_top))
|
||||
devm_clk_put(lcd_driver->dev, lcd_driver->vencl_top);
|
||||
if (!IS_ERR(lcd_driver->vencl_int))
|
||||
devm_clk_put(lcd_driver->dev, lcd_driver->vencl_int);
|
||||
|
||||
lcd_mode_remove(lcd_driver->dev);
|
||||
kfree(lcd_driver);
|
||||
lcd_driver = NULL;
|
||||
}
|
||||
|
||||
LCDPR("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lcd_resume(struct platform_device *pdev)
|
||||
{
|
||||
queue_work(lcd_driver->workqueue, &(lcd_driver->lcd_resume_work));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lcd_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
mutex_lock(&lcd_power_mutex);
|
||||
if (lcd_driver->lcd_status) {
|
||||
aml_lcd_notifier_call_chain(LCD_EVENT_POWER_OFF, NULL);
|
||||
lcd_resume_flag = 0;
|
||||
LCDPR("%s finished\n", __func__);
|
||||
}
|
||||
mutex_unlock(&lcd_power_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lcd_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
if (lcd_debug_print_flag)
|
||||
LCDPR("%s\n", __func__);
|
||||
|
||||
if (lcd_driver->lcd_status)
|
||||
aml_lcd_notifier_call_chain(LCD_EVENT_POWER_OFF, NULL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id lcd_dt_match[] = {
|
||||
{
|
||||
.compatible = "amlogic, lcd",
|
||||
},
|
||||
{},
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct platform_driver lcd_platform_driver = {
|
||||
.probe = lcd_probe,
|
||||
.remove = lcd_remove,
|
||||
.suspend = lcd_suspend,
|
||||
.resume = lcd_resume,
|
||||
.shutdown = lcd_shutdown,
|
||||
.driver = {
|
||||
.name = "mesonlcd",
|
||||
.owner = THIS_MODULE,
|
||||
#ifdef CONFIG_OF
|
||||
.of_match_table = lcd_dt_match,
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
static int __init lcd_init(void)
|
||||
{
|
||||
if (platform_driver_register(&lcd_platform_driver)) {
|
||||
LCDERR("failed to register lcd driver module\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit lcd_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&lcd_platform_driver);
|
||||
}
|
||||
|
||||
subsys_initcall(lcd_init);
|
||||
module_exit(lcd_exit);
|
||||
|
||||
static int __init lcd_panel_type_para_setup(char *str)
|
||||
{
|
||||
if (str != NULL)
|
||||
sprintf(lcd_propname, "%s", str);
|
||||
|
||||
LCDPR("panel_type: %s\n", lcd_propname);
|
||||
return 0;
|
||||
}
|
||||
__setup("panel_type=", lcd_panel_type_para_setup);
|
||||
|
||||
MODULE_DESCRIPTION("Meson LCD Panel Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Amlogic, Inc.");
|
||||
@@ -354,6 +354,7 @@ static const unsigned int tcon_stv1_pins[] = { PIN(GPIODV_24, EE_OFF) };
|
||||
static const unsigned int tcon_sth1_pins[] = { PIN(GPIODV_25, EE_OFF) };
|
||||
static const unsigned int tcon_cph_pins[] = { PIN(GPIODV_26, EE_OFF) };
|
||||
static const unsigned int tcon_vcom_pins[] = { PIN(GPIODV_27, EE_OFF) };
|
||||
static const unsigned int tcon_oeh_pins[] = { PIN(GPIODV_27, EE_OFF) };
|
||||
|
||||
/*i2c_a*/
|
||||
static const unsigned int i2c_sda_a_pins[] = { PIN(GPIODV_24, EE_OFF) };
|
||||
@@ -612,19 +613,23 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = {
|
||||
GROUP(tsout_clk, 1, 27), /*dv15*/
|
||||
GROUP(tsout_d0, 1, 26), /*dv16*/
|
||||
GROUP(tsout_d1_7, 1, 25), /*dv17-23*/
|
||||
GROUP(lcd_r0_1, 3, 10), /*dv0-1*/
|
||||
GROUP(lcd_r2_7, 3, 9), /*dv2-7*/
|
||||
GROUP(lcd_g0_1, 3, 8), /*dv8-9*/
|
||||
GROUP(lcd_g2_7, 3, 7), /*dv10-15*/
|
||||
GROUP(lcd_b0_1, 3, 6), /*dv16-17*/
|
||||
GROUP(lcd_b2_7, 3, 5), /*dv18-23*/
|
||||
GROUP(lcd_r0_1, 3, 10), /*dv0-1*/
|
||||
GROUP(lcd_r2_7, 3, 9), /*dv2-7*/
|
||||
GROUP(lcd_g0_1, 3, 8), /*dv8-9*/
|
||||
GROUP(lcd_g2_7, 3, 7), /*dv10-15*/
|
||||
GROUP(lcd_b0_1, 3, 6), /*dv16-17*/
|
||||
GROUP(lcd_b2_7, 3, 5), /*dv18-23*/
|
||||
GROUP(lcd_vs, 3, 4), /*dv24*/
|
||||
GROUP(lcd_hs, 3, 3), /*dv25*/
|
||||
GROUP(tcon_stv1, 1, 22), /*dv24*/
|
||||
GROUP(tcon_sth1, 1, 21), /*dv25*/
|
||||
GROUP(tcon_cph, 1, 20), /*dv26*/
|
||||
GROUP(tcon_vcom, 1, 19), /*dv27*/
|
||||
GROUP(tcon_oeh, 1, 18), /*dv27*/
|
||||
GROUP(uart_tx_b, 2, 16),
|
||||
GROUP(uart_rx_b, 2, 15),
|
||||
GROUP(uart_cts_b, 2, 14),
|
||||
GROUP(uart_rts_b, 2, 13),
|
||||
GROUP(lcd_vs, 3, 4), /*dv24*/
|
||||
GROUP(lcd_hs, 3, 3), /*dv25*/
|
||||
GROUP(tcon_stv1, 1, 22),
|
||||
GROUP(i2c_sda_a, 1, 15), /*dv24*/
|
||||
GROUP(i2c_scl_a, 1, 14), /*dv25*/
|
||||
GROUP(dmic_in_dv24, 2, 7), /*dv24*/
|
||||
@@ -969,11 +974,12 @@ static const char * const tsout_a_groups[] = {
|
||||
"tsout_d0", "tsout_d1_7",
|
||||
};
|
||||
|
||||
static const char * const lcd_groups[] = {
|
||||
static const char * const lcd_ttl_groups[] = {
|
||||
"lcd_r0_1", "lcd_r2_7",
|
||||
"lcd_g0_1", "lcd_g2_7",
|
||||
"lcd_b0_1", "lcd_b2_7",
|
||||
"lcd_vs", "lcd_hs",
|
||||
"tcon_stv1", "tcon_sth1",
|
||||
"tcon_cph", "tcon_oeh",
|
||||
};
|
||||
|
||||
static const char *const nor_groups[] = {
|
||||
@@ -1022,7 +1028,7 @@ static struct meson_pmx_func meson_gxl_periphs_functions[] = {
|
||||
FUNCTION(tsin_a),
|
||||
FUNCTION(tsin_b),
|
||||
FUNCTION(tsout_a),
|
||||
FUNCTION(lcd),
|
||||
FUNCTION(lcd_ttl),
|
||||
FUNCTION(nor),
|
||||
FUNCTION(dvp),
|
||||
FUNCTION(dmic),
|
||||
|
||||
175
include/linux/amlogic/media/vout/lcd/aml_bl.h
Normal file
175
include/linux/amlogic/media/vout/lcd/aml_bl.h
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* include/linux/amlogic/media/vout/lcd/aml_bl.h
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __INC_AML_BL_H
|
||||
#define __INC_AML_BL_H
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/amlogic/aml_gpio_consumer.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
|
||||
#define BLPR(fmt, args...) pr_info("bl: "fmt"", ## args)
|
||||
#define BLERR(fmt, args...) pr_err("bl error: "fmt"", ## args)
|
||||
#define AML_BL_NAME "aml-bl"
|
||||
|
||||
#define BL_LEVEL_MAX 255
|
||||
#define BL_LEVEL_MIN 10
|
||||
#define BL_LEVEL_OFF 1
|
||||
|
||||
#define BL_LEVEL_MID 128
|
||||
#define BL_LEVEL_MID_MAPPED BL_LEVEL_MID
|
||||
#define BL_LEVEL_DEFAULT BL_LEVEL_MID
|
||||
|
||||
#define XTAL_FREQ_HZ (24*1000*1000) /* unit: Hz */
|
||||
#define XTAL_HALF_FREQ_HZ (24*1000*500) /* 24M/2 in HZ */
|
||||
|
||||
#define BL_FREQ_DEFAULT 1000 /* unit: HZ */
|
||||
#define BL_FREQ_VS_DEFAULT 2 /* multiple 2 of vfreq */
|
||||
|
||||
enum bl_chip_type_e {
|
||||
BL_CHIP_GXTVBB,
|
||||
BL_CHIP_GXL,
|
||||
BL_CHIP_GXM,
|
||||
BL_CHIP_TXL,
|
||||
BL_CHIP_TXLX,
|
||||
BL_CHIP_AXG,
|
||||
BL_CHIP_MAX,
|
||||
};
|
||||
|
||||
/* for lcd backlight power */
|
||||
enum bl_ctrl_method_e {
|
||||
BL_CTRL_GPIO = 0,
|
||||
BL_CTRL_PWM,
|
||||
BL_CTRL_PWM_COMBO,
|
||||
BL_CTRL_LOCAL_DIMING,
|
||||
BL_CTRL_EXTERN,
|
||||
BL_CTRL_MAX,
|
||||
};
|
||||
|
||||
enum bl_pwm_method_e {
|
||||
BL_PWM_NEGATIVE = 0,
|
||||
BL_PWM_POSITIVE,
|
||||
BL_PWM_METHOD_MAX,
|
||||
};
|
||||
|
||||
enum bl_pwm_port_e {
|
||||
BL_PWM_A = 0,
|
||||
BL_PWM_B,
|
||||
BL_PWM_C,
|
||||
BL_PWM_D,
|
||||
BL_PWM_E,
|
||||
BL_PWM_F,
|
||||
BL_PWM_VS,
|
||||
BL_PWM_MAX,
|
||||
};
|
||||
|
||||
enum bl_off_policy_e {
|
||||
BL_OFF_POLICY_NONE = 0,
|
||||
BL_OFF_POLICY_ALWAYS,
|
||||
BL_OFF_POLICY_ONCE,
|
||||
BL_OFF_POLICY_MAX,
|
||||
};
|
||||
|
||||
#define BL_GPIO_OUTPUT_LOW 0
|
||||
#define BL_GPIO_OUTPUT_HIGH 1
|
||||
#define BL_GPIO_INPUT 2
|
||||
|
||||
#define BL_GPIO_MAX 0xff
|
||||
#define BL_GPIO_NUM_MAX 5
|
||||
struct bl_gpio_s {
|
||||
char name[15];
|
||||
struct gpio_desc *gpio;
|
||||
int flag;
|
||||
};
|
||||
|
||||
struct bl_pwm_config_s {
|
||||
unsigned int index;
|
||||
struct pwm_device *bl_pwm_ch;
|
||||
struct aml_pwm_chip *bl_pwm_chip;
|
||||
enum bl_pwm_method_e pwm_method;
|
||||
enum bl_pwm_port_e pwm_port;
|
||||
unsigned int level_max;
|
||||
unsigned int level_min;
|
||||
unsigned int pwm_freq; /* pwm_vs: 1~4(vfreq), pwm: freq(unit: Hz) */
|
||||
unsigned int pwm_duty; /* unit: % */
|
||||
unsigned int pwm_duty_max; /* unit: % */
|
||||
unsigned int pwm_duty_min; /* unit: % */
|
||||
unsigned int pwm_cnt; /* internal used for pwm control */
|
||||
unsigned int pwm_pre_div; /* internal used for pwm control */
|
||||
unsigned int pwm_max; /* internal used for pwm control */
|
||||
unsigned int pwm_min; /* internal used for pwm control */
|
||||
unsigned int pwm_level; /* internal used for pwm control */
|
||||
};
|
||||
|
||||
struct bl_config_s {
|
||||
char name[30];
|
||||
unsigned int level_default;
|
||||
unsigned int level_min;
|
||||
unsigned int level_max;
|
||||
unsigned int level_mid;
|
||||
unsigned int level_mid_mapping;
|
||||
|
||||
enum bl_ctrl_method_e method;
|
||||
unsigned int en_gpio;
|
||||
unsigned int en_gpio_on;
|
||||
unsigned int en_gpio_off;
|
||||
unsigned int power_on_delay;
|
||||
unsigned int power_off_delay;
|
||||
unsigned int dim_max;
|
||||
unsigned int dim_min;
|
||||
|
||||
struct bl_pwm_config_s *bl_pwm;
|
||||
struct bl_pwm_config_s *bl_pwm_combo0;
|
||||
struct bl_pwm_config_s *bl_pwm_combo1;
|
||||
unsigned int pwm_on_delay;
|
||||
unsigned int pwm_off_delay;
|
||||
|
||||
struct bl_gpio_s bl_gpio[BL_GPIO_NUM_MAX];
|
||||
struct pinctrl *pin;
|
||||
unsigned int pinmux_flag;
|
||||
};
|
||||
|
||||
#define BL_INDEX_DEFAULT 0
|
||||
|
||||
/* backlight_properties: state */
|
||||
/* Flags used to signal drivers of state changes */
|
||||
/* Upper 4 bits in bl props are reserved for driver internal use */
|
||||
#define BL_STATE_LCD_ON (1 << 3)
|
||||
#define BL_STATE_BL_POWER_ON (1 << 1)
|
||||
#define BL_STATE_BL_ON (1 << 0)
|
||||
struct aml_bl_drv_s {
|
||||
unsigned int index;
|
||||
unsigned int level;
|
||||
unsigned int state;
|
||||
enum bl_chip_type_e chip_type;
|
||||
struct device *dev;
|
||||
struct bl_config_s *bconf;
|
||||
struct backlight_device *bldev;
|
||||
struct workqueue_struct *workqueue;
|
||||
struct delayed_work bl_delayed_work;
|
||||
};
|
||||
|
||||
extern enum bl_chip_type_e aml_bl_check_chip(void);
|
||||
extern struct aml_bl_drv_s *aml_bl_get_driver(void);
|
||||
extern void bl_pwm_config_init(struct bl_pwm_config_s *bl_pwm);
|
||||
extern enum bl_pwm_port_e bl_pwm_str_to_pwm(const char *str);
|
||||
|
||||
#define BL_GPIO_OUTPUT_LOW 0
|
||||
#define BL_GPIO_OUTPUT_HIGH 1
|
||||
#define BL_GPIO_INPUT 2
|
||||
|
||||
#endif
|
||||
|
||||
76
include/linux/amlogic/media/vout/lcd/aml_bl_extern.h
Normal file
76
include/linux/amlogic/media/vout/lcd/aml_bl_extern.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* include/linux/amlogic/media/vout/lcd/aml_bl_extern.h
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __AMLOGIC_BL_EXTERN_H_
|
||||
#define __AMLOGIC_BL_EXTERN_H_
|
||||
|
||||
#include <linux/amlogic/aml_gpio_consumer.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
|
||||
enum bl_extern_type_e {
|
||||
BL_EXTERN_I2C = 0,
|
||||
BL_EXTERN_SPI,
|
||||
BL_EXTERN_OTHER,
|
||||
BL_EXTERN_MAX,
|
||||
};
|
||||
|
||||
struct bl_extern_config_s {
|
||||
const char *name;
|
||||
enum bl_extern_type_e type;
|
||||
struct gpio_desc *gpio;
|
||||
unsigned char gpio_on;
|
||||
unsigned char gpio_off;
|
||||
|
||||
int i2c_addr;
|
||||
int i2c_bus;
|
||||
struct gpio_desc *spi_cs;
|
||||
struct gpio_desc *spi_clk;
|
||||
struct gpio_desc *spi_data;
|
||||
unsigned int dim_min;
|
||||
unsigned int dim_max;
|
||||
/* unsigned int level_min; */
|
||||
/* unsigned int level_max; */
|
||||
};
|
||||
|
||||
/*******global API******/
|
||||
struct aml_bl_extern_driver_t {
|
||||
const char *name;
|
||||
enum bl_extern_type_e type;
|
||||
int (*power_on)(void);
|
||||
int (*power_off)(void);
|
||||
int (*set_level)(unsigned int level);
|
||||
};
|
||||
|
||||
#define BL_EXTERN_DRIVER "bl_extern"
|
||||
|
||||
|
||||
#define bl_extern_gpio_free(gpio) gpiod_free(gpio, BL_EXTERN_DRIVER)
|
||||
#define bl_extern_gpio_input(gpio) gpiod_direction_input(gpio)
|
||||
#define bl_extern_gpio_output(gpio, val) gpiod_direction_output(gpio, val)
|
||||
#define bl_extern_gpio_get_value(gpio) gpiod_get_value(gpio)
|
||||
#define bl_extern_gpio_set_value(gpio, val) gpiod_set_value(gpio, val)
|
||||
|
||||
|
||||
extern struct aml_bl_extern_driver_t *aml_bl_extern_get_driver(void);
|
||||
extern int bl_extern_driver_check(void);
|
||||
extern int get_bl_extern_dt_data(struct device dev,
|
||||
struct bl_extern_config_s *pdata);
|
||||
|
||||
extern void get_bl_ext_level(struct bl_extern_config_s *bl_ext_cfg);
|
||||
|
||||
#endif
|
||||
|
||||
88
include/linux/amlogic/media/vout/lcd/aml_ldim.h
Normal file
88
include/linux/amlogic/media/vout/lcd/aml_ldim.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* include/linux/amlogic/media/vout/lcd/aml_ldim.h
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _INC_AML_LDIM_H_
|
||||
#define _INC_AML_LDIM_H_
|
||||
#include <linux/types.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/amlogic/aml_gpio_consumer.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/amlogic/media/vout/aml_bl.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
enum ldim_dev_type_e {
|
||||
LDIM_DEV_TYPE_NORMAL = 0,
|
||||
LDIM_DEV_TYPE_SPI,
|
||||
LDIM_DEV_TYPE_I2C,
|
||||
LDIM_DEV_TYPE_MAX,
|
||||
};
|
||||
|
||||
#define LDIM_SPI_INIT_ON_SIZE 300
|
||||
#define LDIM_SPI_INIT_OFF_SIZE 20
|
||||
struct ldim_dev_config_s {
|
||||
char name[20];
|
||||
char pinmux_name[20];
|
||||
unsigned char type;
|
||||
int cs_hold_delay;
|
||||
int cs_clk_delay;
|
||||
int en_gpio;
|
||||
int en_gpio_on;
|
||||
int en_gpio_off;
|
||||
int lamp_err_gpio;
|
||||
unsigned char fault_check;
|
||||
unsigned char write_check;
|
||||
|
||||
unsigned int dim_min;
|
||||
unsigned int dim_max;
|
||||
unsigned char cmd_size;
|
||||
unsigned char *init_on;
|
||||
unsigned char *init_off;
|
||||
|
||||
struct bl_pwm_config_s pwm_config;
|
||||
};
|
||||
|
||||
/*******global API******/
|
||||
struct aml_ldim_driver_s {
|
||||
int valid_flag;
|
||||
int dev_index;
|
||||
int static_pic_flag;
|
||||
struct ldim_dev_config_s *ldev_conf;
|
||||
unsigned short *ldim_matrix_buf;
|
||||
int (*init)(void);
|
||||
int (*power_on)(void);
|
||||
int (*power_off)(void);
|
||||
int (*set_level)(unsigned int level);
|
||||
int (*pinmux_ctrl)(char *pin_str, int status);
|
||||
int (*pwm_vs_update)(void);
|
||||
int (*device_power_on)(void);
|
||||
int (*device_power_off)(void);
|
||||
int (*device_bri_update)(unsigned short *buf, unsigned char len);
|
||||
int (*device_bri_check)(void);
|
||||
void (*config_print)(void);
|
||||
void (*test_ctrl)(int flag);
|
||||
struct pinctrl *pin;
|
||||
struct device *dev;
|
||||
struct spi_device *spi;
|
||||
struct spi_board_info *spi_dev;
|
||||
};
|
||||
|
||||
extern struct aml_ldim_driver_s *aml_ldim_get_driver(void);
|
||||
extern int aml_ldim_probe(struct platform_device *pdev);
|
||||
extern int aml_ldim_remove(void);
|
||||
|
||||
#endif
|
||||
|
||||
87
include/linux/amlogic/media/vout/lcd/lcd_extern.h
Normal file
87
include/linux/amlogic/media/vout/lcd/lcd_extern.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* include/linux/amlogic/media/vout/lcd/lcd_extern.h
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _INC_AML_LCD_EXTERN_H_
|
||||
#define _INC_AML_LCD_EXTERN_H_
|
||||
|
||||
enum lcd_extern_type_e {
|
||||
LCD_EXTERN_I2C = 0,
|
||||
LCD_EXTERN_SPI,
|
||||
LCD_EXTERN_MIPI,
|
||||
LCD_EXTERN_MAX,
|
||||
};
|
||||
|
||||
enum lcd_extern_i2c_bus_e {
|
||||
LCD_EXTERN_I2C_BUS_AO = 0,
|
||||
LCD_EXTERN_I2C_BUS_A,
|
||||
LCD_EXTERN_I2C_BUS_B,
|
||||
LCD_EXTERN_I2C_BUS_C,
|
||||
LCD_EXTERN_I2C_BUS_D,
|
||||
LCD_EXTERN_I2C_BUS_MAX,
|
||||
};
|
||||
#define LCD_EXTERN_I2C_BUS_INVALID 0xff
|
||||
|
||||
#define LCD_EXTERN_SPI_CLK_FREQ_DFT 10000 /* default 10k */
|
||||
|
||||
#define LCD_EXTERN_INIT_TABLE_MAX 500
|
||||
|
||||
#define LCD_EXTERN_INIT_CMD 0x00
|
||||
#define LCD_EXTERN_INIT_CMD2 0x01 /* only for special i2c device */
|
||||
#define LCD_EXTERN_INIT_GPIO 0x10
|
||||
#define LCD_EXTERN_INIT_NONE 0xf0
|
||||
#define LCD_EXTERN_INIT_END 0xff
|
||||
|
||||
|
||||
#define LCD_EXTERN_DYNAMIC_LEN 0xff
|
||||
|
||||
|
||||
#define LCD_EXTERN_GPIO_NUM_MAX 6
|
||||
#define LCD_EXTERN_INDEX_INVALID 0xff
|
||||
#define LCD_EXTERN_NAME_LEN_MAX 30
|
||||
struct lcd_extern_config_s {
|
||||
unsigned char index;
|
||||
char name[LCD_EXTERN_NAME_LEN_MAX];
|
||||
enum lcd_extern_type_e type;
|
||||
unsigned char status;
|
||||
unsigned char i2c_addr;
|
||||
unsigned char i2c_addr2;
|
||||
unsigned char i2c_bus;
|
||||
unsigned char spi_gpio_cs;
|
||||
unsigned char spi_gpio_clk;
|
||||
unsigned char spi_gpio_data;
|
||||
unsigned int spi_clk_freq;
|
||||
unsigned char spi_clk_pol;
|
||||
unsigned char cmd_size;
|
||||
unsigned char table_init_loaded; /* internal use */
|
||||
unsigned char *table_init_on;
|
||||
unsigned char *table_init_off;
|
||||
};
|
||||
|
||||
/* global API */
|
||||
#define LCD_EXT_DRIVER_MAX 10
|
||||
struct aml_lcd_extern_driver_s {
|
||||
struct lcd_extern_config_s config;
|
||||
int (*reg_read)(unsigned char reg, unsigned char *buf);
|
||||
int (*reg_write)(unsigned char reg, unsigned char value);
|
||||
int (*power_on)(void);
|
||||
int (*power_off)(void);
|
||||
};
|
||||
|
||||
extern struct aml_lcd_extern_driver_s *aml_lcd_extern_get_driver(int index);
|
||||
|
||||
#endif
|
||||
|
||||
52
include/linux/amlogic/media/vout/lcd/lcd_mipi.h
Normal file
52
include/linux/amlogic/media/vout/lcd/lcd_mipi.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* include/linux/amlogic/media/vout/lcd/lcd_mipi.h
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _INC_LCD_MIPI_H
|
||||
#define _INC_LCD_MIPI_H
|
||||
|
||||
/* **********************************
|
||||
* mipi-dsi read/write api
|
||||
*/
|
||||
|
||||
/* mipi command(payload) */
|
||||
/* format: data_type, num, data.... */
|
||||
/* special: data_type=0xff,
|
||||
* num<0xff means delay ms, num=0xff means ending.
|
||||
*/
|
||||
|
||||
/* *************************************************************
|
||||
* Function: dsi_write_cmd
|
||||
* Supported Data Type: DT_GEN_SHORT_WR_0, DT_GEN_SHORT_WR_1, DT_GEN_SHORT_WR_2,
|
||||
DT_DCS_SHORT_WR_0, DT_DCS_SHORT_WR_1,
|
||||
DT_GEN_LONG_WR, DT_DCS_LONG_WR,
|
||||
DT_SET_MAX_RET_PKT_SIZE
|
||||
DT_GEN_RD_0, DT_GEN_RD_1, DT_GEN_RD_2,
|
||||
DT_DCS_RD_0
|
||||
* Return: command number
|
||||
*/
|
||||
extern int dsi_write_cmd(unsigned char *payload);
|
||||
|
||||
/* *************************************************************
|
||||
* Function: dsi_read_single
|
||||
* Supported Data Type: DT_GEN_RD_0, DT_GEN_RD_1, DT_GEN_RD_2,
|
||||
DT_DCS_RD_0
|
||||
* Return: data count
|
||||
0 for not support
|
||||
*/
|
||||
extern int dsi_read_single(unsigned char *payload, unsigned char *rd_data,
|
||||
unsigned int rd_byte_len);
|
||||
#endif
|
||||
63
include/linux/amlogic/media/vout/lcd/lcd_notify.h
Normal file
63
include/linux/amlogic/media/vout/lcd/lcd_notify.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* include/linux/amlogic/media/vout/lcd/lcd_notify.h
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _INC_LCD_NOTIFY_H_
|
||||
#define _INC_LCD_NOTIFY_H_
|
||||
|
||||
#include <linux/notifier.h>
|
||||
|
||||
#define LCD_PRIORITY_INIT_CONFIG 4
|
||||
#define LCD_PRIORITY_INIT_VOUT 3
|
||||
|
||||
#define LCD_PRIORITY_BLACK_SCREEN 3
|
||||
#define LCD_PRIORITY_POWER_BL_OFF 2
|
||||
#define LCD_PRIORITY_POWER_LCD 1
|
||||
#define LCD_PRIORITY_POWER_BL_ON 0
|
||||
|
||||
#define LCD_EVENT_BL_ON (1 << 0)
|
||||
#define LCD_EVENT_LCD_ON (1 << 1)
|
||||
#define LCD_EVENT_IF_ON (1 << 2)
|
||||
#define LCD_EVENT_POWER_ON (LCD_EVENT_BL_ON | LCD_EVENT_LCD_ON)
|
||||
#define LCD_EVENT_IF_POWER_ON (LCD_EVENT_BL_ON | LCD_EVENT_IF_ON)
|
||||
#define LCD_EVENT_BLACK_SCREEN (1 << 3)
|
||||
#define LCD_EVENT_BL_OFF (1 << 4)
|
||||
#define LCD_EVENT_LCD_OFF (1 << 5)
|
||||
#define LCD_EVENT_IF_OFF (1 << 6)
|
||||
#define LCD_EVENT_POWER_OFF (LCD_EVENT_BL_OFF | LCD_EVENT_LCD_OFF |\
|
||||
LCD_EVENT_BLACK_SCREEN)
|
||||
#define LCD_EVENT_IF_POWER_OFF (LCD_EVENT_BL_OFF | LCD_EVENT_IF_OFF |\
|
||||
LCD_EVENT_BLACK_SCREEN)
|
||||
|
||||
/* lcd backlight index select */
|
||||
#define LCD_EVENT_BACKLIGHT_SEL (1 << 8)
|
||||
/* lcd backlight pwm_vs vfreq change occurred */
|
||||
#define LCD_EVENT_BACKLIGHT_UPDATE (1 << 9)
|
||||
|
||||
#define LCD_EVENT_GAMMA_UPDATE (1 << 10)
|
||||
|
||||
/* lcd frame rate change occurred */
|
||||
#define LCD_EVENT_FRAME_RATE_ADJUST (1 << 12)
|
||||
/* lcd config change occurred */
|
||||
#define LCD_EVENT_CONFIG_UPDATE (1 << 13)
|
||||
/* lcd bist pattern test occurred */
|
||||
#define LCD_EVENT_TEST_PATTERN (1 << 14)
|
||||
|
||||
extern int aml_lcd_notifier_register(struct notifier_block *nb);
|
||||
extern int aml_lcd_notifier_unregister(struct notifier_block *nb);
|
||||
extern int aml_lcd_notifier_call_chain(unsigned long event, void *v);
|
||||
|
||||
#endif /* _INC_LCD_NOTIFY_H_ */
|
||||
185
include/linux/amlogic/media/vout/lcd/lcd_unifykey.h
Normal file
185
include/linux/amlogic/media/vout/lcd/lcd_unifykey.h
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* include/linux/amlogic/media/vout/lcd/lcd_unifykey.h
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _INC_AML_LCD_UNIFYKEY_H__
|
||||
#define _INC_AML_LCD_UNIFYKEY_H__
|
||||
|
||||
#define LCD_UNIFYKEY_WAIT_TIMEOUT 300
|
||||
|
||||
/* declare external unifykey function */
|
||||
extern int key_unify_read(char *keyname, unsigned char *keydata,
|
||||
unsigned int datalen, unsigned int *reallen);
|
||||
extern int key_unify_size(char *keyname, unsigned int *reallen);
|
||||
extern int key_unify_query(char *keyname, unsigned int *keystate,
|
||||
unsigned int *keypermit);
|
||||
extern int key_unify_get_init_flag(void);
|
||||
|
||||
|
||||
#define LCD_UKEY_RETRY_CNT_MAX 5
|
||||
/*
|
||||
* lcd unifykey data struct: little-endian, for example:
|
||||
* 4byte: d[0]=0x01, d[1]=0x02, d[2] = 0x03, d[3]= 0x04,
|
||||
* data = 0x04030201
|
||||
*/
|
||||
|
||||
/* define lcd unifykey length */
|
||||
|
||||
#define LCD_UKEY_HEAD_SIZE 10
|
||||
#define LCD_UKEY_HEAD_CRC32 4
|
||||
#define LCD_UKEY_HEAD_DATA_LEN 2
|
||||
#define LCD_UKEY_HEAD_VERSION 2
|
||||
#define LCD_UKEY_HEAD_RESERVED 2
|
||||
|
||||
struct aml_lcd_unifykey_header_s {
|
||||
unsigned int crc32;
|
||||
unsigned short data_len;
|
||||
unsigned short version;
|
||||
unsigned short reserved;
|
||||
};
|
||||
|
||||
/* lcd */
|
||||
#define LCD_UKEY_LCD_SIZE 265
|
||||
|
||||
/* header (10Byte) */
|
||||
/* LCD_UKEY_HEAD_SIZE */
|
||||
/* basic (36Byte) */
|
||||
#define LCD_UKEY_MODEL_NAME 30
|
||||
#define LCD_UKEY_INTERFACE 1
|
||||
#define LCD_UKEY_LCD_BITS 1
|
||||
#define LCD_UKEY_SCREEN_WIDTH 2
|
||||
#define LCD_UKEY_SCREEN_HEIGHT 2
|
||||
/* timing (18Byte) */
|
||||
#define LCD_UKEY_H_ACTIVE 2
|
||||
#define LCD_UKEY_V_ACTIVE 2
|
||||
#define LCD_UKEY_H_PERIOD 2
|
||||
#define LCD_UKEY_V_PERIOD 2
|
||||
#define LCD_UKEY_HS_WIDTH 2
|
||||
#define LCD_UKEY_HS_BP 2
|
||||
#define LCD_UKEY_HS_POL 1
|
||||
#define LCD_UKEY_VS_WIDTH 2
|
||||
#define LCD_UKEY_VS_BP 2
|
||||
#define LCD_UKEY_VS_POL 1
|
||||
/* customer (31Byte) */
|
||||
#define LCD_UKEY_FR_ADJ_TYPE 1
|
||||
#define LCD_UKEY_SS_LEVEL 1
|
||||
#define LCD_UKEY_CLK_AUTO_GEN 1
|
||||
#define LCD_UKEY_PCLK 4
|
||||
#define LCD_UKEY_H_PERIOD_MIN 2
|
||||
#define LCD_UKEY_H_PERIOD_MAX 2
|
||||
#define LCD_UKEY_V_PERIOD_MIN 2
|
||||
#define LCD_UKEY_V_PERIOD_MAX 2
|
||||
#define LCD_UKEY_PCLK_MIN 4
|
||||
#define LCD_UKEY_PCLK_MAX 4
|
||||
#define LCD_UKEY_CUST_VAL_8 4
|
||||
#define LCD_UKEY_CUST_VAL_9 4
|
||||
/* interface (20Byte) */
|
||||
#define LCD_UKEY_IF_ATTR_0 2
|
||||
#define LCD_UKEY_IF_ATTR_1 2
|
||||
#define LCD_UKEY_IF_ATTR_2 2
|
||||
#define LCD_UKEY_IF_ATTR_3 2
|
||||
#define LCD_UKEY_IF_ATTR_4 2
|
||||
#define LCD_UKEY_IF_ATTR_5 2
|
||||
#define LCD_UKEY_IF_ATTR_6 2
|
||||
#define LCD_UKEY_IF_ATTR_7 2
|
||||
#define LCD_UKEY_IF_ATTR_8 2
|
||||
#define LCD_UKEY_IF_ATTR_9 2
|
||||
/* power (5Byte * n) */
|
||||
#define LCD_UKEY_PWR_TYPE 1
|
||||
#define LCD_UKEY_PWR_INDEX 1
|
||||
#define LCD_UKEY_PWR_VAL 1
|
||||
#define LCD_UKEY_PWR_DELAY 2
|
||||
|
||||
/* lcd extern */
|
||||
#define LCD_UKEY_LCD_EXT_SIZE 550
|
||||
|
||||
/* header (10Byte) */
|
||||
/* LCD_UKEY_HEAD_SIZE */
|
||||
/* basic (33Byte) */
|
||||
#define LCD_UKEY_EXT_NAME 30
|
||||
#define LCD_UKEY_EXT_INDEX 1
|
||||
#define LCD_UKEY_EXT_TYPE 1
|
||||
#define LCD_UKEY_EXT_STATUS 1
|
||||
/* type (10Byte) */
|
||||
#define LCD_UKEY_EXT_TYPE_VAL_0 1
|
||||
#define LCD_UKEY_EXT_TYPE_VAL_1 1
|
||||
#define LCD_UKEY_EXT_TYPE_VAL_2 1
|
||||
#define LCD_UKEY_EXT_TYPE_VAL_3 1
|
||||
#define LCD_UKEY_EXT_TYPE_VAL_4 1
|
||||
#define LCD_UKEY_EXT_TYPE_VAL_5 1
|
||||
#define LCD_UKEY_EXT_TYPE_VAL_6 1
|
||||
#define LCD_UKEY_EXT_TYPE_VAL_7 1
|
||||
#define LCD_UKEY_EXT_TYPE_VAL_8 1
|
||||
#define LCD_UKEY_EXT_TYPE_VAL_9 1
|
||||
/* init (cmd_size) */
|
||||
#define LCD_UKEY_EXT_INIT_TYPE 1
|
||||
/*#define LCD_UKEY_EXT_INIT_VAL 1 //not defined */
|
||||
#define LCD_UKEY_EXT_INIT_DELAY 1
|
||||
|
||||
/* backlight */
|
||||
#define LCD_UKEY_BL_SIZE 92
|
||||
|
||||
/* header (10Byte) */
|
||||
/* LCD_UKEY_HEAD_SIZE */
|
||||
/* basic (30Byte) */
|
||||
#define LCD_UKEY_BL_NAME 30
|
||||
/* level (12Byte) */
|
||||
#define LCD_UKEY_BL_LEVEL_UBOOT 2
|
||||
#define LCD_UKEY_BL_LEVEL_KERNEL 2
|
||||
#define LCD_UKEY_BL_LEVEL_MAX 2
|
||||
#define LCD_UKEY_BL_LEVEL_MIN 2
|
||||
#define LCD_UKEY_BL_LEVEL_MID 2
|
||||
#define LCD_UKEY_BL_LEVEL_MID_MAP 2
|
||||
/* method (8Byte) */
|
||||
#define LCD_UKEY_BL_METHOD 1
|
||||
#define LCD_UKEY_BL_EN_GPIO 1
|
||||
#define LCD_UKEY_BL_EN_GPIO_ON 1
|
||||
#define LCD_UKEY_BL_EN_GPIO_OFF 1
|
||||
#define LCD_UKEY_BL_ON_DELAY 2
|
||||
#define LCD_UKEY_BL_OFF_DELAY 2
|
||||
/* pwm (32Byte) */
|
||||
#define LCD_UKEY_BL_PWM_ON_DELAY 2
|
||||
#define LCD_UKEY_BL_PWM_OFF_DELAY 2
|
||||
#define LCD_UKEY_BL_PWM_METHOD 1
|
||||
#define LCD_UKEY_BL_PWM_PORT 1
|
||||
#define LCD_UKEY_BL_PWM_FREQ 4
|
||||
#define LCD_UKEY_BL_PWM_DUTY_MAX 1
|
||||
#define LCD_UKEY_BL_PWM_DUTY_MIN 1
|
||||
#define LCD_UKEY_BL_PWM_GPIO 1
|
||||
#define LCD_UKEY_BL_PWM_GPIO_OFF 1
|
||||
#define LCD_UKEY_BL_PWM2_METHOD 1
|
||||
#define LCD_UKEY_BL_PWM2_PORT 1
|
||||
#define LCD_UKEY_BL_PWM2_FREQ 4
|
||||
#define LCD_UKEY_BL_PWM2_DUTY_MAX 1
|
||||
#define LCD_UKEY_BL_PWM2_DUTY_MIN 1
|
||||
#define LCD_UKEY_BL_PWM2_GPIO 1
|
||||
#define LCD_UKEY_BL_PWM2_GPIO_OFF 1
|
||||
#define LCD_UKEY_BL_PWM_LEVEL_MAX 2
|
||||
#define LCD_UKEY_BL_PWM_LEVEL_MIN 2
|
||||
#define LCD_UKEY_BL_PWM2_LEVEL_MAX 2
|
||||
#define LCD_UKEY_BL_PWM2_LEVEL_MIN 2
|
||||
|
||||
|
||||
/* API */
|
||||
extern int lcd_unifykey_len_check(int key_len, int len);
|
||||
extern int lcd_unifykey_check(char *key_name);
|
||||
extern int lcd_unifykey_header_check(unsigned char *buf,
|
||||
struct aml_lcd_unifykey_header_s *header);
|
||||
extern int lcd_unifykey_get(char *key_name,
|
||||
unsigned char *buf, int *len);
|
||||
extern void lcd_unifykey_print(void);
|
||||
|
||||
#endif
|
||||
403
include/linux/amlogic/media/vout/lcd/lcd_vout.h
Normal file
403
include/linux/amlogic/media/vout/lcd/lcd_vout.h
Normal file
@@ -0,0 +1,403 @@
|
||||
/*
|
||||
* include/linux/amlogic/media/vout/lcd/lcd_vout.h
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _INC_LCD_VOUT_H
|
||||
#define _INC_LCD_VOUT_H
|
||||
#include <linux/types.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/amlogic/aml_gpio_consumer.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/amlogic/media/vout/vout_notify.h>
|
||||
|
||||
/* debug print define */
|
||||
/* #define LCD_DEBUG_INFO */
|
||||
extern unsigned char lcd_debug_print_flag;
|
||||
#define LCDPR(fmt, args...) pr_info("lcd: "fmt"", ## args)
|
||||
#define LCDERR(fmt, args...) pr_err("lcd: error: "fmt"", ## args)
|
||||
|
||||
/* clk parameter bit define */
|
||||
/* pll_ctrl, div_ctrl, clk_ctrl */
|
||||
|
||||
/* ******** pll_ctrl ******** */
|
||||
#define PLL_CTRL_OD3 20 /* [21:20] */
|
||||
#define PLL_CTRL_OD2 18 /* [19:18] */
|
||||
#define PLL_CTRL_OD1 16 /* [17:16] */
|
||||
#define PLL_CTRL_N 9 /* [13:9] */
|
||||
#define PLL_CTRL_M 0 /* [8:0] */
|
||||
|
||||
/* ******** div_ctrl ******** */
|
||||
#define DIV_CTRL_EDP_DIV1 24 /* [26:24] */
|
||||
#define DIV_CTRL_EDP_DIV0 20 /* [23:20] */
|
||||
#define DIV_CTRL_DIV_POST 12 /* [14:12] */
|
||||
#define DIV_CTRL_DIV_PRE 8 /* [10:8] */
|
||||
#define DIV_CTRL_DIV_SEL 8 /* [15:8] */
|
||||
#define DIV_CTRL_XD 0 /* [7:0] */
|
||||
|
||||
/* ******** clk_ctrl ******** */
|
||||
#define CLK_CTRL_LEVEL 12 /* [14:12] */
|
||||
#define CLK_CTRL_FRAC 0 /* [11:0] */
|
||||
|
||||
/* VENC to TCON sync delay */
|
||||
#define TTL_DELAY 13
|
||||
|
||||
/* ******** AXG ******** */
|
||||
/* bit[15:11] */
|
||||
#define BIT_PHY_LANE_AXG 11
|
||||
#define PHY_LANE_WIDTH_AXG 5
|
||||
|
||||
/* MIPI-DSI */
|
||||
#define DSI_LANE_0 (1 << 4)
|
||||
#define DSI_LANE_1 (1 << 3)
|
||||
#define DSI_LANE_CLK (1 << 2)
|
||||
#define DSI_LANE_2 (1 << 1)
|
||||
#define DSI_LANE_3 (1 << 0)
|
||||
#define DSI_LANE_COUNT_1 (DSI_LANE_CLK | DSI_LANE_0)
|
||||
#define DSI_LANE_COUNT_2 (DSI_LANE_CLK | DSI_LANE_0 | DSI_LANE_1)
|
||||
#define DSI_LANE_COUNT_3 (DSI_LANE_CLK | DSI_LANE_0 |\
|
||||
DSI_LANE_1 | DSI_LANE_2)
|
||||
#define DSI_LANE_COUNT_4 (DSI_LANE_CLK | DSI_LANE_0 |\
|
||||
DSI_LANE_1 | DSI_LANE_2 | DSI_LANE_3)
|
||||
|
||||
|
||||
/* global control define */
|
||||
enum lcd_mode_e {
|
||||
LCD_MODE_TV = 0,
|
||||
LCD_MODE_TABLET,
|
||||
LCD_MODE_MAX,
|
||||
};
|
||||
|
||||
|
||||
enum lcd_chip_e {
|
||||
LCD_CHIP_GXTVBB = 0,
|
||||
LCD_CHIP_GXL, /* 1 */
|
||||
LCD_CHIP_GXM, /* 2 */
|
||||
LCD_CHIP_TXL, /* 3 */
|
||||
LCD_CHIP_TXLX, /* 4 */
|
||||
LCD_CHIP_AXG, /* 5 */
|
||||
LCD_CHIP_MAX,
|
||||
};
|
||||
|
||||
|
||||
enum lcd_type_e {
|
||||
LCD_TTL = 0,
|
||||
LCD_LVDS,
|
||||
LCD_VBYONE,
|
||||
LCD_MIPI,
|
||||
LCD_TYPE_MAX,
|
||||
};
|
||||
|
||||
#define MOD_LEN_MAX 30
|
||||
struct lcd_basic_s {
|
||||
char model_name[MOD_LEN_MAX];
|
||||
enum lcd_type_e lcd_type;
|
||||
unsigned short lcd_bits;
|
||||
|
||||
unsigned short h_active; /* Horizontal display area */
|
||||
unsigned short v_active; /* Vertical display area */
|
||||
unsigned short h_period; /* Horizontal total period time */
|
||||
unsigned short v_period; /* Vertical total period time */
|
||||
unsigned short h_period_min;
|
||||
unsigned short h_period_max;
|
||||
unsigned short v_period_min;
|
||||
unsigned short v_period_max;
|
||||
unsigned int lcd_clk_min;
|
||||
unsigned int lcd_clk_max;
|
||||
|
||||
unsigned int screen_width; /* screen physical width(unit: mm) */
|
||||
unsigned int screen_height; /* screen physical height(unit: mm) */
|
||||
};
|
||||
|
||||
#define LCD_CLK_FRAC_UPDATE (1 << 0)
|
||||
#define LCD_CLK_PLL_CHANGE (1 << 1)
|
||||
struct lcd_timing_s {
|
||||
unsigned char clk_auto; /* clk parameters auto generation */
|
||||
unsigned int lcd_clk; /* pixel clock(unit: Hz) */
|
||||
unsigned int lcd_clk_dft; /* internal used */
|
||||
unsigned int h_period_dft; /* internal used */
|
||||
unsigned int v_period_dft; /* internal used */
|
||||
unsigned char clk_change; /* internal used */
|
||||
unsigned int pll_ctrl; /* pll settings */
|
||||
unsigned int div_ctrl; /* divider settings */
|
||||
unsigned int clk_ctrl; /* clock settings */
|
||||
|
||||
unsigned char fr_adjust_type; /* 0=clock, 1=htotal, 2=vtotal */
|
||||
unsigned char ss_level;
|
||||
|
||||
unsigned int sync_duration_num;
|
||||
unsigned int sync_duration_den;
|
||||
|
||||
unsigned short video_on_pixel;
|
||||
unsigned short video_on_line;
|
||||
|
||||
unsigned short hsync_width;
|
||||
unsigned short hsync_bp;
|
||||
unsigned short hsync_pol;
|
||||
unsigned short vsync_width;
|
||||
unsigned short vsync_bp;
|
||||
unsigned short vsync_pol;
|
||||
/* unsigned int vsync_h_phase; // [31]sign, [15:0]value */
|
||||
unsigned int h_offset;
|
||||
unsigned int v_offset;
|
||||
|
||||
unsigned short de_hs_addr;
|
||||
unsigned short de_he_addr;
|
||||
unsigned short de_vs_addr;
|
||||
unsigned short de_ve_addr;
|
||||
|
||||
unsigned short hs_hs_addr;
|
||||
unsigned short hs_he_addr;
|
||||
unsigned short hs_vs_addr;
|
||||
unsigned short hs_ve_addr;
|
||||
|
||||
unsigned short vs_hs_addr;
|
||||
unsigned short vs_he_addr;
|
||||
unsigned short vs_vs_addr;
|
||||
unsigned short vs_ve_addr;
|
||||
};
|
||||
|
||||
/* HDR info define */
|
||||
struct lcd_hdr_info_s {
|
||||
unsigned int hdr_support;
|
||||
unsigned int features;
|
||||
unsigned int primaries_r_x;
|
||||
unsigned int primaries_r_y;
|
||||
unsigned int primaries_g_x;
|
||||
unsigned int primaries_g_y;
|
||||
unsigned int primaries_b_x;
|
||||
unsigned int primaries_b_y;
|
||||
unsigned int white_point_x;
|
||||
unsigned int white_point_y;
|
||||
unsigned int luma_max;
|
||||
unsigned int luma_min;
|
||||
unsigned int luma_avg;
|
||||
};
|
||||
|
||||
struct ttl_config_s {
|
||||
unsigned int clk_pol;
|
||||
unsigned int sync_valid; /* [1]DE, [0]hvsync */
|
||||
unsigned int swap_ctrl; /* [1]rb swap, [0]bit swap */
|
||||
};
|
||||
|
||||
#define LVDS_PHY_VSWING_DFT 3
|
||||
#define LVDS_PHY_PREEM_DFT 0
|
||||
#define LVDS_PHY_CLK_VSWING_DFT 0
|
||||
#define LVDS_PHY_CLK_PREEM_DFT 0
|
||||
struct lvds_config_s {
|
||||
unsigned int lvds_vswing;
|
||||
unsigned int lvds_repack;
|
||||
unsigned int dual_port;
|
||||
unsigned int pn_swap;
|
||||
unsigned int port_swap;
|
||||
unsigned int lane_reverse;
|
||||
unsigned int port_sel;
|
||||
unsigned int phy_vswing;
|
||||
unsigned int phy_preem;
|
||||
unsigned int phy_clk_vswing;
|
||||
unsigned int phy_clk_preem;
|
||||
};
|
||||
|
||||
#define VX1_PHY_VSWING_DFT 3
|
||||
#define VX1_PHY_PREEM_DFT 0
|
||||
struct vbyone_config_s {
|
||||
unsigned int lane_count;
|
||||
unsigned int region_num;
|
||||
unsigned int byte_mode;
|
||||
unsigned int color_fmt;
|
||||
unsigned int phy_div;
|
||||
unsigned int bit_rate;
|
||||
unsigned int phy_vswing; /*[4]:ext_pullup, [3:0]vswing*/
|
||||
unsigned int phy_preem;
|
||||
unsigned int intr_en;
|
||||
unsigned int vsync_intr_en;
|
||||
};
|
||||
|
||||
/* mipi-dsi config */
|
||||
/* Operation mode parameters */
|
||||
#define OPERATION_VIDEO_MODE 0
|
||||
#define OPERATION_COMMAND_MODE 1
|
||||
|
||||
#define SYNC_PULSE 0x0
|
||||
#define SYNC_EVENT 0x1
|
||||
#define BURST_MODE 0x2
|
||||
|
||||
/* command config */
|
||||
#define DSI_CMD_INDEX 1 /* byte[1] */
|
||||
|
||||
#define DSI_INIT_ON_MAX 100
|
||||
#define DSI_INIT_OFF_MAX 30
|
||||
|
||||
struct dsi_config_s {
|
||||
unsigned char lane_num;
|
||||
unsigned int bit_rate_max; /* MHz */
|
||||
unsigned int bit_rate_min; /* MHz*/
|
||||
unsigned int bit_rate; /* Hz */
|
||||
unsigned int factor_numerator;
|
||||
unsigned int factor_denominator; /* 100 */
|
||||
unsigned char operation_mode_init; /* 0=video mode, 1=command mode */
|
||||
unsigned char operation_mode_display; /* 0=video mode, 1=command mode */
|
||||
unsigned char video_mode_type; /* 0=sync_pulse, 1=sync_event, 2=burst */
|
||||
unsigned char clk_lp_continuous; /* 0=stop, 1=continue */
|
||||
unsigned char phy_stop_wait; /* 0=auto, 1=standard, 2=slow */
|
||||
|
||||
unsigned int venc_data_width;
|
||||
unsigned int dpi_data_format;
|
||||
unsigned int venc_fmt;
|
||||
|
||||
unsigned char *dsi_init_on;
|
||||
unsigned char *dsi_init_off;
|
||||
unsigned char extern_init;
|
||||
};
|
||||
|
||||
struct lcd_control_config_s {
|
||||
struct ttl_config_s *ttl_config;
|
||||
struct lvds_config_s *lvds_config;
|
||||
struct vbyone_config_s *vbyone_config;
|
||||
struct dsi_config_s *mipi_config;
|
||||
};
|
||||
|
||||
/* power control define */
|
||||
enum lcd_power_type_e {
|
||||
LCD_POWER_TYPE_CPU = 0,
|
||||
LCD_POWER_TYPE_PMU,
|
||||
LCD_POWER_TYPE_SIGNAL,
|
||||
LCD_POWER_TYPE_EXTERN,
|
||||
LCD_POWER_TYPE_MAX,
|
||||
};
|
||||
|
||||
enum lcd_pmu_gpio_e {
|
||||
LCD_PMU_GPIO0 = 0,
|
||||
LCD_PMU_GPIO1,
|
||||
LCD_PMU_GPIO2,
|
||||
LCD_PMU_GPIO3,
|
||||
LCD_PMU_GPIO4,
|
||||
LCD_PMU_GPIO_MAX,
|
||||
};
|
||||
|
||||
#define LCD_GPIO_MAX 0xff
|
||||
#define LCD_GPIO_OUTPUT_LOW 0
|
||||
#define LCD_GPIO_OUTPUT_HIGH 1
|
||||
#define LCD_GPIO_INPUT 2
|
||||
|
||||
/* Power Control */
|
||||
#define LCD_CPU_GPIO_NUM_MAX 10
|
||||
struct lcd_cpu_gpio_s {
|
||||
char name[15];
|
||||
struct gpio_desc *gpio;
|
||||
int flag;
|
||||
};
|
||||
|
||||
#define LCD_PMU_GPIO_NUM_MAX 3
|
||||
struct lcd_pmu_gpio_s {
|
||||
char name[15];
|
||||
int gpio;
|
||||
};
|
||||
|
||||
#define LCD_PWR_STEP_MAX 15
|
||||
struct lcd_power_step_s {
|
||||
unsigned char type;
|
||||
unsigned int index; /* point to lcd_cpu/pmu_gpio_s or lcd_extern */
|
||||
unsigned int value;
|
||||
unsigned int delay;
|
||||
};
|
||||
|
||||
struct lcd_power_ctrl_s {
|
||||
struct lcd_cpu_gpio_s cpu_gpio[LCD_CPU_GPIO_NUM_MAX];
|
||||
struct lcd_pmu_gpio_s pmu_gpio[LCD_PMU_GPIO_NUM_MAX];
|
||||
struct lcd_power_step_s power_on_step[LCD_PWR_STEP_MAX];
|
||||
struct lcd_power_step_s power_off_step[LCD_PWR_STEP_MAX];
|
||||
int power_on_step_max; /* internal use for debug */
|
||||
int power_off_step_max; /* internal use for debug */
|
||||
};
|
||||
|
||||
struct lcd_clk_gate_ctrl_s {
|
||||
struct reset_control *encl;
|
||||
struct reset_control *vencl;
|
||||
};
|
||||
|
||||
struct lcd_config_s {
|
||||
char *lcd_propname;
|
||||
unsigned int backlight_index;
|
||||
struct lcd_basic_s lcd_basic;
|
||||
struct lcd_timing_s lcd_timing;
|
||||
struct lcd_hdr_info_s hdr_info;
|
||||
struct lcd_control_config_s lcd_control;
|
||||
struct lcd_power_ctrl_s *lcd_power;
|
||||
struct pinctrl *pin;
|
||||
unsigned char pinmux_flag;
|
||||
struct lcd_clk_gate_ctrl_s rstc;
|
||||
};
|
||||
|
||||
struct lcd_duration_s {
|
||||
unsigned int duration_num;
|
||||
unsigned int duration_den;
|
||||
};
|
||||
|
||||
struct aml_lcd_drv_s {
|
||||
char *version;
|
||||
enum lcd_chip_e chip_type;
|
||||
unsigned char lcd_mode;
|
||||
unsigned char lcd_status;
|
||||
unsigned char lcd_key_valid;
|
||||
unsigned char lcd_config_load;
|
||||
unsigned char lcd_test_flag;
|
||||
unsigned char lcd_mute;
|
||||
|
||||
struct clk *vencl_top;
|
||||
struct clk *vencl_int;
|
||||
struct clk *dsi_host;
|
||||
struct clk *dsi_phy;
|
||||
struct clk *dsi_meas;
|
||||
|
||||
struct device *dev;
|
||||
struct lcd_config_s *lcd_config;
|
||||
struct vinfo_s *lcd_info;
|
||||
struct class *lcd_debug_class;
|
||||
int fr_auto_policy;
|
||||
struct lcd_duration_s std_duration;
|
||||
|
||||
void (*vout_server_init)(void);
|
||||
void (*driver_init_pre)(void);
|
||||
int (*driver_init)(void);
|
||||
void (*driver_disable)(void);
|
||||
int (*driver_change)(void);
|
||||
void (*module_reset)(void);
|
||||
void (*power_tiny_ctrl)(int status);
|
||||
void (*driver_tiny_enable)(void);
|
||||
void (*driver_tiny_disable)(void);
|
||||
void (*module_tiny_reset)(void);
|
||||
void (*lcd_test_pattern_restore)(void);
|
||||
void (*power_ctrl)(int status);
|
||||
|
||||
struct workqueue_struct *workqueue;
|
||||
struct delayed_work lcd_probe_delayed_work;
|
||||
struct delayed_work lcd_vx1_delayed_work;
|
||||
struct work_struct lcd_resume_work;
|
||||
};
|
||||
|
||||
extern struct aml_lcd_drv_s *aml_lcd_get_driver(void);
|
||||
|
||||
/* IOCTL define */
|
||||
#define LCD_IOC_TYPE 'C'
|
||||
#define LCD_IOC_NR_GET_HDR_INFO 0x0
|
||||
#define LCD_IOC_NR_SET_HDR_INFO 0x1
|
||||
|
||||
#define LCD_IOC_CMD_GET_HDR_INFO \
|
||||
_IOR(LCD_IOC_TYPE, LCD_IOC_NR_GET_HDR_INFO, struct lcd_hdr_info_s)
|
||||
#define LCD_IOC_CMD_SET_HDR_INFO \
|
||||
_IOW(LCD_IOC_TYPE, LCD_IOC_NR_SET_HDR_INFO, struct lcd_hdr_info_s)
|
||||
|
||||
#endif
|
||||
@@ -19,6 +19,7 @@
|
||||
#define _VINFO_H_
|
||||
#include <linux/amlogic/media/vfm/video_common.h>
|
||||
|
||||
|
||||
/* the MSB is represent vmode set by vmode_init */
|
||||
#define VMODE_INIT_BIT_MASK 0x8000
|
||||
#define VMODE_MODE_BIT_MASK 0xff
|
||||
@@ -57,6 +58,7 @@ struct hdr_info {
|
||||
u32 lumi_max; /* RX EDID Lumi Max value */
|
||||
u32 lumi_avg; /* RX EDID Lumi Avg value */
|
||||
u32 lumi_min; /* RX EDID Lumi Min value */
|
||||
u8 sink_flag; /*0 = hdmi, 1 = panel*/
|
||||
};
|
||||
enum eotf_type {
|
||||
EOTF_T_NULL = 0,
|
||||
|
||||
Reference in New Issue
Block a user