From 2d3323c68c4bd357406372f4cccbbbaac21e66b7 Mon Sep 17 00:00:00 2001 From: Evoke Zhang Date: Thu, 3 Jan 2019 06:40:26 -0500 Subject: [PATCH] backlight: ldim: add analog pwm support [1/1] PD#SWPL-3702 Problem: local dimming need analog pwm function Solution: add analog pwm support Verify: x301 Change-Id: I502bb7505947c1f3670f44d0d307f9546f1d57fd Signed-off-by: Evoke Zhang --- arch/arm/boot/dts/amlogic/mesontl1_t309-panel.dtsi | 102 ++++- arch/arm/boot/dts/amlogic/mesontl1_x301-panel.dtsi | 101 +++- .../arm/boot/dts/amlogic/mesontxlx_r311-panel.dtsi | 57 ++- arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts | 2 + .../boot/dts/amlogic/mesontl1_t309-panel.dtsi | 102 ++++- .../boot/dts/amlogic/mesontl1_x301-panel.dtsi | 101 +++- .../boot/dts/amlogic/mesontxlx_r311-panel.dtsi | 58 ++- drivers/amlogic/media/vout/backlight/aml_bl.c | 19 +- .../media/vout/backlight/aml_ldim/global_bl.c | 28 +- .../media/vout/backlight/aml_ldim/iw7027_bl.c | 12 +- .../media/vout/backlight/aml_ldim/ldim_dev_drv.c | 507 ++++++++++++++++++--- .../media/vout/backlight/aml_ldim/ldim_drv.h | 3 +- .../media/vout/backlight/aml_ldim/ob3350_bl.c | 28 +- include/linux/amlogic/media/vout/lcd/aml_bl.h | 9 + include/linux/amlogic/media/vout/lcd/aml_ldim.h | 4 +- 15 files changed, 938 insertions(+), 195 deletions(-) diff --git a/arch/arm/boot/dts/amlogic/mesontl1_t309-panel.dtsi b/arch/arm/boot/dts/amlogic/mesontl1_t309-panel.dtsi index 79fa79d..7aa829b 100644 --- a/arch/arm/boot/dts/amlogic/mesontl1_t309-panel.dtsi +++ b/arch/arm/boot/dts/amlogic/mesontl1_t309-panel.dtsi @@ -909,7 +909,7 @@ bl_level_attr = <255 10 /*max, min*/ 128 128>; /*mid, mid_mapping*/ bl_ctrl_method = <3>; /*1=pwm,2=pwm_combo,3=ldim*/ - bl_power_attr = <0 /*en_gpio_index*/ + bl_power_attr = <0xff /*en_gpio_index*/ 1 0 /*on_value, off_value*/ 200 200>; /*on_delay(ms), off_delay(ms)*/ bl_ldim_region_row_col = <1 1>; @@ -919,6 +919,23 @@ */ ldim_dev_index = <1>; }; + backlight_5{ + index = <5>; + bl_name = "ldim_iw7027"; + bl_level_default_uboot_kernel = <100 100>; + bl_level_attr = <255 10 /*max, min*/ + 128 128>; /*mid, mid_mapping*/ + bl_ctrl_method = <3>; /*1=pwm,2=pwm_combo,3=ldim*/ + bl_power_attr = <0 /*en_gpio_index*/ + 1 0 /*on_value, off_value*/ + 200 200>; /*on_delay(ms), off_delay(ms)*/ + bl_ldim_region_row_col = <1 10>; + bl_ldim_mode = <1>; /*0=left/right side + *1=top/bottom side + *2=direct + */ + ldim_dev_index = <2>; + }; }; bl_pwm_conf:bl_pwm_conf{ @@ -937,10 +954,16 @@ status = "okay"; pinctrl-names = "ldim_pwm", "ldim_pwm_vs", - "ldim_pwm_off"; + "ldim_pwm_combo", + "ldim_pwm_vs_combo", + "ldim_pwm_off", + "ldim_pwm_combo_off"; pinctrl-0 = <&pwm_c_pins3>; pinctrl-1 = <&bl_pwm_vs_on_pins>; - pinctrl-2 = <&bl_pwm_off_pins>; + pinctrl-2 = <&pwm_c_pins3 &pwm_d_pins2>; + pinctrl-3 = <&bl_pwm_vs_on_pins &pwm_d_pins2>; + pinctrl-4 = <&bl_pwm_off_pins>; + pinctrl-5 = <&bl_pwm_combo_off_pins>; pinctrl_version = <1>; /* for uboot */ ldim_pwm_config = <&bl_pwm_conf>; @@ -954,28 +977,83 @@ index = <0>; type = <0>; /*0=normal, 1=spi, 2=i2c*/ ldim_dev_name = "ob3350"; - ldim_pwm_pinmux_sel = "ldim_pwm"; - ldim_pwm_port = "PWM_B"; + ldim_pwm_port = "PWM_C"; ldim_pwm_attr = <0 /* pol */ 200 /*freq(pwm:Hz, pwm_vs:multiple of vs)*/ - 50>;/*duty(%)*/ - dim_max_min = <100 20>; /*dim_max, dim_min*/ + 50>;/*default duty(%)*/ en_gpio_on_off = <0 /*ldim_dev-gpios index*/ 1 0>; /*on_level, off_level*/ + dim_max_min = <100 20>; /*dim_max, dim_min*/ }; ldim_dev_1 { index = <1>; type = <0>; /*0=normal, 1=spi, 2=i2c*/ ldim_dev_name = "global"; - ldim_pwm_pinmux_sel = "ldim_pwm"; ldim_pwm_port = "PWM_C"; ldim_pwm_attr = <1 /* pol */ 180 /*freq(pwm:Hz, pwm_vs:multiple of vs)*/ - 50>;/*duty(%)*/ - dim_max_min = <100 20>; /*dim_max, dim_min*/ - en_gpio_on_off = <2 /*ldim_dev-gpios index*/ + 50>;/*default duty(%)*/ + analog_pwm_port = "PWM_D"; + analog_pwm_attr = <1 /*pol(0=negative, 1=positvie)*/ + 18000 /*freq(pwm:Hz)*/ + 100 25 /*duty_max(%), duty_min(%)*/ + 80>; /*default duty(%)*/ + en_gpio_on_off = <0 /*ldim_dev-gpios index*/ 1 0>; /*on_level, off_level*/ + dim_max_min = <100 20>; /*dim_max, dim_min*/ }; - }; + ldim_dev_2 { + index = <2>; + type = <1>; /* 0=normal,1=spi,2=i2c */ + ldim_dev_name = "iw7027"; + ldim_pwm_port = "PWM_VS"; + ldim_pwm_attr = <1 /* pol */ + 2 /*freq(pwm:Hz, pwm_vs:multiple of vs)*/ + 50>;/*default duty(%)*/ + spi_bus_num = <0>; + spi_chip_select = <0>; + spi_max_frequency = <1000000>; /* unit: hz */ + spi_mode = <0>; /* mode: 0, 1, 2, 3 */ + spi_cs_delay = <10 /* hold_high_delay */ + 100>; /* clk_cs_delay (unit: us) */ + en_gpio_on_off = <0 /* ldim_dev-gpios index */ + 1 /* on_level */ + 0>; /* off_level */ + lamp_err_gpio = <0xff>; + /* ldim_dev-gpios index, 0xff=invalid */ + spi_write_check = <0>; /* 0=disable, 1=enable */ + + dim_max_min = <0xfff 0x7f>; /* dim_max, dim_min */ + ldim_region_mapping = <0 1 2 3 4 5 6 7 8 9>; + + cmd_size = <0xff>; + /* init: (type, data...) */ + /* type: 0x00=cmd with delay, + * 0xc0=cmd, + * 0xfd=delay, + * 0xff=ending + */ + /* data: spi data, fill 0x0 for no use */ + /* delay: unit ms */ + init_on = < + 0xc0 2 0x23 0x03 + 0xc0 2 0x24 0xff + 0xc0 2 0x25 0x00 + 0xc0 2 0x26 0x00 + 0xc0 2 0x27 0x60 + 0xc0 2 0x29 0x00 + 0xc0 2 0x2a 0x00 + 0xc0 2 0x2b 0x00 + 0xc0 2 0x2c 0x73 + 0xc0 2 0x2d 0x37 + 0xc0 2 0x31 0x93 + 0xc0 2 0x32 0x0f + 0xc0 2 0x33 0xff + 0xc0 2 0x34 0xc8 + 0xc0 2 0x35 0xbf + 0xff 0>; + init_off = <0xff 0>; + }; + }; }; /* end of / */ diff --git a/arch/arm/boot/dts/amlogic/mesontl1_x301-panel.dtsi b/arch/arm/boot/dts/amlogic/mesontl1_x301-panel.dtsi index 15c01c2..80d78cc 100644 --- a/arch/arm/boot/dts/amlogic/mesontl1_x301-panel.dtsi +++ b/arch/arm/boot/dts/amlogic/mesontl1_x301-panel.dtsi @@ -912,7 +912,7 @@ bl_level_attr = <255 10 /*max, min*/ 128 128>; /*mid, mid_mapping*/ bl_ctrl_method = <3>; /*1=pwm,2=pwm_combo,3=ldim*/ - bl_power_attr = <0 /*en_gpio_index*/ + bl_power_attr = <0xff /*en_gpio_index*/ 1 0 /*on_value, off_value*/ 200 200>; /*on_delay(ms), off_delay(ms)*/ bl_ldim_region_row_col = <1 1>; @@ -922,6 +922,23 @@ */ ldim_dev_index = <1>; }; + backlight_5{ + index = <5>; + bl_name = "ldim_iw7027"; + bl_level_default_uboot_kernel = <100 100>; + bl_level_attr = <255 10 /*max, min*/ + 128 128>; /*mid, mid_mapping*/ + bl_ctrl_method = <3>; /*1=pwm,2=pwm_combo,3=ldim*/ + bl_power_attr = <0 /*en_gpio_index*/ + 1 0 /*on_value, off_value*/ + 200 200>; /*on_delay(ms), off_delay(ms)*/ + bl_ldim_region_row_col = <1 10>; + bl_ldim_mode = <1>; /*0=left/right side + *1=top/bottom side + *2=direct + */ + ldim_dev_index = <2>; + }; }; bl_pwm_conf:bl_pwm_conf{ @@ -940,10 +957,16 @@ status = "okay"; pinctrl-names = "ldim_pwm", "ldim_pwm_vs", - "ldim_pwm_off"; + "ldim_pwm_combo", + "ldim_pwm_vs_combo", + "ldim_pwm_off", + "ldim_pwm_combo_off"; pinctrl-0 = <&pwm_c_pins3>; pinctrl-1 = <&bl_pwm_vs_on_pins>; - pinctrl-2 = <&bl_pwm_off_pins>; + pinctrl-2 = <&pwm_c_pins3 &pwm_d_pins2>; + pinctrl-3 = <&bl_pwm_vs_on_pins &pwm_d_pins2>; + pinctrl-4 = <&bl_pwm_off_pins>; + pinctrl-5 = <&bl_pwm_combo_off_pins>; pinctrl_version = <1>; /* for uboot */ ldim_pwm_config = <&bl_pwm_conf>; @@ -957,27 +980,83 @@ index = <0>; type = <0>; /*0=normal, 1=spi, 2=i2c*/ ldim_dev_name = "ob3350"; - ldim_pwm_pinmux_sel = "ldim_pwm"; - ldim_pwm_port = "PWM_B"; + ldim_pwm_port = "PWM_C"; ldim_pwm_attr = <0 /* pol */ 200 /*freq(pwm:Hz, pwm_vs:multiple of vs)*/ - 50>;/*duty(%)*/ - dim_max_min = <100 20>; /*dim_max, dim_min*/ + 50>;/*default duty(%)*/ en_gpio_on_off = <0 /*ldim_dev-gpios index*/ 1 0>; /*on_level, off_level*/ + dim_max_min = <100 20>; /*dim_max, dim_min*/ }; ldim_dev_1 { index = <1>; type = <0>; /*0=normal, 1=spi, 2=i2c*/ ldim_dev_name = "global"; - ldim_pwm_pinmux_sel = "ldim_pwm"; ldim_pwm_port = "PWM_C"; ldim_pwm_attr = <1 /* pol */ 180 /*freq(pwm:Hz, pwm_vs:multiple of vs)*/ - 50>;/*duty(%)*/ - dim_max_min = <100 20>; /*dim_max, dim_min*/ - en_gpio_on_off = <2 /*ldim_dev-gpios index*/ + 50>;/*default duty(%)*/ + analog_pwm_port = "PWM_D"; + analog_pwm_attr = <1 /*pol(0=negative, 1=positvie)*/ + 18000 /*freq(pwm:Hz)*/ + 100 25 /*duty_max(%), duty_min(%)*/ + 80>; /*default duty(%)*/ + en_gpio_on_off = <0 /*ldim_dev-gpios index*/ 1 0>; /*on_level, off_level*/ + dim_max_min = <100 20>; /*dim_max, dim_min*/ + }; + + ldim_dev_2 { + index = <2>; + type = <1>; /* 0=normal,1=spi,2=i2c */ + ldim_dev_name = "iw7027"; + ldim_pwm_port = "PWM_VS"; + ldim_pwm_attr = <1 /* pol */ + 2 /*freq(pwm:Hz, pwm_vs:multiple of vs)*/ + 50>;/*default duty(%)*/ + spi_bus_num = <0>; + spi_chip_select = <0>; + spi_max_frequency = <1000000>; /* unit: hz */ + spi_mode = <0>; /* mode: 0, 1, 2, 3 */ + spi_cs_delay = <10 /* hold_high_delay */ + 100>; /* clk_cs_delay (unit: us) */ + en_gpio_on_off = <0 /* ldim_dev-gpios index */ + 1 /* on_level */ + 0>; /* off_level */ + lamp_err_gpio = <0xff>; + /* ldim_dev-gpios index, 0xff=invalid */ + spi_write_check = <0>; /* 0=disable, 1=enable */ + + dim_max_min = <0xfff 0x7f>; /* dim_max, dim_min */ + ldim_region_mapping = <0 1 2 3 4 5 6 7 8 9>; + + cmd_size = <0xff>; + /* init: (type, data...) */ + /* type: 0x00=cmd with delay, + * 0xc0=cmd, + * 0xfd=delay, + * 0xff=ending + */ + /* data: spi data, fill 0x0 for no use */ + /* delay: unit ms */ + init_on = < + 0xc0 2 0x23 0x03 + 0xc0 2 0x24 0xff + 0xc0 2 0x25 0x00 + 0xc0 2 0x26 0x00 + 0xc0 2 0x27 0x60 + 0xc0 2 0x29 0x00 + 0xc0 2 0x2a 0x00 + 0xc0 2 0x2b 0x00 + 0xc0 2 0x2c 0x73 + 0xc0 2 0x2d 0x37 + 0xc0 2 0x31 0x93 + 0xc0 2 0x32 0x0f + 0xc0 2 0x33 0xff + 0xc0 2 0x34 0xc8 + 0xc0 2 0x35 0xbf + 0xff 0>; + init_off = <0xff 0>; }; }; }; /* end of / */ diff --git a/arch/arm/boot/dts/amlogic/mesontxlx_r311-panel.dtsi b/arch/arm/boot/dts/amlogic/mesontxlx_r311-panel.dtsi index 73ed979..3e9c828 100644 --- a/arch/arm/boot/dts/amlogic/mesontxlx_r311-panel.dtsi +++ b/arch/arm/boot/dts/amlogic/mesontxlx_r311-panel.dtsi @@ -678,37 +678,37 @@ }; backlight_4{ index = <4>; - bl_name = "ldim_iw7027"; + bl_name = "ldim_global"; bl_level_default_uboot_kernel = <100 100>; bl_level_attr = <255 10 /*max, min*/ 128 128>; /*mid, mid_mapping*/ bl_ctrl_method = <3>; /*1=pwm,2=pwm_combo,3=ldim*/ - bl_power_attr = <0 /*en_gpio_index*/ - 1 0 /*on_value, off_value*/ - 200 200>; /*on_delay(ms), off_delay(ms)*/ - bl_ldim_region_row_col = <1 10>; + bl_power_attr = <0xff /*en_gpio_index*/ + 1 0 /*on_value, off_value*/ + 200 200>; /* on_delay(ms), off_delay(ms)*/ + bl_ldim_region_row_col = <1 1>; bl_ldim_mode = <1>; /*0=left/right side *1=top/bottom side *2=direct */ - ldim_dev_index = <2>; + ldim_dev_index = <1>; }; backlight_5{ index = <5>; - bl_name = "ldim_global"; + bl_name = "ldim_iw7027"; bl_level_default_uboot_kernel = <100 100>; bl_level_attr = <255 10 /*max, min*/ 128 128>; /*mid, mid_mapping*/ bl_ctrl_method = <3>; /*1=pwm,2=pwm_combo,3=ldim*/ bl_power_attr = <0 /*en_gpio_index*/ - 1 0 /*on_value, off_value*/ - 200 200>; /* on_delay(ms), off_delay(ms)*/ - bl_ldim_region_row_col = <1 1>; + 1 0 /*on_value, off_value*/ + 200 200>; /*on_delay(ms), off_delay(ms)*/ + bl_ldim_region_row_col = <1 10>; bl_ldim_mode = <1>; /*0=left/right side *1=top/bottom side *2=direct */ - ldim_dev_index = <1>; + ldim_dev_index = <2>; }; }; @@ -728,54 +728,63 @@ status = "okay"; pinctrl-names = "ldim_pwm", "ldim_pwm_vs", - "ldim_pwm_off"; + "ldim_pwm_combo", + "ldim_pwm_vs_combo", + "ldim_pwm_off", + "ldim_pwm_combo_off"; pinctrl-0 = <&bl_pwm_on_pins>; pinctrl-1 = <&bl_pwm_vs_on_pins>; - pinctrl-2 = <&bl_pwm_off_pins>; + pinctrl-2 = <&bl_pwm_on_pins &bl_pwm_combo_1_on_pins>; + pinctrl-3 = <&bl_pwm_vs_on_pins &bl_pwm_combo_1_on_pins>; + pinctrl-4 = <&bl_pwm_off_pins>; + pinctrl-5 = <&bl_pwm_combo_off_pins>; pinctrl_version = <1>; /* for uboot */ ldim_pwm_config = <&bl_pwm_conf>; /* pwm port: PWM_A, PWM_B, PWM_C, PWM_D, PWM_E, PWM_F, PWM_VS*/ ldim_dev-gpios = <&gpio GPIOZ_12 GPIO_ACTIVE_HIGH &gpio GPIOZ_6 GPIO_ACTIVE_HIGH - &gpio GPIOZ_7 GPIO_ACTIVE_HIGH>; - ldim_dev_gpio_names = "GPIOZ_12","GPIOZ_6","GPIOZ_7"; + &gpio GPIOZ_7 GPIO_ACTIVE_HIGH + &gpio GPIOZ_4 GPIO_ACTIVE_HIGH>; + ldim_dev_gpio_names = "GPIOZ_12","GPIOZ_6","GPIOZ_7","GPIOZ_4"; ldim_dev_0 { index = <0>; type = <0>; /*0=normal, 1=spi, 2=i2c*/ ldim_dev_name = "ob3350"; - ldim_pwm_pinmux_sel = "ldim_pwm"; ldim_pwm_port = "PWM_B"; ldim_pwm_attr = <0 /* pol */ 200 /*freq(pwm:Hz, pwm_vs:multiple of vs)*/ - 50>;/*duty(%)*/ - dim_max_min = <100 20>; /*dim_max, dim_min*/ + 50>;/*default duty(%)*/ en_gpio_on_off = <0 /*ldim_dev-gpios index*/ 1 0>; /*on_level, off_level*/ + dim_max_min = <100 20>; /*dim_max, dim_min*/ }; ldim_dev_1 { index = <1>; type = <0>; /*0=normal, 1=spi, 2=i2c*/ ldim_dev_name = "global"; - ldim_pwm_pinmux_sel = "ldim_pwm"; ldim_pwm_port = "PWM_B"; ldim_pwm_attr = <1 /* pol */ 180 /*freq(pwm:Hz, pwm_vs:multiple of vs)*/ - 50>;/*duty(%)*/ - dim_max_min = <100 20>; /*dim_max, dim_min*/ - en_gpio_on_off = <2 /*ldim_dev-gpios index*/ + 50>;/*default duty(%)*/ + analog_pwm_port = "PWM_C"; + analog_pwm_attr = <1 /*pol(0=negative, 1=positvie)*/ + 18000 /*freq(pwm:Hz)*/ + 100 25 /*duty_max(%), duty_min(%)*/ + 80>; /*default duty(%)*/ + en_gpio_on_off = <3 /*ldim_dev-gpios index*/ 1 0>; /*on_level, off_level*/ + dim_max_min = <100 20>; /*dim_max, dim_min*/ }; ldim_dev_2 { index = <2>; type = <1>; /* 0=normal,1=spi,2=i2c */ ldim_dev_name = "iw7027"; - ldim_pwm_pinmux_sel = "ldim_pwm_vs"; ldim_pwm_port = "PWM_VS"; ldim_pwm_attr = <1 /* pol */ 2 /*freq(pwm:Hz, pwm_vs:multiple of vs)*/ - 50>;/*duty(%)*/ + 50>;/*default duty(%)*/ spi_bus_num = <0>; spi_chip_select = <0>; spi_max_frequency = <1000000>; /* unit: hz */ diff --git a/arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts b/arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts index 98853d8..ab777dc 100644 --- a/arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts +++ b/arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts @@ -40,6 +40,8 @@ i2c2 = &i2c2; i2c3 = &i2c3; i2c4 = &i2c_AO; + spi0 = &spicc0; + spi1 = &spicc1; }; memory@00000000 { diff --git a/arch/arm64/boot/dts/amlogic/mesontl1_t309-panel.dtsi b/arch/arm64/boot/dts/amlogic/mesontl1_t309-panel.dtsi index 33c1769..1239a61 100644 --- a/arch/arm64/boot/dts/amlogic/mesontl1_t309-panel.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesontl1_t309-panel.dtsi @@ -909,7 +909,7 @@ bl_level_attr = <255 10 /*max, min*/ 128 128>; /*mid, mid_mapping*/ bl_ctrl_method = <3>; /*1=pwm,2=pwm_combo,3=ldim*/ - bl_power_attr = <0 /*en_gpio_index*/ + bl_power_attr = <0xff /*en_gpio_index*/ 1 0 /*on_value, off_value*/ 200 200>; /*on_delay(ms), off_delay(ms)*/ bl_ldim_region_row_col = <1 1>; @@ -919,6 +919,23 @@ */ ldim_dev_index = <1>; }; + backlight_5{ + index = <5>; + bl_name = "ldim_iw7027"; + bl_level_default_uboot_kernel = <100 100>; + bl_level_attr = <255 10 /*max, min*/ + 128 128>; /*mid, mid_mapping*/ + bl_ctrl_method = <3>; /*1=pwm,2=pwm_combo,3=ldim*/ + bl_power_attr = <0 /*en_gpio_index*/ + 1 0 /*on_value, off_value*/ + 200 200>; /*on_delay(ms), off_delay(ms)*/ + bl_ldim_region_row_col = <1 10>; + bl_ldim_mode = <1>; /*0=left/right side + *1=top/bottom side + *2=direct + */ + ldim_dev_index = <2>; + }; }; bl_pwm_conf:bl_pwm_conf{ @@ -937,10 +954,16 @@ status = "okay"; pinctrl-names = "ldim_pwm", "ldim_pwm_vs", - "ldim_pwm_off"; + "ldim_pwm_combo", + "ldim_pwm_vs_combo", + "ldim_pwm_off", + "ldim_pwm_combo_off"; pinctrl-0 = <&pwm_c_pins3>; pinctrl-1 = <&bl_pwm_vs_on_pins>; - pinctrl-2 = <&bl_pwm_off_pins>; + pinctrl-2 = <&pwm_c_pins3 &pwm_d_pins2>; + pinctrl-3 = <&bl_pwm_vs_on_pins &pwm_d_pins2>; + pinctrl-4 = <&bl_pwm_off_pins>; + pinctrl-5 = <&bl_pwm_combo_off_pins>; pinctrl_version = <1>; /* for uboot */ ldim_pwm_config = <&bl_pwm_conf>; @@ -954,28 +977,83 @@ index = <0>; type = <0>; /*0=normal, 1=spi, 2=i2c*/ ldim_dev_name = "ob3350"; - ldim_pwm_pinmux_sel = "ldim_pwm"; - ldim_pwm_port = "PWM_B"; + ldim_pwm_port = "PWM_C"; ldim_pwm_attr = <0 /* pol */ 200 /*freq(pwm:Hz, pwm_vs:multiple of vs)*/ - 50>;/*duty(%)*/ - dim_max_min = <100 20>; /*dim_max, dim_min*/ + 50>;/*default duty(%)*/ en_gpio_on_off = <0 /*ldim_dev-gpios index*/ 1 0>; /*on_level, off_level*/ + dim_max_min = <100 20>; /*dim_max, dim_min*/ }; ldim_dev_1 { index = <1>; type = <0>; /*0=normal, 1=spi, 2=i2c*/ ldim_dev_name = "global"; - ldim_pwm_pinmux_sel = "ldim_pwm"; ldim_pwm_port = "PWM_C"; ldim_pwm_attr = <1 /* pol */ 180 /*freq(pwm:Hz, pwm_vs:multiple of vs)*/ - 50>;/*duty(%)*/ - dim_max_min = <100 20>; /*dim_max, dim_min*/ - en_gpio_on_off = <2 /*ldim_dev-gpios index*/ + 50>;/*default duty(%)*/ + analog_pwm_port = "PWM_D"; + analog_pwm_attr = <1 /*pol(0=negative, 1=positvie)*/ + 18000 /*freq(pwm:Hz)*/ + 100 25 /*duty_max(%), duty_min(%)*/ + 80>; /*default duty(%)*/ + en_gpio_on_off = <0 /*ldim_dev-gpios index*/ 1 0>; /*on_level, off_level*/ + dim_max_min = <100 20>; /*dim_max, dim_min*/ }; - }; + ldim_dev_2 { + index = <2>; + type = <1>; /* 0=normal,1=spi,2=i2c */ + ldim_dev_name = "iw7027"; + ldim_pwm_port = "PWM_VS"; + ldim_pwm_attr = <1 /* pol */ + 2 /*freq(pwm:Hz, pwm_vs:multiple of vs)*/ + 50>;/*default duty(%)*/ + spi_bus_num = <0>; + spi_chip_select = <0>; + spi_max_frequency = <1000000>; /* unit: hz */ + spi_mode = <0>; /* mode: 0, 1, 2, 3 */ + spi_cs_delay = <10 /* hold_high_delay */ + 100>; /* clk_cs_delay (unit: us) */ + en_gpio_on_off = <0 /* ldim_dev-gpios index */ + 1 /* on_level */ + 0>; /* off_level */ + lamp_err_gpio = <0xff>; + /* ldim_dev-gpios index, 0xff=invalid */ + spi_write_check = <0>; /* 0=disable, 1=enable */ + + dim_max_min = <0xfff 0x7f>; /* dim_max, dim_min */ + ldim_region_mapping = <0 1 2 3 4 5 6 7 8 9>; + + cmd_size = <0xff>; + /* init: (type, data...) */ + /* type: 0x00=cmd with delay, + * 0xc0=cmd, + * 0xfd=delay, + * 0xff=ending + */ + /* data: spi data, fill 0x0 for no use */ + /* delay: unit ms */ + init_on = < + 0xc0 2 0x23 0x03 + 0xc0 2 0x24 0xff + 0xc0 2 0x25 0x00 + 0xc0 2 0x26 0x00 + 0xc0 2 0x27 0x60 + 0xc0 2 0x29 0x00 + 0xc0 2 0x2a 0x00 + 0xc0 2 0x2b 0x00 + 0xc0 2 0x2c 0x73 + 0xc0 2 0x2d 0x37 + 0xc0 2 0x31 0x93 + 0xc0 2 0x32 0x0f + 0xc0 2 0x33 0xff + 0xc0 2 0x34 0xc8 + 0xc0 2 0x35 0xbf + 0xff 0>; + init_off = <0xff 0>; + }; + }; }; /* end of / */ diff --git a/arch/arm64/boot/dts/amlogic/mesontl1_x301-panel.dtsi b/arch/arm64/boot/dts/amlogic/mesontl1_x301-panel.dtsi index 95d59da..3d018ed 100644 --- a/arch/arm64/boot/dts/amlogic/mesontl1_x301-panel.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesontl1_x301-panel.dtsi @@ -912,7 +912,7 @@ bl_level_attr = <255 10 /*max, min*/ 128 128>; /*mid, mid_mapping*/ bl_ctrl_method = <3>; /*1=pwm,2=pwm_combo,3=ldim*/ - bl_power_attr = <0 /*en_gpio_index*/ + bl_power_attr = <0xff /*en_gpio_index*/ 1 0 /*on_value, off_value*/ 200 200>; /*on_delay(ms), off_delay(ms)*/ bl_ldim_region_row_col = <1 1>; @@ -922,6 +922,23 @@ */ ldim_dev_index = <1>; }; + backlight_5{ + index = <5>; + bl_name = "ldim_iw7027"; + bl_level_default_uboot_kernel = <100 100>; + bl_level_attr = <255 10 /*max, min*/ + 128 128>; /*mid, mid_mapping*/ + bl_ctrl_method = <3>; /*1=pwm,2=pwm_combo,3=ldim*/ + bl_power_attr = <0 /*en_gpio_index*/ + 1 0 /*on_value, off_value*/ + 200 200>; /*on_delay(ms), off_delay(ms)*/ + bl_ldim_region_row_col = <1 10>; + bl_ldim_mode = <1>; /*0=left/right side + *1=top/bottom side + *2=direct + */ + ldim_dev_index = <2>; + }; }; bl_pwm_conf:bl_pwm_conf{ @@ -940,10 +957,16 @@ status = "okay"; pinctrl-names = "ldim_pwm", "ldim_pwm_vs", - "ldim_pwm_off"; + "ldim_pwm_combo", + "ldim_pwm_vs_combo", + "ldim_pwm_off", + "ldim_pwm_combo_off"; pinctrl-0 = <&pwm_c_pins3>; pinctrl-1 = <&bl_pwm_vs_on_pins>; - pinctrl-2 = <&bl_pwm_off_pins>; + pinctrl-2 = <&pwm_c_pins3 &pwm_d_pins2>; + pinctrl-3 = <&bl_pwm_vs_on_pins &pwm_d_pins2>; + pinctrl-4 = <&bl_pwm_off_pins>; + pinctrl-5 = <&bl_pwm_combo_off_pins>; pinctrl_version = <1>; /* for uboot */ ldim_pwm_config = <&bl_pwm_conf>; @@ -957,27 +980,83 @@ index = <0>; type = <0>; /*0=normal, 1=spi, 2=i2c*/ ldim_dev_name = "ob3350"; - ldim_pwm_pinmux_sel = "ldim_pwm"; - ldim_pwm_port = "PWM_B"; + ldim_pwm_port = "PWM_C"; ldim_pwm_attr = <0 /* pol */ 200 /*freq(pwm:Hz, pwm_vs:multiple of vs)*/ - 50>;/*duty(%)*/ - dim_max_min = <100 20>; /*dim_max, dim_min*/ + 50>;/*default duty(%)*/ en_gpio_on_off = <0 /*ldim_dev-gpios index*/ 1 0>; /*on_level, off_level*/ + dim_max_min = <100 20>; /*dim_max, dim_min*/ }; ldim_dev_1 { index = <1>; type = <0>; /*0=normal, 1=spi, 2=i2c*/ ldim_dev_name = "global"; - ldim_pwm_pinmux_sel = "ldim_pwm"; ldim_pwm_port = "PWM_C"; ldim_pwm_attr = <1 /* pol */ 180 /*freq(pwm:Hz, pwm_vs:multiple of vs)*/ - 50>;/*duty(%)*/ - dim_max_min = <100 20>; /*dim_max, dim_min*/ - en_gpio_on_off = <2 /*ldim_dev-gpios index*/ + 50>;/*default duty(%)*/ + analog_pwm_port = "PWM_D"; + analog_pwm_attr = <1 /*pol(0=negative, 1=positvie)*/ + 18000 /*freq(pwm:Hz)*/ + 100 25 /*duty_max(%), duty_min(%)*/ + 80>; /*default duty(%)*/ + en_gpio_on_off = <0 /*ldim_dev-gpios index*/ 1 0>; /*on_level, off_level*/ + dim_max_min = <100 20>; /*dim_max, dim_min*/ + }; + + ldim_dev_2 { + index = <2>; + type = <1>; /* 0=normal,1=spi,2=i2c */ + ldim_dev_name = "iw7027"; + ldim_pwm_port = "PWM_VS"; + ldim_pwm_attr = <1 /* pol */ + 2 /*freq(pwm:Hz, pwm_vs:multiple of vs)*/ + 50>;/*default duty(%)*/ + spi_bus_num = <0>; + spi_chip_select = <0>; + spi_max_frequency = <1000000>; /* unit: hz */ + spi_mode = <0>; /* mode: 0, 1, 2, 3 */ + spi_cs_delay = <10 /* hold_high_delay */ + 100>; /* clk_cs_delay (unit: us) */ + en_gpio_on_off = <0 /* ldim_dev-gpios index */ + 1 /* on_level */ + 0>; /* off_level */ + lamp_err_gpio = <0xff>; + /* ldim_dev-gpios index, 0xff=invalid */ + spi_write_check = <0>; /* 0=disable, 1=enable */ + + dim_max_min = <0xfff 0x7f>; /* dim_max, dim_min */ + ldim_region_mapping = <0 1 2 3 4 5 6 7 8 9>; + + cmd_size = <0xff>; + /* init: (type, data...) */ + /* type: 0x00=cmd with delay, + * 0xc0=cmd, + * 0xfd=delay, + * 0xff=ending + */ + /* data: spi data, fill 0x0 for no use */ + /* delay: unit ms */ + init_on = < + 0xc0 2 0x23 0x03 + 0xc0 2 0x24 0xff + 0xc0 2 0x25 0x00 + 0xc0 2 0x26 0x00 + 0xc0 2 0x27 0x60 + 0xc0 2 0x29 0x00 + 0xc0 2 0x2a 0x00 + 0xc0 2 0x2b 0x00 + 0xc0 2 0x2c 0x73 + 0xc0 2 0x2d 0x37 + 0xc0 2 0x31 0x93 + 0xc0 2 0x32 0x0f + 0xc0 2 0x33 0xff + 0xc0 2 0x34 0xc8 + 0xc0 2 0x35 0xbf + 0xff 0>; + init_off = <0xff 0>; }; }; }; /* end of / */ diff --git a/arch/arm64/boot/dts/amlogic/mesontxlx_r311-panel.dtsi b/arch/arm64/boot/dts/amlogic/mesontxlx_r311-panel.dtsi index 99c8c93..610a57d 100644 --- a/arch/arm64/boot/dts/amlogic/mesontxlx_r311-panel.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesontxlx_r311-panel.dtsi @@ -678,37 +678,37 @@ }; backlight_4{ index = <4>; - bl_name = "ldim_iw7027"; + bl_name = "ldim_global"; bl_level_default_uboot_kernel = <100 100>; bl_level_attr = <255 10 /*max, min*/ 128 128>; /*mid, mid_mapping*/ bl_ctrl_method = <3>; /*1=pwm,2=pwm_combo,3=ldim*/ - bl_power_attr = <0 /*en_gpio_index*/ - 1 0 /*on_value, off_value*/ - 200 200>; /*on_delay(ms), off_delay(ms)*/ - bl_ldim_region_row_col = <1 10>; + bl_power_attr = <0xff /*en_gpio_index*/ + 1 0 /*on_value, off_value*/ + 200 200>; /* on_delay(ms), off_delay(ms)*/ + bl_ldim_region_row_col = <1 1>; bl_ldim_mode = <1>; /*0=left/right side *1=top/bottom side *2=direct */ - ldim_dev_index = <2>; + ldim_dev_index = <1>; }; backlight_5{ index = <5>; - bl_name = "ldim_global"; + bl_name = "ldim_iw7027"; bl_level_default_uboot_kernel = <100 100>; bl_level_attr = <255 10 /*max, min*/ 128 128>; /*mid, mid_mapping*/ bl_ctrl_method = <3>; /*1=pwm,2=pwm_combo,3=ldim*/ bl_power_attr = <0 /*en_gpio_index*/ - 1 0 /*on_value, off_value*/ - 200 200>; /* on_delay(ms), off_delay(ms)*/ - bl_ldim_region_row_col = <1 1>; + 1 0 /*on_value, off_value*/ + 200 200>; /*on_delay(ms), off_delay(ms)*/ + bl_ldim_region_row_col = <1 10>; bl_ldim_mode = <1>; /*0=left/right side *1=top/bottom side *2=direct */ - ldim_dev_index = <1>; + ldim_dev_index = <2>; }; }; @@ -728,54 +728,63 @@ status = "okay"; pinctrl-names = "ldim_pwm", "ldim_pwm_vs", - "ldim_pwm_off"; + "ldim_pwm_combo", + "ldim_pwm_vs_combo", + "ldim_pwm_off", + "ldim_pwm_combo_off"; pinctrl-0 = <&bl_pwm_on_pins>; pinctrl-1 = <&bl_pwm_vs_on_pins>; - pinctrl-2 = <&bl_pwm_off_pins>; + pinctrl-2 = <&bl_pwm_on_pins &bl_pwm_combo_1_on_pins>; + pinctrl-3 = <&bl_pwm_vs_on_pins &bl_pwm_combo_1_on_pins>; + pinctrl-4 = <&bl_pwm_off_pins>; + pinctrl-5 = <&bl_pwm_combo_off_pins>; pinctrl_version = <1>; /* for uboot */ ldim_pwm_config = <&bl_pwm_conf>; /* pwm port: PWM_A, PWM_B, PWM_C, PWM_D, PWM_E, PWM_F, PWM_VS*/ ldim_dev-gpios = <&gpio GPIOZ_12 GPIO_ACTIVE_HIGH &gpio GPIOZ_6 GPIO_ACTIVE_HIGH - &gpio GPIOZ_7 GPIO_ACTIVE_HIGH>; - ldim_dev_gpio_names = "GPIOZ_12","GPIOZ_6","GPIOZ_7"; + &gpio GPIOZ_7 GPIO_ACTIVE_HIGH + &gpio GPIOZ_4 GPIO_ACTIVE_HIGH>; + ldim_dev_gpio_names = "GPIOZ_12","GPIOZ_6","GPIOZ_7","GPIOZ_4"; ldim_dev_0 { index = <0>; type = <0>; /*0=normal, 1=spi, 2=i2c*/ ldim_dev_name = "ob3350"; - ldim_pwm_pinmux_sel = "ldim_pwm"; ldim_pwm_port = "PWM_B"; ldim_pwm_attr = <0 /* pol */ 200 /*freq(pwm:Hz, pwm_vs:multiple of vs)*/ - 50>;/*duty(%)*/ - dim_max_min = <100 20>; /*dim_max, dim_min*/ + 50>;/*default duty(%)*/ en_gpio_on_off = <0 /*ldim_dev-gpios index*/ 1 0>; /*on_level, off_level*/ + dim_max_min = <100 20>; /*dim_max, dim_min*/ }; ldim_dev_1 { index = <1>; type = <0>; /*0=normal, 1=spi, 2=i2c*/ ldim_dev_name = "global"; - ldim_pwm_pinmux_sel = "ldim_pwm"; ldim_pwm_port = "PWM_B"; ldim_pwm_attr = <1 /* pol */ 180 /*freq(pwm:Hz, pwm_vs:multiple of vs)*/ - 50>;/*duty(%)*/ - dim_max_min = <100 20>; /*dim_max, dim_min*/ - en_gpio_on_off = <2 /*ldim_dev-gpios index*/ + 50>;/*default duty(%)*/ + analog_pwm_port = "PWM_C"; + analog_pwm_attr = <1 /*pol(0=negative, 1=positvie)*/ + 18000 /*freq(pwm:Hz)*/ + 100 25 /*duty_max(%), duty_min(%)*/ + 80>; /*default duty(%)*/ + en_gpio_on_off = <3 /*ldim_dev-gpios index*/ 1 0>; /*on_level, off_level*/ + dim_max_min = <100 20>; /*dim_max, dim_min*/ }; ldim_dev_2 { index = <2>; type = <1>; /* 0=normal,1=spi,2=i2c */ ldim_dev_name = "iw7027"; - ldim_pwm_pinmux_sel = "ldim_pwm_vs"; ldim_pwm_port = "PWM_VS"; ldim_pwm_attr = <1 /* pol */ 2 /*freq(pwm:Hz, pwm_vs:multiple of vs)*/ - 50>;/*duty(%)*/ + 50>;/*default duty(%)*/ spi_bus_num = <0>; spi_chip_select = <0>; spi_max_frequency = <1000000>; /* unit: hz */ @@ -818,6 +827,7 @@ 0xc0 2 0x34 0xc8 0xc0 2 0x35 0xbf 0xff 0>; + init_off = <0xff 0>; }; }; diff --git a/drivers/amlogic/media/vout/backlight/aml_bl.c b/drivers/amlogic/media/vout/backlight/aml_bl.c index 7e8e52e..4e13b6f 100644 --- a/drivers/amlogic/media/vout/backlight/aml_bl.c +++ b/drivers/amlogic/media/vout/backlight/aml_bl.c @@ -330,15 +330,6 @@ static void bl_gpio_set(int index, int value) } } -static inline unsigned int bl_do_div(unsigned long long num, unsigned int den) -{ - unsigned long long ret = num; - - do_div(ret, den); - - return (unsigned int)ret; -} - /* ****************************************************** */ #define BL_PINMUX_MAX 8 static char *bl_pinmux_str[BL_PINMUX_MAX] = { @@ -2868,11 +2859,11 @@ static ssize_t bl_debug_pwm_show(struct class *class, return len; } -#define BL_DEBUG_PWM_FREQ 0 -#define BL_DEBUG_PWM_DUTY 1 -#define BL_DEBUG_PWM_POL 2 -#define BL_DEBUG_PWM_DUTY_MAX 3 -#define BL_DEBUG_PWM_DUTY_MIN 4 +#define BL_DEBUG_PWM_FREQ 0 +#define BL_DEBUG_PWM_DUTY 1 +#define BL_DEBUG_PWM_POL 2 +#define BL_DEBUG_PWM_DUTY_MAX 3 +#define BL_DEBUG_PWM_DUTY_MIN 4 static void bl_debug_pwm_set(unsigned int index, unsigned int value, int state) { struct bl_config_s *bconf = bl_drv->bconf; diff --git a/drivers/amlogic/media/vout/backlight/aml_ldim/global_bl.c b/drivers/amlogic/media/vout/backlight/aml_ldim/global_bl.c index d2dcd99..1a1856c 100644 --- a/drivers/amlogic/media/vout/backlight/aml_ldim/global_bl.c +++ b/drivers/amlogic/media/vout/backlight/aml_ldim/global_bl.c @@ -44,7 +44,8 @@ static int global_hw_init_on(void) { struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver(); - ldim_set_duty_pwm(&(ldim_drv->ldev_conf->pwm_config)); + ldim_set_duty_pwm(&(ldim_drv->ldev_conf->ldim_pwm_config)); + ldim_set_duty_pwm(&(ldim_drv->ldev_conf->analog_pwm_config)); ldim_drv->pinmux_ctrl(1); mdelay(2); ldim_gpio_set(ldim_drv->ldev_conf->en_gpio, @@ -61,7 +62,8 @@ static int global_hw_init_off(void) ldim_gpio_set(ldim_drv->ldev_conf->en_gpio, ldim_drv->ldev_conf->en_gpio_off); ldim_drv->pinmux_ctrl(0); - ldim_pwm_off(&(ldim_drv->ldev_conf->pwm_config)); + ldim_pwm_off(&(ldim_drv->ldev_conf->ldim_pwm_config)); + ldim_pwm_off(&(ldim_drv->ldev_conf->analog_pwm_config)); return 0; } @@ -88,12 +90,22 @@ static int global_smr(unsigned short *buf, unsigned char len) level = buf[0]; val = dim_min + ((level * (dim_max - dim_min)) / LD_DATA_MAX); - ldim_drv->ldev_conf->pwm_config.pwm_duty = val; - ldim_set_duty_pwm(&(ldim_drv->ldev_conf->pwm_config)); + ldim_drv->ldev_conf->ldim_pwm_config.pwm_duty = val; + ldim_set_duty_pwm(&(ldim_drv->ldev_conf->ldim_pwm_config)); return 0; } +static void global_dim_range_update(void) +{ + struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver(); + struct ldim_dev_config_s *ldim_dev; + + ldim_dev = ldim_drv->ldev_conf; + ldim_dev->dim_max = ldim_dev->ldim_pwm_config.pwm_duty_max; + ldim_dev->dim_min = ldim_dev->ldim_pwm_config.pwm_duty_min; +} + static int global_power_on(void) { if (global_on_flag) { @@ -137,7 +149,7 @@ static ssize_t global_show(struct class *class, ldim_drv->ldev_conf->en_gpio_off, ldim_drv->ldev_conf->dim_max, ldim_drv->ldev_conf->dim_min, - ldim_drv->ldev_conf->pwm_config.pwm_duty); + ldim_drv->ldev_conf->ldim_pwm_config.pwm_duty); } return ret; @@ -150,6 +162,12 @@ static struct class_attribute global_class_attrs[] = { static int global_ldim_driver_update(struct aml_ldim_driver_s *ldim_drv) { + struct ldim_dev_config_s *ldim_dev = ldim_drv->ldev_conf; + + ldim_dev->ldim_pwm_config.pwm_duty_max = ldim_dev->dim_max; + ldim_dev->ldim_pwm_config.pwm_duty_min = ldim_dev->dim_min; + ldim_dev->dim_range_update = global_dim_range_update; + ldim_drv->device_power_on = global_power_on; ldim_drv->device_power_off = global_power_off; ldim_drv->device_bri_update = global_smr; diff --git a/drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.c b/drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.c index 6c123d1d..054f3d2 100644 --- a/drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.c +++ b/drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.c @@ -273,7 +273,8 @@ static int iw7027_hw_init_on(void) iw7027_power_on_init(); /* step 5: supply stable vsync */ - ldim_set_duty_pwm(&(ldim_drv->ldev_conf->pwm_config)); + ldim_set_duty_pwm(&(ldim_drv->ldev_conf->ldim_pwm_config)); + ldim_set_duty_pwm(&(ldim_drv->ldev_conf->analog_pwm_config)); ldim_drv->pinmux_ctrl(1); /* step 6: delay for system clock and light bar PSU stable */ @@ -305,7 +306,8 @@ static int iw7027_hw_init_off(void) ldim_gpio_set(ldim_drv->ldev_conf->en_gpio, ldim_drv->ldev_conf->en_gpio_off); ldim_drv->pinmux_ctrl(0); - ldim_pwm_off(&(ldim_drv->ldev_conf->pwm_config)); + ldim_pwm_off(&(ldim_drv->ldev_conf->ldim_pwm_config)); + ldim_pwm_off(&(ldim_drv->ldev_conf->analog_pwm_config)); return 0; } @@ -617,7 +619,7 @@ static ssize_t iw7027_store(struct class *class, struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver(); struct iw7027_s *bl = container_of(class, struct iw7027_s, cls); unsigned int val, val2; - unsigned char reg_addr, reg_val; + unsigned char reg_addr, reg_val, temp; int i; if (!strcmp(attr->attr.name, "init")) { @@ -632,6 +634,10 @@ static ssize_t iw7027_store(struct class *class, reg_addr = (unsigned char)val; reg_val = (unsigned char)val2; iw7027_wreg(bl->spi, reg_addr, reg_val); + iw7027_rreg(bl->spi, reg_addr, &temp); + pr_info( + "reg 0x%02x = 0x%02x, readback 0x%02x\n", + reg_addr, reg_val, temp); mutex_unlock(&iw7027_spi_mutex); } else { LDIMERR("%s: invalid args\n", __func__); diff --git a/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_dev_drv.c b/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_dev_drv.c index 6ed4519..db5a10a 100644 --- a/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_dev_drv.c +++ b/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_dev_drv.c @@ -58,6 +58,7 @@ static struct spi_board_info ldim_spi_info = { static unsigned char *table_init_on_dft; static unsigned char *table_init_off_dft; static int ldim_dev_probe_flag; +static struct class ldim_dev_class; struct ldim_dev_config_s ldim_dev_config = { .type = LDIM_DEV_TYPE_NORMAL, @@ -77,12 +78,20 @@ struct ldim_dev_config_s ldim_dev_config = { .init_off = NULL, .init_on_cnt = 0, .init_off_cnt = 0, - .pwm_config = { + .ldim_pwm_config = { .pwm_method = BL_PWM_POSITIVE, .pwm_port = BL_PWM_MAX, .pwm_duty_max = 100, - .pwm_duty_min = 1, + .pwm_duty_min = 0, }, + .analog_pwm_config = { + .pwm_method = BL_PWM_POSITIVE, + .pwm_port = BL_PWM_MAX, + .pwm_freq = 1000, + .pwm_duty_max = 100, + .pwm_duty_min = 10, + }, + .dim_range_update = NULL, .bl_regnum = 0, }; @@ -246,14 +255,13 @@ unsigned int ldim_gpio_get(int index) void ldim_set_duty_pwm(struct bl_pwm_config_s *bl_pwm) { - unsigned long temp; + unsigned long long temp; if (bl_pwm->pwm_port >= BL_PWM_MAX) return; temp = bl_pwm->pwm_cnt; - temp = (((temp * bl_pwm->pwm_duty) + 50) / 100); - bl_pwm->pwm_level = (unsigned int)temp; + bl_pwm->pwm_level = bl_do_div(((temp * bl_pwm->pwm_duty) + 50), 100); if (ldim_debug_print == 2) { LDIMPR( @@ -277,42 +285,53 @@ void ldim_pwm_off(struct bl_pwm_config_s *bl_pwm) static char *ldim_pinmux_str[] = { "ldim_pwm", /* 0 */ "ldim_pwm_vs", /* 1 */ - "ldim_pwm_off", /* 1 */ - "none", + "ldim_pwm_combo", /* 2 */ + "ldim_pwm_vs_combo", /* 3 */ + "ldim_pwm_off", /* 4 */ + "ldim_pwm_combo_off", /* 5 */ + "custome", }; static int ldim_pwm_pinmux_ctrl(int status) { struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver(); struct bl_pwm_config_s *bl_pwm; + char *str; int ret = 0, index = 0xff; - if (strcmp(ldim_drv->ldev_conf->pinmux_name, "invalid") == 0) + if (ldim_drv->ldev_conf->ldim_pwm_config.pwm_port >= BL_PWM_MAX) return 0; - bl_pwm = &ldim_drv->ldev_conf->pwm_config; - if (bl_pwm->pwm_port >= BL_PWM_MAX) - return 0; - - if (bl_pwm->pwm_port == BL_PWM_VS) - index = (status) ? 1 : 2; - else - index = (status) ? 0 : 2; + if (status) { + bl_pwm = &ldim_drv->ldev_conf->ldim_pwm_config; + if (bl_pwm->pwm_port == BL_PWM_VS) + index = 1; + else + index = 0; + bl_pwm = &ldim_drv->ldev_conf->analog_pwm_config; + if (bl_pwm->pwm_port < BL_PWM_VS) + index += 2; + } else { + bl_pwm = &ldim_drv->ldev_conf->analog_pwm_config; + if (bl_pwm->pwm_port < BL_PWM_VS) + index = 5; + else + index = 4; + } + str = ldim_pinmux_str[index]; if (ldim_drv->pinmux_flag == index) { - LDIMPR("pinmux %s is already selected\n", - ldim_pinmux_str[index]); + LDIMPR("pinmux %s is already selected\n", str); return 0; } /* request pwm pinmux */ - ldim_drv->pin = devm_pinctrl_get_select(ldim_drv->dev, - ldim_pinmux_str[index]); + ldim_drv->pin = devm_pinctrl_get_select(ldim_drv->dev, str); if (IS_ERR(ldim_drv->pin)) { - LDIMERR("set pinmux %s error\n", ldim_pinmux_str[index]); + LDIMERR("set pinmux %s error\n", str); + ret = -1; } else { - LDIMPR("set pinmux %s: 0x%p\n", - ldim_pinmux_str[index], ldim_drv->pin); + LDIMPR("set pinmux %s: 0x%p\n", str, ldim_drv->pin); } ldim_drv->pinmux_flag = index; @@ -321,7 +340,7 @@ static int ldim_pwm_pinmux_ctrl(int status) static int ldim_pwm_vs_update(void) { - struct bl_pwm_config_s *bl_pwm = &ldim_dev_config.pwm_config; + struct bl_pwm_config_s *bl_pwm = &ldim_dev_config.ldim_pwm_config; unsigned int cnt; int ret = 0; @@ -363,6 +382,10 @@ static void ldim_dev_init_table_dynamic_size_print( table = econf->init_off; max_len = econf->init_off_cnt; } + if (max_len == 0) { + kfree(str); + return; + } if (table == NULL) { LDIMERR("init_table %d is NULL\n", flag); kfree(str); @@ -440,6 +463,10 @@ static void ldim_dev_init_table_fixed_size_print( table = econf->init_off; max_len = econf->init_off_cnt; } + if (max_len == 0) { + kfree(str); + return; + } if (table == NULL) { LDIMERR("init_table %d is NULL\n", flag); kfree(str); @@ -476,7 +503,7 @@ static void ldim_dev_config_print(void) pr_info("valid_flag = %d\n" "dev_index = %d\n" - "vsync_change_flag = %d\n", + "vsync_change_flag = %d\n\n", ldim_drv->valid_flag, ldim_drv->dev_index, ldim_drv->vsync_change_flag); @@ -485,7 +512,6 @@ static void ldim_dev_config_print(void) return; } - bl_pwm = &ldim_drv->ldev_conf->pwm_config; pr_info("dev_name = %s\n" "type = %d\n" "en_gpio = %d\n" @@ -548,13 +574,14 @@ static void ldim_dev_config_print(void) default: break; } + bl_pwm = &ldim_drv->ldev_conf->ldim_pwm_config; if (bl_pwm->pwm_port < BL_PWM_MAX) { - pr_info("pwm_port: %d\n" - "pwm_pol: %d\n" - "pwm_freq: %d\n" - "pwm_cnt: %d\n" - "pwm_level: %d\n" - "pwm_duty: %d%%\n", + pr_info("lidm_pwm_port: %d\n" + "lidm_pwm_pol: %d\n" + "lidm_pwm_freq: %d\n" + "lidm_pwm_cnt: %d\n" + "lidm_pwm_level: %d\n" + "lidm_pwm_duty: %d%%\n", bl_pwm->pwm_port, bl_pwm->pwm_method, bl_pwm->pwm_freq, bl_pwm->pwm_cnt, bl_pwm->pwm_level, bl_pwm->pwm_duty); @@ -566,28 +593,28 @@ static void ldim_dev_config_print(void) case BL_PWM_E: case BL_PWM_F: if (IS_ERR_OR_NULL(bl_pwm->pwm_data.pwm)) { - pr_info("pwm invalid\n"); + pr_info("lidm_pwm invalid\n"); break; } - pr_info("pwm_pointer: %p\n", + pr_info("lidm_pwm_pointer: 0x%p\n", bl_pwm->pwm_data.pwm); pwm_get_state(bl_pwm->pwm_data.pwm, &pstate); - pr_info("pwm state:\n" - " period: %d\n" - " duty_cycle: %d\n" - " polarity: %d\n" - " enabled: %d\n", + pr_info("lidm_pwm state:\n" + " period: %d\n" + " duty_cycle: %d\n" + " polarity: %d\n" + " enabled: %d\n", pstate.period, pstate.duty_cycle, pstate.polarity, pstate.enabled); value = bl_cbus_read( bl_drv->data->pwm_reg[bl_pwm->pwm_port]); - pr_info("pwm_reg: 0x%08x\n", value); + pr_info("lidm_pwm_reg: 0x%08x\n", value); break; case BL_PWM_VS: - pr_info("pwm_reg0: 0x%08x\n" - "pwm_reg1: 0x%08x\n" - "pwm_reg2: 0x%08x\n" - "pwm_reg3: 0x%08x\n", + pr_info("lidm_pwm_reg0: 0x%08x\n" + "lidm_pwm_reg1: 0x%08x\n" + "lidm_pwm_reg2: 0x%08x\n" + "lidm_pwm_reg3: 0x%08x\n", bl_vcbus_read(VPU_VPU_PWM_V0), bl_vcbus_read(VPU_VPU_PWM_V1), bl_vcbus_read(VPU_VPU_PWM_V2), @@ -597,16 +624,59 @@ static void ldim_dev_config_print(void) break; } } - pr_info("pinmux_flag: %d\n" - "pinmux_pointer: 0x%p\n\n", + bl_pwm = &ldim_drv->ldev_conf->analog_pwm_config; + if (bl_pwm->pwm_port < BL_PWM_MAX) { + pr_info("\nanalog_pwm_port: %d\n" + "analog_pwm_pol: %d\n" + "analog_pwm_freq: %d\n" + "analog_pwm_cnt: %d\n" + "analog_pwm_level: %d\n" + "analog_pwm_duty: %d%%\n" + "analog_pwm_duty_max: %d%%\n" + "analog_pwm_duty_min: %d%%\n", + bl_pwm->pwm_port, bl_pwm->pwm_method, + bl_pwm->pwm_freq, bl_pwm->pwm_cnt, + bl_pwm->pwm_level, bl_pwm->pwm_duty, + bl_pwm->pwm_duty_max, bl_pwm->pwm_duty_min); + switch (bl_pwm->pwm_port) { + case BL_PWM_A: + case BL_PWM_B: + case BL_PWM_C: + case BL_PWM_D: + case BL_PWM_E: + case BL_PWM_F: + if (IS_ERR_OR_NULL(bl_pwm->pwm_data.pwm)) { + pr_info("analog_pwm invalid\n"); + break; + } + pr_info("analog_pwm_pointer: 0x%p\n", + bl_pwm->pwm_data.pwm); + pwm_get_state(bl_pwm->pwm_data.pwm, &pstate); + pr_info("analog_pwm state:\n" + " period: %d\n" + " duty_cycle: %d\n" + " polarity: %d\n" + " enabled: %d\n", + pstate.period, pstate.duty_cycle, + pstate.polarity, pstate.enabled); + value = bl_cbus_read( + bl_drv->data->pwm_reg[bl_pwm->pwm_port]); + pr_info("analog_pwm_reg: 0x%08x\n", value); + break; + default: + break; + } + } + pr_info("\npinmux_flag: %d\n" + "pinmux_pointer: 0x%p\n\n", ldim_drv->pinmux_flag, ldim_drv->pin); if (ldim_drv->ldev_conf->cmd_size > 0) { - pr_info("table_loaded: %d\n" - "cmd_size: %d\n" - "init_on_cnt: %d\n" - "init_off_cnt: %d\n", + pr_info("table_loaded: %d\n" + "cmd_size: %d\n" + "init_on_cnt: %d\n" + "init_off_cnt: %d\n", ldim_drv->ldev_conf->init_loaded, ldim_drv->ldev_conf->cmd_size, ldim_drv->ldev_conf->init_on_cnt, @@ -892,6 +962,7 @@ static int ldim_dev_get_config_from_dts(struct device_node *np, int index) int i; int ret = 0; struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver(); + struct bl_pwm_config_s *bl_pwm; temp = kcalloc(LD_BLKREGNUM, sizeof(unsigned int), GFP_KERNEL); if (temp == NULL) { @@ -917,48 +988,77 @@ static int ldim_dev_get_config_from_dts(struct device_node *np, int index) ret = of_property_read_string(child, "ldim_pwm_pinmux_sel", &str); if (ret) { - LDIMERR("failed to get ldim_pwm_name\n"); strcpy(ldim_dev_config.pinmux_name, "invalid"); } else { + LDIMPR("find custome ldim_pwm_pinmux_sel: %s\n", str); strcpy(ldim_dev_config.pinmux_name, str); } + /* ldim pwm config */ + bl_pwm = &ldim_dev_config.ldim_pwm_config; ret = of_property_read_string(child, "ldim_pwm_port", &str); if (ret) { LDIMERR("failed to get ldim_pwm_port\n"); - ldim_dev_config.pwm_config.pwm_port = BL_PWM_MAX; } else { - ldim_dev_config.pwm_config.pwm_port = bl_pwm_str_to_pwm(str); + bl_pwm->pwm_port = bl_pwm_str_to_pwm(str); + LDIMPR("ldim_pwm_port: %s(%u)\n", str, bl_pwm->pwm_port); } - LDIMPR("pwm_port: %s(%u)\n", str, ldim_dev_config.pwm_config.pwm_port); - - if (ldim_dev_config.pwm_config.pwm_port < BL_PWM_MAX) { + if (bl_pwm->pwm_port < BL_PWM_MAX) { ret = of_property_read_u32_array(child, "ldim_pwm_attr", temp, 3); if (ret) { LDIMERR("failed to get ldim_pwm_attr\n"); - ldim_dev_config.pwm_config.pwm_method = BL_PWM_POSITIVE; - if (ldim_dev_config.pwm_config.pwm_port == BL_PWM_VS) - ldim_dev_config.pwm_config.pwm_freq = 1; + bl_pwm->pwm_method = BL_PWM_POSITIVE; + if (bl_pwm->pwm_port == BL_PWM_VS) + bl_pwm->pwm_freq = 1; else - ldim_dev_config.pwm_config.pwm_freq = 60; - ldim_dev_config.pwm_config.pwm_duty = 50; + bl_pwm->pwm_freq = 60; + bl_pwm->pwm_duty = 50; } else { - ldim_dev_config.pwm_config.pwm_method = temp[0]; - ldim_dev_config.pwm_config.pwm_freq = temp[1]; - ldim_dev_config.pwm_config.pwm_duty = temp[2]; + bl_pwm->pwm_method = temp[0]; + bl_pwm->pwm_freq = temp[1]; + bl_pwm->pwm_duty = temp[2]; } - LDIMPR("get pwm pol = %d, freq = %d, duty = %d%%\n", - ldim_dev_config.pwm_config.pwm_method, - ldim_dev_config.pwm_config.pwm_freq, - ldim_dev_config.pwm_config.pwm_duty); + LDIMPR( + "get ldim_pwm pol = %d, freq = %d, default duty = %d%%\n", + bl_pwm->pwm_method, bl_pwm->pwm_freq, + bl_pwm->pwm_duty); - bl_pwm_config_init(&ldim_dev_config.pwm_config); + bl_pwm_config_init(bl_pwm); - if (ldim_dev_config.pwm_config.pwm_port < BL_PWM_VS) { - ldim_dev_pwm_channel_register( - &ldim_dev_config.pwm_config, np); + if (bl_pwm->pwm_port < BL_PWM_VS) + ldim_dev_pwm_channel_register(bl_pwm, np); + } + + /* analog pwm config */ + bl_pwm = &ldim_dev_config.analog_pwm_config; + ret = of_property_read_string(child, "analog_pwm_port", &str); + if (ret) + bl_pwm->pwm_port = BL_PWM_MAX; + else + bl_pwm->pwm_port = bl_pwm_str_to_pwm(str); + if (bl_pwm->pwm_port < BL_PWM_VS) { + LDIMPR("find analog_pwm_port: %s(%u)\n", str, bl_pwm->pwm_port); + ret = of_property_read_u32_array(child, "analog_pwm_attr", + temp, 5); + if (ret) { + LDIMERR("failed to get analog_pwm_attr\n"); + } else { + bl_pwm->pwm_method = temp[0]; + bl_pwm->pwm_freq = temp[1]; + bl_pwm->pwm_duty_max = temp[2]; + bl_pwm->pwm_duty_min = temp[3]; + bl_pwm->pwm_duty = temp[4]; } + LDIMPR( +"get analog_pwm pol = %d, freq = %d, duty_max = %d%%, duty_min = %d%%, default duty = %d%%\n", + bl_pwm->pwm_method, bl_pwm->pwm_freq, + bl_pwm->pwm_duty_max, bl_pwm->pwm_duty_min, + bl_pwm->pwm_duty); + + bl_pwm_config_init(bl_pwm); + + ldim_dev_pwm_channel_register(bl_pwm, np); } ret = of_property_read_u32_array(child, "en_gpio_on_off", temp, 3); @@ -1160,6 +1260,268 @@ ldim_get_config_err: return -1; } +static ssize_t ldim_dev_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + int ret = 0; + + ldim_dev_config_print(); + + return ret; +} + +static ssize_t ldim_dev_pwm_ldim_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + struct bl_pwm_config_s *bl_pwm; + ssize_t len = 0; + + bl_pwm = &ldim_dev_config.ldim_pwm_config; + if (bl_pwm->pwm_port < BL_PWM_MAX) { + len += sprintf(buf+len, + "ldim_pwm: freq=%d, pol=%d, duty_max=%d, duty_min=%d,", + bl_pwm->pwm_freq, bl_pwm->pwm_method, + bl_pwm->pwm_duty_max, bl_pwm->pwm_duty_min); + len += sprintf(buf+len, " duty_value=%d%%\n", bl_pwm->pwm_duty); + } + + return len; +} + +static ssize_t ldim_dev_pwm_ldim_store(struct class *class, + struct class_attribute *attr, const char *buf, size_t count) +{ + unsigned int ret; + unsigned int val = 0; + struct bl_pwm_config_s *bl_pwm; + + bl_pwm = &ldim_dev_config.ldim_pwm_config; + if (bl_pwm->pwm_port >= BL_PWM_MAX) + return count; + + switch (buf[0]) { + case 'f': /* frequency */ + ret = sscanf(buf, "freq %d", &val); + if (ret == 1) { + bl_pwm->pwm_freq = val; + bl_pwm_config_init(bl_pwm); + ldim_set_duty_pwm(bl_pwm); + if (ldim_debug_print) { + LDIMPR("set ldim_pwm (port %d): freq = %dHz\n", + bl_pwm->pwm_port, bl_pwm->pwm_freq); + } + } else { + LDIMERR("invalid parameters\n"); + } + break; + case 'd': /* duty */ + ret = sscanf(buf, "duty %d", &val); + if (ret == 1) { + bl_pwm->pwm_duty = val; + ldim_set_duty_pwm(bl_pwm); + if (ldim_debug_print) { + LDIMPR("set ldim_pwm (port %d): duty = %d%%\n", + bl_pwm->pwm_port, bl_pwm->pwm_duty); + } + } else { + LDIMERR("invalid parameters\n"); + } + break; + case 'p': /* polarity */ + ret = sscanf(buf, "pol %d", &val); + if (ret == 1) { + bl_pwm->pwm_method = val; + bl_pwm_config_init(bl_pwm); + ldim_set_duty_pwm(bl_pwm); + if (ldim_debug_print) { + LDIMPR("set ldim_pwm (port %d): method = %d\n", + bl_pwm->pwm_port, bl_pwm->pwm_method); + } + } else { + LDIMERR("invalid parameters\n"); + } + break; + case 'm': + if (buf[1] == 'a') { /* max */ + ret = sscanf(buf, "max %d", &val); + if (ret == 1) { + bl_pwm->pwm_duty_max = val; + if (ldim_dev_config.dim_range_update) + ldim_dev_config.dim_range_update(); + bl_pwm_config_init(bl_pwm); + ldim_set_duty_pwm(bl_pwm); + if (ldim_debug_print) { + LDIMPR( + "set ldim_pwm (port %d): duty_max = %d%%\n", + bl_pwm->pwm_port, + bl_pwm->pwm_duty_max); + } + } else { + LDIMERR("invalid parameters\n"); + } + } else if (buf[1] == 'i') { /* min */ + ret = sscanf(buf, "min %d", &val); + if (ret == 1) { + bl_pwm->pwm_duty_min = val; + if (ldim_dev_config.dim_range_update) + ldim_dev_config.dim_range_update(); + bl_pwm_config_init(bl_pwm); + ldim_set_duty_pwm(bl_pwm); + if (ldim_debug_print) { + LDIMPR( + "set ldim_pwm (port %d): duty_min = %d%%\n", + bl_pwm->pwm_port, + bl_pwm->pwm_duty_min); + } + } else { + LDIMERR("invalid parameters\n"); + } + } + break; + default: + LDIMERR("wrong command\n"); + break; + } + + return count; +} + +static ssize_t ldim_dev_pwm_analog_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + struct bl_pwm_config_s *bl_pwm; + ssize_t len = 0; + + bl_pwm = &ldim_dev_config.analog_pwm_config; + if (bl_pwm->pwm_port < BL_PWM_VS) { + len += sprintf(buf+len, + "analog_pwm: freq=%d, pol=%d, duty_max=%d, duty_min=%d,", + bl_pwm->pwm_freq, bl_pwm->pwm_method, + bl_pwm->pwm_duty_max, bl_pwm->pwm_duty_min); + len += sprintf(buf+len, " duty_value=%d%%\n", bl_pwm->pwm_duty); + } + + return len; +} + +static ssize_t ldim_dev_pwm_analog_store(struct class *class, + struct class_attribute *attr, const char *buf, size_t count) +{ + unsigned int ret; + unsigned int val = 0; + struct bl_pwm_config_s *bl_pwm; + + bl_pwm = &ldim_dev_config.analog_pwm_config; + if (bl_pwm->pwm_port >= BL_PWM_VS) + return count; + + switch (buf[0]) { + case 'f': /* frequency */ + ret = sscanf(buf, "freq %d", &val); + if (ret == 1) { + bl_pwm->pwm_freq = val; + bl_pwm_config_init(bl_pwm); + ldim_set_duty_pwm(bl_pwm); + if (ldim_debug_print) { + LDIMPR("set ldim_pwm (port %d): freq = %dHz\n", + bl_pwm->pwm_port, bl_pwm->pwm_freq); + } + } else { + LDIMERR("invalid parameters\n"); + } + break; + case 'd': /* duty */ + ret = sscanf(buf, "duty %d", &val); + if (ret == 1) { + bl_pwm->pwm_duty = val; + ldim_set_duty_pwm(bl_pwm); + if (ldim_debug_print) { + LDIMPR("set ldim_pwm (port %d): duty = %d%%\n", + bl_pwm->pwm_port, bl_pwm->pwm_duty); + } + } else { + LDIMERR("invalid parameters\n"); + } + break; + case 'p': /* polarity */ + ret = sscanf(buf, "pol %d", &val); + if (ret == 1) { + bl_pwm->pwm_method = val; + bl_pwm_config_init(bl_pwm); + ldim_set_duty_pwm(bl_pwm); + if (ldim_debug_print) { + LDIMPR("set ldim_pwm (port %d): method = %d\n", + bl_pwm->pwm_port, bl_pwm->pwm_method); + } + } else { + LDIMERR("invalid parameters\n"); + } + break; + case 'm': + if (buf[1] == 'a') { /* max */ + ret = sscanf(buf, "max %d", &val); + if (ret == 1) { + bl_pwm->pwm_duty_max = val; + bl_pwm_config_init(bl_pwm); + ldim_set_duty_pwm(bl_pwm); + if (ldim_debug_print) { + LDIMPR( + "set ldim_pwm (port %d): duty_max = %d%%\n", + bl_pwm->pwm_port, + bl_pwm->pwm_duty_max); + } + } else { + LDIMERR("invalid parameters\n"); + } + } else if (buf[1] == 'i') { /* min */ + ret = sscanf(buf, "min %d", &val); + if (ret == 1) { + bl_pwm->pwm_duty_min = val; + bl_pwm_config_init(bl_pwm); + ldim_set_duty_pwm(bl_pwm); + if (ldim_debug_print) { + LDIMPR( + "set ldim_pwm (port %d): duty_min = %d%%\n", + bl_pwm->pwm_port, + bl_pwm->pwm_duty_min); + } + } else { + LDIMERR("invalid parameters\n"); + } + } + break; + default: + LDIMERR("wrong command\n"); + break; + } + + return count; +} + +static struct class_attribute ldim_dev_class_attrs[] = { + __ATTR(status, 0644, ldim_dev_show, NULL), + __ATTR(pwm_ldim, 0644, ldim_dev_pwm_ldim_show, ldim_dev_pwm_ldim_store), + __ATTR(pwm_analog, 0644, ldim_dev_pwm_analog_show, + ldim_dev_pwm_analog_store), + __ATTR_NULL +}; + +static void ldim_dev_class_create(void) +{ + int ret; + + ldim_dev_class.name = kzalloc(10, GFP_KERNEL); + if (ldim_dev_class.name == NULL) { + LDIMERR("%s: malloc failed\n", __func__); + return; + } + sprintf((char *)ldim_dev_class.name, "ldim_dev"); + ldim_dev_class.class_attrs = ldim_dev_class_attrs; + ret = class_register(&ldim_dev_class); + if (ret < 0) + LDIMERR("register ldim_dev_class failed\n"); +} + static int ldim_dev_add_driver(struct aml_ldim_driver_s *ldim_drv) { struct ldim_dev_config_s *ldev_conf = ldim_drv->ldev_conf; @@ -1255,6 +1617,7 @@ static int ldim_dev_probe(struct platform_device *pdev) ldim_dev_get_config_from_dts(pdev->dev.of_node, ldim_drv->dev_index); + ldim_dev_class_create(); ldim_dev_add_driver(ldim_drv); /* init ldim function */ diff --git a/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_drv.h b/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_drv.h index d186f59..76c23ce 100644 --- a/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_drv.h +++ b/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_drv.h @@ -26,7 +26,8 @@ /*20181101: fix ldim_op_func null mistake, add new spi api support */ /*20181203: add 50/60hz change & iw7027 error handle support */ /*20181220: add tl1 support*/ -#define LDIM_DRV_VER "20181220" +/*20190103: add analog pwm support*/ +#define LDIM_DRV_VER "20190103" extern unsigned char ldim_debug_print; diff --git a/drivers/amlogic/media/vout/backlight/aml_ldim/ob3350_bl.c b/drivers/amlogic/media/vout/backlight/aml_ldim/ob3350_bl.c index 4348321..8efef8b 100644 --- a/drivers/amlogic/media/vout/backlight/aml_ldim/ob3350_bl.c +++ b/drivers/amlogic/media/vout/backlight/aml_ldim/ob3350_bl.c @@ -48,7 +48,8 @@ static int ob3350_hw_init_on(void) ldim_drv->ldev_conf->en_gpio_on); mdelay(2); - ldim_set_duty_pwm(&(ldim_drv->ldev_conf->pwm_config)); + ldim_set_duty_pwm(&(ldim_drv->ldev_conf->ldim_pwm_config)); + ldim_set_duty_pwm(&(ldim_drv->ldev_conf->analog_pwm_config)); ldim_drv->pinmux_ctrl(1); mdelay(20); @@ -62,7 +63,8 @@ static int ob3350_hw_init_off(void) ldim_gpio_set(ldim_drv->ldev_conf->en_gpio, ldim_drv->ldev_conf->en_gpio_off); ldim_drv->pinmux_ctrl(0); - ldim_pwm_off(&(ldim_drv->ldev_conf->pwm_config)); + ldim_pwm_off(&(ldim_drv->ldev_conf->ldim_pwm_config)); + ldim_pwm_off(&(ldim_drv->ldev_conf->analog_pwm_config)); return 0; } @@ -89,12 +91,22 @@ static int ob3350_smr(unsigned short *buf, unsigned char len) level = buf[0]; val = dim_min + ((level * (dim_max - dim_min)) / LD_DATA_MAX); - ldim_drv->ldev_conf->pwm_config.pwm_duty = val; - ldim_set_duty_pwm(&(ldim_drv->ldev_conf->pwm_config)); + ldim_drv->ldev_conf->ldim_pwm_config.pwm_duty = val; + ldim_set_duty_pwm(&(ldim_drv->ldev_conf->ldim_pwm_config)); return 0; } +static void ob3350_dim_range_update(void) +{ + struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver(); + struct ldim_dev_config_s *ldim_dev; + + ldim_dev = ldim_drv->ldev_conf; + ldim_dev->dim_max = ldim_dev->ldim_pwm_config.pwm_duty_max; + ldim_dev->dim_min = ldim_dev->ldim_pwm_config.pwm_duty_min; +} + static int ob3350_power_on(void) { if (ob3350_on_flag) { @@ -138,7 +150,7 @@ static ssize_t ob3350_show(struct class *class, ldim_drv->ldev_conf->en_gpio_off, ldim_drv->ldev_conf->dim_max, ldim_drv->ldev_conf->dim_min, - ldim_drv->ldev_conf->pwm_config.pwm_duty); + ldim_drv->ldev_conf->ldim_pwm_config.pwm_duty); } return ret; @@ -151,6 +163,12 @@ static struct class_attribute ob3350_class_attrs[] = { static int ob3350_ldim_driver_update(struct aml_ldim_driver_s *ldim_drv) { + struct ldim_dev_config_s *ldim_dev = ldim_drv->ldev_conf; + + ldim_dev->ldim_pwm_config.pwm_duty_max = ldim_dev->dim_max; + ldim_dev->ldim_pwm_config.pwm_duty_min = ldim_dev->dim_min; + ldim_dev->dim_range_update = ob3350_dim_range_update; + ldim_drv->device_power_on = ob3350_power_on; ldim_drv->device_power_off = ob3350_power_off; ldim_drv->device_bri_update = ob3350_smr; diff --git a/include/linux/amlogic/media/vout/lcd/aml_bl.h b/include/linux/amlogic/media/vout/lcd/aml_bl.h index 67b65e1..8e13c11 100644 --- a/include/linux/amlogic/media/vout/lcd/aml_bl.h +++ b/include/linux/amlogic/media/vout/lcd/aml_bl.h @@ -196,5 +196,14 @@ extern void bl_pwm_ctrl(struct bl_pwm_config_s *bl_pwm, int status); #define BL_GPIO_OUTPUT_HIGH 1 #define BL_GPIO_INPUT 2 +static inline unsigned int bl_do_div(unsigned long long num, unsigned int den) +{ + unsigned long long ret = num; + + do_div(ret, den); + + return (unsigned int)ret; +} + #endif diff --git a/include/linux/amlogic/media/vout/lcd/aml_ldim.h b/include/linux/amlogic/media/vout/lcd/aml_ldim.h index 6638083..c7578e9 100644 --- a/include/linux/amlogic/media/vout/lcd/aml_ldim.h +++ b/include/linux/amlogic/media/vout/lcd/aml_ldim.h @@ -81,7 +81,9 @@ struct ldim_dev_config_s { unsigned int init_on_cnt; unsigned int init_off_cnt; - struct bl_pwm_config_s pwm_config; + struct bl_pwm_config_s ldim_pwm_config; + struct bl_pwm_config_s analog_pwm_config; + void (*dim_range_update)(void); unsigned short bl_regnum; unsigned short bl_mapping[LD_BLKREGNUM]; -- 2.7.4