summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/msm/qcom,osm.txt10
-rw-r--r--Documentation/devicetree/bindings/fb/mdss-dp.txt7
-rw-r--r--Documentation/devicetree/bindings/leds/leds-qpnp.txt14
-rw-r--r--Documentation/devicetree/bindings/media/video/msm-vidc.txt4
-rw-r--r--Documentation/devicetree/bindings/platform/msm/qpnp-coincell.txt2
-rw-r--r--Documentation/devicetree/bindings/power/apm.txt10
-rw-r--r--Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt31
-rw-r--r--Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt12
-rw-r--r--Documentation/devicetree/bindings/regulator/mem-acc-regulator.txt2
-rw-r--r--Documentation/devicetree/bindings/regulator/qpnp-regulator.txt2
-rw-r--r--Documentation/devicetree/bindings/thermal/qpnp-temp-alarm.txt9
-rw-r--r--Documentation/devicetree/bindings/usb/dwc3.txt2
-rw-r--r--Documentation/devicetree/bindings/usb/qpnp-pdphy.txt7
-rw-r--r--arch/arm/boot/dts/qcom/apq8998-v2.1-mediabox.dts6
-rw-r--r--arch/arm/boot/dts/qcom/dsi-panel-nt35597-dualmipi-wqxga-video.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-cmd.dtsi260
-rw-r--r--arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-video.dtsi262
-rw-r--r--arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dualmipi-wqxga-cmd.dtsi256
-rw-r--r--arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dualmipi-wqxga-video.dtsi256
-rw-r--r--arch/arm/boot/dts/qcom/dsi-panel-nt35695b-truly-fhd-cmd.dtsi12
-rw-r--r--arch/arm/boot/dts/qcom/dsi-panel-nt35695b-truly-fhd-video.dtsi15
-rw-r--r--arch/arm/boot/dts/qcom/msm-pm660.dtsi7
-rw-r--r--arch/arm/boot/dts/qcom/msm-pmi8998.dtsi10
-rw-r--r--arch/arm/boot/dts/qcom/msm-smb138x.dtsi26
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-vidc.dtsi3
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-camera.dtsi20
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-mdss.dtsi8
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-mtp.dtsi13
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi13
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-qrd.dtsi13
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-v2-camera.dtsi14
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-v2.dtsi3
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-vidc.dtsi3
-rw-r--r--arch/arm/boot/dts/qcom/msm8998.dtsi20
-rw-r--r--arch/arm/boot/dts/qcom/sdm630-cdp.dtsi21
-rw-r--r--arch/arm/boot/dts/qcom/sdm630-mtp.dtsi21
-rw-r--r--arch/arm/boot/dts/qcom/sdm630-rumi.dts21
-rw-r--r--arch/arm/boot/dts/qcom/sdm630.dtsi295
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-cdp.dtsi9
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-common.dtsi83
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-gpu.dtsi419
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-mdss-panels.dtsi26
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-mdss-pll.dtsi37
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-mdss.dtsi50
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-mtp.dtsi23
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi52
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-vidc.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/sdm660.dtsi50
-rw-r--r--arch/arm/configs/sdm660-perf_defconfig1
-rw-r--r--arch/arm/configs/sdm660_defconfig3
-rw-r--r--arch/arm64/configs/sdm660-perf_defconfig1
-rw-r--r--drivers/char/adsprpc.c142
-rw-r--r--drivers/char/adsprpc_compat.c4
-rw-r--r--drivers/char/diag/diagfwd_bridge.c14
-rw-r--r--drivers/clk/msm/clock-osm.c16
-rw-r--r--drivers/clk/qcom/clk-rcg2.c12
-rw-r--r--drivers/clk/qcom/mmcc-sdm660.c3
-rw-r--r--drivers/crypto/msm/ota_crypto.c6
-rw-r--r--drivers/crypto/msm/qce50.c5
-rw-r--r--drivers/crypto/msm/qcedev.c4
-rw-r--r--drivers/crypto/msm/qcrypto.c6
-rw-r--r--drivers/gpio/Kconfig23
-rw-r--r--drivers/gpio/qpnp-pin.c72
-rw-r--r--drivers/gpu/msm/adreno_a5xx.c3
-rw-r--r--drivers/gpu/msm/kgsl_pwrscale.c16
-rw-r--r--drivers/iio/adc/qcom-rradc.c94
-rw-r--r--drivers/iio/adc/qcom-tadc.c587
-rw-r--r--drivers/iio/inkern.c18
-rw-r--r--drivers/leds/Kconfig69
-rw-r--r--drivers/leds/leds-qpnp-flash-v2.c7
-rw-r--r--drivers/leds/leds-qpnp-flash.c107
-rw-r--r--drivers/leds/leds-qpnp-wled.c50
-rw-r--r--drivers/leds/leds-qpnp.c217
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c24
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c9
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_base.c15
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_base.h2
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_core.c6
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_r1_pipe.c4
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_r1_wb.c2
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c13
-rw-r--r--drivers/media/platform/msm/vidc/msm_vdec.c16
-rw-r--r--drivers/media/platform/msm/vidc/msm_venc.c58
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc.c10
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_res_parse.c9
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_resources.h3
-rw-r--r--drivers/net/ethernet/msm/ecm_ipa.c269
-rw-r--r--drivers/net/wireless/ath/ath10k/Kconfig20
-rw-r--r--drivers/net/wireless/ath/ath10k/Makefile3
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c95
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h8
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.h5
-rw-r--r--drivers/platform/msm/Kconfig18
-rw-r--r--drivers/platform/msm/gsi/gsi.c10
-rw-r--r--drivers/platform/msm/gsi/gsi_reg.h4
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa.c2
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_i.h2
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_utils.c189
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c17
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h12
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h6
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c8
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h4
-rw-r--r--drivers/platform/msm/qpnp-coincell.c4
-rw-r--r--drivers/platform/msm/qpnp-revid.c4
-rw-r--r--drivers/power/power_supply_sysfs.c1
-rw-r--r--drivers/power/qcom/Kconfig12
-rw-r--r--drivers/power/qcom/apm.c80
-rw-r--r--drivers/power/reset/msm-poweroff.c3
-rw-r--r--drivers/power/supply/qcom/battery.c74
-rw-r--r--drivers/power/supply/qcom/fg-core.h9
-rw-r--r--drivers/power/supply/qcom/qpnp-fg-gen3.c337
-rw-r--r--drivers/power/supply/qcom/qpnp-qnovo.c46
-rw-r--r--drivers/power/supply/qcom/qpnp-smb2.c19
-rw-r--r--drivers/power/supply/qcom/smb-lib.c456
-rw-r--r--drivers/power/supply/qcom/smb-lib.h12
-rw-r--r--drivers/power/supply/qcom/smb-reg.h10
-rw-r--r--drivers/power/supply/qcom/smb138x-charger.c301
-rw-r--r--drivers/pwm/Kconfig13
-rw-r--r--drivers/pwm/pwm-qpnp.c143
-rw-r--r--drivers/regulator/Kconfig54
-rw-r--r--drivers/regulator/cpr3-hmss-regulator.c6
-rw-r--r--drivers/regulator/cpr3-mmss-regulator.c2
-rw-r--r--drivers/regulator/cpr3-regulator.c86
-rw-r--r--drivers/regulator/cpr3-regulator.h8
-rw-r--r--drivers/regulator/cpr4-apss-regulator.c4
-rw-r--r--drivers/regulator/cprh-kbss-regulator.c2
-rw-r--r--drivers/regulator/kryo-regulator.c18
-rw-r--r--drivers/regulator/mem-acc-regulator.c47
-rw-r--r--drivers/regulator/msm_gfx_ldo.c24
-rw-r--r--drivers/regulator/qpnp-labibb-regulator.c14
-rw-r--r--drivers/regulator/qpnp-lcdb-regulator.c6
-rw-r--r--drivers/regulator/qpnp-oledb-regulator.c2
-rw-r--r--drivers/regulator/qpnp-regulator.c49
-rw-r--r--drivers/rtc/Kconfig21
-rw-r--r--drivers/rtc/qpnp-rtc.c37
-rw-r--r--drivers/soc/qcom/Kconfig12
-rw-r--r--drivers/soc/qcom/glink_smem_native_xprt.c9
-rw-r--r--drivers/soc/qcom/glink_ssr.c3
-rw-r--r--drivers/soc/qcom/icnss.c22
-rw-r--r--drivers/soc/qcom/peripheral-loader.c8
-rw-r--r--drivers/soc/qcom/qdsp6v2/apr_tal_glink.c112
-rw-r--r--drivers/soc/qcom/qpnp-haptic.c125
-rw-r--r--drivers/soc/qcom/spcom.c20
-rw-r--r--drivers/thermal/Kconfig25
-rw-r--r--drivers/thermal/msm-tsens.c2
-rw-r--r--drivers/thermal/msm_lmh_dcvs.c21
-rw-r--r--drivers/thermal/qpnp-temp-alarm.c4
-rw-r--r--drivers/usb/dwc3/core.h2
-rw-r--r--drivers/usb/dwc3/debugfs.c5
-rw-r--r--drivers/usb/dwc3/ep0.c14
-rw-r--r--drivers/usb/dwc3/gadget.c7
-rw-r--r--drivers/usb/dwc3/gadget.h8
-rw-r--r--drivers/usb/dwc3/host.c6
-rw-r--r--drivers/usb/gadget/function/u_data_ipa.c1
-rw-r--r--drivers/usb/host/xhci-plat.c14
-rw-r--r--drivers/usb/pd/policy_engine.c55
-rw-r--r--drivers/video/fbdev/msm/mdp3_ctrl.c8
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.c166
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.h26
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_util.c47
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_util.h17
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.c18
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_tx.c201
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_tx.h4
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.c18
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_ctl.c15
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c32
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_video.c36
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c51
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_overlay.c6
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pipe.c10
-rw-r--r--drivers/video/fbdev/msm/mdss_panel.h5
-rw-r--r--fs/jbd2/journal.c2
-rw-r--r--include/linux/iio/consumer.h10
-rw-r--r--include/linux/msm_ext_display.h5
-rw-r--r--include/linux/msm_gsi.h21
-rw-r--r--include/linux/power_supply.h1
-rw-r--r--include/linux/qdsp6v2/apr_tal.h3
-rw-r--r--include/linux/regulator/qpnp-regulator.h6
-rw-r--r--include/linux/sched/sysctl.h8
-rw-r--r--include/linux/usb/xhci_pdriver.h4
-rw-r--r--include/net/cfg80211.h15
-rw-r--r--include/sound/apr_audio-v2.h10
-rw-r--r--include/sound/cpe_core.h4
-rw-r--r--include/sound/q6adm-v2.h4
-rw-r--r--include/sound/q6lsm.h71
-rw-r--r--include/uapi/linux/v4l2-controls.h3
-rw-r--r--include/uapi/media/msm_vidc.h2
-rw-r--r--include/uapi/sound/lsm_params.h51
-rw-r--r--kernel/sched/boost.c9
-rw-r--r--kernel/sched/core.c10
-rw-r--r--kernel/sched/fair.c29
-rw-r--r--kernel/sched/hmp.c42
-rw-r--r--kernel/sched/rt.c20
-rw-r--r--kernel/sched/sched.h13
-rw-r--r--kernel/sysctl.c5
-rw-r--r--net/core/skbuff.c3
-rw-r--r--net/mac80211/pm.c2
-rw-r--r--net/wireless/ap.c4
-rw-r--r--net/wireless/core.c121
-rw-r--r--net/wireless/core.h10
-rw-r--r--net/wireless/mesh.c4
-rw-r--r--net/wireless/rdev-ops.h7
-rw-r--r--net/wireless/sysfs.c11
-rw-r--r--net/wireless/trace.h16
-rw-r--r--net/wireless/util.c5
-rw-r--r--sound/core/pcm_lib.c3
-rw-r--r--sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c76
-rw-r--r--sound/soc/codecs/wcd-dsp-mgr.c45
-rw-r--r--sound/soc/codecs/wcd-mbhc-v2.c8
-rw-r--r--sound/soc/codecs/wcd-spi.c141
-rw-r--r--sound/soc/codecs/wcd934x/wcd934x-routing.h16
-rw-r--r--sound/soc/codecs/wcd934x/wcd934x.c280
-rw-r--r--sound/soc/codecs/wcd_cpe_core.c26
-rw-r--r--sound/soc/msm/msm-cpe-lsm.c252
-rw-r--r--sound/soc/msm/msm-dai-fe.c82
-rw-r--r--sound/soc/msm/msm8998.c4
-rw-r--r--sound/soc/msm/qdsp6v2/audio_cal_utils.c4
-rw-r--r--sound/soc/msm/qdsp6v2/msm-lsm-client.c523
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c2735
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h9
-rw-r--r--sound/soc/msm/qdsp6v2/q6adm.c63
-rw-r--r--sound/soc/msm/qdsp6v2/q6afe.c70
-rw-r--r--sound/soc/msm/qdsp6v2/q6asm.c18
-rw-r--r--sound/soc/msm/qdsp6v2/q6lsm.c293
-rw-r--r--sound/soc/msm/qdsp6v2/q6voice.c6
-rw-r--r--sound/soc/msm/sdm660-internal.c5
229 files changed, 9443 insertions, 3558 deletions
diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt b/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt
index 7cf6871894dc..38c9fe749abb 100644
--- a/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt
+++ b/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt
@@ -282,6 +282,16 @@ Properties:
performance mode with a total of 4 tuples corresponding
to each supported performance mode.
+- qcom,pwrcl-apcs-mem-acc-threshold-voltage
+ Usage: optional
+ Value type: <u32>
+ Definition: Specifies the highest MEM ACC threshold voltage in
+ microvolts for the Power cluster. This voltage is
+ used to determine which MEM ACC setting is used for the
+ highest frequencies. If specified, the voltage must match
+ the MEM ACC threshold voltage specified for the
+ corresponding CPRh device.
+
- qcom,perfcl-apcs-mem-acc-val
Usage: required if qcom,osm-no-tz is specified
Value type: <prop-encoded-array>
diff --git a/Documentation/devicetree/bindings/fb/mdss-dp.txt b/Documentation/devicetree/bindings/fb/mdss-dp.txt
index 27516d3b54a5..7bf7b9bacb60 100644
--- a/Documentation/devicetree/bindings/fb/mdss-dp.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-dp.txt
@@ -27,6 +27,7 @@ Required properties
- qcom,aux-en-gpio: Specifies the aux-channel enable gpio.
- qcom,aux-sel-gpio: Specifies the aux-channel select gpio.
- qcom,usbplug-cc-gpio: Specifies the usbplug orientation gpio.
+- qcom,aux-cfg-settings: An array that specifies the DP AUX configuration settings.
Optional properties:
- qcom,<type>-supply-entries: A node that lists the elements of the supply used by the
@@ -51,6 +52,8 @@ Optional properties:
- pinctrl-<0..n>: Lists phandles each pointing to the pin configuration node within a pin
controller. These pin configurations are installed in the pinctrl
device node. Refer to pinctrl-bindings.txt
+- qcom,logical2physical-lane-map: An array that specifies the DP logical to physical lane map setting.
+- qcom,phy-register-offset: An integer specifying the offset value of DP PHY register space.
Example:
mdss_dp_ctrl: qcom,dp_ctrl@c990000 {
@@ -83,6 +86,10 @@ Example:
"core_aux_clk", "core_cfg_ahb_clk", "ctrl_link_clk",
"ctrl_link_iface_clk", "ctrl_crypto_clk", "ctrl_pixel_clk";
+ qcom,aux-cfg-settings = [00 13 00 10 0a 26 0a 03 8b 03];
+ qcom,logical2physical-lane-map = [02 03 01 00];
+ qcom,phy-register-offset = <0x4>;
+
qcom,core-supply-entries {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/Documentation/devicetree/bindings/leds/leds-qpnp.txt b/Documentation/devicetree/bindings/leds/leds-qpnp.txt
index 4564bfff3996..85e097586466 100644
--- a/Documentation/devicetree/bindings/leds/leds-qpnp.txt
+++ b/Documentation/devicetree/bindings/leds/leds-qpnp.txt
@@ -1,10 +1,10 @@
-Qualcomm QPNP Leds
+Qualcomm Technologies, Inc. QPNP LEDs
-QPNP (Qualcomm Plug N Play) LEDs driver is used for
-controlling LEDs that are part of PMIC on Qualcomm reference
-platforms. The PMIC is connected to Host processor via
-SPMI bus. This driver supports various LED modules such as
-Keypad backlight, WLED (white LED), RGB LED and flash LED.
+Qualcomm Technologies, Inc. Plug N Play (QPNP) LED modules
+are used for controlling LEDs that are connected to a QPNP PMIC.
+The PMIC is connected to a host processor via the SPMI bus. Various
+LED modules are supported such as Keypad backlight, WLED (white LED),
+RGB LED and flash LED.
Each LED module is represented as a node of "leds-qpnp". This
node will further contain the type of LED supported and its
@@ -83,7 +83,7 @@ Optional properties for RGB led:
- qcom,turn-off-delay-ms: delay in millisecond for turning off the led when its default-state is "on". Value is being ignored in case default-state is "off".
- qcom,use-blink: Use blink sysfs entry for switching into lpg mode. For optimal use, set default mode to pwm. All required lpg parameters must be supplied.
-MPP LED is an LED controled through a Multi Purpose Pin.
+MPP LED is an LED controlled through a Multi Purpose Pin.
Optional properties for MPP LED:
- linux,default-trigger: trigger the led from external modules such as display
diff --git a/Documentation/devicetree/bindings/media/video/msm-vidc.txt b/Documentation/devicetree/bindings/media/video/msm-vidc.txt
index 50b9b1ac8704..6ca0ac31a581 100644
--- a/Documentation/devicetree/bindings/media/video/msm-vidc.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-vidc.txt
@@ -132,6 +132,9 @@ value is typically max(latencies of every cluster at all power levels) + 1
memory, performance etc.
- qcom,debug-timeout = A bool indicating that FW errors such as SYS_ERROR,
SESSION_ERROR and timeouts will be treated as Fatal.
+- qcom,power-conf = Indicates the value at which or beyond, a video session
+ is configured in low power mode to have power benefits. Value is defined
+ interms of HxW of the video session beyond which power benefit is desired.
[Second level nodes]
Context Banks
@@ -226,6 +229,7 @@ Example:
qcom,qdss-presets = <0xFC307000 0x1000>,
<0xFC322000 0x1000>;
qcom,max-hw-load = <1224450>; /* 4k @ 30 + 1080p @ 30*/
+ qcom,power-conf = <8294400>; /* WxH - 3840*2160 */
qcom,never-unload-fw;
clock-names = "foo_clk", "bar_clk", "baz_clk";
qcom,clock-configs = <0x3 0x1 0x0>;
diff --git a/Documentation/devicetree/bindings/platform/msm/qpnp-coincell.txt b/Documentation/devicetree/bindings/platform/msm/qpnp-coincell.txt
index 10c1bbf3c604..4d55f0cecefe 100644
--- a/Documentation/devicetree/bindings/platform/msm/qpnp-coincell.txt
+++ b/Documentation/devicetree/bindings/platform/msm/qpnp-coincell.txt
@@ -1,4 +1,4 @@
-Qualcomm QPNP Coincell - coincell battery charger devices
+Qualcomm Technologies, Inc. QPNP Coincell - coincell battery charger devices
Required properties:
- compatible: Must be "qcom,qpnp-coincell".
diff --git a/Documentation/devicetree/bindings/power/apm.txt b/Documentation/devicetree/bindings/power/apm.txt
index 6cc53df11d02..fa03edfbb83c 100644
--- a/Documentation/devicetree/bindings/power/apm.txt
+++ b/Documentation/devicetree/bindings/power/apm.txt
@@ -7,7 +7,7 @@ SRAM minimum operating voltage, the APM controller can be used to request a
switch to a power supply that will guarantee logic state retention.
Required properties
-- compatible: "qcom,msm-apm", "qcom,msm8996pro-apm", "qcom,msmtitanium-apm"
+- compatible: "qcom,msm-apm", "qcom,msm8996pro-apm", "qcom,msm8953-apm"
- reg: Specifies physical base address and size of memory mapped regions
containing the APM controller, APCS CSR, APC PLL controller, and
SPM event registers.
@@ -23,16 +23,16 @@ Optional properties
completes.
- qcom,apm-post-halt-delay: The APM controller post halt delay counter value that SW needs
to program one time before starting the APM HW controller for
- msmtitanium target.
+ msm8953 target.
- qcom,apm-halt-clk-delay: The APM controller halt clock delay counter value that SW
needs to program one time before starting the APM HW controller
- for msmtitanium target.
+ for msm8953 target.
- qcom,apm-resume-clk-delay: The APM controller resume clock delay counter value that SW
needs to program one time before starting the APM HW controller
- for msmtitanium target.
+ for msm8953 target.
- qcom,apm-sel-switch-delay: The APM controller switch selection delay counter value that SW
needs to program one time before starting the APM HW controller
- for msmtitanium target.
+ for msm8953 target.
MSM APM Users
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
index 221657780178..8adfeebb1580 100644
--- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
+++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
@@ -99,10 +99,10 @@ First Level Node - FG Gen3 device
- qcom,fg-delta-soc-thr
Usage: optional
Value type: <u32>
- Definition: Percentage of monotonic SOC increase upon which the delta
- SOC interrupt will be triggered. If this property is not
- specified, then the default value will be 1. Possible
- values are in the range of 0 to 12.
+ Definition: Percentage of SOC increase upon which the delta monotonic &
+ battery SOC interrupts will be triggered. If this property
+ is not specified, then the default value will be 1.
+ Possible values are in the range of 0 to 12.
- qcom,fg-recharge-soc-thr
Usage: optional
@@ -156,12 +156,12 @@ First Level Node - FG Gen3 device
- qcom,cycle-counter-en
Usage: optional
- Value type: <bool>
+ Value type: <empty>
Definition: Enables the cycle counter feature.
- qcom,fg-force-load-profile
Usage: optional
- Value type: <bool>
+ Value type: <empty>
Definition: If set, battery profile will be force loaded if the profile
loaded earlier by bootloader doesn't match with the profile
available in the device tree.
@@ -229,13 +229,13 @@ First Level Node - FG Gen3 device
Definition: Battery temperature delta interrupt threshold. Possible
values are: 2, 4, 6 and 10. Unit is in Kelvin.
-- qcom,hold-soc-while-full:
+- qcom,hold-soc-while-full
Usage: optional
- Value type: <bool>
+ Value type: <empty>
Definition: A boolean property that when defined holds SOC at 100% when
the battery is full.
-- qcom,ki-coeff-soc-dischg:
+- qcom,ki-coeff-soc-dischg
Usage: optional
Value type: <prop-encoded-array>
Definition: Array of monotonic SOC threshold values to change the ki
@@ -243,7 +243,7 @@ First Level Node - FG Gen3 device
This should be defined in the ascending order and in the
range of 0-100. Array limit is set to 3.
-- qcom,ki-coeff-med-dischg:
+- qcom,ki-coeff-med-dischg
Usage: optional
Value type: <prop-encoded-array>
Definition: Array of ki coefficient values for medium discharge current
@@ -254,7 +254,7 @@ First Level Node - FG Gen3 device
is specified to make it fully functional. Value has no
unit. Allowed range is 0 to 62200 in micro units.
-- qcom,ki-coeff-hi-dischg:
+- qcom,ki-coeff-hi-dischg
Usage: optional
Value type: <prop-encoded-array>
Definition: Array of ki coefficient values for high discharge current
@@ -311,6 +311,15 @@ First Level Node - FG Gen3 device
148438 (14.84 %) will be used. Lowest possible value is
1954 (0.19 %).
+- qcom,fg-auto-recharge-soc
+ Usage: optional
+ Value type: <empty>
+ Definition: A boolean property when defined will configure automatic
+ recharge SOC threshold. If not specified, automatic
+ recharge voltage threshold will be configured. This has
+ to be configured in conjunction with the charger side
+ configuration for proper functionality.
+
==========================================================
Second Level Nodes - Peripherals managed by FG Gen3 driver
==========================================================
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt b/Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt
index 0244f910017a..c8f2a5a8e496 100644
--- a/Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt
+++ b/Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt
@@ -52,6 +52,18 @@ Charger specific properties:
Value type: <u32>
Definition: Specifies the DC input current limit in micro-amps.
+- qcom,charger-temp-max-mdegc
+ Usage: optional
+ Value type: <u32>
+ Definition: Specifies the maximum charger temperature in milli-degrees
+ Celsius. If unspecified a default of 80000 will be used.
+
+- qcom,connector-temp-max-mdegc
+ Usage: optional
+ Value type: <u32>
+ Definition: Specifies the maximum connector temperature in milli-degrees
+ Celsius. If unspecified a default value of 105000 will be used.
+
- io-channels
Usage: optional
Value type: List of <phandle u32>
diff --git a/Documentation/devicetree/bindings/regulator/mem-acc-regulator.txt b/Documentation/devicetree/bindings/regulator/mem-acc-regulator.txt
index d217a4ea9fc8..55154579840a 100644
--- a/Documentation/devicetree/bindings/regulator/mem-acc-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/mem-acc-regulator.txt
@@ -1,4 +1,4 @@
-Qualcomm Technologies Memory Accelerator
+Qualcomm Technologies, Inc. Memory Accelerator
Memory accelerator configures the power-mode (corner) for the
accelerator.
diff --git a/Documentation/devicetree/bindings/regulator/qpnp-regulator.txt b/Documentation/devicetree/bindings/regulator/qpnp-regulator.txt
index e1ebaf636ec3..601903bc60de 100644
--- a/Documentation/devicetree/bindings/regulator/qpnp-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/qpnp-regulator.txt
@@ -1,4 +1,4 @@
-Qualcomm QPNP Regulators
+Qualcomm Technologies, Inc. QPNP Regulators
qpnp-regulator is a regulator driver which supports regulators inside of PMICs
that utilize the MSM SPMI implementation.
diff --git a/Documentation/devicetree/bindings/thermal/qpnp-temp-alarm.txt b/Documentation/devicetree/bindings/thermal/qpnp-temp-alarm.txt
index 545cdedeca4c..bb20644afde6 100644
--- a/Documentation/devicetree/bindings/thermal/qpnp-temp-alarm.txt
+++ b/Documentation/devicetree/bindings/thermal/qpnp-temp-alarm.txt
@@ -1,8 +1,9 @@
-Qualcomm QPNP Temperature Alarm
+Qualcomm Technologies, Inc. QPNP Temperature Alarm
-QPNP temperature alarm peripherals are found inside of Qualcomm PMIC chips that
-utilize the MSM SPMI implementation. These peripherals provide an interrupt
-signal and status register to identify high PMIC die temperature.
+QPNP temperature alarm peripherals are found inside of Qualcomm Technologies,
+Inc. PMIC chips that utilize the MSM SPMI implementation. These peripherals
+provide an interrupt signal and status register to identify high PMIC die
+temperature.
Required properties:
- compatible: Must be "qcom,qpnp-temp-alarm".
diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
index 3136687adb57..ddca4c39e2de 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -60,6 +60,7 @@ Optional properties:
- snps,num-normal-evt-buffs: If present, specifies number of normal event buffers. Default is 1.
- snps,num-gsi-evt-buffs: If present, specifies number of GSI based hardware accelerated event buffers.
1 event buffer is needed per h/w accelerated endpoint.
+ - xhci-imod-value: Interrupt moderation interval for host mode (in increments of 250nsec).
This is usually a subnode to DWC3 glue to which it is connected.
@@ -74,4 +75,5 @@ dwc3@4a030000 {
tx-fifo-resize;
snps,usb3-u1u2-disable;
snps,num-gsi-evt-buffs = <0x2>;
+ xhci-imod-value = <4000>;
};
diff --git a/Documentation/devicetree/bindings/usb/qpnp-pdphy.txt b/Documentation/devicetree/bindings/usb/qpnp-pdphy.txt
index f3c3163f0a3f..cf0628a26c5a 100644
--- a/Documentation/devicetree/bindings/usb/qpnp-pdphy.txt
+++ b/Documentation/devicetree/bindings/usb/qpnp-pdphy.txt
@@ -43,6 +43,9 @@ Optional properties:
- qcom,vconn-uses-external-source: Indicates whether VCONN supply is sourced
from an external regulator. If omitted, then it is
assumed it is connected to VBUS.
+- qcom,default-sink-caps: List of 32-bit values representing the nominal sink
+ capabilities in voltage (millivolts) and current
+ (milliamps) pairs.
Example:
qcom,qpnp-pdphy@1700 {
@@ -64,4 +67,8 @@ Example:
"msg-tx-failed",
"msg-tx-discarded",
"msg-rx-discarded";
+
+ qcom,default-sink-caps = <5000 3000>, /* 5V @ 3A */
+ <9000 3000>, /* 9V @ 3A */
+ <12000 2250>; /* 12V @ 2.25A */
};
diff --git a/arch/arm/boot/dts/qcom/apq8998-v2.1-mediabox.dts b/arch/arm/boot/dts/qcom/apq8998-v2.1-mediabox.dts
index bc18fb54400f..78fdba4fdb9b 100644
--- a/arch/arm/boot/dts/qcom/apq8998-v2.1-mediabox.dts
+++ b/arch/arm/boot/dts/qcom/apq8998-v2.1-mediabox.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -25,6 +25,10 @@
status = "disabled";
};
+&msm_ath10k_wlan {
+ status = "enabled";
+};
+
&mdss_mdp {
qcom,mdss-pref-prim-intf = "hdmi";
};
diff --git a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dualmipi-wqxga-video.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dualmipi-wqxga-video.dtsi
index f7122d34d8a9..5971a3d1025e 100644
--- a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dualmipi-wqxga-video.dtsi
+++ b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-dualmipi-wqxga-video.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -27,7 +27,7 @@
qcom,mdss-dsi-v-front-porch = <8>;
qcom,mdss-dsi-v-pulse-width = <1>;
qcom,mdss-dsi-bpp = <24>;
- qcom,mdss-dsi-underflow-color = <0xff>;
+ qcom,mdss-dsi-underflow-color = <0x3ff>;
qcom,mdss-dsi-border-color = <0>;
qcom,mdss-dsi-panel-hdr-enabled;
qcom,mdss-dsi-panel-hdr-color-primaries = <14500 15500 32000
diff --git a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-cmd.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-cmd.dtsi
index 89bf222231fb..39d3db3067e6 100644
--- a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-cmd.dtsi
+++ b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-cmd.dtsi
@@ -37,162 +37,162 @@
qcom,mdss-dsi-border-color = <0>;
qcom,mdss-dsi-on-command = [
/* CMD2_P0 */
- 15 01 00 00 10 00 02 ff 20
- 15 01 00 00 10 00 02 fb 01
- 15 01 00 00 10 00 02 00 01
- 15 01 00 00 10 00 02 01 55
- 15 01 00 00 10 00 02 02 45
- 15 01 00 00 10 00 02 05 40
- 15 01 00 00 10 00 02 06 19
- 15 01 00 00 10 00 02 07 1e
- 15 01 00 00 10 00 02 0b 73
- 15 01 00 00 10 00 02 0c 73
- 15 01 00 00 10 00 02 0e b0
- 15 01 00 00 10 00 02 0f ae
- 15 01 00 00 10 00 02 11 b8
- 15 01 00 00 10 00 02 13 00
- 15 01 00 00 10 00 02 58 80
- 15 01 00 00 10 00 02 59 01
- 15 01 00 00 10 00 02 5a 00
- 15 01 00 00 10 00 02 5b 01
- 15 01 00 00 10 00 02 5c 80
- 15 01 00 00 10 00 02 5d 81
- 15 01 00 00 10 00 02 5e 00
- 15 01 00 00 10 00 02 5f 01
- 15 01 00 00 10 00 02 72 31
- 15 01 00 00 10 00 02 68 03
+ 15 01 00 00 00 00 02 ff 20
+ 15 01 00 00 00 00 02 fb 01
+ 15 01 00 00 00 00 02 00 01
+ 15 01 00 00 00 00 02 01 55
+ 15 01 00 00 00 00 02 02 45
+ 15 01 00 00 00 00 02 05 40
+ 15 01 00 00 00 00 02 06 19
+ 15 01 00 00 00 00 02 07 1e
+ 15 01 00 00 00 00 02 0b 73
+ 15 01 00 00 00 00 02 0c 73
+ 15 01 00 00 00 00 02 0e b0
+ 15 01 00 00 00 00 02 0f ae
+ 15 01 00 00 00 00 02 11 b8
+ 15 01 00 00 00 00 02 13 00
+ 15 01 00 00 00 00 02 58 80
+ 15 01 00 00 00 00 02 59 01
+ 15 01 00 00 00 00 02 5a 00
+ 15 01 00 00 00 00 02 5b 01
+ 15 01 00 00 00 00 02 5c 80
+ 15 01 00 00 00 00 02 5d 81
+ 15 01 00 00 00 00 02 5e 00
+ 15 01 00 00 00 00 02 5f 01
+ 15 01 00 00 00 00 02 72 31
+ 15 01 00 00 00 00 02 68 03
/* CMD2_P4 */
- 15 01 00 00 10 00 02 ff 24
- 15 01 00 00 10 00 02 fb 01
- 15 01 00 00 10 00 02 00 1c
- 15 01 00 00 10 00 02 01 0b
- 15 01 00 00 10 00 02 02 0c
- 15 01 00 00 10 00 02 03 01
- 15 01 00 00 10 00 02 04 0f
- 15 01 00 00 10 00 02 05 10
- 15 01 00 00 10 00 02 06 10
- 15 01 00 00 10 00 02 07 10
- 15 01 00 00 10 00 02 08 89
- 15 01 00 00 10 00 02 09 8a
- 15 01 00 00 10 00 02 0a 13
- 15 01 00 00 10 00 02 0b 13
- 15 01 00 00 10 00 02 0c 15
- 15 01 00 00 10 00 02 0d 15
- 15 01 00 00 10 00 02 0e 17
- 15 01 00 00 10 00 02 0f 17
- 15 01 00 00 10 00 02 10 1c
- 15 01 00 00 10 00 02 11 0b
- 15 01 00 00 10 00 02 12 0c
- 15 01 00 00 10 00 02 13 01
- 15 01 00 00 10 00 02 14 0f
- 15 01 00 00 10 00 02 15 10
- 15 01 00 00 10 00 02 16 10
- 15 01 00 00 10 00 02 17 10
- 15 01 00 00 10 00 02 18 89
- 15 01 00 00 10 00 02 19 8a
- 15 01 00 00 10 00 02 1a 13
- 15 01 00 00 10 00 02 1b 13
- 15 01 00 00 10 00 02 1c 15
- 15 01 00 00 10 00 02 1d 15
- 15 01 00 00 10 00 02 1e 17
- 15 01 00 00 10 00 02 1f 17
+ 15 01 00 00 00 00 02 ff 24
+ 15 01 00 00 00 00 02 fb 01
+ 15 01 00 00 00 00 02 00 1c
+ 15 01 00 00 00 00 02 01 0b
+ 15 01 00 00 00 00 02 02 0c
+ 15 01 00 00 00 00 02 03 01
+ 15 01 00 00 00 00 02 04 0f
+ 15 01 00 00 00 00 02 05 10
+ 15 01 00 00 00 00 02 06 10
+ 15 01 00 00 00 00 02 07 10
+ 15 01 00 00 00 00 02 08 89
+ 15 01 00 00 00 00 02 09 8a
+ 15 01 00 00 00 00 02 0a 13
+ 15 01 00 00 00 00 02 0b 13
+ 15 01 00 00 00 00 02 0c 15
+ 15 01 00 00 00 00 02 0d 15
+ 15 01 00 00 00 00 02 0e 17
+ 15 01 00 00 00 00 02 0f 17
+ 15 01 00 00 00 00 02 10 1c
+ 15 01 00 00 00 00 02 11 0b
+ 15 01 00 00 00 00 02 12 0c
+ 15 01 00 00 00 00 02 13 01
+ 15 01 00 00 00 00 02 14 0f
+ 15 01 00 00 00 00 02 15 10
+ 15 01 00 00 00 00 02 16 10
+ 15 01 00 00 00 00 02 17 10
+ 15 01 00 00 00 00 02 18 89
+ 15 01 00 00 00 00 02 19 8a
+ 15 01 00 00 00 00 02 1a 13
+ 15 01 00 00 00 00 02 1b 13
+ 15 01 00 00 00 00 02 1c 15
+ 15 01 00 00 00 00 02 1d 15
+ 15 01 00 00 00 00 02 1e 17
+ 15 01 00 00 00 00 02 1f 17
/* STV */
- 15 01 00 00 10 00 02 20 40
- 15 01 00 00 10 00 02 21 01
- 15 01 00 00 10 00 02 22 00
- 15 01 00 00 10 00 02 23 40
- 15 01 00 00 10 00 02 24 40
- 15 01 00 00 10 00 02 25 6d
- 15 01 00 00 10 00 02 26 40
- 15 01 00 00 10 00 02 27 40
+ 15 01 00 00 00 00 02 20 40
+ 15 01 00 00 00 00 02 21 01
+ 15 01 00 00 00 00 02 22 00
+ 15 01 00 00 00 00 02 23 40
+ 15 01 00 00 00 00 02 24 40
+ 15 01 00 00 00 00 02 25 6d
+ 15 01 00 00 00 00 02 26 40
+ 15 01 00 00 00 00 02 27 40
/* Vend */
- 15 01 00 00 10 00 02 e0 00
- 15 01 00 00 10 00 02 dc 21
- 15 01 00 00 10 00 02 dd 22
- 15 01 00 00 10 00 02 de 07
- 15 01 00 00 10 00 02 df 07
- 15 01 00 00 10 00 02 e3 6D
- 15 01 00 00 10 00 02 e1 07
- 15 01 00 00 10 00 02 e2 07
+ 15 01 00 00 00 00 02 e0 00
+ 15 01 00 00 00 00 02 dc 21
+ 15 01 00 00 00 00 02 dd 22
+ 15 01 00 00 00 00 02 de 07
+ 15 01 00 00 00 00 02 df 07
+ 15 01 00 00 00 00 02 e3 6D
+ 15 01 00 00 00 00 02 e1 07
+ 15 01 00 00 00 00 02 e2 07
/* UD */
- 15 01 00 00 10 00 02 29 d8
- 15 01 00 00 10 00 02 2a 2a
+ 15 01 00 00 00 00 02 29 d8
+ 15 01 00 00 00 00 02 2a 2a
/* CLK */
- 15 01 00 00 10 00 02 4b 03
- 15 01 00 00 10 00 02 4c 11
- 15 01 00 00 10 00 02 4d 10
- 15 01 00 00 10 00 02 4e 01
- 15 01 00 00 10 00 02 4f 01
- 15 01 00 00 10 00 02 50 10
- 15 01 00 00 10 00 02 51 00
- 15 01 00 00 10 00 02 52 80
- 15 01 00 00 10 00 02 53 00
- 15 01 00 00 10 00 02 56 00
- 15 01 00 00 10 00 02 54 07
- 15 01 00 00 10 00 02 58 07
- 15 01 00 00 10 00 02 55 25
+ 15 01 00 00 00 00 02 4b 03
+ 15 01 00 00 00 00 02 4c 11
+ 15 01 00 00 00 00 02 4d 10
+ 15 01 00 00 00 00 02 4e 01
+ 15 01 00 00 00 00 02 4f 01
+ 15 01 00 00 00 00 02 50 10
+ 15 01 00 00 00 00 02 51 00
+ 15 01 00 00 00 00 02 52 80
+ 15 01 00 00 00 00 02 53 00
+ 15 01 00 00 00 00 02 56 00
+ 15 01 00 00 00 00 02 54 07
+ 15 01 00 00 00 00 02 58 07
+ 15 01 00 00 00 00 02 55 25
/* Reset XDONB */
- 15 01 00 00 10 00 02 5b 43
- 15 01 00 00 10 00 02 5c 00
- 15 01 00 00 10 00 02 5f 73
- 15 01 00 00 10 00 02 60 73
- 15 01 00 00 10 00 02 63 22
- 15 01 00 00 10 00 02 64 00
- 15 01 00 00 10 00 02 67 08
- 15 01 00 00 10 00 02 68 04
+ 15 01 00 00 00 00 02 5b 43
+ 15 01 00 00 00 00 02 5c 00
+ 15 01 00 00 00 00 02 5f 73
+ 15 01 00 00 00 00 02 60 73
+ 15 01 00 00 00 00 02 63 22
+ 15 01 00 00 00 00 02 64 00
+ 15 01 00 00 00 00 02 67 08
+ 15 01 00 00 00 00 02 68 04
/* Resolution:1440x2560*/
- 15 01 00 00 10 00 02 72 02
+ 15 01 00 00 00 00 02 72 02
/* mux */
- 15 01 00 00 10 00 02 7a 80
- 15 01 00 00 10 00 02 7b 91
- 15 01 00 00 10 00 02 7c D8
- 15 01 00 00 10 00 02 7d 60
- 15 01 00 00 10 00 02 7f 15
- 15 01 00 00 10 00 02 75 15
+ 15 01 00 00 00 00 02 7a 80
+ 15 01 00 00 00 00 02 7b 91
+ 15 01 00 00 00 00 02 7c D8
+ 15 01 00 00 00 00 02 7d 60
+ 15 01 00 00 00 00 02 7f 15
+ 15 01 00 00 00 00 02 75 15
/* ABOFF */
- 15 01 00 00 10 00 02 b3 C0
- 15 01 00 00 10 00 02 b4 00
- 15 01 00 00 10 00 02 b5 00
+ 15 01 00 00 00 00 02 b3 C0
+ 15 01 00 00 00 00 02 b4 00
+ 15 01 00 00 00 00 02 b5 00
/* Source EQ */
- 15 01 00 00 10 00 02 78 00
- 15 01 00 00 10 00 02 79 00
- 15 01 00 00 10 00 02 80 00
- 15 01 00 00 10 00 02 83 00
+ 15 01 00 00 00 00 02 78 00
+ 15 01 00 00 00 00 02 79 00
+ 15 01 00 00 00 00 02 80 00
+ 15 01 00 00 00 00 02 83 00
/* FP BP */
- 15 01 00 00 10 00 02 93 0a
- 15 01 00 00 10 00 02 94 0a
+ 15 01 00 00 00 00 02 93 0a
+ 15 01 00 00 00 00 02 94 0a
/* Inversion Type */
- 15 01 00 00 10 00 02 8a 00
- 15 01 00 00 10 00 02 9b ff
+ 15 01 00 00 00 00 02 8a 00
+ 15 01 00 00 00 00 02 9b ff
/* IMGSWAP =1 @PortSwap=1 */
- 15 01 00 00 10 00 02 9d b0
- 15 01 00 00 10 00 02 9f 63
- 15 01 00 00 10 00 02 98 10
+ 15 01 00 00 00 00 02 9d b0
+ 15 01 00 00 00 00 02 9f 63
+ 15 01 00 00 00 00 02 98 10
/* FRM */
- 15 01 00 00 10 00 02 ec 00
+ 15 01 00 00 00 00 02 ec 00
/* CMD1 */
- 15 01 00 00 10 00 02 ff 10
+ 15 01 00 00 00 00 02 ff 10
/* VESA DSC PPS settings(1440x2560 slide 16H) */
- 39 01 00 00 10 00 11 c1 09 20 00 10 02 00 02 68
+ 39 01 00 00 00 00 11 c1 09 20 00 10 02 00 02 68
01 bb 00 0a 06 67 04 c5
- 39 01 00 00 10 00 03 c2 10 f0
+ 39 01 00 00 00 00 03 c2 10 f0
/* C0h = 0x0(2 Port SDC)0x01(1 PortA FBC)
* 0x02(MTK) 0x03(1 PortA VESA)
*/
- 15 01 00 00 10 00 02 c0 03
+ 15 01 00 00 00 00 02 c0 03
/* VBP+VSA=,VFP = 10H */
- 15 01 00 00 10 00 04 3b 03 0a 0a
+ 15 01 00 00 00 00 04 3b 03 0a 0a
/* FTE on */
- 15 01 00 00 10 00 02 35 00
+ 15 01 00 00 00 00 02 35 00
/* EN_BK =1(auto black) */
- 15 01 00 00 10 00 02 e5 01
+ 15 01 00 00 00 00 02 e5 01
/* CMD mode(10) VDO mode(03) */
- 15 01 00 00 10 00 02 bb 10
+ 15 01 00 00 00 00 02 bb 10
/* Non Reload MTP */
- 15 01 00 00 10 00 02 fb 01
+ 15 01 00 00 00 00 02 fb 01
/* SlpOut + DispOn */
- 05 01 00 00 a0 00 02 11 00
- 05 01 00 00 a0 00 02 29 00
+ 05 01 00 00 78 00 02 11 00
+ 05 01 00 00 78 00 02 29 00
];
qcom,mdss-dsi-off-command = [05 01 00 00 78 00 02 28 00
05 01 00 00 78 00 02 10 00];
diff --git a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-video.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-video.dtsi
index ca2ff6eb4924..353b3b2b09bd 100644
--- a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-video.dtsi
+++ b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-video.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -32,162 +32,162 @@
qcom,mdss-dsi-border-color = <0>;
qcom,mdss-dsi-on-command = [
/* CMD2_P0 */
- 15 01 00 00 10 00 02 ff 20
- 15 01 00 00 10 00 02 fb 01
- 15 01 00 00 10 00 02 00 01
- 15 01 00 00 10 00 02 01 55
- 15 01 00 00 10 00 02 02 45
- 15 01 00 00 10 00 02 05 40
- 15 01 00 00 10 00 02 06 19
- 15 01 00 00 10 00 02 07 1e
- 15 01 00 00 10 00 02 0b 73
- 15 01 00 00 10 00 02 0c 73
- 15 01 00 00 10 00 02 0e b0
- 15 01 00 00 10 00 02 0f aE
- 15 01 00 00 10 00 02 11 b8
- 15 01 00 00 10 00 02 13 00
- 15 01 00 00 10 00 02 58 80
- 15 01 00 00 10 00 02 59 01
- 15 01 00 00 10 00 02 5a 00
- 15 01 00 00 10 00 02 5b 01
- 15 01 00 00 10 00 02 5c 80
- 15 01 00 00 10 00 02 5d 81
- 15 01 00 00 10 00 02 5e 00
- 15 01 00 00 10 00 02 5f 01
- 15 01 00 00 10 00 02 72 31
- 15 01 00 00 10 00 02 68 03
+ 15 01 00 00 00 00 02 ff 20
+ 15 01 00 00 00 00 02 fb 01
+ 15 01 00 00 00 00 02 00 01
+ 15 01 00 00 00 00 02 01 55
+ 15 01 00 00 00 00 02 02 45
+ 15 01 00 00 00 00 02 05 40
+ 15 01 00 00 00 00 02 06 19
+ 15 01 00 00 00 00 02 07 1e
+ 15 01 00 00 00 00 02 0b 73
+ 15 01 00 00 00 00 02 0c 73
+ 15 01 00 00 00 00 02 0e b0
+ 15 01 00 00 00 00 02 0f aE
+ 15 01 00 00 00 00 02 11 b8
+ 15 01 00 00 00 00 02 13 00
+ 15 01 00 00 00 00 02 58 80
+ 15 01 00 00 00 00 02 59 01
+ 15 01 00 00 00 00 02 5a 00
+ 15 01 00 00 00 00 02 5b 01
+ 15 01 00 00 00 00 02 5c 80
+ 15 01 00 00 00 00 02 5d 81
+ 15 01 00 00 00 00 02 5e 00
+ 15 01 00 00 00 00 02 5f 01
+ 15 01 00 00 00 00 02 72 31
+ 15 01 00 00 00 00 02 68 03
/* CMD2_P4 */
- 15 01 00 00 10 00 02 ff 24
- 15 01 00 00 10 00 02 fb 01
- 15 01 00 00 10 00 02 00 1c
- 15 01 00 00 10 00 02 01 0b
- 15 01 00 00 10 00 02 02 0c
- 15 01 00 00 10 00 02 03 01
- 15 01 00 00 10 00 02 04 0f
- 15 01 00 00 10 00 02 05 10
- 15 01 00 00 10 00 02 06 10
- 15 01 00 00 10 00 02 07 10
- 15 01 00 00 10 00 02 08 89
- 15 01 00 00 10 00 02 09 8a
- 15 01 00 00 10 00 02 0a 13
- 15 01 00 00 10 00 02 0b 13
- 15 01 00 00 10 00 02 0c 15
- 15 01 00 00 10 00 02 0d 15
- 15 01 00 00 10 00 02 0e 17
- 15 01 00 00 10 00 02 0f 17
- 15 01 00 00 10 00 02 10 1c
- 15 01 00 00 10 00 02 11 0b
- 15 01 00 00 10 00 02 12 0c
- 15 01 00 00 10 00 02 13 01
- 15 01 00 00 10 00 02 14 0f
- 15 01 00 00 10 00 02 15 10
- 15 01 00 00 10 00 02 16 10
- 15 01 00 00 10 00 02 17 10
- 15 01 00 00 10 00 02 18 89
- 15 01 00 00 10 00 02 19 8a
- 15 01 00 00 10 00 02 1a 13
- 15 01 00 00 10 00 02 1b 13
- 15 01 00 00 10 00 02 1c 15
- 15 01 00 00 10 00 02 1d 15
- 15 01 00 00 10 00 02 1e 17
- 15 01 00 00 10 00 02 1f 17
+ 15 01 00 00 00 00 02 ff 24
+ 15 01 00 00 00 00 02 fb 01
+ 15 01 00 00 00 00 02 00 1c
+ 15 01 00 00 00 00 02 01 0b
+ 15 01 00 00 00 00 02 02 0c
+ 15 01 00 00 00 00 02 03 01
+ 15 01 00 00 00 00 02 04 0f
+ 15 01 00 00 00 00 02 05 10
+ 15 01 00 00 00 00 02 06 10
+ 15 01 00 00 00 00 02 07 10
+ 15 01 00 00 00 00 02 08 89
+ 15 01 00 00 00 00 02 09 8a
+ 15 01 00 00 00 00 02 0a 13
+ 15 01 00 00 00 00 02 0b 13
+ 15 01 00 00 00 00 02 0c 15
+ 15 01 00 00 00 00 02 0d 15
+ 15 01 00 00 00 00 02 0e 17
+ 15 01 00 00 00 00 02 0f 17
+ 15 01 00 00 00 00 02 10 1c
+ 15 01 00 00 00 00 02 11 0b
+ 15 01 00 00 00 00 02 12 0c
+ 15 01 00 00 00 00 02 13 01
+ 15 01 00 00 00 00 02 14 0f
+ 15 01 00 00 00 00 02 15 10
+ 15 01 00 00 00 00 02 16 10
+ 15 01 00 00 00 00 02 17 10
+ 15 01 00 00 00 00 02 18 89
+ 15 01 00 00 00 00 02 19 8a
+ 15 01 00 00 00 00 02 1a 13
+ 15 01 00 00 00 00 02 1b 13
+ 15 01 00 00 00 00 02 1c 15
+ 15 01 00 00 00 00 02 1d 15
+ 15 01 00 00 00 00 02 1e 17
+ 15 01 00 00 00 00 02 1f 17
/* STV */
- 15 01 00 00 10 00 02 20 40
- 15 01 00 00 10 00 02 21 01
- 15 01 00 00 10 00 02 22 00
- 15 01 00 00 10 00 02 23 40
- 15 01 00 00 10 00 02 24 40
- 15 01 00 00 10 00 02 25 6d
- 15 01 00 00 10 00 02 26 40
- 15 01 00 00 10 00 02 27 40
+ 15 01 00 00 00 00 02 20 40
+ 15 01 00 00 00 00 02 21 01
+ 15 01 00 00 00 00 02 22 00
+ 15 01 00 00 00 00 02 23 40
+ 15 01 00 00 00 00 02 24 40
+ 15 01 00 00 00 00 02 25 6d
+ 15 01 00 00 00 00 02 26 40
+ 15 01 00 00 00 00 02 27 40
/* Vend */
- 15 01 00 00 10 00 02 e0 00
- 15 01 00 00 10 00 02 dc 21
- 15 01 00 00 10 00 02 dd 22
- 15 01 00 00 10 00 02 de 07
- 15 01 00 00 10 00 02 df 07
- 15 01 00 00 10 00 02 e3 6d
- 15 01 00 00 10 00 02 e1 07
- 15 01 00 00 10 00 02 e2 07
+ 15 01 00 00 00 00 02 e0 00
+ 15 01 00 00 00 00 02 dc 21
+ 15 01 00 00 00 00 02 dd 22
+ 15 01 00 00 00 00 02 de 07
+ 15 01 00 00 00 00 02 df 07
+ 15 01 00 00 00 00 02 e3 6d
+ 15 01 00 00 00 00 02 e1 07
+ 15 01 00 00 00 00 02 e2 07
/* UD */
- 15 01 00 00 10 00 02 29 d8
- 15 01 00 00 10 00 02 2a 2a
+ 15 01 00 00 00 00 02 29 d8
+ 15 01 00 00 00 00 02 2a 2a
/* CLK */
- 15 01 00 00 10 00 02 4b 03
- 15 01 00 00 10 00 02 4c 11
- 15 01 00 00 10 00 02 4d 10
- 15 01 00 00 10 00 02 4e 01
- 15 01 00 00 10 00 02 4f 01
- 15 01 00 00 10 00 02 50 10
- 15 01 00 00 10 00 02 51 00
- 15 01 00 00 10 00 02 52 80
- 15 01 00 00 10 00 02 53 00
- 15 01 00 00 10 00 02 56 00
- 15 01 00 00 10 00 02 54 07
- 15 01 00 00 10 00 02 58 07
- 15 01 00 00 10 00 02 55 25
+ 15 01 00 00 00 00 02 4b 03
+ 15 01 00 00 00 00 02 4c 11
+ 15 01 00 00 00 00 02 4d 10
+ 15 01 00 00 00 00 02 4e 01
+ 15 01 00 00 00 00 02 4f 01
+ 15 01 00 00 00 00 02 50 10
+ 15 01 00 00 00 00 02 51 00
+ 15 01 00 00 00 00 02 52 80
+ 15 01 00 00 00 00 02 53 00
+ 15 01 00 00 00 00 02 56 00
+ 15 01 00 00 00 00 02 54 07
+ 15 01 00 00 00 00 02 58 07
+ 15 01 00 00 00 00 02 55 25
/* Reset XDONB */
- 15 01 00 00 10 00 02 5b 43
- 15 01 00 00 10 00 02 5c 00
- 15 01 00 00 10 00 02 5f 73
- 15 01 00 00 10 00 02 60 73
- 15 01 00 00 10 00 02 63 22
- 15 01 00 00 10 00 02 64 00
- 15 01 00 00 10 00 02 67 08
- 15 01 00 00 10 00 02 68 04
+ 15 01 00 00 00 00 02 5b 43
+ 15 01 00 00 00 00 02 5c 00
+ 15 01 00 00 00 00 02 5f 73
+ 15 01 00 00 00 00 02 60 73
+ 15 01 00 00 00 00 02 63 22
+ 15 01 00 00 00 00 02 64 00
+ 15 01 00 00 00 00 02 67 08
+ 15 01 00 00 00 00 02 68 04
/* Resolution:1440x2560*/
- 15 01 00 00 10 00 02 72 02
+ 15 01 00 00 00 00 02 72 02
/* mux */
- 15 01 00 00 10 00 02 7a 80
- 15 01 00 00 10 00 02 7b 91
- 15 01 00 00 10 00 02 7c d8
- 15 01 00 00 10 00 02 7d 60
- 15 01 00 00 10 00 02 7f 15
- 15 01 00 00 10 00 02 75 15
+ 15 01 00 00 00 00 02 7a 80
+ 15 01 00 00 00 00 02 7b 91
+ 15 01 00 00 00 00 02 7c d8
+ 15 01 00 00 00 00 02 7d 60
+ 15 01 00 00 00 00 02 7f 15
+ 15 01 00 00 00 00 02 75 15
/* ABOFF */
- 15 01 00 00 10 00 02 b3 c0
- 15 01 00 00 10 00 02 b4 00
- 15 01 00 00 10 00 02 b5 00
+ 15 01 00 00 00 00 02 b3 c0
+ 15 01 00 00 00 00 02 b4 00
+ 15 01 00 00 00 00 02 b5 00
/* Source EQ */
- 15 01 00 00 10 00 02 78 00
- 15 01 00 00 10 00 02 79 00
- 15 01 00 00 10 00 02 80 00
- 15 01 00 00 10 00 02 83 00
+ 15 01 00 00 00 00 02 78 00
+ 15 01 00 00 00 00 02 79 00
+ 15 01 00 00 00 00 02 80 00
+ 15 01 00 00 00 00 02 83 00
/* FP BP */
- 15 01 00 00 10 00 02 93 0a
- 15 01 00 00 10 00 02 94 0a
+ 15 01 00 00 00 00 02 93 0a
+ 15 01 00 00 00 00 02 94 0a
/* Inversion Type */
- 15 01 00 00 10 00 02 8a 00
- 15 01 00 00 10 00 02 9b ff
+ 15 01 00 00 00 00 02 8a 00
+ 15 01 00 00 00 00 02 9b ff
/* IMGSWAP =1 @PortSwap=1 */
- 15 01 00 00 10 00 02 9d b0
- 15 01 00 00 10 00 02 9f 63
- 15 01 00 00 10 00 02 98 10
+ 15 01 00 00 00 00 02 9d b0
+ 15 01 00 00 00 00 02 9f 63
+ 15 01 00 00 00 00 02 98 10
/* FRM */
- 15 01 00 00 10 00 02 ec 00
+ 15 01 00 00 00 00 02 ec 00
/* CMD1 */
- 15 01 00 00 10 00 02 ff 10
+ 15 01 00 00 00 00 02 ff 10
/* VESA DSC PPS settings(1440x2560 slide 16H) */
- 39 01 00 00 10 00 11 c1 09 20 00 10 02 00 02 68 01
+ 39 01 00 00 00 00 11 c1 09 20 00 10 02 00 02 68 01
bb 00 0a 06 67 04 c5
- 39 01 00 00 10 00 03 c2 10 f0
+ 39 01 00 00 00 00 03 c2 10 f0
/* C0h = 0x00(2 Port SDC); 0x01(1 PortA FBC);
* 0x02(MTK); 0x03(1 PortA VESA)
*/
- 15 01 00 00 10 00 02 c0 03
+ 15 01 00 00 00 00 02 c0 03
/* VBP+VSA=,VFP = 10H */
- 39 01 00 00 10 00 04 3b 03 0a 0a
+ 39 01 00 00 00 00 04 3b 03 0a 0a
/* FTE on */
- 15 01 00 00 10 00 02 35 00
+ 15 01 00 00 00 00 02 35 00
/* EN_BK =1(auto black) */
- 15 01 00 00 10 00 02 e5 01
+ 15 01 00 00 00 00 02 e5 01
/* CMD mode(10) VDO mode(03) */
- 15 01 00 00 10 00 02 bb 03
+ 15 01 00 00 00 00 02 bb 03
/* Non Reload MTP */
- 15 01 00 00 10 00 02 fb 01
+ 15 01 00 00 00 00 02 fb 01
/* SlpOut + DispOn */
- 05 01 00 00 a0 00 02 11 00
- 05 01 00 00 a0 00 02 29 00
+ 05 01 00 00 78 00 02 11 00
+ 05 01 00 00 78 00 02 29 00
];
qcom,mdss-dsi-off-command = [05 01 00 00 78 00 02 28 00
05 01 00 00 78 00 02 10 00];
diff --git a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dualmipi-wqxga-cmd.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dualmipi-wqxga-cmd.dtsi
index 28b0d6d9cf14..6ff016676de7 100644
--- a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dualmipi-wqxga-cmd.dtsi
+++ b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dualmipi-wqxga-cmd.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -61,154 +61,154 @@
qcom,ulps-enabled;
qcom,mdss-dsi-on-command = [
/* CMD2_P0 */
- 15 01 00 00 10 00 02 FF 20
- 15 01 00 00 10 00 02 fb 01
- 15 01 00 00 10 00 02 00 01
- 15 01 00 00 10 00 02 01 55
- 15 01 00 00 10 00 02 02 45
- 15 01 00 00 10 00 02 05 40
- 15 01 00 00 10 00 02 06 19
- 15 01 00 00 10 00 02 07 1E
- 15 01 00 00 10 00 02 0B 73
- 15 01 00 00 10 00 02 0C 73
- 15 01 00 00 10 00 02 0E B0
- 15 01 00 00 10 00 02 0F AE
- 15 01 00 00 10 00 02 11 B8
- 15 01 00 00 10 00 02 13 00
- 15 01 00 00 10 00 02 58 80
- 15 01 00 00 10 00 02 59 01
- 15 01 00 00 10 00 02 5A 00
- 15 01 00 00 10 00 02 5B 01
- 15 01 00 00 10 00 02 5C 80
- 15 01 00 00 10 00 02 5D 81
- 15 01 00 00 10 00 02 5E 00
- 15 01 00 00 10 00 02 5F 01
- 15 01 00 00 10 00 02 72 31
- 15 01 00 00 10 00 02 68 03
+ 15 01 00 00 00 00 02 FF 20
+ 15 01 00 00 00 00 02 fb 01
+ 15 01 00 00 00 00 02 00 01
+ 15 01 00 00 00 00 02 01 55
+ 15 01 00 00 00 00 02 02 45
+ 15 01 00 00 00 00 02 05 40
+ 15 01 00 00 00 00 02 06 19
+ 15 01 00 00 00 00 02 07 1E
+ 15 01 00 00 00 00 02 0B 73
+ 15 01 00 00 00 00 02 0C 73
+ 15 01 00 00 00 00 02 0E B0
+ 15 01 00 00 00 00 02 0F AE
+ 15 01 00 00 00 00 02 11 B8
+ 15 01 00 00 00 00 02 13 00
+ 15 01 00 00 00 00 02 58 80
+ 15 01 00 00 00 00 02 59 01
+ 15 01 00 00 00 00 02 5A 00
+ 15 01 00 00 00 00 02 5B 01
+ 15 01 00 00 00 00 02 5C 80
+ 15 01 00 00 00 00 02 5D 81
+ 15 01 00 00 00 00 02 5E 00
+ 15 01 00 00 00 00 02 5F 01
+ 15 01 00 00 00 00 02 72 31
+ 15 01 00 00 00 00 02 68 03
/* CMD2_P4 */
- 15 01 00 00 10 00 02 ff 24
- 15 01 00 00 10 00 02 fb 01
- 15 01 00 00 10 00 02 00 1C
- 15 01 00 00 10 00 02 01 0B
- 15 01 00 00 10 00 02 02 0C
- 15 01 00 00 10 00 02 03 01
- 15 01 00 00 10 00 02 04 0F
- 15 01 00 00 10 00 02 05 10
- 15 01 00 00 10 00 02 06 10
- 15 01 00 00 10 00 02 07 10
- 15 01 00 00 10 00 02 08 89
- 15 01 00 00 10 00 02 09 8A
- 15 01 00 00 10 00 02 0A 13
- 15 01 00 00 10 00 02 0B 13
- 15 01 00 00 10 00 02 0C 15
- 15 01 00 00 10 00 02 0D 15
- 15 01 00 00 10 00 02 0E 17
- 15 01 00 00 10 00 02 0F 17
- 15 01 00 00 10 00 02 10 1C
- 15 01 00 00 10 00 02 11 0B
- 15 01 00 00 10 00 02 12 0C
- 15 01 00 00 10 00 02 13 01
- 15 01 00 00 10 00 02 14 0F
- 15 01 00 00 10 00 02 15 10
- 15 01 00 00 10 00 02 16 10
- 15 01 00 00 10 00 02 17 10
- 15 01 00 00 10 00 02 18 89
- 15 01 00 00 10 00 02 19 8A
- 15 01 00 00 10 00 02 1A 13
- 15 01 00 00 10 00 02 1B 13
- 15 01 00 00 10 00 02 1C 15
- 15 01 00 00 10 00 02 1D 15
- 15 01 00 00 10 00 02 1E 17
- 15 01 00 00 10 00 02 1F 17
+ 15 01 00 00 00 00 02 ff 24
+ 15 01 00 00 00 00 02 fb 01
+ 15 01 00 00 00 00 02 00 1C
+ 15 01 00 00 00 00 02 01 0B
+ 15 01 00 00 00 00 02 02 0C
+ 15 01 00 00 00 00 02 03 01
+ 15 01 00 00 00 00 02 04 0F
+ 15 01 00 00 00 00 02 05 10
+ 15 01 00 00 00 00 02 06 10
+ 15 01 00 00 00 00 02 07 10
+ 15 01 00 00 00 00 02 08 89
+ 15 01 00 00 00 00 02 09 8A
+ 15 01 00 00 00 00 02 0A 13
+ 15 01 00 00 00 00 02 0B 13
+ 15 01 00 00 00 00 02 0C 15
+ 15 01 00 00 00 00 02 0D 15
+ 15 01 00 00 00 00 02 0E 17
+ 15 01 00 00 00 00 02 0F 17
+ 15 01 00 00 00 00 02 10 1C
+ 15 01 00 00 00 00 02 11 0B
+ 15 01 00 00 00 00 02 12 0C
+ 15 01 00 00 00 00 02 13 01
+ 15 01 00 00 00 00 02 14 0F
+ 15 01 00 00 00 00 02 15 10
+ 15 01 00 00 00 00 02 16 10
+ 15 01 00 00 00 00 02 17 10
+ 15 01 00 00 00 00 02 18 89
+ 15 01 00 00 00 00 02 19 8A
+ 15 01 00 00 00 00 02 1A 13
+ 15 01 00 00 00 00 02 1B 13
+ 15 01 00 00 00 00 02 1C 15
+ 15 01 00 00 00 00 02 1D 15
+ 15 01 00 00 00 00 02 1E 17
+ 15 01 00 00 00 00 02 1F 17
/* STV */
- 15 01 00 00 10 00 02 20 40
- 15 01 00 00 10 00 02 21 01
- 15 01 00 00 10 00 02 22 00
- 15 01 00 00 10 00 02 23 40
- 15 01 00 00 10 00 02 24 40
- 15 01 00 00 10 00 02 25 6D
- 15 01 00 00 10 00 02 26 40
- 15 01 00 00 10 00 02 27 40
+ 15 01 00 00 00 00 02 20 40
+ 15 01 00 00 00 00 02 21 01
+ 15 01 00 00 00 00 02 22 00
+ 15 01 00 00 00 00 02 23 40
+ 15 01 00 00 00 00 02 24 40
+ 15 01 00 00 00 00 02 25 6D
+ 15 01 00 00 00 00 02 26 40
+ 15 01 00 00 00 00 02 27 40
/* Vend */
- 15 01 00 00 10 00 02 E0 00
- 15 01 00 00 10 00 02 DC 21
- 15 01 00 00 10 00 02 DD 22
- 15 01 00 00 10 00 02 DE 07
- 15 01 00 00 10 00 02 DF 07
- 15 01 00 00 10 00 02 E3 6D
- 15 01 00 00 10 00 02 E1 07
- 15 01 00 00 10 00 02 E2 07
+ 15 01 00 00 00 00 02 E0 00
+ 15 01 00 00 00 00 02 DC 21
+ 15 01 00 00 00 00 02 DD 22
+ 15 01 00 00 00 00 02 DE 07
+ 15 01 00 00 00 00 02 DF 07
+ 15 01 00 00 00 00 02 E3 6D
+ 15 01 00 00 00 00 02 E1 07
+ 15 01 00 00 00 00 02 E2 07
/* UD */
- 15 01 00 00 10 00 02 29 D8
- 15 01 00 00 10 00 02 2A 2A
+ 15 01 00 00 00 00 02 29 D8
+ 15 01 00 00 00 00 02 2A 2A
/* CLK */
- 15 01 00 00 10 00 02 4B 03
- 15 01 00 00 10 00 02 4C 11
- 15 01 00 00 10 00 02 4D 10
- 15 01 00 00 10 00 02 4E 01
- 15 01 00 00 10 00 02 4F 01
- 15 01 00 00 10 00 02 50 10
- 15 01 00 00 10 00 02 51 00
- 15 01 00 00 10 00 02 52 80
- 15 01 00 00 10 00 02 53 00
- 15 01 00 00 10 00 02 56 00
- 15 01 00 00 10 00 02 54 07
- 15 01 00 00 10 00 02 58 07
- 15 01 00 00 10 00 02 55 25
+ 15 01 00 00 00 00 02 4B 03
+ 15 01 00 00 00 00 02 4C 11
+ 15 01 00 00 00 00 02 4D 10
+ 15 01 00 00 00 00 02 4E 01
+ 15 01 00 00 00 00 02 4F 01
+ 15 01 00 00 00 00 02 50 10
+ 15 01 00 00 00 00 02 51 00
+ 15 01 00 00 00 00 02 52 80
+ 15 01 00 00 00 00 02 53 00
+ 15 01 00 00 00 00 02 56 00
+ 15 01 00 00 00 00 02 54 07
+ 15 01 00 00 00 00 02 58 07
+ 15 01 00 00 00 00 02 55 25
/* Reset XDONB */
- 15 01 00 00 10 00 02 5B 43
- 15 01 00 00 10 00 02 5C 00
- 15 01 00 00 10 00 02 5F 73
- 15 01 00 00 10 00 02 60 73
- 15 01 00 00 10 00 02 63 22
- 15 01 00 00 10 00 02 64 00
- 15 01 00 00 10 00 02 67 08
- 15 01 00 00 10 00 02 68 04
+ 15 01 00 00 00 00 02 5B 43
+ 15 01 00 00 00 00 02 5C 00
+ 15 01 00 00 00 00 02 5F 73
+ 15 01 00 00 00 00 02 60 73
+ 15 01 00 00 00 00 02 63 22
+ 15 01 00 00 00 00 02 64 00
+ 15 01 00 00 00 00 02 67 08
+ 15 01 00 00 00 00 02 68 04
/* Resolution:1440x2560*/
- 15 01 00 00 10 00 02 72 02
+ 15 01 00 00 00 00 02 72 02
/* mux */
- 15 01 00 00 10 00 02 7A 80
- 15 01 00 00 10 00 02 7B 91
- 15 01 00 00 10 00 02 7C D8
- 15 01 00 00 10 00 02 7D 60
- 15 01 00 00 10 00 02 7F 15
- 15 01 00 00 10 00 02 75 15
+ 15 01 00 00 00 00 02 7A 80
+ 15 01 00 00 00 00 02 7B 91
+ 15 01 00 00 00 00 02 7C D8
+ 15 01 00 00 00 00 02 7D 60
+ 15 01 00 00 00 00 02 7F 15
+ 15 01 00 00 00 00 02 75 15
/* ABOFF */
- 15 01 00 00 10 00 02 B3 C0
- 15 01 00 00 10 00 02 B4 00
- 15 01 00 00 10 00 02 B5 00
+ 15 01 00 00 00 00 02 B3 C0
+ 15 01 00 00 00 00 02 B4 00
+ 15 01 00 00 00 00 02 B5 00
/* Source EQ */
- 15 01 00 00 10 00 02 78 00
- 15 01 00 00 10 00 02 79 00
- 15 01 00 00 10 00 02 80 00
- 15 01 00 00 10 00 02 83 00
+ 15 01 00 00 00 00 02 78 00
+ 15 01 00 00 00 00 02 79 00
+ 15 01 00 00 00 00 02 80 00
+ 15 01 00 00 00 00 02 83 00
/* FP BP */
- 15 01 00 00 10 00 02 93 0A
- 15 01 00 00 10 00 02 94 0A
+ 15 01 00 00 00 00 02 93 0A
+ 15 01 00 00 00 00 02 94 0A
/* Inversion Type */
- 15 01 00 00 10 00 02 8A 00
- 15 01 00 00 10 00 02 9B FF
+ 15 01 00 00 00 00 02 8A 00
+ 15 01 00 00 00 00 02 9B FF
/* IMGSWAP =1 @PortSwap=1 */
- 15 01 00 00 10 00 02 9D B0
- 15 01 00 00 10 00 02 9F 63
- 15 01 00 00 10 00 02 98 10
+ 15 01 00 00 00 00 02 9D B0
+ 15 01 00 00 00 00 02 9F 63
+ 15 01 00 00 00 00 02 98 10
/* FRM */
- 15 01 00 00 10 00 02 EC 00
+ 15 01 00 00 00 00 02 EC 00
/* CMD1 */
- 15 01 00 00 10 00 02 ff 10
+ 15 01 00 00 00 00 02 ff 10
/* VBP+VSA=,VFP = 10H */
- 15 01 00 00 10 00 04 3B 03 0A 0A
+ 15 01 00 00 00 00 04 3B 03 0A 0A
/* FTE on */
- 15 01 00 00 10 00 02 35 00
+ 15 01 00 00 00 00 02 35 00
/* EN_BK =1(auto black) */
- 15 01 00 00 10 00 02 E5 01
+ 15 01 00 00 00 00 02 E5 01
/* CMD mode(10) VDO mode(03) */
- 15 01 00 00 10 00 02 BB 10
+ 15 01 00 00 00 00 02 BB 10
/* Non Reload MTP */
- 15 01 00 00 10 00 02 FB 01
+ 15 01 00 00 00 00 02 FB 01
/* SlpOut + DispOn */
- 05 01 00 00 a0 00 02 11 00
- 05 01 00 00 a0 00 02 29 00
+ 05 01 00 00 78 00 02 11 00
+ 05 01 00 00 78 00 02 29 00
];
qcom,mdss-dsi-off-command = [05 01 00 00 78 00 02 28 00
05 01 00 00 78 00 02 10 00];
diff --git a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dualmipi-wqxga-video.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dualmipi-wqxga-video.dtsi
index f2f77e3ed9cb..d179acd043ed 100644
--- a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dualmipi-wqxga-video.dtsi
+++ b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dualmipi-wqxga-video.dtsi
@@ -28,158 +28,158 @@
qcom,mdss-dsi-v-front-porch = <8>;
qcom,mdss-dsi-v-pulse-width = <1>;
qcom,mdss-dsi-bpp = <24>;
- qcom,mdss-dsi-underflow-color = <0xff>;
+ qcom,mdss-dsi-underflow-color = <0x3ff>;
qcom,mdss-dsi-border-color = <0>;
qcom,mdss-dsi-on-command = [
/* CMD2_P0 */
- 15 01 00 00 10 00 02 FF 20
- 15 01 00 00 10 00 02 FB 01
- 15 01 00 00 10 00 02 00 01
- 15 01 00 00 10 00 02 01 55
- 15 01 00 00 10 00 02 02 45
- 15 01 00 00 10 00 02 05 40
- 15 01 00 00 10 00 02 06 19
- 15 01 00 00 10 00 02 07 1E
- 15 01 00 00 10 00 02 0B 73
- 15 01 00 00 10 00 02 0C 73
- 15 01 00 00 10 00 02 0E B0
- 15 01 00 00 10 00 02 0F AE
- 15 01 00 00 10 00 02 11 B8
- 15 01 00 00 10 00 02 13 00
- 15 01 00 00 10 00 02 58 80
- 15 01 00 00 10 00 02 59 01
- 15 01 00 00 10 00 02 5A 00
- 15 01 00 00 10 00 02 5B 01
- 15 01 00 00 10 00 02 5C 80
- 15 01 00 00 10 00 02 5D 81
- 15 01 00 00 10 00 02 5E 00
- 15 01 00 00 10 00 02 5F 01
- 15 01 00 00 10 00 02 72 31
- 15 01 00 00 10 00 02 68 03
+ 15 01 00 00 00 00 02 FF 20
+ 15 01 00 00 00 00 02 FB 01
+ 15 01 00 00 00 00 02 00 01
+ 15 01 00 00 00 00 02 01 55
+ 15 01 00 00 00 00 02 02 45
+ 15 01 00 00 00 00 02 05 40
+ 15 01 00 00 00 00 02 06 19
+ 15 01 00 00 00 00 02 07 1E
+ 15 01 00 00 00 00 02 0B 73
+ 15 01 00 00 00 00 02 0C 73
+ 15 01 00 00 00 00 02 0E B0
+ 15 01 00 00 00 00 02 0F AE
+ 15 01 00 00 00 00 02 11 B8
+ 15 01 00 00 00 00 02 13 00
+ 15 01 00 00 00 00 02 58 80
+ 15 01 00 00 00 00 02 59 01
+ 15 01 00 00 00 00 02 5A 00
+ 15 01 00 00 00 00 02 5B 01
+ 15 01 00 00 00 00 02 5C 80
+ 15 01 00 00 00 00 02 5D 81
+ 15 01 00 00 00 00 02 5E 00
+ 15 01 00 00 00 00 02 5F 01
+ 15 01 00 00 00 00 02 72 31
+ 15 01 00 00 00 00 02 68 03
/* CMD2_P4 */
- 15 01 00 00 10 00 02 FF 24
- 15 01 00 00 10 00 02 FB 01
- 15 01 00 00 10 00 02 00 1C
- 15 01 00 00 10 00 02 01 0B
- 15 01 00 00 10 00 02 02 0C
- 15 01 00 00 10 00 02 03 01
- 15 01 00 00 10 00 02 04 0F
- 15 01 00 00 10 00 02 05 10
- 15 01 00 00 10 00 02 06 10
- 15 01 00 00 10 00 02 07 10
- 15 01 00 00 10 00 02 08 89
- 15 01 00 00 10 00 02 09 8A
- 15 01 00 00 10 00 02 0A 13
- 15 01 00 00 10 00 02 0B 13
- 15 01 00 00 10 00 02 0C 15
- 15 01 00 00 10 00 02 0D 15
- 15 01 00 00 10 00 02 0E 17
- 15 01 00 00 10 00 02 0F 17
- 15 01 00 00 10 00 02 10 1C
- 15 01 00 00 10 00 02 11 0B
- 15 01 00 00 10 00 02 12 0C
- 15 01 00 00 10 00 02 13 01
- 15 01 00 00 10 00 02 14 0F
- 15 01 00 00 10 00 02 15 10
- 15 01 00 00 10 00 02 16 10
- 15 01 00 00 10 00 02 17 10
- 15 01 00 00 10 00 02 18 89
- 15 01 00 00 10 00 02 19 8A
- 15 01 00 00 10 00 02 1A 13
- 15 01 00 00 10 00 02 1B 13
- 15 01 00 00 10 00 02 1C 15
- 15 01 00 00 10 00 02 1D 15
- 15 01 00 00 10 00 02 1E 17
- 15 01 00 00 10 00 02 1F 17
+ 15 01 00 00 00 00 02 FF 24
+ 15 01 00 00 00 00 02 FB 01
+ 15 01 00 00 00 00 02 00 1C
+ 15 01 00 00 00 00 02 01 0B
+ 15 01 00 00 00 00 02 02 0C
+ 15 01 00 00 00 00 02 03 01
+ 15 01 00 00 00 00 02 04 0F
+ 15 01 00 00 00 00 02 05 10
+ 15 01 00 00 00 00 02 06 10
+ 15 01 00 00 00 00 02 07 10
+ 15 01 00 00 00 00 02 08 89
+ 15 01 00 00 00 00 02 09 8A
+ 15 01 00 00 00 00 02 0A 13
+ 15 01 00 00 00 00 02 0B 13
+ 15 01 00 00 00 00 02 0C 15
+ 15 01 00 00 00 00 02 0D 15
+ 15 01 00 00 00 00 02 0E 17
+ 15 01 00 00 00 00 02 0F 17
+ 15 01 00 00 00 00 02 10 1C
+ 15 01 00 00 00 00 02 11 0B
+ 15 01 00 00 00 00 02 12 0C
+ 15 01 00 00 00 00 02 13 01
+ 15 01 00 00 00 00 02 14 0F
+ 15 01 00 00 00 00 02 15 10
+ 15 01 00 00 00 00 02 16 10
+ 15 01 00 00 00 00 02 17 10
+ 15 01 00 00 00 00 02 18 89
+ 15 01 00 00 00 00 02 19 8A
+ 15 01 00 00 00 00 02 1A 13
+ 15 01 00 00 00 00 02 1B 13
+ 15 01 00 00 00 00 02 1C 15
+ 15 01 00 00 00 00 02 1D 15
+ 15 01 00 00 00 00 02 1E 17
+ 15 01 00 00 00 00 02 1F 17
/* STV */
- 15 01 00 00 10 00 02 20 40
- 15 01 00 00 10 00 02 21 01
- 15 01 00 00 10 00 02 22 00
- 15 01 00 00 10 00 02 23 40
- 15 01 00 00 10 00 02 24 40
- 15 01 00 00 10 00 02 25 6D
- 15 01 00 00 10 00 02 26 40
- 15 01 00 00 10 00 02 27 40
+ 15 01 00 00 00 00 02 20 40
+ 15 01 00 00 00 00 02 21 01
+ 15 01 00 00 00 00 02 22 00
+ 15 01 00 00 00 00 02 23 40
+ 15 01 00 00 00 00 02 24 40
+ 15 01 00 00 00 00 02 25 6D
+ 15 01 00 00 00 00 02 26 40
+ 15 01 00 00 00 00 02 27 40
/* Vend */
- 15 01 00 00 10 00 02 E0 00
- 15 01 00 00 10 00 02 DC 21
- 15 01 00 00 10 00 02 DD 22
- 15 01 00 00 10 00 02 DE 07
- 15 01 00 00 10 00 02 DF 07
- 15 01 00 00 10 00 02 E3 6D
- 15 01 00 00 10 00 02 E1 07
- 15 01 00 00 10 00 02 E2 07
+ 15 01 00 00 00 00 02 E0 00
+ 15 01 00 00 00 00 02 DC 21
+ 15 01 00 00 00 00 02 DD 22
+ 15 01 00 00 00 00 02 DE 07
+ 15 01 00 00 00 00 02 DF 07
+ 15 01 00 00 00 00 02 E3 6D
+ 15 01 00 00 00 00 02 E1 07
+ 15 01 00 00 00 00 02 E2 07
/* UD */
- 15 01 00 00 10 00 02 29 D8
- 15 01 00 00 10 00 02 2A 2A
+ 15 01 00 00 00 00 02 29 D8
+ 15 01 00 00 00 00 02 2A 2A
/* CLK */
- 15 01 00 00 10 00 02 4B 03
- 15 01 00 00 10 00 02 4C 11
- 15 01 00 00 10 00 02 4D 10
- 15 01 00 00 10 00 02 4E 01
- 15 01 00 00 10 00 02 4F 01
- 15 01 00 00 10 00 02 50 10
- 15 01 00 00 10 00 02 51 00
- 15 01 00 00 10 00 02 52 80
- 15 01 00 00 10 00 02 53 00
- 15 01 00 00 10 00 02 56 00
- 15 01 00 00 10 00 02 54 07
- 15 01 00 00 10 00 02 58 07
- 15 01 00 00 10 00 02 55 25
+ 15 01 00 00 00 00 02 4B 03
+ 15 01 00 00 00 00 02 4C 11
+ 15 01 00 00 00 00 02 4D 10
+ 15 01 00 00 00 00 02 4E 01
+ 15 01 00 00 00 00 02 4F 01
+ 15 01 00 00 00 00 02 50 10
+ 15 01 00 00 00 00 02 51 00
+ 15 01 00 00 00 00 02 52 80
+ 15 01 00 00 00 00 02 53 00
+ 15 01 00 00 00 00 02 56 00
+ 15 01 00 00 00 00 02 54 07
+ 15 01 00 00 00 00 02 58 07
+ 15 01 00 00 00 00 02 55 25
/* Reset XDONB */
- 15 01 00 00 10 00 02 5B 43
- 15 01 00 00 10 00 02 5C 00
- 15 01 00 00 10 00 02 5F 73
- 15 01 00 00 10 00 02 60 73
- 15 01 00 00 10 00 02 63 22
- 15 01 00 00 10 00 02 64 00
- 15 01 00 00 10 00 02 67 08
- 15 01 00 00 10 00 02 68 04
+ 15 01 00 00 00 00 02 5B 43
+ 15 01 00 00 00 00 02 5C 00
+ 15 01 00 00 00 00 02 5F 73
+ 15 01 00 00 00 00 02 60 73
+ 15 01 00 00 00 00 02 63 22
+ 15 01 00 00 00 00 02 64 00
+ 15 01 00 00 00 00 02 67 08
+ 15 01 00 00 00 00 02 68 04
/* Resolution:1440x2560*/
- 15 01 00 00 10 00 02 72 02
+ 15 01 00 00 00 00 02 72 02
/* mux */
- 15 01 00 00 10 00 02 7A 80
- 15 01 00 00 10 00 02 7B 91
- 15 01 00 00 10 00 02 7C D8
- 15 01 00 00 10 00 02 7D 60
- 15 01 00 00 10 00 02 7F 15
- 15 01 00 00 10 00 02 75 15
+ 15 01 00 00 00 00 02 7A 80
+ 15 01 00 00 00 00 02 7B 91
+ 15 01 00 00 00 00 02 7C D8
+ 15 01 00 00 00 00 02 7D 60
+ 15 01 00 00 00 00 02 7F 15
+ 15 01 00 00 00 00 02 75 15
/* ABOFF */
- 15 01 00 00 10 00 02 B3 C0
- 15 01 00 00 10 00 02 B4 00
- 15 01 00 00 10 00 02 B5 00
+ 15 01 00 00 00 00 02 B3 C0
+ 15 01 00 00 00 00 02 B4 00
+ 15 01 00 00 00 00 02 B5 00
/* Source EQ */
- 15 01 00 00 10 00 02 78 00
- 15 01 00 00 10 00 02 79 00
- 15 01 00 00 10 00 02 80 00
- 15 01 00 00 10 00 02 83 00
+ 15 01 00 00 00 00 02 78 00
+ 15 01 00 00 00 00 02 79 00
+ 15 01 00 00 00 00 02 80 00
+ 15 01 00 00 00 00 02 83 00
/* FP BP */
- 15 01 00 00 10 00 02 93 0A
- 15 01 00 00 10 00 02 94 0A
+ 15 01 00 00 00 00 02 93 0A
+ 15 01 00 00 00 00 02 94 0A
/* Inversion Type */
- 15 01 00 00 10 00 02 8A 00
- 15 01 00 00 10 00 02 9B FF
+ 15 01 00 00 00 00 02 8A 00
+ 15 01 00 00 00 00 02 9B FF
/* IMGSWAP =1 @PortSwap=1 */
- 15 01 00 00 10 00 02 9D B0
- 15 01 00 00 10 00 02 9F 63
- 15 01 00 00 10 00 02 98 10
+ 15 01 00 00 00 00 02 9D B0
+ 15 01 00 00 00 00 02 9F 63
+ 15 01 00 00 00 00 02 98 10
/* FRM */
- 15 01 00 00 10 00 02 EC 00
+ 15 01 00 00 00 00 02 EC 00
/* CMD1 */
- 15 01 00 00 10 00 02 FF 10
+ 15 01 00 00 00 00 02 FF 10
/* VBP+VSA=,VFP = 10H */
- 15 01 00 00 10 00 04 3B 03 0A 0A
+ 15 01 00 00 00 00 04 3B 03 0A 0A
/* FTE on */
- 15 01 00 00 10 00 02 35 00
+ 15 01 00 00 00 00 02 35 00
/* EN_BK =1(auto black) */
- 15 01 00 00 10 00 02 E5 01
+ 15 01 00 00 00 00 02 E5 01
/* CMD mode(10) VDO mode(03) */
- 15 01 00 00 10 00 02 BB 03
+ 15 01 00 00 00 00 02 BB 03
/* Non Reload MTP */
- 15 01 00 00 10 00 02 FB 01
+ 15 01 00 00 00 00 02 FB 01
/* SlpOut + DispOn */
- 05 01 00 00 a0 00 02 11 00
- 05 01 00 00 a0 00 02 29 00
+ 05 01 00 00 78 00 02 11 00
+ 05 01 00 00 78 00 02 29 00
];
qcom,mdss-dsi-off-command = [05 01 00 00 78 00 02 28 00
05 01 00 00 78 00 02 10 00];
diff --git a/arch/arm/boot/dts/qcom/dsi-panel-nt35695b-truly-fhd-cmd.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-nt35695b-truly-fhd-cmd.dtsi
index 3c0134b665fc..e3f60de3c3eb 100644
--- a/arch/arm/boot/dts/qcom/dsi-panel-nt35695b-truly-fhd-cmd.dtsi
+++ b/arch/arm/boot/dts/qcom/dsi-panel-nt35695b-truly-fhd-cmd.dtsi
@@ -20,13 +20,13 @@
qcom,mdss-dsi-stream = <0>;
qcom,mdss-dsi-panel-width = <1080>;
qcom,mdss-dsi-panel-height = <1920>;
- qcom,mdss-dsi-h-front-porch = <96>;
- qcom,mdss-dsi-h-back-porch = <64>;
- qcom,mdss-dsi-h-pulse-width = <16>;
+ qcom,mdss-dsi-h-front-porch = <120>;
+ qcom,mdss-dsi-h-back-porch = <60>;
+ qcom,mdss-dsi-h-pulse-width = <12>;
qcom,mdss-dsi-h-sync-skew = <0>;
- qcom,mdss-dsi-v-back-porch = <16>;
- qcom,mdss-dsi-v-front-porch = <4>;
- qcom,mdss-dsi-v-pulse-width = <1>;
+ qcom,mdss-dsi-v-back-porch = <2>;
+ qcom,mdss-dsi-v-front-porch = <12>;
+ qcom,mdss-dsi-v-pulse-width = <2>;
qcom,mdss-dsi-h-left-border = <0>;
qcom,mdss-dsi-h-right-border = <0>;
qcom,mdss-dsi-v-top-border = <0>;
diff --git a/arch/arm/boot/dts/qcom/dsi-panel-nt35695b-truly-fhd-video.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-nt35695b-truly-fhd-video.dtsi
index d6b24f4e54d2..068459bf2504 100644
--- a/arch/arm/boot/dts/qcom/dsi-panel-nt35695b-truly-fhd-video.dtsi
+++ b/arch/arm/boot/dts/qcom/dsi-panel-nt35695b-truly-fhd-video.dtsi
@@ -20,13 +20,13 @@
qcom,mdss-dsi-stream = <0>;
qcom,mdss-dsi-panel-width = <1080>;
qcom,mdss-dsi-panel-height = <1920>;
- qcom,mdss-dsi-h-front-porch = <96>;
- qcom,mdss-dsi-h-back-porch = <64>;
- qcom,mdss-dsi-h-pulse-width = <16>;
+ qcom,mdss-dsi-h-front-porch = <120>;
+ qcom,mdss-dsi-h-back-porch = <60>;
+ qcom,mdss-dsi-h-pulse-width = <12>;
qcom,mdss-dsi-h-sync-skew = <0>;
- qcom,mdss-dsi-v-back-porch = <16>;
- qcom,mdss-dsi-v-front-porch = <4>;
- qcom,mdss-dsi-v-pulse-width = <1>;
+ qcom,mdss-dsi-v-back-porch = <2>;
+ qcom,mdss-dsi-v-front-porch = <12>;
+ qcom,mdss-dsi-v-pulse-width = <2>;
qcom,mdss-dsi-h-left-border = <0>;
qcom,mdss-dsi-h-right-border = <0>;
qcom,mdss-dsi-v-top-border = <0>;
@@ -169,8 +169,7 @@
15 01 00 00 00 00 02 e3 00
15 01 00 00 00 00 02 ec 00
15 01 00 00 00 00 02 ff 10
- 15 01 00 00 00 00 02 bb 10
- 15 01 00 00 00 00 02 35 02
+ 15 01 00 00 00 00 02 bb 03
05 01 00 00 78 00 02 11 00
05 01 00 00 78 00 02 29 00];
qcom,mdss-dsi-off-command = [05 01 00 00 14 00 02 28 00
diff --git a/arch/arm/boot/dts/qcom/msm-pm660.dtsi b/arch/arm/boot/dts/qcom/msm-pm660.dtsi
index e8e773a33622..1154c28bb9ea 100644
--- a/arch/arm/boot/dts/qcom/msm-pm660.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pm660.dtsi
@@ -497,6 +497,7 @@
#address-cells = <1>;
#size-cells = <0>;
#io-channel-cells = <1>;
+ qcom,pmic-revid = <&pm660_revid>;
};
pm660_fg: qpnp,fg {
@@ -517,8 +518,10 @@
reg = <0x4000 0x100>;
interrupts = <0x0 0x40 0x0 IRQ_TYPE_EDGE_BOTH>,
<0x0 0x40 0x1 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x40 0x2 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x40 0x3 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x40 0x2
+ IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x40 0x3
+ IRQ_TYPE_EDGE_RISING>,
<0x0 0x40 0x4 IRQ_TYPE_EDGE_BOTH>,
<0x0 0x40 0x5
IRQ_TYPE_EDGE_RISING>,
diff --git a/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi b/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi
index be47b6483288..72f9f9ea9b2d 100644
--- a/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi
@@ -290,6 +290,10 @@
"msg-tx-failed",
"msg-tx-discarded",
"msg-rx-discarded";
+
+ qcom,default-sink-caps = <5000 3000>, /* 5V @ 3A */
+ <9000 3000>, /* 9V @ 3A */
+ <12000 2250>; /* 12V @ 2.25A */
};
bcl@4200 {
@@ -333,8 +337,10 @@
reg = <0x4000 0x100>;
interrupts = <0x2 0x40 0x0 IRQ_TYPE_EDGE_BOTH>,
<0x2 0x40 0x1 IRQ_TYPE_EDGE_BOTH>,
- <0x2 0x40 0x2 IRQ_TYPE_EDGE_BOTH>,
- <0x2 0x40 0x3 IRQ_TYPE_EDGE_BOTH>,
+ <0x2 0x40 0x2
+ IRQ_TYPE_EDGE_RISING>,
+ <0x2 0x40 0x3
+ IRQ_TYPE_EDGE_RISING>,
<0x2 0x40 0x4 IRQ_TYPE_EDGE_BOTH>,
<0x2 0x40 0x5
IRQ_TYPE_EDGE_RISING>,
diff --git a/arch/arm/boot/dts/qcom/msm-smb138x.dtsi b/arch/arm/boot/dts/qcom/msm-smb138x.dtsi
index e6e04f19d7ea..138fa2b57248 100644
--- a/arch/arm/boot/dts/qcom/msm-smb138x.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-smb138x.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -57,8 +57,8 @@
die_temp@2 {
reg = <2>;
- qcom,scale = <(-1032)>;
- qcom,offset = <344125>;
+ qcom,scale = <(-1306)>;
+ qcom,offset = <397904>;
};
batt_i@3 {
@@ -96,16 +96,24 @@
#size-cells = <1>;
interrupt-parent = <&smb138x>;
io-channels = <&smb138x_tadc 2>,
- <&smb138x_tadc 12>,
- <&smb138x_tadc 3>;
+ <&smb138x_tadc 3>,
+ <&smb138x_tadc 14>,
+ <&smb138x_tadc 15>,
+ <&smb138x_tadc 16>,
+ <&smb138x_tadc 17>;
io-channel-names = "charger_temp",
- "charger_temp_max",
- "batt_i";
+ "batt_i",
+ "connector_temp_thr1",
+ "connector_temp_thr2",
+ "connector_temp_thr3",
+ "charger_temp_max";
qcom,chgr-misc@1600 {
reg = <0x1600 0x100>;
- interrupts = <0x16 0x1 IRQ_TYPE_EDGE_RISING>;
- interrupt-names = "wdog-bark";
+ interrupts = <0x16 0x1 IRQ_TYPE_EDGE_RISING>,
+ <0x16 0x6 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "wdog-bark",
+ "temperature-change";
};
};
};
diff --git a/arch/arm/boot/dts/qcom/msm8996-vidc.dtsi b/arch/arm/boot/dts/qcom/msm8996-vidc.dtsi
index 3ed55f9d8671..5ac31e3dd0cb 100644
--- a/arch/arm/boot/dts/qcom/msm8996-vidc.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-vidc.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, 2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -32,6 +32,7 @@
<0x0818C000 0x2000>,
<0x0818E000 0x2000>;
qcom,max-hw-load = <2563200>; /* Full 4k @ 60 + 1080p @ 60 */
+ qcom,power-conf = <8294400>; /* WxH - 3840*2160 */
qcom,firmware-name = "venus";
qcom,imem-size = <524288>; /* 512 kB */
qcom,never-unload-fw;
diff --git a/arch/arm/boot/dts/qcom/msm8998-camera.dtsi b/arch/arm/boot/dts/qcom/msm8998-camera.dtsi
index f8dae210bc4e..c35ea886408d 100644
--- a/arch/arm/boot/dts/qcom/msm8998-camera.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-camera.dtsi
@@ -51,8 +51,8 @@
"csi_src_clk", "csi_clk", "cphy_csid_clk",
"csiphy_timer_src_clk", "csiphy_timer_clk",
"camss_ispif_ahb_clk", "csiphy_clk_src", "csiphy_clk";
- qcom,clock-rates = <0 0 0 0 0 0 256000000 0 0 200000000 0
- 0 256000000 0>;
+ qcom,clock-rates = <0 0 0 0 0 0 274290000 0 0 200000000 0
+ 0 274290000 0>;
status = "ok";
};
@@ -86,8 +86,8 @@
"csi_src_clk", "csi_clk", "cphy_csid_clk",
"csiphy_timer_src_clk", "csiphy_timer_clk",
"camss_ispif_ahb_clk", "csiphy_clk_src", "csiphy_clk";
- qcom,clock-rates = <0 0 0 0 0 0 256000000 0 0 200000000 0
- 0 256000000 0>;
+ qcom,clock-rates = <0 0 0 0 0 0 274290000 0 0 200000000 0
+ 0 274290000 0>;
status = "ok";
};
@@ -121,8 +121,8 @@
"csi_src_clk", "csi_clk", "cphy_csid_clk",
"csiphy_timer_src_clk", "csiphy_timer_clk",
"camss_ispif_ahb_clk", "csiphy_clk_src", "csiphy_clk";
- qcom,clock-rates = <0 0 0 0 0 0 256000000 0 0 200000000 0
- 0 256000000 0>;
+ qcom,clock-rates = <0 0 0 0 0 0 274290000 0 0 200000000 0
+ 0 274290000 0>;
status = "ok";
};
@@ -159,7 +159,7 @@
"ispif_ahb_clk", "csi_src_clk", "csiphy_clk_src",
"csi_clk", "csi_ahb_clk", "csi_rdi_clk",
"csi_pix_clk", "cphy_csid_clk";
- qcom,clock-rates = <0 0 0 0 0 0 0 256000000 256000000
+ qcom,clock-rates = <0 0 0 0 0 0 0 274290000 274290000
0 0 0 0 0>;
status = "ok";
};
@@ -197,7 +197,7 @@
"ispif_ahb_clk", "csi_src_clk", "csiphy_clk_src",
"csi_clk", "csi_ahb_clk", "csi_rdi_clk",
"csi_pix_clk", "cphy_csid_clk";
- qcom,clock-rates = <0 0 0 0 0 0 0 256000000 256000000
+ qcom,clock-rates = <0 0 0 0 0 0 0 274290000 274290000
0 0 0 0 0>;
status = "ok";
};
@@ -235,7 +235,7 @@
"ispif_ahb_clk", "csi_src_clk", "csiphy_clk_src",
"csi_clk", "csi_ahb_clk", "csi_rdi_clk",
"csi_pix_clk", "cphy_csid_clk";
- qcom,clock-rates = <0 0 0 0 0 0 0 256000000 256000000
+ qcom,clock-rates = <0 0 0 0 0 0 0 274290000 274290000
0 0 0 0 0>;
status = "ok";
};
@@ -273,7 +273,7 @@
"ispif_ahb_clk", "csi_src_clk", "csiphy_clk_src",
"csi_clk", "csi_ahb_clk", "csi_rdi_clk",
"csi_pix_clk", "cphy_csid_clk";
- qcom,clock-rates = <0 0 0 0 0 0 0 256000000 256000000
+ qcom,clock-rates = <0 0 0 0 0 0 0 274290000 274290000
0 0 0 0 0>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/qcom/msm8998-mdss.dtsi b/arch/arm/boot/dts/qcom/msm8998-mdss.dtsi
index 845c96eb5ef4..7dfcd34c2743 100644
--- a/arch/arm/boot/dts/qcom/msm8998-mdss.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-mdss.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -21,6 +21,7 @@
interrupt-controller;
#interrupt-cells = <1>;
vdd-supply = <&gdsc_mdss>;
+ gdsc-core-supply = <&gdsc_bimc_smmu>;
/* Bus Scale Settings */
qcom,msm-bus,name = "mdss_mdp";
@@ -126,7 +127,7 @@
<0x012ac 0xc0000ccc>,
<0x012b4 0xc0000ccc>,
<0x012bc 0x00cccccc>,
- <0x012c4 0x000000cc>,
+ <0x012c4 0x0000cccc>,
<0x013a8 0x0cccc0c0>,
<0x013b0 0xccccc0c0>,
<0x013b8 0xcccc0000>,
@@ -500,6 +501,9 @@
qcom,msm_ext_disp = <&msm_ext_disp>;
+ qcom,aux-cfg-settings = [00 13 00 10 0a 26 0a 03 8b 03];
+ qcom,logical2physical-lane-map = [02 03 01 00];
+
qcom,core-supply-entries {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/qcom/msm8998-mtp.dtsi b/arch/arm/boot/dts/qcom/msm8998-mtp.dtsi
index 4aadd4802b51..236020385e1c 100644
--- a/arch/arm/boot/dts/qcom/msm8998-mtp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-mtp.dtsi
@@ -171,6 +171,19 @@
};
};
+&pmi8998_gpios {
+ /* GPIO 6 for the internal QNOVO discharge FET control signal */
+ gpio@c500 {
+ status = "okay";
+ qcom,mode = <1>;
+ qcom,pull = <5>;
+ qcom,vin-sel = <0>;
+ qcom,src-sel = <2>;
+ qcom,out-strength = <1>;
+ qcom,master-en = <1>;
+ };
+};
+
&i2c_5 {
status = "okay";
synaptics@20 {
diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi
index 25e381c2cb18..3c1c49edcc82 100644
--- a/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi
@@ -143,6 +143,19 @@
};
};
+&pmi8998_gpios {
+ /* GPIO 6 for the internal QNOVO discharge FET control signal */
+ gpio@c500 {
+ status = "okay";
+ qcom,mode = <1>;
+ qcom,pull = <5>;
+ qcom,vin-sel = <0>;
+ qcom,src-sel = <2>;
+ qcom,out-strength = <1>;
+ qcom,master-en = <1>;
+ };
+};
+
&soc {
gpio_keys {
compatible = "gpio-keys";
diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd.dtsi
index fb69a793a680..38072e447fba 100644
--- a/arch/arm/boot/dts/qcom/msm8998-qrd.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-qrd.dtsi
@@ -159,6 +159,19 @@
};
};
+&pmi8998_gpios {
+ /* GPIO 6 for the internal QNOVO discharge FET control signal */
+ gpio@c500 {
+ status = "okay";
+ qcom,mode = <1>;
+ qcom,pull = <5>;
+ qcom,vin-sel = <0>;
+ qcom,src-sel = <2>;
+ qcom,out-strength = <1>;
+ qcom,master-en = <1>;
+ };
+};
+
&i2c_5 {
status = "okay";
synaptics@20 {
diff --git a/arch/arm/boot/dts/qcom/msm8998-v2-camera.dtsi b/arch/arm/boot/dts/qcom/msm8998-v2-camera.dtsi
index fdc452a47a46..93da11e66799 100644
--- a/arch/arm/boot/dts/qcom/msm8998-v2-camera.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-v2-camera.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -42,8 +42,8 @@
"csi_src_clk", "csi_clk", "cphy_csid_clk",
"csiphy_timer_src_clk", "csiphy_timer_clk",
"camss_ispif_ahb_clk", "csiphy_clk_src", "csiphy_clk";
- qcom,clock-rates = <0 0 0 0 0 0 256000000 0 0 200000000 0
- 0 256000000 0>;
+ qcom,clock-rates = <0 0 0 0 0 0 274290000 0 0 200000000 0
+ 0 274290000 0>;
status = "ok";
};
@@ -77,8 +77,8 @@
"csi_src_clk", "csi_clk", "cphy_csid_clk",
"csiphy_timer_src_clk", "csiphy_timer_clk",
"camss_ispif_ahb_clk", "csiphy_clk_src", "csiphy_clk";
- qcom,clock-rates = <0 0 0 0 0 0 256000000 0 0 200000000 0
- 0 256000000 0>;
+ qcom,clock-rates = <0 0 0 0 0 0 274290000 0 0 200000000 0
+ 0 274290000 0>;
status = "ok";
};
@@ -112,8 +112,8 @@
"csi_src_clk", "csi_clk", "cphy_csid_clk",
"csiphy_timer_src_clk", "csiphy_timer_clk",
"camss_ispif_ahb_clk", "csiphy_clk_src", "csiphy_clk";
- qcom,clock-rates = <0 0 0 0 0 0 256000000 0 0 200000000 0
- 0 256000000 0>;
+ qcom,clock-rates = <0 0 0 0 0 0 274290000 0 0 200000000 0
+ 0 274290000 0>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.dtsi b/arch/arm/boot/dts/qcom/msm8998-v2.dtsi
index 1d8fe225c9af..b6ddd549efe5 100644
--- a/arch/arm/boot/dts/qcom/msm8998-v2.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-v2.dtsi
@@ -44,6 +44,7 @@
qcom,acdextint0-val = <0x2cf9ae8 0x2cf9ae8>;
qcom,acdextint1-val = <0x2cf9afe 0x2cf9afe>;
qcom,acdautoxfer-val = <0x00000015 0x00000015>;
+ qcom,pwrcl-apcs-mem-acc-threshold-voltage = <852000>;
qcom,perfcl-apcs-mem-acc-threshold-voltage = <852000>;
qcom,apm-threshold-voltage = <800000>;
@@ -452,6 +453,8 @@
qcom,cpr-aging-ref-voltage = <1056000>;
qcom,apm-threshold-voltage = <800000>;
qcom,apm-hysteresis-voltage = <0>;
+ qcom,mem-acc-threshold-voltage = <852000>;
+ qcom,mem-acc-crossover-voltage = <852000>;
};
&apc0_pwrcl_vreg {
diff --git a/arch/arm/boot/dts/qcom/msm8998-vidc.dtsi b/arch/arm/boot/dts/qcom/msm8998-vidc.dtsi
index e449d81a25e5..3e7cacac9d43 100644
--- a/arch/arm/boot/dts/qcom/msm8998-vidc.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-vidc.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -39,6 +39,7 @@
qcom,imem-size = <524288>; /* 512 kB */
qcom,max-hw-load = <2563200>; /* Full 4k @ 60 + 1080p @ 60 */
+ qcom,power-conf = <8294400>; /* WxH - 3840*2160 */
qcom,load-freq-tbl =
/* Encoders */
<972000 465000000 0x55555555>, /* 4k UHD @ 30 */
diff --git a/arch/arm/boot/dts/qcom/msm8998.dtsi b/arch/arm/boot/dts/qcom/msm8998.dtsi
index 30679791006b..2e41f3a3567d 100644
--- a/arch/arm/boot/dts/qcom/msm8998.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998.dtsi
@@ -3041,7 +3041,25 @@
};
- qcom,icnss@18800000 {
+ msm_ath10k_wlan: qcom,msm_ath10k_wlan@18000000 {
+ status = "disabled";
+ compatible = "qcom,wcn3990-wifi";
+ interrupts =
+ <0 413 0 /* CE0 */ >,
+ <0 414 0 /* CE1 */ >,
+ <0 415 0 /* CE2 */ >,
+ <0 416 0 /* CE3 */ >,
+ <0 417 0 /* CE4 */ >,
+ <0 418 0 /* CE5 */ >,
+ <0 420 0 /* CE6 */ >,
+ <0 421 0 /* CE7 */ >,
+ <0 422 0 /* CE8 */ >,
+ <0 423 0 /* CE9 */ >,
+ <0 424 0 /* CE10 */ >,
+ <0 425 0 /* CE11 */ >;
+ };
+
+ qcom,icnss@18800000 {
compatible = "qcom,icnss";
reg = <0x18800000 0x800000>,
<0xa0000000 0x10000000>,
diff --git a/arch/arm/boot/dts/qcom/sdm630-cdp.dtsi b/arch/arm/boot/dts/qcom/sdm630-cdp.dtsi
index 2232327f1302..af288ff26d06 100644
--- a/arch/arm/boot/dts/qcom/sdm630-cdp.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm630-cdp.dtsi
@@ -25,6 +25,27 @@
qcom,led-strings-list = [01 02];
};
+&ufsphy1 {
+ vdda-phy-supply = <&pm660l_l1>;
+ vdda-pll-supply = <&pm660_l10>;
+ vddp-ref-clk-supply = <&pm660_l1>;
+ vdda-phy-max-microamp = <51400>;
+ vdda-pll-max-microamp = <14200>;
+ vddp-ref-clk-max-microamp = <100>;
+ vddp-ref-clk-always-on;
+ status = "ok";
+};
+
+&ufs1 {
+ vdd-hba-supply = <&gdsc_ufs>;
+ vdd-hba-fixed-regulator;
+ vcc-supply = <&pm660l_l4>;
+ vccq2-supply = <&pm660_l8>;
+ vcc-max-microamp = <500000>;
+ vccq2-max-microamp = <600000>;
+ status = "ok";
+};
+
&soc {
};
diff --git a/arch/arm/boot/dts/qcom/sdm630-mtp.dtsi b/arch/arm/boot/dts/qcom/sdm630-mtp.dtsi
index b07a9190331b..a47f8419f41a 100644
--- a/arch/arm/boot/dts/qcom/sdm630-mtp.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm630-mtp.dtsi
@@ -26,6 +26,27 @@
pinctrl-0 = <&uart_console_active>;
};
+&ufsphy1 {
+ vdda-phy-supply = <&pm660l_l1>;
+ vdda-pll-supply = <&pm660_l10>;
+ vddp-ref-clk-supply = <&pm660_l1>;
+ vdda-phy-max-microamp = <51400>;
+ vdda-pll-max-microamp = <14200>;
+ vddp-ref-clk-max-microamp = <100>;
+ vddp-ref-clk-always-on;
+ status = "ok";
+};
+
+&ufs1 {
+ vdd-hba-supply = <&gdsc_ufs>;
+ vdd-hba-fixed-regulator;
+ vcc-supply = <&pm660l_l4>;
+ vccq2-supply = <&pm660_l8>;
+ vcc-max-microamp = <500000>;
+ vccq2-max-microamp = <600000>;
+ status = "ok";
+};
+
&mem_client_3_size {
qcom,peripheral-size = <0x500000>;
};
diff --git a/arch/arm/boot/dts/qcom/sdm630-rumi.dts b/arch/arm/boot/dts/qcom/sdm630-rumi.dts
index 2ea1af4da90c..018429a4ebb1 100644
--- a/arch/arm/boot/dts/qcom/sdm630-rumi.dts
+++ b/arch/arm/boot/dts/qcom/sdm630-rumi.dts
@@ -67,6 +67,27 @@
pinctrl-0 = <&uart_console_active>;
};
+&ufsphy1 {
+ vdda-phy-supply = <&pm660l_l1>;
+ vdda-pll-supply = <&pm660_l10>;
+ vddp-ref-clk-supply = <&pm660_l1>;
+ vdda-phy-max-microamp = <51400>;
+ vdda-pll-max-microamp = <14200>;
+ vddp-ref-clk-max-microamp = <100>;
+ vddp-ref-clk-always-on;
+ status = "ok";
+};
+
+&ufs1 {
+ vdd-hba-supply = <&gdsc_ufs>;
+ vdd-hba-fixed-regulator;
+ vcc-supply = <&pm660l_l4>;
+ vccq2-supply = <&pm660_l8>;
+ vcc-max-microamp = <500000>;
+ vccq2-max-microamp = <600000>;
+ status = "ok";
+};
+
&clock_gcc {
compatible = "qcom,dummycc";
clock-output-names = "gcc_clocks";
diff --git a/arch/arm/boot/dts/qcom/sdm630.dtsi b/arch/arm/boot/dts/qcom/sdm630.dtsi
index 7a1507163c26..38df4a63c5f5 100644
--- a/arch/arm/boot/dts/qcom/sdm630.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm630.dtsi
@@ -17,6 +17,7 @@
#include <dt-bindings/clock/qcom,rpmcc.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/regulator/qcom,rpm-smd-regulator.h>
+#include <dt-bindings/clock/qcom,cpu-osm.h>
/ {
model = "Qualcomm Technologies, Inc. SDM630";
@@ -50,6 +51,7 @@
reg = <0x0 0x100>;
enable-method = "psci";
qcom,limits-info = <&mitigation_profile0>;
+ qcom,ea = <&ea0>;
efficiency = <1126>;
next-level-cache = <&L2_1>;
L2_1: l2-cache {
@@ -74,6 +76,7 @@
reg = <0x0 0x101>;
enable-method = "psci";
qcom,limits-info = <&mitigation_profile1>;
+ qcom,ea = <&ea1>;
efficiency = <1126>;
next-level-cache = <&L2_1>;
L1_I_101: l1-icache {
@@ -92,6 +95,7 @@
reg = <0x0 0x102>;
enable-method = "psci";
qcom,limits-info = <&mitigation_profile2>;
+ qcom,ea = <&ea2>;
efficiency = <1126>;
next-level-cache = <&L2_1>;
L1_I_102: l1-icache {
@@ -110,6 +114,7 @@
reg = <0x0 0x103>;
enable-method = "psci";
qcom,limits-info = <&mitigation_profile3>;
+ qcom,ea = <&ea3>;
efficiency = <1126>;
next-level-cache = <&L2_1>;
L1_I_103: l1-icache {
@@ -128,6 +133,7 @@
reg = <0x0 0x0>;
enable-method = "psci";
qcom,limits-info = <&mitigation_profile4>;
+ qcom,ea = <&ea4>;
efficiency = <1024>;
next-level-cache = <&L2_0>;
L2_0: l2-cache {
@@ -152,6 +158,7 @@
reg = <0x0 0x1>;
enable-method = "psci";
qcom,limits-info = <&mitigation_profile4>;
+ qcom,ea = <&ea5>;
efficiency = <1024>;
next-level-cache = <&L2_0>;
L1_I_1: l1-icache {
@@ -170,6 +177,7 @@
reg = <0x0 0x2>;
enable-method = "psci";
qcom,limits-info = <&mitigation_profile4>;
+ qcom,ea = <&ea6>;
efficiency = <1024>;
next-level-cache = <&L2_0>;
L1_I_2: l1-icache {
@@ -188,6 +196,7 @@
reg = <0x0 0x3>;
enable-method = "psci";
qcom,limits-info = <&mitigation_profile4>;
+ qcom,ea = <&ea7>;
efficiency = <1024>;
next-level-cache = <&L2_0>;
L1_I_3: l1-icache {
@@ -293,7 +302,7 @@
alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
reusable;
alignment = <0x0 0x400000>;
- size = <0x0 0x400000>;
+ size = <0x0 0xa00000>;
};
qseecom_mem: qseecom_region {
@@ -493,6 +502,8 @@
reg-names = "tsens_physical";
interrupts = <0 184 0>, <0 430 0>;
interrupt-names = "tsens-upper-lower", "tsens-critical";
+ qcom,client-id = <0 1 2 3 4 5 6 7 8 9 10 11>;
+ qcom,sensor-id = <0 8 10 4 5 6 7 9 2 1 3 11>;
qcom,sensors = <12>;
};
@@ -680,6 +691,45 @@
};
};
+ qcom,msm-core@780000 {
+ compatible = "qcom,apss-core-ea";
+ reg = <0x780000 0x1000>;
+ qcom,low-hyst-temp = <10>;
+ qcom,high-hyst-temp = <5>;
+
+ ea0: ea0 {
+ sensor = <&sensor_information3>;
+ };
+
+ ea1: ea1 {
+ sensor = <&sensor_information4>;
+ };
+
+ ea2: ea2 {
+ sensor = <&sensor_information5>;
+ };
+
+ ea3: ea3 {
+ sensor = <&sensor_information6>;
+ };
+
+ ea4: ea4 {
+ sensor = <&sensor_information7>;
+ };
+
+ ea5: ea5 {
+ sensor = <&sensor_information7>;
+ };
+
+ ea6: ea6 {
+ sensor = <&sensor_information7>;
+ };
+
+ ea7: ea7 {
+ sensor = <&sensor_information7>;
+ };
+ };
+
wdog: qcom,wdt@17817000 {
status = "disabled";
compatible = "qcom,msm-watchdog";
@@ -690,6 +740,7 @@
qcom,pet-time = <10000>;
qcom,ipi-ping;
qcom,wakeup-enable;
+ qcom,scandump-size = <0x40000>;
};
uartblsp1dm1: serial@0c170000 {
@@ -905,6 +956,7 @@
qcom,use-ipa-tethering-bridge;
qcom,modem-cfg-emb-pipe-flt;
qcom,ipa-wdi2;
+ qcom,use-dma-zone;
qcom,msm-bus,name = "ipa";
qcom,msm-bus,num-cases = <4>;
qcom,msm-bus,num-paths = <2>;
@@ -958,6 +1010,105 @@
qcom,ipa-advertise-sg-support;
};
+ clock_cpu: qcom,clk-cpu-630@179c0000 {
+ compatible = "qcom,clk-cpu-osm-sdm630";
+ status = "disabled";
+ reg = <0x179c0000 0x4000>, <0x17916000 0x1000>,
+ <0x17816000 0x1000>, <0x179d1000 0x1000>,
+ <0x00784130 0x8>;
+ reg-names = "osm", "pwrcl_pll", "perfcl_pll",
+ "apcs_common", "perfcl_efuse";
+
+ interrupts = <GIC_SPI 35 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 36 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "pwrcl-irq", "perfcl-irq";
+
+ qcom,pwrcl-speedbin0-v0 =
+ < 300000000 0x0004000f 0x01200020 0x1 1 >,
+ < 614400000 0x05040020 0x03200020 0x1 2 >,
+ < 883200000 0x0404002e 0x04250025 0x1 3 >,
+ < 1094400000 0x04040039 0x052e002e 0x2 4 >,
+ < 1382400000 0x04040048 0x07390039 0x2 5 >,
+ < 1536000000 0x04040050 0x08400040 0x3 6 >,
+ < 1728000000 0x0404005a 0x09480048 0x3 7 >,
+ < 1843200000 0x04040060 0x094c004c 0x3 8 >;
+
+ qcom,perfcl-speedbin0-v0 =
+ < 300000000 0x0004000f 0x01200020 0x1 1 >,
+ < 787200000 0x05040029 0x04200020 0x1 2 >,
+ < 1113600000 0x0404003a 0x052e002e 0x1 3 >,
+ < 1344000000 0x04040046 0x07380038 0x2 4 >,
+ < 1516800000 0x0404004f 0x073f003f 0x2 5 >,
+ < 1670400000 0x04040057 0x08450045 0x2 6 >,
+ < 1881600000 0x04040062 0x094e004e 0x3 7 >,
+ < 2016000000 0x04040069 0x0a540054 0x3 8 >,
+ < 2150400000 0x04040070 0x0b590059 0x3 9 >,
+ < 2380800000 0x0404007c 0x0c630063 0x3 10 >;
+
+ qcom,perfcl-speedbin1-v0 =
+ < 300000000 0x0004000f 0x01200020 0x1 1 >,
+ < 787200000 0x05040029 0x04200020 0x1 2 >,
+ < 1113600000 0x0404003a 0x052e002e 0x1 3 >,
+ < 1344000000 0x04040046 0x07380038 0x2 4 >,
+ < 1516800000 0x0404004f 0x073f003f 0x2 5 >,
+ < 1670400000 0x04040057 0x08450045 0x2 6 >,
+ < 1881600000 0x04040062 0x094e004e 0x3 7 >,
+ < 2016000000 0x04040069 0x0a540054 0x3 8 >,
+ < 2150400000 0x04040070 0x0b590059 0x3 8 >,
+ < 2208000000 0x04040073 0x0b5c005c 0x3 10 >;
+
+ qcom,perfcl-speedbin2-v0 =
+ < 300000000 0x0004000f 0x01200020 0x1 1 >,
+ < 787200000 0x05040029 0x04200020 0x1 2 >,
+ < 1113600000 0x0404003a 0x052e002e 0x1 3 >,
+ < 1344000000 0x04040046 0x07380038 0x2 4 >,
+ < 1516800000 0x0404004f 0x073f003f 0x2 5 >,
+ < 1670400000 0x04040057 0x08450045 0x2 6 >,
+ < 1881600000 0x04040062 0x094e004e 0x3 7 >,
+ < 2016000000 0x04040069 0x0a540054 0x3 8 >,
+ < 2150400000 0x04040070 0x0b590059 0x3 9 >,
+ < 2380800000 0x0404007c 0x0c630063 0x3 10 >,
+ < 2515200000 0x04040083 0x0d680068 0x3 11 >;
+
+ qcom,up-timer = <1000 1000>;
+ qcom,down-timer = <1000 1000>;
+ qcom,pc-override-index = <0 0>;
+ qcom,set-ret-inactive;
+ qcom,enable-llm-freq-vote;
+ qcom,llm-freq-up-timer = <327675 327675>;
+ qcom,llm-freq-down-timer = <327675 327675>;
+ qcom,enable-llm-volt-vote;
+ qcom,llm-volt-up-timer = <327675 327675>;
+ qcom,llm-volt-down-timer = <327675 327675>;
+ qcom,cc-reads = <10>;
+ qcom,cc-delay = <5>;
+ qcom,cc-factor = <100>;
+ qcom,osm-clk-rate = <200000000>;
+ qcom,xo-clk-rate = <19200000>;
+
+ qcom,l-val-base = <0x17916004 0x17816004>;
+ qcom,apcs-itm-present = <0x179d143c 0x179d143c>;
+ qcom,apcs-pll-user-ctl = <0x1791600c 0x1781600c>;
+ qcom,apcs-cfg-rcgr = <0x17911054 0x17811054>;
+ qcom,apcs-cmd-rcgr = <0x17911050 0x17811050>;
+ qcom,apm-mode-ctl = <0x179d0004 0x179d0010>;
+ qcom,apm-ctrl-status = <0x179d000c 0x179d0018>;
+
+ qcom,apm-threshold-voltage = <872000>;
+ qcom,boost-fsm-en;
+ qcom,safe-fsm-en;
+ qcom,ps-fsm-en;
+ qcom,droop-fsm-en;
+ qcom,wfx-fsm-en;
+ qcom,pc-fsm-en;
+
+ clock-names = "aux_clk", "xo_a";
+ clocks = <&clock_gcc HMSS_GPLL0_CLK_SRC>,
+ <&clock_rpmcc RPM_XO_A_CLK_SRC>;
+
+ #clock-cells = <1>;
+ };
+
qcom,ipc-spinlock@1f40000 {
compatible = "qcom,ipc-spinlock-sfpb";
reg = <0x1f40000 0x8000>;
@@ -975,6 +1126,41 @@
qcom,mpu-enabled;
};
+ qcom,msm-adsprpc-mem {
+ compatible = "qcom,msm-adsprpc-mem-region";
+ memory-region = <&adsp_mem>;
+ };
+
+ qcom,msm_fastrpc {
+ compatible = "qcom,msm-fastrpc-adsp";
+ qcom,fastrpc-glink;
+
+ qcom,msm_fastrpc_compute_cb1 {
+ compatible = "qcom,msm-fastrpc-compute-cb";
+ label = "adsprpc-smd";
+ iommus = <&lpass_q6_smmu 3>;
+ dma-coherent;
+ };
+ qcom,msm_fastrpc_compute_cb2 {
+ compatible = "qcom,msm-fastrpc-compute-cb";
+ label = "adsprpc-smd";
+ iommus = <&lpass_q6_smmu 7>;
+ dma-coherent;
+ };
+ qcom,msm_fastrpc_compute_cb3 {
+ compatible = "qcom,msm-fastrpc-compute-cb";
+ label = "adsprpc-smd";
+ iommus = <&lpass_q6_smmu 8>;
+ dma-coherent;
+ };
+ qcom,msm_fastrpc_compute_cb4 {
+ compatible = "qcom,msm-fastrpc-compute-cb";
+ label = "adsprpc-smd";
+ iommus = <&lpass_q6_smmu 9>;
+ dma-coherent;
+ };
+ };
+
dcc: dcc@10b3000 {
compatible = "qcom,dcc";
reg = <0x10b3000 0x1000>,
@@ -1397,6 +1583,108 @@
0x178a80b8 0x178b80b8>;
};
+ jtag_fuse: jtagfuse@786040 {
+ compatible = "qcom,jtag-fuse-v4";
+ reg = <0x786040 0x8>;
+ reg-names = "fuse-base";
+ };
+
+ jtag_mm0: jtagmm@7840000 {
+ compatible = "qcom,jtagv8-mm";
+ reg = <0x7840000 0x1000>;
+ reg-names = "etm-base";
+
+ clocks = <&clock_rpmcc RPM_QDSS_CLK>,
+ <&clock_rpmcc RPM_QDSS_A_CLK>;
+ clock-names = "core_clk", "core_a_clk";
+
+ qcom,coresight-jtagmm-cpu = <&CPU4>;
+ };
+
+ jtag_mm1: jtagmm@7940000 {
+ compatible = "qcom,jtagv8-mm";
+ reg = <0x7940000 0x1000>;
+ reg-names = "etm-base";
+
+ clocks = <&clock_rpmcc RPM_QDSS_CLK>,
+ <&clock_rpmcc RPM_QDSS_A_CLK>;
+ clock-names = "core_clk", "core_a_clk";
+
+ qcom,coresight-jtagmm-cpu = <&CPU5>;
+ };
+
+ jtag_mm2: jtagmm@7a40000 {
+ compatible = "qcom,jtagv8-mm";
+ reg = <0x7a40000 0x1000>;
+ reg-names = "etm-base";
+
+ clocks = <&clock_rpmcc RPM_QDSS_CLK>,
+ <&clock_rpmcc RPM_QDSS_A_CLK>;
+ clock-names = "core_clk", "core_a_clk";
+
+ qcom,coresight-jtagmm-cpu = <&CPU6>;
+ };
+
+ jtag_mm3: jtagmm@7b40000 {
+ compatible = "qcom,jtagv8-mm";
+ reg = <0x7b40000 0x1000>;
+ reg-names = "etm-base";
+
+ clocks = <&clock_rpmcc RPM_QDSS_CLK>,
+ <&clock_rpmcc RPM_QDSS_A_CLK>;
+ clock-names = "core_clk", "core_a_clk";
+
+ qcom,coresight-jtagmm-cpu = <&CPU7>;
+ };
+
+ jtag_mm4: jtagmm@7c40000 {
+ compatible = "qcom,jtagv8-mm";
+ reg = <0x7c40000 0x1000>;
+ reg-names = "etm-base";
+
+ clocks = <&clock_rpmcc RPM_QDSS_CLK>,
+ <&clock_rpmcc RPM_QDSS_A_CLK>;
+ clock-names = "core_clk", "core_a_clk";
+
+ qcom,coresight-jtagmm-cpu = <&CPU0>;
+ };
+
+ jtag_mm5: jtagmm@7d40000 {
+ compatible = "qcom,jtagv8-mm";
+ reg = <0x7d40000 0x1000>;
+ reg-names = "etm-base";
+
+ clocks = <&clock_rpmcc RPM_QDSS_CLK>,
+ <&clock_rpmcc RPM_QDSS_A_CLK>;
+ clock-names = "core_clk", "core_a_clk";
+
+ qcom,coresight-jtagmm-cpu = <&CPU1>;
+ };
+
+ jtag_mm6: jtagmm@7e40000 {
+ compatible = "qcom,jtagv8-mm";
+ reg = <0x7e40000 0x1000>;
+ reg-names = "etm-base";
+
+ clocks = <&clock_rpmcc RPM_QDSS_CLK>,
+ <&clock_rpmcc RPM_QDSS_A_CLK>;
+ clock-names = "core_clk", "core_a_clk";
+
+ qcom,coresight-jtagmm-cpu = <&CPU2>;
+ };
+
+ jtag_mm7: jtagmm@7f40000 {
+ compatible = "qcom,jtagv8-mm";
+ reg = <0x7f40000 0x1000>;
+ reg-names = "etm-base";
+
+ clocks = <&clock_rpmcc RPM_QDSS_CLK>,
+ <&clock_rpmcc RPM_QDSS_A_CLK>;
+ clock-names = "core_clk", "core_a_clk";
+
+ qcom,coresight-jtagmm-cpu = <&CPU3>;
+ };
+
spmi_bus: qcom,spmi@800f000 {
compatible = "qcom,spmi-pmic-arb";
reg = <0x800f000 0x1000>,
@@ -1541,6 +1829,7 @@
#include "msm-arm-smmu-630.dtsi"
#include "sdm660-camera.dtsi"
#include "sdm630-pm.dtsi"
+#include "sdm660-vidc.dtsi"
&gdsc_usb30 {
status = "ok";
@@ -1608,3 +1897,7 @@
&gdsc_gpu_cx {
status = "ok";
};
+
+&blsp2_uart1_hs {
+ status = "ok";
+};
diff --git a/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi b/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi
index 5bdca492fee2..1145bfa63cba 100644
--- a/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi
@@ -184,6 +184,15 @@
qcom,panel-roi-alignment = <2 2 4 2 1080 2>;
};
+&mdss_dp_ctrl {
+ pinctrl-names = "mdss_dp_active", "mdss_dp_sleep";
+ pinctrl-0 = <&mdss_dp_aux_active &mdss_dp_usbplug_cc_active>;
+ pinctrl-1 = <&mdss_dp_aux_suspend &mdss_dp_usbplug_cc_suspend>;
+ qcom,aux-en-gpio = <&tlmm 55 0>;
+ qcom,aux-sel-gpio = <&tlmm 56 0>;
+ qcom,usbplug-cc-gpio = <&tlmm 58 0>;
+};
+
&sdhc_1 {
/* device core power supply */
vdd-supply = <&pm660l_l4>;
diff --git a/arch/arm/boot/dts/qcom/sdm660-common.dtsi b/arch/arm/boot/dts/qcom/sdm660-common.dtsi
index a5e66f38df3c..5a0997faf133 100644
--- a/arch/arm/boot/dts/qcom/sdm660-common.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-common.dtsi
@@ -11,6 +11,89 @@
*/
&soc {
+ ufsphy1: ufsphy@1da7000 {
+ compatible = "qcom,ufs-phy-qmp-v3-660";
+ reg = <0x1da7000 0xdb8>;
+ reg-names = "phy_mem";
+ #phy-cells = <0>;
+ clock-names = "ref_clk_src",
+ "ref_clk",
+ "ref_aux_clk";
+ clocks = <&clock_rpmcc RPM_LN_BB_CLK1>,
+ <&clock_gcc GCC_UFS_CLKREF_CLK>,
+ <&clock_gcc GCC_UFS_PHY_AUX_CLK>;
+ status = "disabled";
+ };
+
+ ufs1: ufshc@1da4000 {
+ compatible = "qcom,ufshc";
+ reg = <0x1da4000 0x3000>;
+ interrupts = <0 265 0>;
+ phys = <&ufsphy1>;
+ phy-names = "ufsphy";
+
+ clock-names =
+ "core_clk",
+ "bus_aggr_clk",
+ "iface_clk",
+ "core_clk_unipro",
+ "core_clk_ice",
+ "ref_clk",
+ "tx_lane0_sync_clk",
+ "rx_lane0_sync_clk";
+ clocks =
+ <&clock_gcc GCC_UFS_AXI_CLK>,
+ <&clock_gcc GCC_AGGRE2_UFS_AXI_CLK>,
+ <&clock_gcc GCC_UFS_AHB_CLK>,
+ <&clock_gcc GCC_UFS_UNIPRO_CORE_CLK>,
+ <&clock_gcc GCC_UFS_ICE_CORE_CLK>,
+ <&clock_rpmcc RPM_LN_BB_CLK1>,
+ <&clock_gcc GCC_UFS_TX_SYMBOL_0_CLK>,
+ <&clock_gcc GCC_UFS_RX_SYMBOL_0_CLK>;
+ freq-table-hz =
+ <50000000 200000000>,
+ <0 0>,
+ <0 0>,
+ <37500000 150000000>,
+ <75000000 300000000>,
+ <0 0>,
+ <0 0>,
+ <0 0>;
+
+ lanes-per-direction = <1>;
+
+ qcom,msm-bus,name = "ufs1";
+ qcom,msm-bus,num-cases = <12>;
+ qcom,msm-bus,num-paths = <2>;
+ qcom,msm-bus,vectors-KBps =
+ <95 512 0 0>, <1 650 0 0>, /* No vote */
+ <95 512 922 0>, <1 650 1000 0>, /* PWM G1 */
+ <95 512 1844 0>, <1 650 1000 0>, /* PWM G2 */
+ <95 512 3688 0>, <1 650 1000 0>, /* PWM G3 */
+ <95 512 7376 0>, <1 650 1000 0>, /* PWM G4 */
+ <95 512 127796 0>, <1 650 1000 0>, /* HS G1 RA */
+ <95 512 255591 0>, <1 650 1000 0>, /* HS G2 RA */
+ <95 512 2097152 0>, <1 650 102400 0>, /* HS G3 RA */
+ <95 512 149422 0>, <1 650 1000 0>, /* HS G1 RB */
+ <95 512 298189 0>, <1 650 1000 0>, /* HS G2 RB */
+ <95 512 2097152 0>, <1 650 102400 0>, /* HS G3 RB */
+ <95 512 7643136 0>, <1 650 307200 0>; /* Max. bandwidth */
+ qcom,bus-vector-names = "MIN",
+ "PWM_G1_L1", "PWM_G2_L1", "PWM_G3_L1", "PWM_G4_L1",
+ "HS_RA_G1_L1", "HS_RA_G2_L1", "HS_RA_G3_L1",
+ "HS_RB_G1_L1", "HS_RB_G2_L1", "HS_RB_G3_L1",
+ "MAX";
+
+ qcom,pm-qos-cpu-groups = <0x0F 0xF0>;
+ qcom,pm-qos-cpu-group-latency-us = <26 26>;
+ qcom,pm-qos-default-cpu = <0>;
+
+ resets = <&clock_gcc GCC_UFS_BCR>;
+ reset-names = "core_reset";
+
+ status = "disabled";
+ };
+
usb3: ssusb@a800000 {
compatible = "qcom,dwc-usb3-msm";
reg = <0x0a800000 0xfc100>,
diff --git a/arch/arm/boot/dts/qcom/sdm660-gpu.dtsi b/arch/arm/boot/dts/qcom/sdm660-gpu.dtsi
index 2adc4cfae77f..e5cf0b1534ec 100644
--- a/arch/arm/boot/dts/qcom/sdm660-gpu.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-gpu.dtsi
@@ -58,8 +58,9 @@
label = "kgsl-3d0";
compatible = "qcom,kgsl-3d0", "qcom,kgsl-3d";
status = "ok";
- reg = <0x5000000 0x40000>;
- reg-names = "kgsl_3d0_reg_memory";
+ reg = <0x5000000 0x40000
+ 0x780000 0x6220>;
+ reg-names = "kgsl_3d0_reg_memory", "qfprom_memory";
interrupts = <0 300 0>;
interrupt-names = "kgsl_3d0_irq";
qcom,id = <0>;
@@ -70,7 +71,6 @@
/* <HZ/12> */
qcom,idle-timeout = <80>;
- qcom,no-nap;
qcom,highest-bank-bit = <14>;
@@ -135,6 +135,8 @@
/* Context aware jump target power level */
qcom,ca-target-pwrlevel = <4>;
+ qcom,gpu-speed-bin = <0x41a0 0x1fe00000 21>;
+
/* GPU Mempools */
qcom,gpu-mempools {
#address-cells= <1>;
@@ -155,92 +157,349 @@
};
};
- /* Power levels */
- qcom,gpu-pwrlevels {
+ /*
+ * Speed-bin zero is default speed bin.
+ * For rest of the speed bins, speed-bin value
+ * is calulated as FMAX/4.8 MHz round up to zero
+ * decimal places.
+ */
+ qcom,gpu-pwrlevel-bins {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "qcom,gpu-pwrlevels";
-
- /* TURBO */
- qcom,gpu-pwrlevel@0 {
- reg = <0>;
- qcom,gpu-freq = <750000000>;
- qcom,bus-freq = <13>;
- qcom,bus-min = <12>;
- qcom,bus-max = <13>;
- };
-
- /* TURBO */
- qcom,gpu-pwrlevel@1 {
- reg = <1>;
- qcom,gpu-freq = <700000000>;
- qcom,bus-freq = <11>;
- qcom,bus-min = <11>;
- qcom,bus-max = <13>;
- };
-
- /* NOM_L1 */
- qcom,gpu-pwrlevel@2 {
- reg = <2>;
- qcom,gpu-freq = <647000000>;
- qcom,bus-freq = <11>;
- qcom,bus-min = <10>;
- qcom,bus-max = <12>;
- };
-
- /* NOM */
- qcom,gpu-pwrlevel@3 {
- reg = <3>;
- qcom,gpu-freq = <588000000>;
- qcom,bus-freq = <10>;
- qcom,bus-min = <9>;
- qcom,bus-max = <12>;
- };
-
- /* SVS_L1 */
- qcom,gpu-pwrlevel@4 {
- reg = <4>;
- qcom,gpu-freq = <465000000>;
- qcom,bus-freq = <9>;
- qcom,bus-min = <8>;
- qcom,bus-max = <11>;
- };
-
- /* SVS */
- qcom,gpu-pwrlevel@5 {
- reg = <5>;
- qcom,gpu-freq = <370000000>;
- qcom,bus-freq = <8>;
- qcom,bus-min = <6>;
- qcom,bus-max = <9>;
+ compatible="qcom,gpu-pwrlevel-bins";
+
+ qcom,gpu-pwrlevels-0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,speed-bin = <0>;
+
+ qcom,initial-pwrlevel = <6>;
+
+ /* TURBO */
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <750000000>;
+ qcom,bus-freq = <13>;
+ qcom,bus-min = <12>;
+ qcom,bus-max = <13>;
+ };
+
+ /* TURBO */
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gpu-freq = <700000000>;
+ qcom,bus-freq = <11>;
+ qcom,bus-min = <11>;
+ qcom,bus-max = <13>;
+ };
+
+ /* NOM_L1 */
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
+ qcom,gpu-freq = <647000000>;
+ qcom,bus-freq = <11>;
+ qcom,bus-min = <10>;
+ qcom,bus-max = <12>;
+ };
+
+ /* NOM */
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
+ qcom,gpu-freq = <588000000>;
+ qcom,bus-freq = <10>;
+ qcom,bus-min = <9>;
+ qcom,bus-max = <12>;
+ };
+
+ /* SVS_L1 */
+ qcom,gpu-pwrlevel@4 {
+ reg = <4>;
+ qcom,gpu-freq = <465000000>;
+ qcom,bus-freq = <9>;
+ qcom,bus-min = <8>;
+ qcom,bus-max = <11>;
+ };
+
+ /* SVS */
+ qcom,gpu-pwrlevel@5 {
+ reg = <5>;
+ qcom,gpu-freq = <370000000>;
+ qcom,bus-freq = <8>;
+ qcom,bus-min = <6>;
+ qcom,bus-max = <9>;
+ };
+
+ /* Low SVS */
+ qcom,gpu-pwrlevel@6 {
+ reg = <6>;
+ qcom,gpu-freq = <266000000>;
+ qcom,bus-freq = <3>;
+ qcom,bus-min = <3>;
+ qcom,bus-max = <6>;
+ };
+
+ /* Min SVS */
+ qcom,gpu-pwrlevel@7 {
+ reg = <7>;
+ qcom,gpu-freq = <160000000>;
+ qcom,bus-freq = <3>;
+ qcom,bus-min = <3>;
+ qcom,bus-max = <5>;
+ };
+
+ /* XO */
+ qcom,gpu-pwrlevel@8 {
+ reg = <8>;
+ qcom,gpu-freq = <19200000>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
+ };
};
- /* Low SVS */
- qcom,gpu-pwrlevel@6 {
- reg = <6>;
- qcom,gpu-freq = <266000000>;
- qcom,bus-freq = <3>;
- qcom,bus-min = <3>;
- qcom,bus-max = <6>;
+ qcom,gpu-pwrlevels-1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,speed-bin = <157>;
+
+ qcom,initial-pwrlevel = <6>;
+
+ /* TURBO */
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <750000000>;
+ qcom,bus-freq = <13>;
+ qcom,bus-min = <12>;
+ qcom,bus-max = <13>;
+ };
+
+ /* TURBO */
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gpu-freq = <700000000>;
+ qcom,bus-freq = <11>;
+ qcom,bus-min = <11>;
+ qcom,bus-max = <13>;
+ };
+
+ /* NOM_L1 */
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
+ qcom,gpu-freq = <647000000>;
+ qcom,bus-freq = <11>;
+ qcom,bus-min = <10>;
+ qcom,bus-max = <12>;
+ };
+
+ /* NOM */
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
+ qcom,gpu-freq = <588000000>;
+ qcom,bus-freq = <10>;
+ qcom,bus-min = <9>;
+ qcom,bus-max = <12>;
+ };
+
+ /* SVS_L1 */
+ qcom,gpu-pwrlevel@4 {
+ reg = <4>;
+ qcom,gpu-freq = <465000000>;
+ qcom,bus-freq = <9>;
+ qcom,bus-min = <8>;
+ qcom,bus-max = <11>;
+ };
+
+ /* SVS */
+ qcom,gpu-pwrlevel@5 {
+ reg = <5>;
+ qcom,gpu-freq = <370000000>;
+ qcom,bus-freq = <8>;
+ qcom,bus-min = <6>;
+ qcom,bus-max = <9>;
+ };
+
+ /* Low SVS */
+ qcom,gpu-pwrlevel@6 {
+ reg = <6>;
+ qcom,gpu-freq = <266000000>;
+ qcom,bus-freq = <3>;
+ qcom,bus-min = <3>;
+ qcom,bus-max = <6>;
+ };
+
+ /* Min SVS */
+ qcom,gpu-pwrlevel@7 {
+ reg = <7>;
+ qcom,gpu-freq = <160000000>;
+ qcom,bus-freq = <3>;
+ qcom,bus-min = <3>;
+ qcom,bus-max = <5>;
+ };
+
+ /* XO */
+ qcom,gpu-pwrlevel@8 {
+ reg = <8>;
+ qcom,gpu-freq = <19200000>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
+ };
};
- /* Min SVS */
- qcom,gpu-pwrlevel@7 {
- reg = <7>;
- qcom,gpu-freq = <160000000>;
- qcom,bus-freq = <3>;
- qcom,bus-min = <3>;
- qcom,bus-max = <5>;
+ qcom,gpu-pwrlevels-2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,speed-bin = <146>;
+
+ qcom,initial-pwrlevel = <5>;
+
+ /* TURBO */
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <700000000>;
+ qcom,bus-freq = <13>;
+ qcom,bus-min = <12>;
+ qcom,bus-max = <13>;
+ };
+
+ /* NOM_L1 */
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gpu-freq = <647000000>;
+ qcom,bus-freq = <11>;
+ qcom,bus-min = <10>;
+ qcom,bus-max = <12>;
+ };
+
+ /* NOM */
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
+ qcom,gpu-freq = <588000000>;
+ qcom,bus-freq = <10>;
+ qcom,bus-min = <9>;
+ qcom,bus-max = <12>;
+ };
+
+ /* SVS_L1 */
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
+ qcom,gpu-freq = <465000000>;
+ qcom,bus-freq = <9>;
+ qcom,bus-min = <8>;
+ qcom,bus-max = <11>;
+ };
+
+ /* SVS */
+ qcom,gpu-pwrlevel@4 {
+ reg = <4>;
+ qcom,gpu-freq = <370000000>;
+ qcom,bus-freq = <8>;
+ qcom,bus-min = <6>;
+ qcom,bus-max = <9>;
+ };
+
+ /* Low SVS */
+ qcom,gpu-pwrlevel@5 {
+ reg = <5>;
+ qcom,gpu-freq = <266000000>;
+ qcom,bus-freq = <3>;
+ qcom,bus-min = <3>;
+ qcom,bus-max = <6>;
+ };
+
+ /* Min SVS */
+ qcom,gpu-pwrlevel@6 {
+ reg = <6>;
+ qcom,gpu-freq = <160000000>;
+ qcom,bus-freq = <3>;
+ qcom,bus-min = <3>;
+ qcom,bus-max = <5>;
+ };
+
+ /* XO */
+ qcom,gpu-pwrlevel@7 {
+ reg = <7>;
+ qcom,gpu-freq = <19200000>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
+ };
};
- /* XO */
- qcom,gpu-pwrlevel@8 {
- reg = <8>;
- qcom,gpu-freq = <19200000>;
- qcom,bus-freq = <0>;
- qcom,bus-min = <0>;
- qcom,bus-max = <0>;
+ qcom,gpu-pwrlevels-3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,speed-bin = <135>;
+
+ qcom,initial-pwrlevel = <4>;
+
+ /* NOM_L1 */
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <647000000>;
+ qcom,bus-freq = <13>;
+ qcom,bus-min = <12>;
+ qcom,bus-max = <13>;
+ };
+
+ /* NOM */
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gpu-freq = <588000000>;
+ qcom,bus-freq = <10>;
+ qcom,bus-min = <9>;
+ qcom,bus-max = <12>;
+ };
+
+ /* SVS_L1 */
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
+ qcom,gpu-freq = <465000000>;
+ qcom,bus-freq = <9>;
+ qcom,bus-min = <8>;
+ qcom,bus-max = <11>;
+ };
+
+ /* SVS */
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
+ qcom,gpu-freq = <370000000>;
+ qcom,bus-freq = <8>;
+ qcom,bus-min = <6>;
+ qcom,bus-max = <9>;
+ };
+
+ /* Low SVS */
+ qcom,gpu-pwrlevel@4 {
+ reg = <4>;
+ qcom,gpu-freq = <266000000>;
+ qcom,bus-freq = <3>;
+ qcom,bus-min = <3>;
+ qcom,bus-max = <6>;
+ };
+
+ /* Min SVS */
+ qcom,gpu-pwrlevel@5 {
+ reg = <5>;
+ qcom,gpu-freq = <160000000>;
+ qcom,bus-freq = <3>;
+ qcom,bus-min = <3>;
+ qcom,bus-max = <5>;
+ };
+
+ /* XO */
+ qcom,gpu-pwrlevel@6 {
+ reg = <6>;
+ qcom,gpu-freq = <19200000>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/qcom/sdm660-mdss-panels.dtsi b/arch/arm/boot/dts/qcom/sdm660-mdss-panels.dtsi
index a0cc0a6180e5..ce8273e4f1b8 100644
--- a/arch/arm/boot/dts/qcom/sdm660-mdss-panels.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-mdss-panels.dtsi
@@ -33,7 +33,7 @@
qcom,panel-supply-entry@0 {
reg = <0>;
qcom,supply-name = "wqhd-vddio";
- qcom,supply-min-voltage = <1880000>;
+ qcom,supply-min-voltage = <1800000>;
qcom,supply-max-voltage = <1950000>;
qcom,supply-enable-load = <32000>;
qcom,supply-disable-load = <80>;
@@ -196,19 +196,23 @@
};
&dsi_nt35695b_truly_fhd_video {
- qcom,mdss-dsi-panel-timings-phy-v2 = [23 1e 07 08 05 03 04 a0
- 23 1e 07 08 05 03 04 a0
- 23 1e 07 08 05 03 04 a0
- 23 1e 07 08 05 03 04 a0
- 23 18 07 08 04 03 04 a0];
+ qcom,mdss-dsi-panel-timings-phy-v2 = [24 1e 08 09 05 03 04 a0
+ 24 1e 08 09 05 03 04 a0
+ 24 1e 08 09 05 03 04 a0
+ 24 1e 08 09 05 03 04 a0
+ 24 1a 08 09 05 03 04 a0];
+ qcom,mdss-dsi-min-refresh-rate = <48>;
+ qcom,mdss-dsi-max-refresh-rate = <60>;
+ qcom,mdss-dsi-pan-enable-dynamic-fps;
+ qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp";
};
&dsi_nt35695b_truly_fhd_cmd {
- qcom,mdss-dsi-panel-timings-phy-v2 = [23 1e 07 08 05 03 04 a0
- 23 1e 07 08 05 03 04 a0
- 23 1e 07 08 05 03 04 a0
- 23 1e 07 08 05 03 04 a0
- 23 18 07 08 04 03 04 a0];
+ qcom,mdss-dsi-panel-timings-phy-v2 = [24 1e 08 09 05 03 04 a0
+ 24 1e 08 09 05 03 04 a0
+ 24 1e 08 09 05 03 04 a0
+ 24 1e 08 09 05 03 04 a0
+ 24 1a 08 09 05 03 04 a0];
};
&dsi_truly_1080_vid {
diff --git a/arch/arm/boot/dts/qcom/sdm660-mdss-pll.dtsi b/arch/arm/boot/dts/qcom/sdm660-mdss-pll.dtsi
index d2134c56541e..69d3736d4ba8 100644
--- a/arch/arm/boot/dts/qcom/sdm660-mdss-pll.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-mdss-pll.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -79,4 +79,39 @@
};
};
};
+
+ mdss_dp_pll: qcom,mdss_dp_pll@c011000 {
+ compatible = "qcom,mdss_dp_pll_sdm660";
+ status = "ok";
+ label = "MDSS DP PLL";
+ cell-index = <0>;
+ #clock-cells = <1>;
+
+ reg = <0xc011c00 0x190>,
+ <0xc011000 0x910>,
+ <0x0c8c2300 0x8>;
+ reg-names = "pll_base", "phy_base", "gdsc_base";
+
+ gdsc-supply = <&gdsc_mdss>;
+
+ clocks = <&clock_mmss MMSS_MDSS_AHB_CLK>,
+ <&clock_rpmcc RPM_LN_BB_CLK1>,
+ <&clock_gcc GCC_USB3_CLKREF_CLK>;
+ clock-names = "iface_clk", "ref_clk_src", "ref_clk";
+ clock-rate = <0>;
+
+ qcom,platform-supply-entries {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,platform-supply-entry@0 {
+ reg = <0>;
+ qcom,supply-name = "gdsc";
+ qcom,supply-min-voltage = <0>;
+ qcom,supply-max-voltage = <0>;
+ qcom,supply-enable-load = <0>;
+ qcom,supply-disable-load = <0>;
+ };
+ };
+ };
};
diff --git a/arch/arm/boot/dts/qcom/sdm660-mdss.dtsi b/arch/arm/boot/dts/qcom/sdm660-mdss.dtsi
index 5257e79816a3..b7329121ca49 100644
--- a/arch/arm/boot/dts/qcom/sdm660-mdss.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-mdss.dtsi
@@ -46,8 +46,9 @@
/* VBIF QoS remapper settings*/
qcom,mdss-vbif-qos-rt-setting = <1 2 2 2>;
- qcom,vbif-settings = <0x00ac 0x00000040>,
- <0x00d0 0x00001010>; /* v1 only */
+ qcom,mdss-vbif-qos-nrt-setting = <1 1 1 1>;
+ qcom,vbif-settings = <0x00ac 0x00008040>,
+ <0x00d0 0x00002828>;
qcom,mdss-has-panic-ctrl;
qcom,mdss-per-pipe-panic-luts = <0x000f>,
@@ -127,7 +128,7 @@
<0x012ac 0xc0000ccc>,
<0x012b4 0xc0000ccc>,
<0x012bc 0x00cccccc>,
- <0x012c4 0x000000cc>,
+ <0x012c4 0x0000cccc>,
<0x013a8 0x0cccc0c0>,
<0x013b0 0xccccc0c0>,
<0x013b8 0xcccc0000>,
@@ -436,7 +437,7 @@
};
msm_ext_disp: qcom,msm_ext_disp {
- status = "disabled";
+ status = "ok";
compatible = "qcom,msm-ext-disp";
ext_disp_audio_codec: qcom,msm-ext-disp-audio-codec-rx {
@@ -446,16 +447,16 @@
};
mdss_dp_ctrl: qcom,dp_ctrl@c990000 {
- status = "disabled";
+ status = "ok";
cell-index = <0>;
compatible = "qcom,mdss-dp";
qcom,mdss-fb-map = <&mdss_fb2>;
gdsc-supply = <&gdsc_mdss>;
- vdda-1p2-supply = <&pm660_l1>;
+ vdda-1p8-supply = <&pm660_l10>;
vdda-0p9-supply = <&pm660l_l1>;
- reg = <0xc990000 0xa84>,
+ reg = <0xc990000 0xa8c>,
<0xc011000 0x910>,
<0x1fcb200 0x050>,
<0xc8c2200 0x1a0>,
@@ -464,8 +465,37 @@
reg-names = "dp_ctrl", "dp_phy", "tcsr_regs", "dp_mmss_cc",
"qfprom_physical","hdcp_physical";
+ clocks = <&clock_mmss MMSS_MNOC_AHB_CLK>,
+ <&clock_mmss MMSS_MDSS_AHB_CLK>,
+ <&clock_mmss MMSS_MDSS_AXI_CLK>,
+ <&clock_mmss MMSS_MDSS_MDP_CLK>,
+ <&clock_mmss MMSS_MDSS_HDMI_DP_AHB_CLK>,
+ <&clock_mmss MMSS_MDSS_DP_AUX_CLK>,
+ <&clock_rpmcc RPM_LN_BB_CLK1>,
+ <&clock_gcc GCC_USB3_CLKREF_CLK>,
+ <&clock_gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
+ <&clock_mmss MMSS_MDSS_DP_LINK_CLK>,
+ <&clock_mmss MMSS_MDSS_DP_LINK_INTF_CLK>,
+ <&clock_mmss MMSS_MDSS_DP_CRYPTO_CLK>,
+ <&clock_mmss MMSS_MDSS_DP_PIXEL_CLK>,
+ <&clock_mmss DP_PIXEL_CLK_SRC>,
+ <&mdss_dp_pll DP_VCO_DIVIDED_CLK_SRC_MUX>;
+ clock-names = "core_mnoc_clk", "core_iface_clk", "core_bus_clk",
+ "core_mdp_core_clk", "core_alt_iface_clk",
+ "core_aux_clk", "core_ref_clk_src", "core_ref_clk",
+ "core_ahb_phy_clk", "ctrl_link_clk",
+ "ctrl_link_iface_clk", "ctrl_crypto_clk",
+ "ctrl_pixel_clk", "pixel_clk_rcg", "pixel_parent";
+
+ qcom,dp-usbpd-detection = <&pm660_pdphy>;
+
qcom,msm_ext_disp = <&msm_ext_disp>;
+ qcom,aux-cfg-settings = [00 13 00 00 0a 28 0a 03 b7 03];
+ qcom,logical2physical-lane-map = [00 01 02 03];
+ qcom,phy-register-offset = <0x4>;
+ qcom,max-pclk-frequency-khz = <593470>;
+
qcom,core-supply-entries {
#address-cells = <1>;
#size-cells = <0>;
@@ -486,9 +516,9 @@
qcom,ctrl-supply-entry@0 {
reg = <0>;
- qcom,supply-name = "vdda-1p2";
- qcom,supply-min-voltage = <1200000>;
- qcom,supply-max-voltage = <1250000>;
+ qcom,supply-name = "vdda-1p8";
+ qcom,supply-min-voltage = <1780000>;
+ qcom,supply-max-voltage = <1950000>;
qcom,supply-enable-load = <12560>;
qcom,supply-disable-load = <4>;
};
diff --git a/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi b/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi
index b666d846ca04..150b88c10646 100644
--- a/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi
@@ -106,6 +106,15 @@
qcom,platform-te-gpio = <&tlmm 59 0>;
};
+&mdss_dp_ctrl {
+ pinctrl-names = "mdss_dp_active", "mdss_dp_sleep";
+ pinctrl-0 = <&mdss_dp_aux_active &mdss_dp_usbplug_cc_active>;
+ pinctrl-1 = <&mdss_dp_aux_suspend &mdss_dp_usbplug_cc_suspend>;
+ qcom,aux-en-gpio = <&tlmm 55 0>;
+ qcom,aux-sel-gpio = <&tlmm 56 0>;
+ qcom,usbplug-cc-gpio = <&tlmm 58 0>;
+};
+
&pm660l_wled {
qcom,led-strings-list = [01 02];
};
@@ -147,6 +156,20 @@
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
};
+&dsi_nt35695b_truly_fhd_video {
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+};
+
+&dsi_nt35695b_truly_fhd_cmd {
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+};
+
&sdhc_1 {
/* device core power supply */
vdd-supply = <&pm660l_l4>;
diff --git a/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi b/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi
index dbc98a97fc8d..273f196364ce 100644
--- a/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi
@@ -1439,6 +1439,58 @@
};
};
+ mdss_dp_aux_active: mdss_dp_aux_active {
+ mux {
+ pins = "gpio55", "gpio56";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio55", "gpio56";
+ bias-disable = <0>; /* no pull */
+ drive-strength = <8>;
+ };
+ };
+
+ mdss_dp_aux_suspend: mdss_dp_aux_suspend {
+ mux {
+ pins = "gpio55", "gpio56";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio55", "gpio56";
+ bias-pull-down;
+ drive-strength = <2>;
+ };
+ };
+
+ mdss_dp_usbplug_cc_active: mdss_dp_usbplug_cc_active {
+ mux {
+ pins = "gpio58";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio58";
+ bias-disable;
+ drive-strength = <16>;
+ };
+ };
+
+ mdss_dp_usbplug_cc_suspend: mdss_dp_usbplug_cc_suspend {
+ mux {
+ pins = "gpio58";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio58";
+ bias-pull-down;
+ drive-strength = <2>;
+ };
+ };
+
ts_mux {
ts_active: ts_active {
mux {
diff --git a/arch/arm/boot/dts/qcom/sdm660-vidc.dtsi b/arch/arm/boot/dts/qcom/sdm660-vidc.dtsi
index ae3f1949115a..82e6a5be4d10 100644
--- a/arch/arm/boot/dts/qcom/sdm660-vidc.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-vidc.dtsi
@@ -109,8 +109,8 @@
qcom,clock-freq-tbl {
qcom,profile-enc {
qcom,codec-mask = <0x55555555>;
- qcom,cycles-per-mb = <863>;
- qcom,low-power-mode-factor = <35616>;
+ qcom,cycles-per-mb = <931>;
+ qcom,low-power-mode-factor = <33286>;
};
qcom,profile-dec {
qcom,codec-mask = <0xf3ffffff>;
diff --git a/arch/arm/boot/dts/qcom/sdm660.dtsi b/arch/arm/boot/dts/qcom/sdm660.dtsi
index 358ff9c96292..f35619d2a21e 100644
--- a/arch/arm/boot/dts/qcom/sdm660.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660.dtsi
@@ -1251,6 +1251,51 @@
< 2457600 >;
};
+ ufs_ice: ufsice@1db0000 {
+ compatible = "qcom,ice";
+ reg = <0x1db0000 0x8000>;
+ qcom,enable-ice-clk;
+ clock-names = "ufs_core_clk", "bus_clk",
+ "iface_clk", "ice_core_clk";
+ clocks = <&clock_gcc GCC_UFS_AXI_CLK>,
+ <&clock_gcc GCC_UFS_CLKREF_CLK>,
+ <&clock_gcc GCC_UFS_AHB_CLK>,
+ <&clock_gcc GCC_UFS_ICE_CORE_CLK>;
+ qcom,op-freq-hz = <0>, <0>, <0>, <300000000>;
+ vdd-hba-supply = <&gdsc_ufs>;
+ qcom,msm-bus,name = "ufs_ice_noc";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <1 650 0 0>, /* No vote */
+ <1 650 1000 0>; /* Max. bandwidth */
+ qcom,bus-vector-names = "MIN",
+ "MAX";
+ qcom,instance-type = "ufs";
+ };
+
+ sdcc1_ice: sdcc1ice@c0c8000 {
+ compatible = "qcom,ice";
+ reg = <0xc0c8000 0x8000>;
+ qcom,enable-ice-clk;
+ clock-names = "ice_core_clk_src", "ice_core_clk",
+ "bus_clk", "iface_clk";
+ clocks = <&clock_gcc SDCC1_ICE_CORE_CLK_SRC>,
+ <&clock_gcc GCC_SDCC1_ICE_CORE_CLK>,
+ <&clock_gcc GCC_SDCC1_APPS_CLK>,
+ <&clock_gcc GCC_SDCC1_AHB_CLK>;
+ qcom,op-freq-hz = <300000000>, <0>, <0>, <0>;
+ qcom,msm-bus,name = "sdcc_ice_noc";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <78 512 0 0>, /* No vote */
+ <78 512 1000 0>; /* Max. bandwidth */
+ qcom,bus-vector-names = "MIN",
+ "MAX";
+ qcom,instance-type = "sdcc";
+ };
+
sdhc_1: sdhci@c0c4000 {
compatible = "qcom,sdhci-msm-v5";
reg = <0xc0c4000 0x1000>, <0xc0c5000 0x1000>;
@@ -1261,6 +1306,7 @@
qcom,bus-width = <8>;
qcom,large-address-bus;
+ sdhc-msm-crypto = <&sdcc1_ice>;
qcom,devfreq,freq-table = <50000000 200000000>;
@@ -1342,6 +1388,7 @@
qcom,use-ipa-tethering-bridge;
qcom,modem-cfg-emb-pipe-flt;
qcom,ipa-wdi2;
+ qcom,use-dma-zone;
qcom,msm-bus,name = "ipa";
qcom,msm-bus,num-cases = <4>;
qcom,msm-bus,num-paths = <2>;
@@ -1511,7 +1558,7 @@
dcc: dcc@10b3000 {
compatible = "qcom,dcc";
reg = <0x10b3000 0x1000>,
- <0x10b4000 0x2000>;
+ <0x10b4000 0x800>;
reg-names = "dcc-base", "dcc-ram-base";
clocks = <&clock_gcc GCC_DCC_AHB_CLK>;
@@ -2129,6 +2176,7 @@
interrupts = <0 265 0>;
phys = <&ufsphy1>;
phy-names = "ufsphy";
+ ufs-qcom-crypto = <&ufs_ice>;
clock-names =
"core_clk",
diff --git a/arch/arm/configs/sdm660-perf_defconfig b/arch/arm/configs/sdm660-perf_defconfig
index 0028dbbb5c68..d7eb67ff85c1 100644
--- a/arch/arm/configs/sdm660-perf_defconfig
+++ b/arch/arm/configs/sdm660-perf_defconfig
@@ -610,7 +610,6 @@ CONFIG_CORESIGHT_EVENT=y
CONFIG_CORESIGHT_QCOM_REPLICATOR=y
CONFIG_CORESIGHT_STM=y
CONFIG_CORESIGHT_HWEVENT=y
-CONFIG_CORESIGHT_CTI=y
CONFIG_CORESIGHT_TPDA=y
CONFIG_CORESIGHT_TPDM=y
CONFIG_CORESIGHT_QPDI=y
diff --git a/arch/arm/configs/sdm660_defconfig b/arch/arm/configs/sdm660_defconfig
index c2ceac22f15f..dfab3902ec99 100644
--- a/arch/arm/configs/sdm660_defconfig
+++ b/arch/arm/configs/sdm660_defconfig
@@ -7,7 +7,6 @@ CONFIG_RCU_EXPERT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_CPU_MAX_BUF_SHIFT=17
-CONFIG_CGROUPS=y
CONFIG_CGROUP_DEBUG=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CPUSETS=y
@@ -15,7 +14,6 @@ CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_SCHEDTUNE=y
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
-CONFIG_CGROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_SCHED_HMP=y
CONFIG_SCHED_HMP_CSTATE_AWARE=y
@@ -23,6 +21,7 @@ CONFIG_SCHED_CORE_CTL=y
CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set
+CONFIG_SCHED_AUTOGROUP=y
CONFIG_SCHED_TUNE=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_RD_XZ is not set
diff --git a/arch/arm64/configs/sdm660-perf_defconfig b/arch/arm64/configs/sdm660-perf_defconfig
index d8a62f634ecc..b24885a89bff 100644
--- a/arch/arm64/configs/sdm660-perf_defconfig
+++ b/arch/arm64/configs/sdm660-perf_defconfig
@@ -626,7 +626,6 @@ CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
CONFIG_CORESIGHT_QCOM_REPLICATOR=y
CONFIG_CORESIGHT_STM=y
CONFIG_CORESIGHT_HWEVENT=y
-CONFIG_CORESIGHT_CTI=y
CONFIG_CORESIGHT_TPDA=y
CONFIG_CORESIGHT_TPDM=y
CONFIG_CORESIGHT_QPDI=y
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 3c8c1f9acbfa..9a7411a33127 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -815,9 +815,9 @@ static int overlap_ptr_cmp(const void *a, const void *b)
return st == 0 ? ed : st;
}
-static void context_build_overlap(struct smq_invoke_ctx *ctx)
+static int context_build_overlap(struct smq_invoke_ctx *ctx)
{
- int i;
+ int i, err = 0;
remote_arg_t *lpra = ctx->lpra;
int inbufs = REMOTE_SCALARS_INBUFS(ctx->sc);
int outbufs = REMOTE_SCALARS_OUTBUFS(ctx->sc);
@@ -826,6 +826,11 @@ static void context_build_overlap(struct smq_invoke_ctx *ctx)
for (i = 0; i < nbufs; ++i) {
ctx->overs[i].start = (uintptr_t)lpra[i].buf.pv;
ctx->overs[i].end = ctx->overs[i].start + lpra[i].buf.len;
+ if (lpra[i].buf.len) {
+ VERIFY(err, ctx->overs[i].end > ctx->overs[i].start);
+ if (err)
+ goto bail;
+ }
ctx->overs[i].raix = i;
ctx->overps[i] = &ctx->overs[i];
}
@@ -851,6 +856,8 @@ static void context_build_overlap(struct smq_invoke_ctx *ctx)
max = *ctx->overps[i];
}
}
+bail:
+ return err;
}
#define K_COPY_FROM_USER(err, kernel, dst, src, size) \
@@ -923,8 +930,11 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel,
}
ctx->sc = invoke->sc;
- if (bufs)
- context_build_overlap(ctx);
+ if (bufs) {
+ VERIFY(err, 0 == context_build_overlap(ctx));
+ if (err)
+ goto bail;
+ }
ctx->retval = -1;
ctx->pid = current->pid;
ctx->tgid = current->tgid;
@@ -1493,6 +1503,7 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
return err;
}
+static int fastrpc_channel_open(struct fastrpc_file *fl);
static int fastrpc_init_process(struct fastrpc_file *fl,
struct fastrpc_ioctl_init_attrs *uproc)
{
@@ -1501,6 +1512,10 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
struct fastrpc_ioctl_init *init = &uproc->init;
struct smq_phy_page pages[1];
struct fastrpc_mmap *file = 0, *mem = 0;
+
+ VERIFY(err, !fastrpc_channel_open(fl));
+ if (err)
+ goto bail;
if (init->flags == FASTRPC_INIT_ATTACH) {
remote_arg_t ra[1];
int tgid = current->tgid;
@@ -1625,7 +1640,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
fds[2] = 0;
ioctl.inv.handle = 1;
- ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 3, 0);
+ ioctl.inv.sc = REMOTE_SCALARS_MAKE(8, 3, 0);
ioctl.inv.pra = ra;
ioctl.fds = 0;
ioctl.attrs = 0;
@@ -1651,6 +1666,9 @@ static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl)
remote_arg_t ra[1];
int tgid = 0;
+ VERIFY(err, fl->cid >= 0 && fl->cid < NUM_CHANNELS);
+ if (err)
+ goto bail;
VERIFY(err, fl->apps->channel[fl->cid].chan != 0);
if (err)
goto bail;
@@ -2307,42 +2325,20 @@ static const struct file_operations debugfs_fops = {
.open = fastrpc_debugfs_open,
.read = fastrpc_debugfs_read,
};
-
-static int fastrpc_device_open(struct inode *inode, struct file *filp)
+static int fastrpc_channel_open(struct fastrpc_file *fl)
{
- int cid = MINOR(inode->i_rdev);
- struct dentry *debugfs_file;
- int err = 0;
struct fastrpc_apps *me = &gfa;
- struct fastrpc_file *fl = 0;
-
- VERIFY(err, fl = kzalloc(sizeof(*fl), GFP_KERNEL));
- if (err)
- return err;
-
- filp->private_data = fl;
+ int cid, err = 0;
mutex_lock(&me->smd_mutex);
- debugfs_file = debugfs_create_file(current->comm, 0644, debugfs_root,
- fl, &debugfs_fops);
- context_list_ctor(&fl->clst);
- spin_lock_init(&fl->hlock);
- INIT_HLIST_HEAD(&fl->maps);
- INIT_HLIST_HEAD(&fl->bufs);
- INIT_HLIST_NODE(&fl->hn);
- fl->tgid = current->tgid;
- fl->apps = me;
- fl->cid = cid;
- if (debugfs_file != NULL)
- fl->debugfs_file = debugfs_file;
- memset(&fl->perf, 0, sizeof(fl->perf));
-
- VERIFY(err, !fastrpc_session_alloc_locked(&me->channel[cid], 0,
- &fl->sctx));
+ VERIFY(err, fl && fl->sctx);
+ if (err)
+ goto bail;
+ cid = fl->cid;
+ VERIFY(err, cid >= 0 && cid < NUM_CHANNELS);
if (err)
goto bail;
- fl->cid = cid;
fl->ssrcount = me->channel[cid].ssrcount;
if ((kref_get_unless_zero(&me->channel[cid].kref) == 0) ||
(me->channel[cid].chan == 0)) {
@@ -2368,25 +2364,58 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
me->channel[cid].ssrcount;
}
}
- spin_lock(&me->hlock);
- hlist_add_head(&fl->hn, &me->drivers);
- spin_unlock(&me->hlock);
bail:
mutex_unlock(&me->smd_mutex);
-
- if (err && fl)
- fastrpc_device_release(inode, filp);
return err;
}
+static int fastrpc_device_open(struct inode *inode, struct file *filp)
+{
+ int err = 0;
+ struct fastrpc_file *fl = 0;
+ struct fastrpc_apps *me = &gfa;
+
+ VERIFY(err, fl = kzalloc(sizeof(*fl), GFP_KERNEL));
+ if (err)
+ return err;
+
+ context_list_ctor(&fl->clst);
+ spin_lock_init(&fl->hlock);
+ INIT_HLIST_HEAD(&fl->maps);
+ INIT_HLIST_HEAD(&fl->bufs);
+ INIT_HLIST_NODE(&fl->hn);
+ fl->tgid = current->tgid;
+ fl->apps = me;
+ fl->mode = FASTRPC_MODE_SERIAL;
+ fl->cid = -1;
+ filp->private_data = fl;
+ spin_lock(&me->hlock);
+ hlist_add_head(&fl->hn, &me->drivers);
+ spin_unlock(&me->hlock);
+ return 0;
+}
+
static int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info)
{
int err = 0;
+ uint32_t cid;
- VERIFY(err, fl && fl->sctx);
+ VERIFY(err, fl != 0);
if (err)
goto bail;
+ if (fl->cid == -1) {
+ cid = *info;
+ VERIFY(err, cid < NUM_CHANNELS);
+ if (err)
+ goto bail;
+ fl->cid = cid;
+ fl->ssrcount = fl->apps->channel[cid].ssrcount;
+ VERIFY(err, !fastrpc_session_alloc_locked(
+ &fl->apps->channel[cid], 0, &fl->sctx));
+ if (err)
+ goto bail;
+ }
*info = (fl->sctx->smmu.enabled ? 1 : 0);
bail:
return err;
@@ -2487,6 +2516,9 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
goto bail;
break;
case FASTRPC_IOCTL_GETINFO:
+ VERIFY(err, 0 == copy_from_user(&info, param, sizeof(info)));
+ if (err)
+ goto bail;
VERIFY(err, 0 == (err = fastrpc_get_info(fl, &info)));
if (err)
goto bail;
@@ -2802,6 +2834,7 @@ static struct platform_driver fastrpc_driver = {
static int __init fastrpc_device_init(void)
{
struct fastrpc_apps *me = &gfa;
+ struct device *dev = 0;
int err = 0, i;
memset(me, 0, sizeof(*me));
@@ -2818,7 +2851,7 @@ static int __init fastrpc_device_init(void)
cdev_init(&me->cdev, &fops);
me->cdev.owner = THIS_MODULE;
VERIFY(err, 0 == cdev_add(&me->cdev, MKDEV(MAJOR(me->dev_no), 0),
- NUM_CHANNELS));
+ 1));
if (err)
goto cdev_init_bail;
me->class = class_create(THIS_MODULE, "fastrpc");
@@ -2826,15 +2859,14 @@ static int __init fastrpc_device_init(void)
if (err)
goto class_create_bail;
me->compat = (NULL == fops.compat_ioctl) ? 0 : 1;
+ dev = device_create(me->class, NULL,
+ MKDEV(MAJOR(me->dev_no), 0),
+ NULL, gcinfo[0].name);
+ VERIFY(err, !IS_ERR_OR_NULL(dev));
+ if (err)
+ goto device_create_bail;
for (i = 0; i < NUM_CHANNELS; i++) {
- if (!gcinfo[i].name)
- continue;
- me->channel[i].dev = device_create(me->class, NULL,
- MKDEV(MAJOR(me->dev_no), i),
- NULL, gcinfo[i].name);
- VERIFY(err, !IS_ERR(me->channel[i].dev));
- if (err)
- goto device_create_bail;
+ me->channel[i].dev = dev;
me->channel[i].ssrcount = 0;
me->channel[i].prevssrcount = 0;
me->channel[i].ramdumpenabled = 0;
@@ -2853,12 +2885,12 @@ static int __init fastrpc_device_init(void)
return 0;
device_create_bail:
for (i = 0; i < NUM_CHANNELS; i++) {
- if (IS_ERR_OR_NULL(me->channel[i].dev))
- continue;
- device_destroy(me->class, MKDEV(MAJOR(me->dev_no), i));
- subsys_notif_unregister_notifier(me->channel[i].handle,
- &me->channel[i].nb);
+ if (me->channel[i].handle)
+ subsys_notif_unregister_notifier(me->channel[i].handle,
+ &me->channel[i].nb);
}
+ if (!IS_ERR_OR_NULL(dev))
+ device_destroy(me->class, MKDEV(MAJOR(me->dev_no), 0));
class_destroy(me->class);
class_create_bail:
cdev_del(&me->cdev);
diff --git a/drivers/char/adsprpc_compat.c b/drivers/char/adsprpc_compat.c
index f7e84dd55606..fcd6d1142618 100644
--- a/drivers/char/adsprpc_compat.c
+++ b/drivers/char/adsprpc_compat.c
@@ -391,6 +391,10 @@ long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd,
sizeof(*info))));
if (err)
return -EFAULT;
+ err = get_user(u, info32);
+ err |= put_user(u, info);
+ if (err)
+ return err;
ret = filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_GETINFO,
(unsigned long)info);
if (ret)
diff --git a/drivers/char/diag/diagfwd_bridge.c b/drivers/char/diag/diagfwd_bridge.c
index 0462a64614f3..3342984eb795 100644
--- a/drivers/char/diag/diagfwd_bridge.c
+++ b/drivers/char/diag/diagfwd_bridge.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -90,6 +90,18 @@ static int diagfwd_bridge_mux_disconnect(int id, int mode)
{
if (id < 0 || id >= NUM_REMOTE_DEV)
return -EINVAL;
+
+ if ((mode == DIAG_USB_MODE &&
+ driver->logging_mode == DIAG_MEMORY_DEVICE_MODE) ||
+ (mode == DIAG_MEMORY_DEVICE_MODE &&
+ driver->logging_mode == DIAG_USB_MODE)) {
+ /*
+ * Don't close the MHI channels when usb is disconnected
+ * and a process is running in memory device mode.
+ */
+ return 0;
+ }
+
if (bridge_info[id].dev_ops && bridge_info[id].dev_ops->close)
bridge_info[id].dev_ops->close(bridge_info[id].ctxt);
return 0;
diff --git a/drivers/clk/msm/clock-osm.c b/drivers/clk/msm/clock-osm.c
index 79e8a7d8eb00..1639b1b7f94b 100644
--- a/drivers/clk/msm/clock-osm.c
+++ b/drivers/clk/msm/clock-osm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -83,6 +83,7 @@ enum clk_osm_trace_packet_id {
#define VERSION_REG 0x0
#define OSM_TABLE_SIZE 40
+#define MAX_VIRTUAL_CORNER (OSM_TABLE_SIZE - 1)
#define MAX_CLUSTER_CNT 2
#define CORE_COUNT_VAL(val) ((val & GENMASK(18, 16)) >> 16)
#define SINGLE_CORE 1
@@ -1662,6 +1663,14 @@ static int clk_osm_resolve_crossover_corners(struct clk_osm *c,
break;
}
}
+
+ /*
+ * This assumes the OSM table uses corners
+ * 0 to MAX_VIRTUAL_CORNER - 1.
+ */
+ if (!c->mem_acc_threshold_vc)
+ c->mem_acc_threshold_vc =
+ MAX_VIRTUAL_CORNER;
}
return 0;
@@ -3232,9 +3241,10 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev)
return rc;
}
- rc = clk_osm_resolve_crossover_corners(&pwrcl_clk, pdev, NULL);
+ rc = clk_osm_resolve_crossover_corners(&pwrcl_clk, pdev,
+ "qcom,pwrcl-apcs-mem-acc-threshold-voltage");
if (rc)
- dev_info(&pdev->dev, "No APM crossover corner programmed\n");
+ dev_info(&pdev->dev, "No MEM-ACC crossover corner programmed\n");
rc = clk_osm_resolve_crossover_corners(&perfcl_clk, pdev,
"qcom,perfcl-apcs-mem-acc-threshold-voltage");
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 40c592457ea1..6e6adbff4676 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -1111,6 +1111,16 @@ static int clk_dp_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
return clk_dp_set_rate(hw, rate, parent_rate);
}
+static int clk_dp_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ req->best_parent_rate = clk_hw_round_rate(req->best_parent_hw,
+ req->best_parent_rate);
+ req->rate = req->rate;
+
+ return 0;
+}
+
const struct clk_ops clk_dp_ops = {
.is_enabled = clk_rcg2_is_enabled,
.get_parent = clk_rcg2_get_parent,
@@ -1118,7 +1128,7 @@ const struct clk_ops clk_dp_ops = {
.recalc_rate = clk_rcg2_recalc_rate,
.set_rate = clk_dp_set_rate,
.set_rate_and_parent = clk_dp_set_rate_and_parent,
- .determine_rate = clk_pixel_determine_rate,
+ .determine_rate = clk_dp_determine_rate,
.list_registers = clk_rcg2_list_registers,
};
EXPORT_SYMBOL_GPL(clk_dp_ops);
diff --git a/drivers/clk/qcom/mmcc-sdm660.c b/drivers/clk/qcom/mmcc-sdm660.c
index 934779f16107..aec73d62bc18 100644
--- a/drivers/clk/qcom/mmcc-sdm660.c
+++ b/drivers/clk/qcom/mmcc-sdm660.c
@@ -965,8 +965,9 @@ static struct clk_rcg2 dp_pixel_clk_src = {
.parent_names = mmcc_parent_names_6,
.num_parents = 4,
.ops = &clk_dp_ops,
+ .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
VDD_DIG_FMAX_MAP3(
- LOWER, 148380,
+ LOWER, 154000,
LOW, 296740,
NOMINAL, 593470),
},
diff --git a/drivers/crypto/msm/ota_crypto.c b/drivers/crypto/msm/ota_crypto.c
index 9b4a001bec95..674913cb20bf 100644
--- a/drivers/crypto/msm/ota_crypto.c
+++ b/drivers/crypto/msm/ota_crypto.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2014,2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -880,8 +880,8 @@ static ssize_t _debug_stats_read(struct file *file, char __user *buf,
int len;
len = _disp_stats();
-
- rc = simple_read_from_buffer((void __user *) buf, len,
+ if (len <= count)
+ rc = simple_read_from_buffer((void __user *) buf, len,
ppos, (void *) _debug_read_buf, len);
return rc;
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index 8d17ea89e266..ee7e735761e2 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -4967,6 +4967,11 @@ int qce_aead_req(void *handle, struct qce_req *q_req)
else
q_req->cryptlen = areq->cryptlen - authsize;
+ if (q_req->cryptlen > UINT_MAX - areq->assoclen) {
+ pr_err("Integer overflow on total aead req length.\n");
+ return -EINVAL;
+ }
+
totallen = q_req->cryptlen + areq->assoclen;
if (pce_dev->support_cmd_dscr) {
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index a629c621648c..5ce87a6edcc3 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -1987,9 +1987,9 @@ static ssize_t _debug_stats_read(struct file *file, char __user *buf,
len = _disp_stats(qcedev);
- rc = simple_read_from_buffer((void __user *) buf, len,
+ if (len <= count)
+ rc = simple_read_from_buffer((void __user *) buf, len,
ppos, (void *) _debug_read_buf, len);
-
return rc;
}
diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c
index a898dbcbd0ca..893b0b6da6b8 100644
--- a/drivers/crypto/msm/qcrypto.c
+++ b/drivers/crypto/msm/qcrypto.c
@@ -1,6 +1,6 @@
/* Qualcomm Crypto driver
*
- * Copyright (c) 2010-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2010-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -5419,9 +5419,9 @@ static ssize_t _debug_stats_read(struct file *file, char __user *buf,
len = _disp_stats(qcrypto);
- rc = simple_read_from_buffer((void __user *) buf, len,
+ if (len <= count)
+ rc = simple_read_from_buffer((void __user *) buf, len,
ppos, (void *) _debug_read_buf, len);
-
return rc;
}
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 008b8babf31e..d4729fa59edb 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -339,22 +339,23 @@ config GPIO_PXA
Say yes here to support the PXA GPIO device
config GPIO_QPNP_PIN
+ tristate "Qualcomm Technologies, Inc. QPNP GPIO support"
depends on SPMI
- tristate "Qualcomm QPNP gpio support"
help
- Say 'y' here to include support for the Qualcomm QPNP gpio
- driver. This driver supports Device Tree and allows a
- device_node to be registered as a gpio-controller. It
- does not handle gpio interrupts directly, they are handled
- via the spmi arbiter interrupt driver.
+ Say 'y' here to include support for the Qualcomm Technologies, Inc.
+ QPNP GPIO driver. This driver supports Device Tree and allows a
+ device_node to be registered as a gpio-controller. It does not handle
+ GPIO interrupts directly; they are handled via the SPMI arbiter
+ interrupt driver.
config GPIO_QPNP_PIN_DEBUG
- depends on GPIO_QPNP_PIN
- depends on DEBUG_FS
- bool "Qualcomm QPNP GPIO debug support"
+ bool "Qualcomm Technologies, Inc. QPNP GPIO debug support"
+ depends on GPIO_QPNP_PIN && DEBUG_FS
help
- Say 'y' here to include debug support for the Qualcomm
- QPNP gpio driver.
+ Say 'y' here to include debug support for the Qualcomm Technologies,
+ Inc. QPNP GPIO driver. This provides a userspace debug interface to
+ get and set all of the supported features of PMIC GPIO and MPP pins
+ including those which are managed by the gpio framework.
config GPIO_RCAR
tristate "Renesas R-Car GPIO"
diff --git a/drivers/gpio/qpnp-pin.c b/drivers/gpio/qpnp-pin.c
index de24d99ea34e..62cd78a95303 100644
--- a/drivers/gpio/qpnp-pin.c
+++ b/drivers/gpio/qpnp-pin.c
@@ -295,7 +295,7 @@ static int qpnp_pin_check_config(enum qpnp_pin_param_type idx,
if (val >= QPNP_PIN_GPIO_LV_MV_MODE_INVALID)
return -EINVAL;
} else if (val >= QPNP_PIN_GPIO_MODE_INVALID) {
- return -EINVAL;
+ return -EINVAL;
}
} else if (q_spec->type == Q_MPP_TYPE) {
if (val >= QPNP_PIN_MPP_MODE_INVALID)
@@ -753,16 +753,17 @@ int qpnp_pin_config(int gpio, struct qpnp_pin_cfg *param)
}
EXPORT_SYMBOL(qpnp_pin_config);
-#define Q_MAX_CHIP_NAME 128
int qpnp_pin_map(const char *name, uint32_t pmic_pin)
{
struct qpnp_pin_chip *q_chip;
struct qpnp_pin_spec *q_spec = NULL;
+ if (!name)
+ return -EINVAL;
+
mutex_lock(&qpnp_pin_chips_lock);
list_for_each_entry(q_chip, &qpnp_pin_chips, chip_list) {
- if (strncmp(q_chip->gpio_chip.label, name,
- Q_MAX_CHIP_NAME) != 0)
+ if (strcmp(q_chip->gpio_chip.label, name) != 0)
continue;
if (q_chip->pmic_pin_lowest <= pmic_pin &&
q_chip->pmic_pin_highest >= pmic_pin) {
@@ -778,7 +779,7 @@ int qpnp_pin_map(const char *name, uint32_t pmic_pin)
}
EXPORT_SYMBOL(qpnp_pin_map);
-static int qpnp_pin_to_irq(struct gpio_chip *gpio_chip, unsigned offset)
+static int qpnp_pin_to_irq(struct gpio_chip *gpio_chip, unsigned int offset)
{
struct qpnp_pin_chip *q_chip = dev_get_drvdata(gpio_chip->dev);
struct qpnp_pin_spec *q_spec;
@@ -811,14 +812,13 @@ static int qpnp_pin_to_irq(struct gpio_chip *gpio_chip, unsigned offset)
return q_spec->irq;
}
-static int qpnp_pin_get(struct gpio_chip *gpio_chip, unsigned offset)
+static int qpnp_pin_get(struct gpio_chip *gpio_chip, unsigned int offset)
{
- int rc, ret_val;
struct qpnp_pin_chip *q_chip = dev_get_drvdata(gpio_chip->dev);
struct qpnp_pin_spec *q_spec = NULL;
- u8 buf[1], en_mask;
- u8 shift, mask, reg;
- int val;
+ u8 buf, en_mask, shift, mask, reg;
+ unsigned int val;
+ int rc;
if (WARN_ON(!q_chip))
return -ENODEV;
@@ -840,7 +840,9 @@ static int qpnp_pin_get(struct gpio_chip *gpio_chip, unsigned offset)
== QPNP_PIN_MODE_DIG_IN) {
rc = regmap_read(q_chip->regmap,
Q_REG_ADDR(q_spec, Q_REG_STATUS1), &val);
- buf[0] = (u8)val;
+ if (rc)
+ return rc;
+ buf = val;
if (q_spec->type == Q_GPIO_TYPE && q_spec->dig_major_rev == 0)
en_mask = Q_REG_STATUS1_GPIO_EN_REV0_MASK;
@@ -850,26 +852,23 @@ static int qpnp_pin_get(struct gpio_chip *gpio_chip, unsigned offset)
else /* MPP */
en_mask = Q_REG_STATUS1_MPP_EN_MASK;
- if (!(buf[0] & en_mask))
+ if (!(buf & en_mask))
return -EPERM;
- return buf[0] & Q_REG_STATUS1_VAL_MASK;
- } else {
- if (is_gpio_lv_mv(q_spec)) {
- shift = Q_REG_DIG_OUT_SRC_INVERT_SHIFT;
- mask = Q_REG_DIG_OUT_SRC_INVERT_MASK;
- reg = q_spec->regs[Q_REG_I_DIG_OUT_SRC_CTL];
- } else {
- shift = Q_REG_OUT_INVERT_SHIFT;
- mask = Q_REG_OUT_INVERT_MASK;
- reg = q_spec->regs[Q_REG_I_MODE_CTL];
- }
+ return buf & Q_REG_STATUS1_VAL_MASK;
+ }
- ret_val = (reg & mask) >> shift;
- return ret_val;
+ if (is_gpio_lv_mv(q_spec)) {
+ shift = Q_REG_DIG_OUT_SRC_INVERT_SHIFT;
+ mask = Q_REG_DIG_OUT_SRC_INVERT_MASK;
+ reg = q_spec->regs[Q_REG_I_DIG_OUT_SRC_CTL];
+ } else {
+ shift = Q_REG_OUT_INVERT_SHIFT;
+ mask = Q_REG_OUT_INVERT_MASK;
+ reg = q_spec->regs[Q_REG_I_MODE_CTL];
}
- return 0;
+ return (reg & mask) >> shift;
}
static int __qpnp_pin_set(struct qpnp_pin_chip *q_chip,
@@ -905,7 +904,7 @@ static int __qpnp_pin_set(struct qpnp_pin_chip *q_chip,
static void qpnp_pin_set(struct gpio_chip *gpio_chip,
- unsigned offset, int value)
+ unsigned int offset, int value)
{
struct qpnp_pin_chip *q_chip = dev_get_drvdata(gpio_chip->dev);
struct qpnp_pin_spec *q_spec;
@@ -950,7 +949,7 @@ static int qpnp_pin_set_mode(struct qpnp_pin_chip *q_chip,
}
static int qpnp_pin_direction_input(struct gpio_chip *gpio_chip,
- unsigned offset)
+ unsigned int offset)
{
struct qpnp_pin_chip *q_chip = dev_get_drvdata(gpio_chip->dev);
struct qpnp_pin_spec *q_spec;
@@ -966,8 +965,7 @@ static int qpnp_pin_direction_input(struct gpio_chip *gpio_chip,
}
static int qpnp_pin_direction_output(struct gpio_chip *gpio_chip,
- unsigned offset,
- int val)
+ unsigned int offset, int val)
{
int rc;
struct qpnp_pin_chip *q_chip = dev_get_drvdata(gpio_chip->dev);
@@ -1343,7 +1341,7 @@ struct qpnp_pin_debugfs_args {
const char *filename;
};
-static struct qpnp_pin_debugfs_args dfs_args[] = {
+static struct qpnp_pin_debugfs_args dfs_args[Q_NUM_PARAMS] = {
{ Q_PIN_CFG_MODE, "mode" },
{ Q_PIN_CFG_OUTPUT_TYPE, "output_type" },
{ Q_PIN_CFG_INVERT, "invert" },
@@ -1371,8 +1369,6 @@ static int qpnp_pin_debugfs_create(struct qpnp_pin_chip *q_chip)
struct dentry *dfs, *dfs_io_dir;
int i, j, rc;
- BUG_ON(Q_NUM_PARAMS != ARRAY_SIZE(dfs_args));
-
q_chip->dfs_dir = debugfs_create_dir(q_chip->gpio_chip.label,
driver_dfs_dir);
if (q_chip->dfs_dir == NULL) {
@@ -1403,12 +1399,8 @@ static int qpnp_pin_debugfs_create(struct qpnp_pin_chip *q_chip)
continue;
params[type] = type;
- dfs = debugfs_create_file(
- filename,
- S_IRUGO | S_IWUSR,
- dfs_io_dir,
- &q_spec->params[type],
- &qpnp_pin_fops);
+ dfs = debugfs_create_file(filename, 0644, dfs_io_dir,
+ &q_spec->params[type], &qpnp_pin_fops);
if (dfs == NULL)
goto dfs_err;
}
@@ -1674,7 +1666,7 @@ static int qpnp_pin_remove(struct platform_device *pdev)
return qpnp_pin_free_chip(q_chip);
}
-static struct of_device_id spmi_match_table[] = {
+static const struct of_device_id spmi_match_table[] = {
{ .compatible = "qcom,qpnp-pin",
},
{}
diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c
index 15c4b9427f8e..7e2e3aa91fce 100644
--- a/drivers/gpu/msm/adreno_a5xx.c
+++ b/drivers/gpu/msm/adreno_a5xx.c
@@ -1639,7 +1639,8 @@ static void a5xx_pwrlevel_change_settings(struct adreno_device *adreno_dev,
static void a5xx_clk_set_options(struct adreno_device *adreno_dev,
const char *name, struct clk *clk)
{
- if (adreno_is_a540(adreno_dev)) {
+ /* Handle clock settings for GFX PSCBCs */
+ if (adreno_is_a540(adreno_dev) || adreno_is_a512(adreno_dev)) {
if (!strcmp(name, "mem_iface_clk")) {
clk_set_flags(clk, CLKFLAG_NORETAIN_PERIPH);
clk_set_flags(clk, CLKFLAG_NORETAIN_MEM);
diff --git a/drivers/gpu/msm/kgsl_pwrscale.c b/drivers/gpu/msm/kgsl_pwrscale.c
index 413a3098b0ef..7f93ab8fa8d4 100644
--- a/drivers/gpu/msm/kgsl_pwrscale.c
+++ b/drivers/gpu/msm/kgsl_pwrscale.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -917,11 +917,15 @@ int kgsl_pwrscale_init(struct device *dev, const char *governor)
"qcom,enable-midframe-timer")) {
kgsl_midframe = kzalloc(
sizeof(struct kgsl_midframe_info), GFP_KERNEL);
- hrtimer_init(&kgsl_midframe->timer,
- CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- kgsl_midframe->timer.function =
- kgsl_pwrscale_midframe_timer;
- kgsl_midframe->device = device;
+ if (kgsl_midframe) {
+ hrtimer_init(&kgsl_midframe->timer,
+ CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ kgsl_midframe->timer.function =
+ kgsl_pwrscale_midframe_timer;
+ kgsl_midframe->device = device;
+ } else
+ KGSL_PWR_ERR(device,
+ "Failed to enable-midframe-timer feature\n");
}
/*
diff --git a/drivers/iio/adc/qcom-rradc.c b/drivers/iio/adc/qcom-rradc.c
index b7504fdd380f..57145ea72e90 100644
--- a/drivers/iio/adc/qcom-rradc.c
+++ b/drivers/iio/adc/qcom-rradc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -165,10 +165,19 @@
#define FAB_ID_GF 0x30
#define FAB_ID_SMIC 0x11
+#define FAB_ID_660_GF 0x0
+#define FAB_ID_660_TSMC 0x2
+#define FAB_ID_660_MX 0x3
#define FG_ADC_RR_CHG_TEMP_GF_OFFSET_UV 1303168
#define FG_ADC_RR_CHG_TEMP_GF_SLOPE_UV_PER_C 3784
#define FG_ADC_RR_CHG_TEMP_SMIC_OFFSET_UV 1338433
#define FG_ADC_RR_CHG_TEMP_SMIC_SLOPE_UV_PER_C 3655
+#define FG_ADC_RR_CHG_TEMP_660_GF_OFFSET_UV 1309001
+#define FG_RR_CHG_TEMP_660_GF_SLOPE_UV_PER_C 3403
+#define FG_ADC_RR_CHG_TEMP_660_SMIC_OFFSET_UV 1295898
+#define FG_RR_CHG_TEMP_660_SMIC_SLOPE_UV_PER_C 3596
+#define FG_ADC_RR_CHG_TEMP_660_MGNA_OFFSET_UV 1314779
+#define FG_RR_CHG_TEMP_660_MGNA_SLOPE_UV_PER_C 3496
#define FG_ADC_RR_CHG_TEMP_OFFSET_MILLI_DEGC 25000
#define FG_ADC_RR_CHG_THRESHOLD_SCALE 4
@@ -388,23 +397,70 @@ static int rradc_post_process_die_temp(struct rradc_chip *chip,
return 0;
}
+static int rradc_get_660_fab_coeff(struct rradc_chip *chip,
+ int64_t *offset, int64_t *slope)
+{
+ switch (chip->pmic_fab_id->fab_id) {
+ case FAB_ID_660_GF:
+ *offset = FG_ADC_RR_CHG_TEMP_660_GF_OFFSET_UV;
+ *slope = FG_RR_CHG_TEMP_660_GF_SLOPE_UV_PER_C;
+ break;
+ case FAB_ID_660_TSMC:
+ *offset = FG_ADC_RR_CHG_TEMP_660_SMIC_OFFSET_UV;
+ *slope = FG_RR_CHG_TEMP_660_SMIC_SLOPE_UV_PER_C;
+ break;
+ default:
+ *offset = FG_ADC_RR_CHG_TEMP_660_MGNA_OFFSET_UV;
+ *slope = FG_RR_CHG_TEMP_660_MGNA_SLOPE_UV_PER_C;
+ }
+
+ return 0;
+}
+
+static int rradc_get_8998_fab_coeff(struct rradc_chip *chip,
+ int64_t *offset, int64_t *slope)
+{
+ switch (chip->pmic_fab_id->fab_id) {
+ case FAB_ID_GF:
+ *offset = FG_ADC_RR_CHG_TEMP_GF_OFFSET_UV;
+ *slope = FG_ADC_RR_CHG_TEMP_GF_SLOPE_UV_PER_C;
+ break;
+ case FAB_ID_SMIC:
+ *offset = FG_ADC_RR_CHG_TEMP_SMIC_OFFSET_UV;
+ *slope = FG_ADC_RR_CHG_TEMP_SMIC_SLOPE_UV_PER_C;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int rradc_post_process_chg_temp_hot(struct rradc_chip *chip,
struct rradc_chan_prop *prop, u16 adc_code,
int *result_millidegc)
{
int64_t uv = 0, offset = 0, slope = 0;
+ int rc = 0;
if (chip->revid_dev_node) {
- switch (chip->pmic_fab_id->fab_id) {
- case FAB_ID_GF:
- offset = FG_ADC_RR_CHG_TEMP_GF_OFFSET_UV;
- slope = FG_ADC_RR_CHG_TEMP_GF_SLOPE_UV_PER_C;
+ switch (chip->pmic_fab_id->pmic_subtype) {
+ case PM660_SUBTYPE:
+ rc = rradc_get_660_fab_coeff(chip, &offset, &slope);
+ if (rc < 0) {
+ pr_err("Unable to get fab id coefficients\n");
+ return -EINVAL;
+ }
break;
- case FAB_ID_SMIC:
- offset = FG_ADC_RR_CHG_TEMP_SMIC_OFFSET_UV;
- slope = FG_ADC_RR_CHG_TEMP_SMIC_SLOPE_UV_PER_C;
+ case PMI8998_SUBTYPE:
+ rc = rradc_get_8998_fab_coeff(chip, &offset, &slope);
+ if (rc < 0) {
+ pr_err("Unable to get fab id coefficients\n");
+ return -EINVAL;
+ }
break;
default:
+ pr_err("No PMIC subtype found\n");
return -EINVAL;
}
} else {
@@ -444,18 +500,26 @@ static int rradc_post_process_chg_temp(struct rradc_chip *chip,
int *result_millidegc)
{
int64_t uv = 0, offset = 0, slope = 0;
+ int rc = 0;
if (chip->revid_dev_node) {
- switch (chip->pmic_fab_id->fab_id) {
- case FAB_ID_GF:
- offset = FG_ADC_RR_CHG_TEMP_GF_OFFSET_UV;
- slope = FG_ADC_RR_CHG_TEMP_GF_SLOPE_UV_PER_C;
+ switch (chip->pmic_fab_id->pmic_subtype) {
+ case PM660_SUBTYPE:
+ rc = rradc_get_660_fab_coeff(chip, &offset, &slope);
+ if (rc < 0) {
+ pr_err("Unable to get fab id coefficients\n");
+ return -EINVAL;
+ }
break;
- case FAB_ID_SMIC:
- offset = FG_ADC_RR_CHG_TEMP_SMIC_OFFSET_UV;
- slope = FG_ADC_RR_CHG_TEMP_SMIC_SLOPE_UV_PER_C;
+ case PMI8998_SUBTYPE:
+ rc = rradc_get_8998_fab_coeff(chip, &offset, &slope);
+ if (rc < 0) {
+ pr_err("Unable to get fab id coefficients\n");
+ return -EINVAL;
+ }
break;
default:
+ pr_err("No PMIC subtype found\n");
return -EINVAL;
}
} else {
diff --git a/drivers/iio/adc/qcom-tadc.c b/drivers/iio/adc/qcom-tadc.c
index 4a56847a43e7..9241288c1d43 100644
--- a/drivers/iio/adc/qcom-tadc.c
+++ b/drivers/iio/adc/qcom-tadc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -10,6 +10,8 @@
* GNU General Public License for more details.
*/
+#define pr_fmt(fmt) "TADC: %s: " fmt, __func__
+
#include <linux/iio/iio.h>
#include <linux/interrupt.h>
#include <linux/module.h>
@@ -101,8 +103,16 @@ enum tadc_chan_id {
TADC_BATT_P,
TADC_INPUT_P,
TADC_THERM1_THR1,
+ TADC_THERM1_THR2,
+ TADC_THERM1_THR3,
+ TADC_THERM1_THR4,
TADC_THERM2_THR1,
+ TADC_THERM2_THR2,
+ TADC_THERM2_THR3,
TADC_DIE_TEMP_THR1,
+ TADC_DIE_TEMP_THR2,
+ TADC_DIE_TEMP_THR3,
+ TADC_CHAN_ID_MAX,
};
#define TADC_CHAN(_name, _type, _channel, _info_mask) \
@@ -164,19 +174,39 @@ static const struct iio_chan_spec tadc_iio_chans[] = {
[TADC_INPUT_P] = TADC_POWER_CHAN(
"input", TADC_INPUT_P),
[TADC_THERM1_THR1] = TADC_THERM_CHAN(
- "batt_hot", TADC_THERM1_THR1),
+ "batt_warm", TADC_THERM1_THR1),
+ [TADC_THERM1_THR2] = TADC_THERM_CHAN(
+ "batt_cool", TADC_THERM1_THR2),
+ [TADC_THERM1_THR3] = TADC_THERM_CHAN(
+ "batt_cold", TADC_THERM1_THR3),
+ [TADC_THERM1_THR4] = TADC_THERM_CHAN(
+ "batt_hot", TADC_THERM1_THR4),
[TADC_THERM2_THR1] = TADC_THERM_CHAN(
- "skin_hot", TADC_THERM2_THR1),
+ "skin_lb", TADC_THERM2_THR1),
+ [TADC_THERM2_THR2] = TADC_THERM_CHAN(
+ "skin_ub", TADC_THERM2_THR2),
+ [TADC_THERM2_THR3] = TADC_THERM_CHAN(
+ "skin_rst", TADC_THERM2_THR3),
[TADC_DIE_TEMP_THR1] = TADC_THERM_CHAN(
- "die_hot", TADC_DIE_TEMP_THR1),
+ "die_lb", TADC_DIE_TEMP_THR1),
+ [TADC_DIE_TEMP_THR2] = TADC_THERM_CHAN(
+ "die_ub", TADC_DIE_TEMP_THR2),
+ [TADC_DIE_TEMP_THR3] = TADC_THERM_CHAN(
+ "die_rst", TADC_DIE_TEMP_THR3),
+};
+
+struct tadc_therm_thr {
+ int addr_lo;
+ int addr_hi;
};
struct tadc_chan_data {
- s32 scale;
- s32 offset;
- u32 rbias;
- const struct tadc_pt *table;
- size_t tablesize;
+ s32 scale;
+ s32 offset;
+ u32 rbias;
+ const struct tadc_pt *table;
+ size_t tablesize;
+ struct tadc_therm_thr thr[4];
};
struct tadc_chip {
@@ -186,6 +216,7 @@ struct tadc_chip {
u32 tadc_cmp_base;
struct tadc_chan_data chans[TADC_NUM_CH];
struct completion eoc_complete;
+ struct mutex write_lock;
};
struct tadc_pt {
@@ -238,14 +269,24 @@ static const struct tadc_pt tadc_therm_3450b_68k[] = {
{ 1712127, -40000 },
};
-static int tadc_read(struct tadc_chip *chip, u16 reg, u8 *val,
- size_t val_count)
+static bool tadc_is_reg_locked(struct tadc_chip *chip, u16 reg)
+{
+ if ((reg & 0xFF00) == chip->tadc_cmp_base)
+ return true;
+
+ if (reg == TADC_HWTRIG_CONV_CH_EN_REG(chip))
+ return true;
+
+ return false;
+}
+
+static int tadc_read(struct tadc_chip *chip, u16 reg, u8 *val, size_t count)
{
int rc = 0;
- rc = regmap_bulk_read(chip->regmap, reg, val, val_count);
+ rc = regmap_bulk_read(chip->regmap, reg, val, count);
if (rc < 0)
- pr_err("Couldn't read %04x rc=%d\n", reg, rc);
+ pr_err("Couldn't read 0x%04x rc=%d\n", reg, rc);
return rc;
}
@@ -254,57 +295,108 @@ static int tadc_write(struct tadc_chip *chip, u16 reg, u8 data)
{
int rc = 0;
+ mutex_lock(&chip->write_lock);
+ if (tadc_is_reg_locked(chip, reg)) {
+ rc = regmap_write(chip->regmap, (reg & 0xFF00) | 0xD0, 0xA5);
+ if (rc < 0) {
+ pr_err("Couldn't unlock secure register rc=%d\n", rc);
+ goto unlock;
+ }
+ }
+
rc = regmap_write(chip->regmap, reg, data);
- if (rc < 0)
- pr_err("Couldn't write %02x to %04x rc=%d\n",
- data, reg, rc);
+ if (rc < 0) {
+ pr_err("Couldn't write 0x%02x to 0x%04x rc=%d\n",
+ data, reg, rc);
+ goto unlock;
+ }
+
+unlock:
+ mutex_unlock(&chip->write_lock);
+ return rc;
+}
+static int tadc_bulk_write(struct tadc_chip *chip, u16 reg, u8 *data,
+ size_t count)
+{
+ int rc = 0, i;
+
+ mutex_lock(&chip->write_lock);
+ for (i = 0; i < count; ++i, ++reg) {
+ if (tadc_is_reg_locked(chip, reg)) {
+ rc = regmap_write(chip->regmap,
+ (reg & 0xFF00) | 0xD0, 0xA5);
+ if (rc < 0) {
+ pr_err("Couldn't unlock secure register rc=%d\n",
+ rc);
+ goto unlock;
+ }
+ }
+
+ rc = regmap_write(chip->regmap, reg, data[i]);
+ if (rc < 0) {
+ pr_err("Couldn't write 0x%02x to 0x%04x rc=%d\n",
+ data[i], reg, rc);
+ goto unlock;
+ }
+ }
+unlock:
+ mutex_unlock(&chip->write_lock);
return rc;
}
-static int tadc_lerp(const struct tadc_pt *pts, size_t tablesize, s32 input,
- s32 *output)
+static int tadc_lerp(const struct tadc_pt *pts, size_t size, bool inv,
+ s32 input, s32 *output)
{
int i;
s64 temp;
+ bool ascending;
if (pts == NULL) {
pr_err("Table is NULL\n");
return -EINVAL;
}
- if (tablesize < 1) {
+ if (size < 1) {
pr_err("Table has no entries\n");
return -ENOENT;
}
- if (tablesize == 1) {
- *output = pts[0].y;
+ if (size == 1) {
+ *output = inv ? pts[0].x : pts[0].y;
return 0;
}
- if (pts[0].x > pts[1].x) {
- pr_err("Table is not in acending order\n");
- return -EINVAL;
- }
-
- if (input <= pts[0].x) {
- *output = pts[0].y;
+ ascending = inv ? (pts[0].y < pts[1].y) : (pts[0].x < pts[1].x);
+ if (ascending ? (input <= (inv ? pts[0].y : pts[0].x)) :
+ (input >= (inv ? pts[0].y : pts[0].x))) {
+ *output = inv ? pts[0].x : pts[0].y;
return 0;
}
- if (input >= pts[tablesize - 1].x) {
- *output = pts[tablesize - 1].y;
+ if (ascending ? (input >= (inv ? pts[size - 1].y : pts[size - 1].x)) :
+ (input <= (inv ? pts[size - 1].y : pts[size - 1].x))) {
+ *output = inv ? pts[size - 1].x : pts[size - 1].y;
return 0;
}
- for (i = 1; i < tablesize; i++)
- if (input <= pts[i].x)
+ for (i = 1; i < size; i++)
+ if (ascending ? (input <= (inv ? pts[i].y : pts[i].x)) :
+ (input >= (inv ? pts[i].y : pts[i].x)))
break;
- temp = (s64)(pts[i].y - pts[i - 1].y) * (s64)(input - pts[i - 1].x);
- temp = div_s64(temp, pts[i].x - pts[i - 1].x);
- *output = temp + pts[i - 1].y;
+ if (inv) {
+ temp = (s64)(pts[i].x - pts[i - 1].x) *
+ (s64)(input - pts[i - 1].y);
+ temp = div_s64(temp, pts[i].y - pts[i - 1].y);
+ *output = temp + pts[i - 1].x;
+ } else {
+ temp = (s64)(pts[i].y - pts[i - 1].y) *
+ (s64)(input - pts[i - 1].x);
+ temp = div_s64(temp, pts[i].x - pts[i - 1].x);
+ *output = temp + pts[i - 1].y;
+ }
+
return 0;
}
@@ -321,15 +413,32 @@ static int tadc_lerp(const struct tadc_pt *pts, size_t tablesize, s32 input,
* Combine these equations and solve for Rtherm
* Rtherm = (ADC * Rbias) / (1024 - ADC)
*/
-static int tadc_process_therm(const struct tadc_chan_data *chan_data,
- s16 adc, s32 *result)
+static int tadc_get_processed_therm(const struct tadc_chan_data *chan_data,
+ s16 adc, s32 *result)
{
- s64 rtherm;
+ s32 rtherm;
- rtherm = (s64)adc * (s64)chan_data->rbias;
- rtherm = div_s64(rtherm, TADC_RESOLUTION - adc);
- return tadc_lerp(chan_data->table, chan_data->tablesize, rtherm,
- result);
+ rtherm = div_s64((s64)adc * chan_data->rbias, TADC_RESOLUTION - adc);
+ return tadc_lerp(chan_data->table, chan_data->tablesize, false, rtherm,
+ result);
+}
+
+static int tadc_get_raw_therm(const struct tadc_chan_data *chan_data,
+ int mdegc, int *result)
+{
+ int rc;
+ s32 rtherm;
+
+ rc = tadc_lerp(chan_data->table, chan_data->tablesize, true, mdegc,
+ &rtherm);
+ if (rc < 0) {
+ pr_err("Couldn't interpolate %d\n rc=%d", mdegc, rc);
+ return rc;
+ }
+
+ *result = div64_s64((s64)rtherm * TADC_RESOLUTION,
+ (s64)chan_data->rbias + rtherm);
+ return 0;
}
static int tadc_read_channel(struct tadc_chip *chip, u16 address, int *adc)
@@ -339,12 +448,31 @@ static int tadc_read_channel(struct tadc_chip *chip, u16 address, int *adc)
rc = tadc_read(chip, address, val, ARRAY_SIZE(val));
if (rc < 0) {
- dev_err(chip->dev, "Couldn't read channel rc=%d\n", rc);
+ pr_err("Couldn't read channel rc=%d\n", rc);
return rc;
}
- *adc = (s16)(val[0] | val[1] << BITS_PER_BYTE);
- return 0;
+ /* the 10th bit is the sign bit for all channels */
+ *adc = sign_extend32(val[0] | val[1] << BITS_PER_BYTE, 10);
+ return rc;
+}
+
+static int tadc_write_channel(struct tadc_chip *chip, u16 address, int adc)
+{
+ u8 val[2];
+ int rc;
+
+ /* the 10th bit is the sign bit for all channels */
+ adc = sign_extend32(adc, 10);
+ val[0] = (u8)adc;
+ val[1] = (u8)(adc >> BITS_PER_BYTE);
+ rc = tadc_bulk_write(chip, address, val, 2);
+ if (rc < 0) {
+ pr_err("Couldn't write to channel rc=%d\n", rc);
+ return rc;
+ }
+
+ return rc;
}
#define CONVERSION_TIMEOUT_MS 100
@@ -356,8 +484,7 @@ static int tadc_do_conversion(struct tadc_chip *chip, u8 channels, s16 *adc)
rc = tadc_read(chip, TADC_MBG_ERR_REG(chip), val, 1);
if (rc < 0) {
- dev_err(chip->dev, "Couldn't read mbg error status rc=%d\n",
- rc);
+ pr_err("Couldn't read mbg error status rc=%d\n", rc);
return rc;
}
@@ -368,8 +495,7 @@ static int tadc_do_conversion(struct tadc_chip *chip, u8 channels, s16 *adc)
rc = tadc_write(chip, TADC_CONV_REQ_REG(chip), channels);
if (rc < 0) {
- dev_err(chip->dev, "Couldn't write conversion request rc=%d\n",
- rc);
+ pr_err("Couldn't write conversion request rc=%d\n", rc);
return rc;
}
@@ -379,21 +505,19 @@ static int tadc_do_conversion(struct tadc_chip *chip, u8 channels, s16 *adc)
if (timeleft == 0) {
rc = tadc_read(chip, TADC_SW_CH_CONV_REG(chip), val, 1);
if (rc < 0) {
- dev_err(chip->dev, "Couldn't read conversion status rc=%d\n",
- rc);
+ pr_err("Couldn't read conversion status rc=%d\n", rc);
return rc;
}
if (val[0] != channels) {
- dev_err(chip->dev, "Conversion timed out\n");
+ pr_err("Conversion timed out\n");
return -ETIMEDOUT;
}
}
rc = tadc_read(chip, TADC_CH1_ADC_LO_REG(chip), val, ARRAY_SIZE(val));
if (rc < 0) {
- dev_err(chip->dev, "Couldn't read adc channels rc=%d\n",
- rc);
+ pr_err("Couldn't read adc channels rc=%d\n", rc);
return rc;
}
@@ -404,84 +528,102 @@ static int tadc_do_conversion(struct tadc_chip *chip, u8 channels, s16 *adc)
}
static int tadc_read_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan, int *val, int *val2,
- long mask)
+ struct iio_chan_spec const *chan, int *val, int *val2,
+ long mask)
{
struct tadc_chip *chip = iio_priv(indio_dev);
- const struct tadc_chan_data *chan_data = &chip->chans[chan->channel];
- int rc = 0, offset = 0, scale, scale2, scale_type;
+ struct tadc_chan_data *chan_data = NULL;
+ int rc, offset = 0, scale, scale2, scale_type;
s16 adc[TADC_NUM_CH];
switch (chan->channel) {
case TADC_THERM1_THR1:
+ case TADC_THERM1_THR2:
+ case TADC_THERM1_THR3:
+ case TADC_THERM1_THR4:
chan_data = &chip->chans[TADC_THERM1];
break;
case TADC_THERM2_THR1:
+ case TADC_THERM2_THR2:
+ case TADC_THERM2_THR3:
chan_data = &chip->chans[TADC_THERM2];
break;
case TADC_DIE_TEMP_THR1:
+ case TADC_DIE_TEMP_THR2:
+ case TADC_DIE_TEMP_THR3:
chan_data = &chip->chans[TADC_DIE_TEMP];
break;
default:
+ if (chan->channel >= ARRAY_SIZE(chip->chans)) {
+ pr_err("Channel %d is out of bounds\n", chan->channel);
+ return -EINVAL;
+ }
+
+ chan_data = &chip->chans[chan->channel];
break;
}
+ if (!chan_data)
+ return -EINVAL;
+
switch (mask) {
case IIO_CHAN_INFO_RAW:
switch (chan->channel) {
case TADC_THERM1_THR1:
+ case TADC_THERM2_THR1:
+ case TADC_DIE_TEMP_THR1:
rc = tadc_read_channel(chip,
- TADC_CMP_THR1_CH1_CMP_LO_REG(chip), val);
- if (rc < 0) {
- dev_err(chip->dev, "Couldn't read THERM1 threshold rc=%d\n",
- rc);
- return rc;
- }
+ chan_data->thr[0].addr_lo, val);
break;
- case TADC_THERM2_THR1:
+ case TADC_THERM1_THR2:
+ case TADC_THERM2_THR2:
+ case TADC_DIE_TEMP_THR2:
rc = tadc_read_channel(chip,
- TADC_CMP_THR1_CH2_CMP_LO_REG(chip), val);
- if (rc < 0) {
- dev_err(chip->dev, "Couldn't read THERM2 threshold rc=%d\n",
- rc);
- return rc;
- }
+ chan_data->thr[1].addr_lo, val);
break;
- case TADC_DIE_TEMP_THR1:
+ case TADC_THERM1_THR3:
+ case TADC_THERM2_THR3:
+ case TADC_DIE_TEMP_THR3:
rc = tadc_read_channel(chip,
- TADC_CMP_THR1_CH3_CMP_LO_REG(chip), val);
- if (rc < 0) {
- dev_err(chip->dev, "Couldn't read DIE_TEMP threshold rc=%d\n",
- rc);
- return rc;
- }
+ chan_data->thr[2].addr_lo, val);
+ break;
+ case TADC_THERM1_THR4:
+ rc = tadc_read_channel(chip,
+ chan_data->thr[3].addr_lo, val);
break;
default:
rc = tadc_do_conversion(chip, BIT(chan->channel), adc);
- if (rc < 0) {
- dev_err(chip->dev, "Couldn't read channel %d\n",
- chan->channel);
- return rc;
- }
- *val = adc[chan->channel];
+ if (rc >= 0)
+ *val = adc[chan->channel];
break;
}
+
+ if (rc < 0) {
+ pr_err("Couldn't read channel %d\n", chan->channel);
+ return rc;
+ }
+
return IIO_VAL_INT;
case IIO_CHAN_INFO_PROCESSED:
switch (chan->channel) {
case TADC_THERM1:
case TADC_THERM2:
case TADC_THERM1_THR1:
+ case TADC_THERM1_THR2:
+ case TADC_THERM1_THR3:
+ case TADC_THERM1_THR4:
case TADC_THERM2_THR1:
+ case TADC_THERM2_THR2:
+ case TADC_THERM2_THR3:
rc = tadc_read_raw(indio_dev, chan, val, NULL,
- IIO_CHAN_INFO_RAW);
+ IIO_CHAN_INFO_RAW);
if (rc < 0)
return rc;
- rc = tadc_process_therm(chan_data, *val, val);
+ rc = tadc_get_processed_therm(chan_data, *val, val);
if (rc < 0) {
- dev_err(chip->dev, "Couldn't process 0x%04x from channel %d rc=%d\n",
- *val, chan->channel, rc);
+ pr_err("Couldn't process 0x%04x from channel %d rc=%d\n",
+ *val, chan->channel, rc);
return rc;
}
break;
@@ -489,7 +631,8 @@ static int tadc_read_raw(struct iio_dev *indio_dev,
rc = tadc_do_conversion(chip,
BIT(TADC_BATT_I) | BIT(TADC_BATT_V), adc);
if (rc < 0) {
- dev_err(chip->dev, "Couldn't read battery current and voltage channels\n");
+ pr_err("Couldn't read battery current and voltage channels rc=%d\n",
+ rc);
return rc;
}
@@ -499,7 +642,8 @@ static int tadc_read_raw(struct iio_dev *indio_dev,
rc = tadc_do_conversion(chip,
BIT(TADC_INPUT_I) | BIT(TADC_INPUT_V), adc);
if (rc < 0) {
- dev_err(chip->dev, "Couldn't read input current and voltage channels\n");
+ pr_err("Couldn't read input current and voltage channels rc=%d\n",
+ rc);
return rc;
}
@@ -507,13 +651,13 @@ static int tadc_read_raw(struct iio_dev *indio_dev,
break;
default:
rc = tadc_read_raw(indio_dev, chan, val, NULL,
- IIO_CHAN_INFO_RAW);
+ IIO_CHAN_INFO_RAW);
if (rc < 0)
return rc;
/* offset is optional */
rc = tadc_read_raw(indio_dev, chan, &offset, NULL,
- IIO_CHAN_INFO_OFFSET);
+ IIO_CHAN_INFO_OFFSET);
if (rc < 0)
return rc;
@@ -525,18 +669,20 @@ static int tadc_read_raw(struct iio_dev *indio_dev,
break;
case IIO_VAL_FRACTIONAL:
*val = div_s64((s64)*val * scale + offset,
- scale2);
+ scale2);
break;
default:
return -EINVAL;
}
break;
}
+
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
switch (chan->channel) {
case TADC_DIE_TEMP:
case TADC_DIE_TEMP_THR1:
+ case TADC_DIE_TEMP_THR2:
*val = chan_data->scale;
return IIO_VAL_INT;
case TADC_BATT_I:
@@ -548,14 +694,134 @@ static int tadc_read_raw(struct iio_dev *indio_dev,
*val2 = TADC_RESOLUTION;
return IIO_VAL_FRACTIONAL;
}
+
return -EINVAL;
case IIO_CHAN_INFO_OFFSET:
*val = chan_data->offset;
return IIO_VAL_INT;
}
+
return -EINVAL;
}
+static int tadc_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int val, int val2,
+ long mask)
+{
+ struct tadc_chip *chip = iio_priv(indio_dev);
+ const struct tadc_chan_data *chan_data;
+ int rc, raw;
+ s32 rem;
+
+ switch (chan->channel) {
+ case TADC_THERM1_THR1:
+ case TADC_THERM1_THR2:
+ case TADC_THERM1_THR3:
+ case TADC_THERM1_THR4:
+ chan_data = &chip->chans[TADC_THERM1];
+ break;
+ case TADC_THERM2_THR1:
+ case TADC_THERM2_THR2:
+ case TADC_THERM2_THR3:
+ chan_data = &chip->chans[TADC_THERM2];
+ break;
+ case TADC_DIE_TEMP_THR1:
+ case TADC_DIE_TEMP_THR2:
+ case TADC_DIE_TEMP_THR3:
+ chan_data = &chip->chans[TADC_DIE_TEMP];
+ break;
+ default:
+ if (chan->channel >= ARRAY_SIZE(chip->chans)) {
+ pr_err("Channel %d is out of bounds\n", chan->channel);
+ return -EINVAL;
+ }
+
+ chan_data = &chip->chans[chan->channel];
+ break;
+ }
+
+ if (!chan_data)
+ return -EINVAL;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_PROCESSED:
+ switch (chan->channel) {
+ case TADC_THERM1_THR1:
+ case TADC_THERM1_THR2:
+ case TADC_THERM1_THR3:
+ case TADC_THERM1_THR4:
+ case TADC_THERM2_THR1:
+ case TADC_THERM2_THR2:
+ case TADC_THERM2_THR3:
+ rc = tadc_get_raw_therm(chan_data, val, &raw);
+ if (rc < 0) {
+ pr_err("Couldn't get raw value rc=%d\n", rc);
+ return rc;
+ }
+ break;
+ case TADC_DIE_TEMP_THR1:
+ case TADC_DIE_TEMP_THR2:
+ case TADC_DIE_TEMP_THR3:
+ /* DIV_ROUND_CLOSEST does not like negative numbers */
+ raw = div_s64_rem(val - chan_data->offset,
+ chan_data->scale, &rem);
+ if (abs(rem) >= abs(chan_data->scale / 2))
+ raw++;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ rc = tadc_write_raw(indio_dev, chan, raw, 0,
+ IIO_CHAN_INFO_RAW);
+ if (rc < 0) {
+ pr_err("Couldn't write raw rc=%d\n", rc);
+ return rc;
+ }
+
+ break;
+ case IIO_CHAN_INFO_RAW:
+ switch (chan->channel) {
+ case TADC_THERM1_THR1:
+ case TADC_THERM2_THR1:
+ case TADC_DIE_TEMP_THR1:
+ rc = tadc_write_channel(chip,
+ chan_data->thr[0].addr_lo, val);
+ break;
+ case TADC_THERM1_THR2:
+ case TADC_THERM2_THR2:
+ case TADC_DIE_TEMP_THR2:
+ rc = tadc_write_channel(chip,
+ chan_data->thr[1].addr_lo, val);
+ break;
+ case TADC_THERM1_THR3:
+ case TADC_THERM2_THR3:
+ case TADC_DIE_TEMP_THR3:
+ rc = tadc_write_channel(chip,
+ chan_data->thr[2].addr_lo, val);
+ break;
+ case TADC_THERM1_THR4:
+ rc = tadc_write_channel(chip,
+ chan_data->thr[3].addr_lo, val);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (rc < 0) {
+ pr_err("Couldn't write channel %d\n", chan->channel);
+ return rc;
+ }
+
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
static irqreturn_t handle_eoc(int irq, void *dev_id)
{
struct tadc_chip *chip = dev_id;
@@ -587,72 +853,144 @@ static int tadc_parse_dt(struct tadc_chip *chip)
for_each_available_child_of_node(node, child) {
rc = of_property_read_u32(child, "reg", &chan_id);
if (rc < 0) {
- dev_err(chip->dev, "Couldn't find channel for %s rc=%d",
- child->name, rc);
+ pr_err("Couldn't find channel for %s rc=%d",
+ child->name, rc);
return rc;
}
if (chan_id > TADC_NUM_CH - 1) {
- dev_err(chip->dev, "Channel %d is out of range [0, %d]\n",
- chan_id, TADC_NUM_CH - 1);
+ pr_err("Channel %d is out of range [0, %d]\n",
+ chan_id, TADC_NUM_CH - 1);
return -EINVAL;
}
chan_data = &chip->chans[chan_id];
- switch (chan_id) {
- case TADC_THERM1:
- case TADC_THERM2:
+ if (chan_id == TADC_THERM1 || chan_id == TADC_THERM2) {
rc = of_property_read_u32(child,
"qcom,rbias", &chan_data->rbias);
if (rc < 0) {
- dev_err(chip->dev, "Couldn't read qcom,rbias rc=%d\n",
- rc);
+ pr_err("Couldn't read qcom,rbias rc=%d\n", rc);
return rc;
}
rc = of_property_read_u32(child,
"qcom,beta-coefficient", &beta);
if (rc < 0) {
- dev_err(chip->dev, "Couldn't read qcom,beta-coefficient rc=%d\n",
- rc);
+ pr_err("Couldn't read qcom,beta-coefficient rc=%d\n",
+ rc);
return rc;
}
rc = of_property_read_u32(child,
"qcom,rtherm-at-25degc", &rtherm);
if (rc < 0) {
- dev_err(chip->dev, "Couldn't read qcom,rtherm-at-25degc rc=%d\n",
+ pr_err("Couldn't read qcom,rtherm-at-25degc rc=%d\n",
rc);
return rc;
}
rc = tadc_set_therm_table(chan_data, beta, rtherm);
if (rc < 0) {
- dev_err(chip->dev, "Couldn't set therm table rc=%d\n",
- rc);
+ pr_err("Couldn't set therm table rc=%d\n", rc);
return rc;
}
- break;
- default:
+ } else {
rc = of_property_read_s32(child, "qcom,scale",
- &chan_data->scale);
+ &chan_data->scale);
if (rc < 0) {
- dev_err(chip->dev, "Couldn't read scale rc=%d\n",
- rc);
+ pr_err("Couldn't read scale rc=%d\n", rc);
return rc;
}
of_property_read_s32(child, "qcom,offset",
- &chan_data->offset);
- break;
+ &chan_data->offset);
}
}
return rc;
}
+static int tadc_init_hw(struct tadc_chip *chip)
+{
+ int rc;
+
+ chip->chans[TADC_THERM1].thr[0].addr_lo =
+ TADC_CMP_THR1_CH1_CMP_LO_REG(chip);
+ chip->chans[TADC_THERM1].thr[0].addr_hi =
+ TADC_CMP_THR1_CH1_CMP_HI_REG(chip);
+ chip->chans[TADC_THERM1].thr[1].addr_lo =
+ TADC_CMP_THR2_CH1_CMP_LO_REG(chip);
+ chip->chans[TADC_THERM1].thr[1].addr_hi =
+ TADC_CMP_THR2_CH1_CMP_HI_REG(chip);
+ chip->chans[TADC_THERM1].thr[2].addr_lo =
+ TADC_CMP_THR3_CH1_CMP_LO_REG(chip);
+ chip->chans[TADC_THERM1].thr[2].addr_hi =
+ TADC_CMP_THR3_CH1_CMP_HI_REG(chip);
+ chip->chans[TADC_THERM1].thr[3].addr_lo =
+ TADC_CMP_THR4_CH1_CMP_LO_REG(chip);
+ chip->chans[TADC_THERM1].thr[3].addr_hi =
+ TADC_CMP_THR4_CH1_CMP_HI_REG(chip);
+
+ chip->chans[TADC_THERM2].thr[0].addr_lo =
+ TADC_CMP_THR1_CH2_CMP_LO_REG(chip);
+ chip->chans[TADC_THERM2].thr[0].addr_hi =
+ TADC_CMP_THR1_CH2_CMP_HI_REG(chip);
+ chip->chans[TADC_THERM2].thr[1].addr_lo =
+ TADC_CMP_THR2_CH2_CMP_LO_REG(chip);
+ chip->chans[TADC_THERM2].thr[1].addr_hi =
+ TADC_CMP_THR2_CH2_CMP_HI_REG(chip);
+ chip->chans[TADC_THERM2].thr[2].addr_lo =
+ TADC_CMP_THR3_CH2_CMP_LO_REG(chip);
+ chip->chans[TADC_THERM2].thr[2].addr_hi =
+ TADC_CMP_THR3_CH2_CMP_HI_REG(chip);
+
+ chip->chans[TADC_DIE_TEMP].thr[0].addr_lo =
+ TADC_CMP_THR1_CH3_CMP_LO_REG(chip);
+ chip->chans[TADC_DIE_TEMP].thr[0].addr_hi =
+ TADC_CMP_THR1_CH3_CMP_HI_REG(chip);
+ chip->chans[TADC_DIE_TEMP].thr[1].addr_lo =
+ TADC_CMP_THR2_CH3_CMP_LO_REG(chip);
+ chip->chans[TADC_DIE_TEMP].thr[1].addr_hi =
+ TADC_CMP_THR2_CH3_CMP_HI_REG(chip);
+ chip->chans[TADC_DIE_TEMP].thr[2].addr_lo =
+ TADC_CMP_THR3_CH3_CMP_LO_REG(chip);
+ chip->chans[TADC_DIE_TEMP].thr[2].addr_hi =
+ TADC_CMP_THR3_CH3_CMP_HI_REG(chip);
+
+ rc = tadc_write(chip, TADC_CMP_THR1_CMP_REG(chip), 0);
+ if (rc < 0) {
+ pr_err("Couldn't enable hardware triggers rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = tadc_write(chip, TADC_CMP_THR2_CMP_REG(chip), 0);
+ if (rc < 0) {
+ pr_err("Couldn't enable hardware triggers rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = tadc_write(chip, TADC_CMP_THR3_CMP_REG(chip), 0);
+ if (rc < 0) {
+ pr_err("Couldn't enable hardware triggers rc=%d\n", rc);
+ return rc;
+ }
+
+ /* enable all temperature hardware triggers */
+ rc = tadc_write(chip, TADC_HWTRIG_CONV_CH_EN_REG(chip),
+ BIT(TADC_THERM1) |
+ BIT(TADC_THERM2) |
+ BIT(TADC_DIE_TEMP));
+ if (rc < 0) {
+ pr_err("Couldn't enable hardware triggers rc=%d\n", rc);
+ return rc;
+ }
+
+ return 0;
+}
+
static const struct iio_info tadc_info = {
.read_raw = &tadc_read_raw,
+ .write_raw = &tadc_write_raw,
.driver_module = THIS_MODULE,
};
@@ -661,7 +999,7 @@ static int tadc_probe(struct platform_device *pdev)
struct device_node *node = pdev->dev.of_node;
struct iio_dev *indio_dev;
struct tadc_chip *chip;
- int rc = 0, irq;
+ int rc, irq;
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*chip));
if (!indio_dev)
@@ -673,11 +1011,12 @@ static int tadc_probe(struct platform_device *pdev)
rc = of_property_read_u32(node, "reg", &chip->tadc_base);
if (rc < 0) {
- dev_err(chip->dev, "Couldn't read base address rc=%d\n", rc);
+ pr_err("Couldn't read base address rc=%d\n", rc);
return rc;
}
chip->tadc_cmp_base = chip->tadc_base + 0x100;
+ mutex_init(&chip->write_lock);
chip->regmap = dev_get_regmap(chip->dev->parent, NULL);
if (!chip->regmap) {
pr_err("Couldn't get regmap\n");
@@ -690,6 +1029,12 @@ static int tadc_probe(struct platform_device *pdev)
return rc;
}
+ rc = tadc_init_hw(chip);
+ if (rc < 0) {
+ pr_err("Couldn't initialize hardware rc=%d\n", rc);
+ return rc;
+ }
+
irq = of_irq_get_byname(node, "eoc");
if (irq < 0) {
pr_err("Couldn't get eoc irq rc=%d\n", irq);
@@ -697,7 +1042,7 @@ static int tadc_probe(struct platform_device *pdev)
}
rc = devm_request_threaded_irq(chip->dev, irq, NULL, handle_eoc,
- IRQF_ONESHOT, "eoc", chip);
+ IRQF_ONESHOT, "eoc", chip);
if (rc < 0) {
pr_err("Couldn't request irq %d rc=%d\n", irq, rc);
return rc;
@@ -711,10 +1056,12 @@ static int tadc_probe(struct platform_device *pdev)
indio_dev->num_channels = ARRAY_SIZE(tadc_iio_chans);
rc = devm_iio_device_register(chip->dev, indio_dev);
- if (rc < 0)
- dev_err(chip->dev, "Couldn't register IIO device rc=%d\n", rc);
+ if (rc < 0) {
+ pr_err("Couldn't register IIO device rc=%d\n", rc);
+ return rc;
+ }
- return rc;
+ return 0;
}
static int tadc_remove(struct platform_device *pdev)
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index 217e9306aa0f..407b2ef4d2e9 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -664,3 +664,21 @@ err_unlock:
return ret;
}
EXPORT_SYMBOL_GPL(iio_write_channel_raw);
+
+int iio_write_channel_processed(struct iio_channel *chan, int val)
+{
+ int ret;
+
+ mutex_lock(&chan->indio_dev->info_exist_lock);
+ if (chan->indio_dev->info == NULL) {
+ ret = -ENODEV;
+ goto err_unlock;
+ }
+
+ ret = iio_channel_write(chan, val, 0, IIO_CHAN_INFO_PROCESSED);
+err_unlock:
+ mutex_unlock(&chan->indio_dev->info_exist_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(iio_write_channel_processed);
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 0fc18922801e..966227a3df1a 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -581,40 +581,6 @@ config LEDS_POWERNV
depends on LEDS_CLASS
depends on PPC_POWERNV
depends on OF
-
-config LEDS_QPNP
- tristate "Support for QPNP LEDs"
- depends on LEDS_CLASS && SPMI
- help
- This driver supports the leds functionality of Qualcomm PNP PMIC. It
- includes RGB Leds, WLED and Flash Led.
-
- To compile this driver as a module, choose M here: the module will
- be called leds-qpnp.
-
-config LEDS_QPNP_FLASH
- tristate "Support for QPNP Flash LEDs"
- depends on LEDS_CLASS && SPMI
- help
- This driver supports the leds functionality of Qualcomm Technologies
- PNP PMIC. It includes Flash Led.
-
- To compile this driver as a module, choose M here: the module will
- be called leds-qpnp-flash.
-
-config LEDS_QPNP_FLASH_V2
- tristate "Support for QPNP V2 Flash LEDs"
- depends on LEDS_CLASS && MFD_SPMI_PMIC
- help
- This driver supports the leds functionality of Qualcomm Technologies
- PNP PMIC. It includes Flash Led.
-
- To compile this driver as a module, choose M here: the module will
- be called leds-qpnp-flash-v2.
-
-config LEDS_QPNP_WLED
- tristate "Support for QPNP WLED"
- depends on LEDS_CLASS && SPMI
help
This option enables support for the system LEDs present on
PowerNV platforms. Say 'y' to enable this support in kernel.
@@ -625,31 +591,38 @@ config LEDS_QPNP
tristate "Support for QPNP LEDs"
depends on LEDS_CLASS && SPMI
help
- This driver supports the leds functionality of Qualcomm PNP PMIC. It
- includes RGB Leds, WLED and Flash Led.
-
- To compile this driver as a module, choose M here: the module will
- be called leds-qpnp.
+ This driver supports the LED functionality of Qualcomm Technologies,
+ Inc. QPNP PMICs. It primarily supports controlling tri-color RGB
+ LEDs in both PWM and light pattern generator (LPG) modes. For older
+ PMICs, it also supports WLEDs and flash LEDs.
config LEDS_QPNP_FLASH
tristate "Support for QPNP Flash LEDs"
depends on LEDS_CLASS && SPMI
help
- This driver supports the leds functionality of Qualcomm Technologies
- PNP PMIC. It includes Flash Led.
+ This driver supports the flash LED functionality of Qualcomm
+ Technologies, Inc. QPNP PMICs. This driver supports PMICs up through
+ PM8994. It can configure the flash LED target current for several
+ independent channels.
- To compile this driver as a module, choose M here: the module will
- be called leds-qpnp-flash.
+config LEDS_QPNP_FLASH_V2
+ tristate "Support for QPNP V2 Flash LEDs"
+ depends on LEDS_CLASS && MFD_SPMI_PMIC && !LEDS_QPNP_FLASH
+ help
+ This driver supports the flash V2 LED functionality of Qualcomm
+ Technologies, Inc. QPNP PMICs. This driver supports PMICs starting
+ from PMI8998. It can configure the flash LED target current for
+ several independent channels. It also supports various over current
+ and over temperature mitigation features.
config LEDS_QPNP_WLED
tristate "Support for QPNP WLED"
depends on LEDS_CLASS && SPMI
help
- This driver supports the WLED (White LED) functionality of
- Qualcomm Technologies PNP PMIC. WLED is used for display backlight.
-
- To compile this driver as a module, choose M here: the module will
- be called leds-qpnp-wled.
+ This driver supports the WLED (White LED) functionality of Qualcomm
+ Technologies, Inc. QPNP PMICs. WLED is used for LCD backlight with
+ variable brightness. It also supports outputting the Avdd supply for
+ AMOLED displays.
config LEDS_SYSCON
bool "LED support for LEDs on system controllers"
diff --git a/drivers/leds/leds-qpnp-flash-v2.c b/drivers/leds/leds-qpnp-flash-v2.c
index b6aa4a87f31d..08809a93d4b2 100644
--- a/drivers/leds/leds-qpnp-flash-v2.c
+++ b/drivers/leds/leds-qpnp-flash-v2.c
@@ -1166,6 +1166,10 @@ static void qpnp_flash_led_brightness_set(struct led_classdev *led_cdev,
struct qpnp_flash_led *led = NULL;
int rc;
+ /*
+ * strncmp() must be used here since a prefix comparison is required
+ * in order to support names like led:switch_0 and led:flash_1.
+ */
if (!strncmp(led_cdev->name, "led:switch", strlen("led:switch"))) {
snode = container_of(led_cdev, struct flash_switch_data, cdev);
led = dev_get_drvdata(&snode->pdev->dev);
@@ -1214,8 +1218,7 @@ static ssize_t qpnp_flash_led_max_current_show(struct device *dev,
/* sysfs attributes exported by flash_led */
static struct device_attribute qpnp_flash_led_attrs[] = {
- __ATTR(max_current, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_flash_led_max_current_show, NULL),
+ __ATTR(max_current, 0664, qpnp_flash_led_max_current_show, NULL),
};
static int flash_led_psy_notifier_call(struct notifier_block *nb,
diff --git a/drivers/leds/leds-qpnp-flash.c b/drivers/leds/leds-qpnp-flash.c
index 98dfa56add51..c27c0593cd10 100644
--- a/drivers/leds/leds-qpnp-flash.c
+++ b/drivers/leds/leds-qpnp-flash.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -608,10 +608,9 @@ qpnp_flash_led_get_max_avail_current(struct flash_node_data *flash_node,
}
/*
- * When charging is enabled, enforce this new
- * enabelment sequence to reduce fuel gauge
- * resolution reading.
- */
+ * When charging is enabled, enforce this new enablement
+ * sequence to reduce fuel gauge reading resolution.
+ */
if (led->charging_enabled) {
rc = qpnp_led_masked_write(led,
FLASH_MODULE_ENABLE_CTRL(led->base),
@@ -637,10 +636,10 @@ qpnp_flash_led_get_max_avail_current(struct flash_node_data *flash_node,
max_curr_avail_ma = (prop.intval / FLASH_LED_UA_PER_MA);
}
- /* When thermal mitigation is available, this logic
- * will execute, to derate current based on PMIC die
- * temperature.
- */
+ /*
+ * When thermal mitigation is available, this logic will execute to
+ * derate current based upon the PMIC die temperature.
+ */
if (led->pdata->die_current_derate_en) {
chg_temp_milidegc = qpnp_flash_led_get_die_temp(led);
if (chg_temp_milidegc < 0)
@@ -797,21 +796,14 @@ static ssize_t qpnp_flash_led_max_current_show(struct device *dev,
}
static struct device_attribute qpnp_flash_led_attrs[] = {
- __ATTR(strobe, (S_IRUGO | S_IWUSR | S_IWGRP),
- NULL,
- qpnp_led_strobe_type_store),
- __ATTR(reg_dump, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_flash_led_dump_regs_show,
- NULL),
- __ATTR(enable_current_derate, (S_IRUGO | S_IWUSR | S_IWGRP),
- NULL,
- qpnp_flash_led_current_derate_store),
- __ATTR(max_allowed_current, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_flash_led_max_current_show,
- NULL),
- __ATTR(enable_die_temp_current_derate, (S_IRUGO | S_IWUSR | S_IWGRP),
- NULL,
- qpnp_flash_led_die_temp_store),
+ __ATTR(strobe, 0664, NULL, qpnp_led_strobe_type_store),
+ __ATTR(reg_dump, 0664, qpnp_flash_led_dump_regs_show, NULL),
+ __ATTR(enable_current_derate, 0664, NULL,
+ qpnp_flash_led_current_derate_store),
+ __ATTR(max_allowed_current, 0664, qpnp_flash_led_max_current_show,
+ NULL),
+ __ATTR(enable_die_temp_current_derate, 0664, NULL,
+ qpnp_flash_led_die_temp_store),
};
static int qpnp_flash_led_get_thermal_derate_rate(const char *rate)
@@ -1771,8 +1763,6 @@ error_enable_gpio:
flash_node->flash_on = false;
mutex_unlock(&led->flash_led_lock);
-
- return;
}
static void qpnp_flash_led_brightness_set(struct led_classdev *led_cdev,
@@ -1823,8 +1813,6 @@ static void qpnp_flash_led_brightness_set(struct led_classdev *led_cdev,
}
queue_work(led->ordered_workq, &flash_node->work);
-
- return;
}
static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led)
@@ -2359,26 +2347,24 @@ static int qpnp_flash_led_parse_common_dt(
dev_err(&led->pdev->dev, "Unable to acquire pinctrl\n");
led->pinctrl = NULL;
return 0;
- } else {
- led->gpio_state_active =
- pinctrl_lookup_state(led->pinctrl, "flash_led_enable");
- if (IS_ERR_OR_NULL(led->gpio_state_active)) {
- dev_err(&led->pdev->dev,
- "Can not lookup LED active state\n");
- devm_pinctrl_put(led->pinctrl);
- led->pinctrl = NULL;
- return PTR_ERR(led->gpio_state_active);
- }
- led->gpio_state_suspend =
- pinctrl_lookup_state(led->pinctrl,
+ }
+
+ led->gpio_state_active = pinctrl_lookup_state(led->pinctrl,
+ "flash_led_enable");
+ if (IS_ERR_OR_NULL(led->gpio_state_active)) {
+ dev_err(&led->pdev->dev, "Cannot lookup LED active state\n");
+ devm_pinctrl_put(led->pinctrl);
+ led->pinctrl = NULL;
+ return PTR_ERR(led->gpio_state_active);
+ }
+
+ led->gpio_state_suspend = pinctrl_lookup_state(led->pinctrl,
"flash_led_disable");
- if (IS_ERR_OR_NULL(led->gpio_state_suspend)) {
- dev_err(&led->pdev->dev,
- "Can not lookup LED disable state\n");
- devm_pinctrl_put(led->pinctrl);
- led->pinctrl = NULL;
- return PTR_ERR(led->gpio_state_suspend);
- }
+ if (IS_ERR_OR_NULL(led->gpio_state_suspend)) {
+ dev_err(&led->pdev->dev, "Cannot lookup LED disable state\n");
+ devm_pinctrl_put(led->pinctrl);
+ led->pinctrl = NULL;
+ return PTR_ERR(led->gpio_state_suspend);
}
return 0;
@@ -2408,13 +2394,10 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
return rc;
}
- led = devm_kzalloc(&pdev->dev, sizeof(struct qpnp_flash_led),
- GFP_KERNEL);
- if (!led) {
- dev_err(&pdev->dev,
- "Unable to allocate memory for flash LED\n");
+ led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
+ if (!led)
return -ENOMEM;
- }
+
led->regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!led->regmap) {
dev_err(&pdev->dev, "Couldn't get parent's regmap\n");
@@ -2426,13 +2409,9 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
led->current_addr = FLASH_LED0_CURRENT(led->base);
led->current2_addr = FLASH_LED1_CURRENT(led->base);
- led->pdata = devm_kzalloc(&pdev->dev,
- sizeof(struct flash_led_platform_data), GFP_KERNEL);
- if (!led->pdata) {
- dev_err(&pdev->dev,
- "Unable to allocate memory for platform data\n");
+ led->pdata = devm_kzalloc(&pdev->dev, sizeof(*led->pdata), GFP_KERNEL);
+ if (!led->pdata)
return -ENOMEM;
- }
led->peripheral_type = (u8)qpnp_flash_led_get_peripheral_type(led);
if (led->peripheral_type < 0) {
@@ -2571,21 +2550,21 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
}
led->dbgfs_root = root;
- file = debugfs_create_file("enable_debug", S_IRUSR | S_IWUSR, root,
- led, &flash_led_dfs_dbg_feature_fops);
+ file = debugfs_create_file("enable_debug", 0600, root, led,
+ &flash_led_dfs_dbg_feature_fops);
if (!file) {
pr_err("error creating 'enable_debug' entry\n");
goto error_led_debugfs;
}
- file = debugfs_create_file("latched", S_IRUSR | S_IWUSR, root, led,
+ file = debugfs_create_file("latched", 0600, root, led,
&flash_led_dfs_latched_reg_fops);
if (!file) {
pr_err("error creating 'latched' entry\n");
goto error_led_debugfs;
}
- file = debugfs_create_file("strobe", S_IRUSR | S_IWUSR, root, led,
+ file = debugfs_create_file("strobe", 0600, root, led,
&flash_led_dfs_strobe_reg_fops);
if (!file) {
pr_err("error creating 'strobe' entry\n");
@@ -2639,7 +2618,7 @@ static int qpnp_flash_led_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id spmi_match_table[] = {
+static const struct of_device_id spmi_match_table[] = {
{ .compatible = "qcom,qpnp-flash-led",},
{ },
};
diff --git a/drivers/leds/leds-qpnp-wled.c b/drivers/leds/leds-qpnp-wled.c
index 718badb16ea1..1e24c79c3f0a 100644
--- a/drivers/leds/leds-qpnp-wled.c
+++ b/drivers/leds/leds-qpnp-wled.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -721,10 +721,11 @@ static ssize_t qpnp_wled_ramp_ms_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct qpnp_wled *wled = dev_get_drvdata(dev);
- int data;
+ int data, rc;
- if (sscanf(buf, "%d", &data) != 1)
- return -EINVAL;
+ rc = kstrtoint(buf, 10, &data);
+ if (rc)
+ return rc;
wled->ramp_ms = data;
return count;
@@ -744,10 +745,11 @@ static ssize_t qpnp_wled_ramp_step_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct qpnp_wled *wled = dev_get_drvdata(dev);
- int data;
+ int data, rc;
- if (sscanf(buf, "%d", &data) != 1)
- return -EINVAL;
+ rc = kstrtoint(buf, 10, &data);
+ if (rc)
+ return rc;
wled->ramp_step = data;
return count;
@@ -832,8 +834,9 @@ static ssize_t qpnp_wled_fs_curr_ua_store(struct device *dev,
int data, i, rc, temp;
u8 reg;
- if (sscanf(buf, "%d", &data) != 1)
- return -EINVAL;
+ rc = kstrtoint(buf, 10, &data);
+ if (rc)
+ return rc;
for (i = 0; i < wled->num_strings; i++) {
if (data < QPNP_WLED_FS_CURR_MIN_UA)
@@ -869,24 +872,15 @@ static ssize_t qpnp_wled_fs_curr_ua_store(struct device *dev,
/* sysfs attributes exported by wled */
static struct device_attribute qpnp_wled_attrs[] = {
- __ATTR(dump_regs, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_wled_dump_regs_show,
- NULL),
- __ATTR(dim_mode, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_wled_dim_mode_show,
- qpnp_wled_dim_mode_store),
- __ATTR(fs_curr_ua, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_wled_fs_curr_ua_show,
- qpnp_wled_fs_curr_ua_store),
- __ATTR(start_ramp, (S_IRUGO | S_IWUSR | S_IWGRP),
- NULL,
- qpnp_wled_ramp_store),
- __ATTR(ramp_ms, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_wled_ramp_ms_show,
- qpnp_wled_ramp_ms_store),
- __ATTR(ramp_step, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_wled_ramp_step_show,
- qpnp_wled_ramp_step_store),
+ __ATTR(dump_regs, 0664, qpnp_wled_dump_regs_show, NULL),
+ __ATTR(dim_mode, 0664, qpnp_wled_dim_mode_show,
+ qpnp_wled_dim_mode_store),
+ __ATTR(fs_curr_ua, 0664, qpnp_wled_fs_curr_ua_show,
+ qpnp_wled_fs_curr_ua_store),
+ __ATTR(start_ramp, 0664, NULL, qpnp_wled_ramp_store),
+ __ATTR(ramp_ms, 0664, qpnp_wled_ramp_ms_show, qpnp_wled_ramp_ms_store),
+ __ATTR(ramp_step, 0664, qpnp_wled_ramp_step_show,
+ qpnp_wled_ramp_step_store),
};
/* worker for setting wled brightness */
@@ -2196,7 +2190,7 @@ static int qpnp_wled_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id spmi_match_table[] = {
+static const struct of_device_id spmi_match_table[] = {
{ .compatible = "qcom,qpnp-wled",},
{ },
};
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
index d16fcc3c97ae..85a6be824485 100644
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, 2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -666,7 +666,7 @@ static int qpnp_wled_set(struct qpnp_led_data *led)
return rc;
}
- usleep_range(WLED_OVP_DELAY, WLED_OVP_DELAY);
+ usleep_range(WLED_OVP_DELAY, WLED_OVP_DELAY + 10);
} else if (led->wled_cfg->pmic_version == PMIC_VER_8941) {
if (led->wled_cfg->num_physical_strings <=
WLED_THREE_STRINGS) {
@@ -696,7 +696,8 @@ static int qpnp_wled_set(struct qpnp_led_data *led)
"WLED write sink reg failed");
return rc;
}
- usleep_range(WLED_OVP_DELAY, WLED_OVP_DELAY);
+ usleep_range(WLED_OVP_DELAY,
+ WLED_OVP_DELAY + 10);
} else {
val = WLED_DISABLE_ALL_SINKS;
rc = regmap_write(led->regmap,
@@ -724,7 +725,8 @@ static int qpnp_wled_set(struct qpnp_led_data *led)
msleep(WLED_OVP_DELAY_LOOP);
tries++;
}
- usleep_range(WLED_OVP_DELAY, WLED_OVP_DELAY);
+ usleep_range(WLED_OVP_DELAY,
+ WLED_OVP_DELAY + 10);
}
}
@@ -859,9 +861,7 @@ static int qpnp_mpp_set(struct qpnp_led_data *led)
led->mpp_cfg->enable = true;
if (led->cdev.brightness < led->mpp_cfg->min_brightness) {
- dev_warn(&led->pdev->dev,
- "brightness is less than supported..." \
- "set to minimum supported\n");
+ dev_warn(&led->pdev->dev, "brightness is less than supported, set to minimum supported\n");
led->cdev.brightness = led->mpp_cfg->min_brightness;
}
@@ -940,9 +940,7 @@ static int qpnp_mpp_set(struct qpnp_led_data *led)
LED_MPP_EN_CTRL(led->base), LED_MPP_EN_MASK,
LED_MPP_EN_ENABLE);
if (rc) {
- dev_err(&led->pdev->dev,
- "Failed to write led enable " \
- "reg\n");
+ dev_err(&led->pdev->dev, "Failed to write led enable reg\n");
goto err_mpp_reg_write;
}
} else {
@@ -1102,30 +1100,27 @@ static int qpnp_flash_regulator_operate(struct qpnp_led_data *led, bool on)
led_array[i].flash_cfg->
flash_wa_reg);
if (rc) {
- dev_err(&led->pdev->dev,
- "Flash wa regulator"
- "enable failed(%d)\n",
+ dev_err(&led->pdev->dev, "Flash wa regulator enable failed(%d)\n",
rc);
return rc;
}
}
rc = regulator_enable(
- led_array[i].flash_cfg->\
- flash_boost_reg);
+ led_array[i].flash_cfg->flash_boost_reg);
if (rc) {
if (led_array[i].flash_cfg->
flash_wa_reg_get)
- /* Disable flash wa regulator
+ /*
+ * Disable flash wa regulator
* when flash boost regulator
* enable fails
*/
regulator_disable(
led_array[i].flash_cfg->
flash_wa_reg);
- dev_err(&led->pdev->dev,
- "Flash boost regulator enable"
- "failed(%d)\n", rc);
+ dev_err(&led->pdev->dev, "Flash boost regulator enable failed(%d)\n",
+ rc);
return rc;
}
led->flash_cfg->flash_on = true;
@@ -1150,12 +1145,11 @@ regulator_turn_off:
rc);
}
- rc = regulator_disable(led_array[i].flash_cfg->\
- flash_boost_reg);
+ rc = regulator_disable(
+ led_array[i].flash_cfg->flash_boost_reg);
if (rc) {
- dev_err(&led->pdev->dev,
- "Flash boost regulator disable"
- "failed(%d)\n", rc);
+ dev_err(&led->pdev->dev, "Flash boost regulator disable failed(%d)\n",
+ rc);
return rc;
}
if (led_array[i].flash_cfg->flash_wa_reg_get) {
@@ -1163,9 +1157,7 @@ regulator_turn_off:
led_array[i].flash_cfg->
flash_wa_reg);
if (rc) {
- dev_err(&led->pdev->dev,
- "Flash_wa regulator"
- "disable failed(%d)\n",
+ dev_err(&led->pdev->dev, "Flash_wa regulator disable failed(%d)\n",
rc);
return rc;
}
@@ -1416,7 +1408,8 @@ static int qpnp_flash_set(struct qpnp_led_data *led)
/*
* Add 1ms delay for bharger enter stable state
*/
- usleep_range(FLASH_RAMP_UP_DELAY_US, FLASH_RAMP_UP_DELAY_US);
+ usleep_range(FLASH_RAMP_UP_DELAY_US,
+ FLASH_RAMP_UP_DELAY_US + 10);
if (!led->flash_cfg->strobe_type)
led->flash_cfg->trigger_flash &=
@@ -1480,7 +1473,8 @@ static int qpnp_flash_set(struct qpnp_led_data *led)
* Disable module after ramp down complete for stable
* behavior
*/
- usleep_range(FLASH_RAMP_UP_DELAY_US, FLASH_RAMP_UP_DELAY_US);
+ usleep_range(FLASH_RAMP_UP_DELAY_US,
+ FLASH_RAMP_UP_DELAY_US + 10);
rc = qpnp_led_masked_write(led,
FLASH_ENABLE_CONTROL(led->base),
@@ -1658,9 +1652,7 @@ static int qpnp_kpdbl_set(struct qpnp_led_data *led)
KPDBL_MODULE_EN_MASK,
KPDBL_MODULE_DIS);
if (rc) {
- dev_err(&led->pdev->dev,
- "Failed to write led"
- " enable reg\n");
+ dev_err(&led->pdev->dev, "Failed to write led enable reg\n");
return rc;
}
}
@@ -1854,8 +1846,6 @@ static void qpnp_led_work(struct work_struct *work)
struct qpnp_led_data, work);
__qpnp_led_work(led, led->cdev.brightness);
-
- return;
}
static int qpnp_led_set_max_brightness(struct qpnp_led_data *led)
@@ -1942,7 +1932,7 @@ static int qpnp_wled_init(struct qpnp_led_data *led)
return -EINVAL;
}
- if ((led->max_current > WLED_MAX_CURR)) {
+ if (led->max_current > WLED_MAX_CURR) {
dev_err(&led->pdev->dev, "Invalid max current\n");
return -EINVAL;
}
@@ -3048,7 +3038,7 @@ static int qpnp_get_common_configs(struct qpnp_led_data *led,
rc = of_property_read_string(node, "qcom,default-state",
&temp_string);
if (!rc) {
- if (strncmp(temp_string, "on", sizeof("on")) == 0)
+ if (strcmp(temp_string, "on") == 0)
led->default_on = true;
} else if (rc != -EINVAL)
return rc;
@@ -3075,10 +3065,8 @@ static int qpnp_get_config_wled(struct qpnp_led_data *led,
led->wled_cfg = devm_kzalloc(&led->pdev->dev,
sizeof(struct wled_config_data), GFP_KERNEL);
- if (!led->wled_cfg) {
- dev_err(&led->pdev->dev, "Unable to allocate memory\n");
+ if (!led->wled_cfg)
return -ENOMEM;
- }
rc = regmap_read(led->regmap, PMIC_VERSION_REG, &tmp);
if (rc) {
@@ -3161,10 +3149,8 @@ static int qpnp_get_config_flash(struct qpnp_led_data *led,
led->flash_cfg = devm_kzalloc(&led->pdev->dev,
sizeof(struct flash_config_data), GFP_KERNEL);
- if (!led->flash_cfg) {
- dev_err(&led->pdev->dev, "Unable to allocate memory\n");
+ if (!led->flash_cfg)
return -ENOMEM;
- }
rc = regmap_read(led->regmap, FLASH_PERIPHERAL_SUBTYPE(led->base),
&tmp);
@@ -3297,23 +3283,23 @@ static int qpnp_get_config_flash(struct qpnp_led_data *led,
}
return 0;
- } else {
- rc = of_property_read_u32(node, "qcom,duration", &val);
- if (!rc)
- led->flash_cfg->duration = (u8)((val - 10) / 10);
- else if (rc == -EINVAL)
- led->flash_cfg->duration = FLASH_DURATION_200ms;
- else
- goto error_get_flash_reg;
-
- rc = of_property_read_u32(node, "qcom,current", &val);
- if (!rc)
- led->flash_cfg->current_prgm = (val *
- FLASH_MAX_LEVEL / led->max_current);
- else
- goto error_get_flash_reg;
}
+ rc = of_property_read_u32(node, "qcom,duration", &val);
+ if (!rc)
+ led->flash_cfg->duration = (u8)((val - 10) / 10);
+ else if (rc == -EINVAL)
+ led->flash_cfg->duration = FLASH_DURATION_200ms;
+ else
+ goto error_get_flash_reg;
+
+ rc = of_property_read_u32(node, "qcom,current", &val);
+ if (!rc)
+ led->flash_cfg->current_prgm = val * FLASH_MAX_LEVEL
+ / led->max_current;
+ else
+ goto error_get_flash_reg;
+
rc = of_property_read_u32(node, "qcom,headroom", &val);
if (!rc)
led->flash_cfg->headroom = (u8) val;
@@ -3512,11 +3498,11 @@ bad_lpg_params:
static int qpnp_led_get_mode(const char *mode)
{
- if (strncmp(mode, "manual", strlen(mode)) == 0)
+ if (strcmp(mode, "manual") == 0)
return MANUAL_MODE;
- else if (strncmp(mode, "pwm", strlen(mode)) == 0)
+ else if (strcmp(mode, "pwm") == 0)
return PWM_MODE;
- else if (strncmp(mode, "lpg", strlen(mode)) == 0)
+ else if (strcmp(mode, "lpg") == 0)
return LPG_MODE;
else
return -EINVAL;
@@ -3532,10 +3518,8 @@ static int qpnp_get_config_kpdbl(struct qpnp_led_data *led,
led->kpdbl_cfg = devm_kzalloc(&led->pdev->dev,
sizeof(struct kpdbl_config_data), GFP_KERNEL);
- if (!led->kpdbl_cfg) {
- dev_err(&led->pdev->dev, "Unable to allocate memory\n");
+ if (!led->kpdbl_cfg)
return -ENOMEM;
- }
rc = of_property_read_string(node, "qcom,mode", &mode);
if (!rc) {
@@ -3547,11 +3531,9 @@ static int qpnp_get_config_kpdbl(struct qpnp_led_data *led,
led->kpdbl_cfg->pwm_cfg = devm_kzalloc(&led->pdev->dev,
sizeof(struct pwm_config_data),
GFP_KERNEL);
- if (!led->kpdbl_cfg->pwm_cfg) {
- dev_err(&led->pdev->dev,
- "Unable to allocate memory\n");
+ if (!led->kpdbl_cfg->pwm_cfg)
return -ENOMEM;
- }
+
led->kpdbl_cfg->pwm_cfg->mode = led_mode;
led->kpdbl_cfg->pwm_cfg->default_mode = led_mode;
} else {
@@ -3589,10 +3571,8 @@ static int qpnp_get_config_rgb(struct qpnp_led_data *led,
led->rgb_cfg = devm_kzalloc(&led->pdev->dev,
sizeof(struct rgb_config_data), GFP_KERNEL);
- if (!led->rgb_cfg) {
- dev_err(&led->pdev->dev, "Unable to allocate memory\n");
+ if (!led->rgb_cfg)
return -ENOMEM;
- }
if (led->id == QPNP_ID_RGB_RED)
led->rgb_cfg->enable = RGB_LED_ENABLE_RED;
@@ -3641,10 +3621,8 @@ static int qpnp_get_config_mpp(struct qpnp_led_data *led,
led->mpp_cfg = devm_kzalloc(&led->pdev->dev,
sizeof(struct mpp_config_data), GFP_KERNEL);
- if (!led->mpp_cfg) {
- dev_err(&led->pdev->dev, "Unable to allocate memory\n");
+ if (!led->mpp_cfg)
return -ENOMEM;
- }
if (of_find_property(of_get_parent(node), "mpp-power-supply", NULL)) {
led->mpp_cfg->mpp_reg =
@@ -3770,11 +3748,8 @@ static int qpnp_get_config_gpio(struct qpnp_led_data *led,
led->gpio_cfg = devm_kzalloc(&led->pdev->dev,
sizeof(struct gpio_config_data), GFP_KERNEL);
- if (!led->gpio_cfg) {
- dev_err(&led->pdev->dev,
- "Unable to allocate memory gpio struct\n");
+ if (!led->gpio_cfg)
return -ENOMEM;
- }
led->gpio_cfg->source_sel = LED_GPIO_SOURCE_SEL_DEFAULT;
rc = of_property_read_u32(node, "qcom,source-sel", &val);
@@ -3823,12 +3798,10 @@ static int qpnp_leds_probe(struct platform_device *pdev)
if (!num_leds)
return -ECHILD;
- led_array = devm_kzalloc(&pdev->dev,
- (sizeof(struct qpnp_led_data) * num_leds), GFP_KERNEL);
- if (!led_array) {
- dev_err(&pdev->dev, "Unable to allocate memory\n");
+ led_array = devm_kcalloc(&pdev->dev, num_leds, sizeof(*led_array),
+ GFP_KERNEL);
+ if (!led_array)
return -ENOMEM;
- }
for_each_child_of_node(node, temp) {
led = &led_array[parsed_leds];
@@ -3881,24 +3854,22 @@ static int qpnp_leds_probe(struct platform_device *pdev)
rc = qpnp_get_common_configs(led, temp);
if (rc) {
- dev_err(&led->pdev->dev,
- "Failure reading common led configuration," \
- " rc = %d\n", rc);
+ dev_err(&led->pdev->dev, "Failure reading common led configuration, rc = %d\n",
+ rc);
goto fail_id_check;
}
led->cdev.brightness_set = qpnp_led_set;
led->cdev.brightness_get = qpnp_led_get;
- if (strncmp(led_label, "wled", sizeof("wled")) == 0) {
+ if (strcmp(led_label, "wled") == 0) {
rc = qpnp_get_config_wled(led, temp);
if (rc < 0) {
dev_err(&led->pdev->dev,
"Unable to read wled config data\n");
goto fail_id_check;
}
- } else if (strncmp(led_label, "flash", sizeof("flash"))
- == 0) {
+ } else if (strcmp(led_label, "flash") == 0) {
if (!of_find_property(node, "flash-boost-supply", NULL))
regulator_probe = true;
rc = qpnp_get_config_flash(led, temp, &regulator_probe);
@@ -3907,14 +3878,14 @@ static int qpnp_leds_probe(struct platform_device *pdev)
"Unable to read flash config data\n");
goto fail_id_check;
}
- } else if (strncmp(led_label, "rgb", sizeof("rgb")) == 0) {
+ } else if (strcmp(led_label, "rgb") == 0) {
rc = qpnp_get_config_rgb(led, temp);
if (rc < 0) {
dev_err(&led->pdev->dev,
"Unable to read rgb config data\n");
goto fail_id_check;
}
- } else if (strncmp(led_label, "mpp", sizeof("mpp")) == 0) {
+ } else if (strcmp(led_label, "mpp") == 0) {
rc = qpnp_get_config_mpp(led, temp);
if (rc < 0) {
dev_err(&led->pdev->dev,
@@ -3928,7 +3899,7 @@ static int qpnp_leds_probe(struct platform_device *pdev)
"Unable to read gpio config data\n");
goto fail_id_check;
}
- } else if (strncmp(led_label, "kpdbl", sizeof("kpdbl")) == 0) {
+ } else if (strcmp(led_label, "kpdbl") == 0) {
bitmap_zero(kpdbl_leds_in_use, NUM_KPDBL_LEDS);
is_kpdbl_master_turn_on = false;
rc = qpnp_get_config_kpdbl(led, temp);
@@ -4113,8 +4084,8 @@ static int qpnp_leds_remove(struct platform_device *pdev)
case QPNP_ID_FLASH1_LED0:
case QPNP_ID_FLASH1_LED1:
if (led_array[i].flash_cfg->flash_reg_get)
- regulator_put(led_array[i].flash_cfg-> \
- flash_boost_reg);
+ regulator_put(
+ led_array[i].flash_cfg->flash_boost_reg);
if (led_array[i].flash_cfg->torch_enable)
if (!led_array[i].flash_cfg->no_smbb_support)
regulator_put(led_array[i].
@@ -4126,49 +4097,49 @@ static int qpnp_leds_remove(struct platform_device *pdev)
case QPNP_ID_RGB_GREEN:
case QPNP_ID_RGB_BLUE:
if (led_array[i].rgb_cfg->pwm_cfg->mode == PWM_MODE)
- sysfs_remove_group(&led_array[i].cdev.dev->\
- kobj, &pwm_attr_group);
+ sysfs_remove_group(&led_array[i].cdev.dev->kobj,
+ &pwm_attr_group);
if (led_array[i].rgb_cfg->pwm_cfg->use_blink) {
- sysfs_remove_group(&led_array[i].cdev.dev->\
- kobj, &blink_attr_group);
- sysfs_remove_group(&led_array[i].cdev.dev->\
- kobj, &lpg_attr_group);
- } else if (led_array[i].rgb_cfg->pwm_cfg->mode\
- == LPG_MODE)
- sysfs_remove_group(&led_array[i].cdev.dev->\
- kobj, &lpg_attr_group);
+ sysfs_remove_group(&led_array[i].cdev.dev->kobj,
+ &blink_attr_group);
+ sysfs_remove_group(&led_array[i].cdev.dev->kobj,
+ &lpg_attr_group);
+ } else if (led_array[i].rgb_cfg->pwm_cfg->mode
+ == LPG_MODE)
+ sysfs_remove_group(&led_array[i].cdev.dev->kobj,
+ &lpg_attr_group);
break;
case QPNP_ID_LED_MPP:
if (!led_array[i].mpp_cfg->pwm_cfg)
break;
if (led_array[i].mpp_cfg->pwm_cfg->mode == PWM_MODE)
- sysfs_remove_group(&led_array[i].cdev.dev->\
- kobj, &pwm_attr_group);
+ sysfs_remove_group(&led_array[i].cdev.dev->kobj,
+ &pwm_attr_group);
if (led_array[i].mpp_cfg->pwm_cfg->use_blink) {
- sysfs_remove_group(&led_array[i].cdev.dev->\
- kobj, &blink_attr_group);
- sysfs_remove_group(&led_array[i].cdev.dev->\
- kobj, &lpg_attr_group);
- } else if (led_array[i].mpp_cfg->pwm_cfg->mode\
- == LPG_MODE)
- sysfs_remove_group(&led_array[i].cdev.dev->\
- kobj, &lpg_attr_group);
+ sysfs_remove_group(&led_array[i].cdev.dev->kobj,
+ &blink_attr_group);
+ sysfs_remove_group(&led_array[i].cdev.dev->kobj,
+ &lpg_attr_group);
+ } else if (led_array[i].mpp_cfg->pwm_cfg->mode
+ == LPG_MODE)
+ sysfs_remove_group(&led_array[i].cdev.dev->kobj,
+ &lpg_attr_group);
if (led_array[i].mpp_cfg->mpp_reg)
regulator_put(led_array[i].mpp_cfg->mpp_reg);
break;
case QPNP_ID_KPDBL:
if (led_array[i].kpdbl_cfg->pwm_cfg->mode == PWM_MODE)
- sysfs_remove_group(&led_array[i].cdev.dev->
- kobj, &pwm_attr_group);
+ sysfs_remove_group(&led_array[i].cdev.dev->kobj,
+ &pwm_attr_group);
if (led_array[i].kpdbl_cfg->pwm_cfg->use_blink) {
- sysfs_remove_group(&led_array[i].cdev.dev->
- kobj, &blink_attr_group);
- sysfs_remove_group(&led_array[i].cdev.dev->
- kobj, &lpg_attr_group);
+ sysfs_remove_group(&led_array[i].cdev.dev->kobj,
+ &blink_attr_group);
+ sysfs_remove_group(&led_array[i].cdev.dev->kobj,
+ &lpg_attr_group);
} else if (led_array[i].kpdbl_cfg->pwm_cfg->mode
- == LPG_MODE)
- sysfs_remove_group(&led_array[i].cdev.dev->
- kobj, &lpg_attr_group);
+ == LPG_MODE)
+ sysfs_remove_group(&led_array[i].cdev.dev->kobj,
+ &lpg_attr_group);
break;
default:
dev_err(&led_array->pdev->dev,
@@ -4182,7 +4153,7 @@ static int qpnp_leds_remove(struct platform_device *pdev)
}
#ifdef CONFIG_OF
-static struct of_device_id spmi_match_table[] = {
+static const struct of_device_id spmi_match_table[] = {
{ .compatible = "qcom,leds-qpnp",},
{ },
};
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index dd7d1c836809..1ddf51407884 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -846,6 +846,7 @@ void msm_isp_increment_frame_id(struct vfe_device *vfe_dev,
enum msm_vfe_dual_hw_type dual_hw_type;
enum msm_vfe_dual_hw_ms_type ms_type;
unsigned long flags;
+ int i;
struct master_slave_resource_info *ms_res =
&vfe_dev->common_data->ms_resource;
@@ -869,8 +870,27 @@ void msm_isp_increment_frame_id(struct vfe_device *vfe_dev,
src_info->dual_hw_ms_info.index)) {
pr_err("Frame out of sync on vfe %d\n",
vfe_dev->pdev->id);
- msm_isp_halt_send_error(vfe_dev,
- ISP_EVENT_BUF_FATAL_ERROR);
+ /*
+ * set this isp as async mode to force
+ *it sync again at the next sof
+ */
+ src_info->dual_hw_ms_info.sync_state =
+ MSM_ISP_DUAL_CAM_ASYNC;
+ /*
+ * set the other isp as async mode to force
+ * it sync again at the next sof
+ */
+ for (i = 0; i < MAX_VFE * VFE_SRC_MAX; i++) {
+ if (ms_res->src_info[i] == NULL)
+ continue;
+ if (src_info == ms_res->src_info[i] ||
+ ms_res->src_info[i]->
+ active == 0)
+ continue;
+ ms_res->src_info[i]->dual_hw_ms_info.
+ sync_state =
+ MSM_ISP_DUAL_CAM_ASYNC;
+ }
}
ms_res->src_sof_mask |= (1 <<
src_info->dual_hw_ms_info.index);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
index e3022b2dbe34..55a743737c59 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -58,6 +58,7 @@
#define TRUE 1
#define FALSE 0
+#define MAX_LANE_COUNT 4
#define CSID_TIMEOUT msecs_to_jiffies(100)
#undef CDBG
@@ -284,6 +285,12 @@ static int msm_csid_config(struct csid_device *csid_dev,
csid_params->lane_assign);
CDBG("%s csid_params phy_sel = %d\n", __func__,
csid_params->phy_sel);
+ if ((csid_params->lane_cnt == 0) ||
+ (csid_params->lane_cnt > MAX_LANE_COUNT)) {
+ pr_err("%s:%d invalid lane count = %d\n",
+ __func__, __LINE__, csid_params->lane_cnt);
+ return -EINVAL;
+ }
csid_dev->csid_lane_cnt = csid_params->lane_cnt;
rc = msm_csid_reset(csid_dev);
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_base.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_base.c
index 9048d54bed38..1f92186feeef 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_base.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_base.c
@@ -30,6 +30,7 @@
#include "sde_rotator_base.h"
#include "sde_rotator_util.h"
#include "sde_rotator_trace.h"
+#include "sde_rotator_debug.h"
static inline u64 fudge_factor(u64 val, u32 numer, u32 denom)
{
@@ -237,6 +238,8 @@ static u32 get_ot_limit(u32 reg_off, u32 bit_off,
exit:
SDEROT_DBG("ot_lim=%d\n", ot_lim);
+ SDEROT_EVTLOG(params->width, params->height, params->fmt, params->fps,
+ ot_lim);
return ot_lim;
}
@@ -248,6 +251,7 @@ void sde_mdp_set_ot_limit(struct sde_mdp_set_ot_params *params)
params->reg_off_vbif_lim_conf;
u32 bit_off_vbif_lim_conf = (params->xin_id % 4) * 8;
u32 reg_val;
+ u32 sts;
bool forced_on;
ot_lim = get_ot_limit(
@@ -258,6 +262,16 @@ void sde_mdp_set_ot_limit(struct sde_mdp_set_ot_params *params)
if (ot_lim == 0)
goto exit;
+ if (params->rotsts_base && params->rotsts_busy_mask) {
+ sts = readl_relaxed(params->rotsts_base);
+ if (sts & params->rotsts_busy_mask) {
+ SDEROT_ERR(
+ "Rotator still busy, should not modify VBIF\n");
+ SDEROT_EVTLOG_TOUT_HANDLER(
+ "rot", "vbif_dbg_bus", "panic");
+ }
+ }
+
trace_rot_perf_set_ot(params->num, params->xin_id, ot_lim);
forced_on = force_on_xin_clk(params->bit_off_mdp_clk_ctrl,
@@ -283,6 +297,7 @@ void sde_mdp_set_ot_limit(struct sde_mdp_set_ot_params *params)
force_on_xin_clk(params->bit_off_mdp_clk_ctrl,
params->reg_off_mdp_clk_ctrl, false);
+ SDEROT_EVTLOG(params->num, params->xin_id, ot_lim);
exit:
return;
}
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_base.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_base.h
index c04e71f459d1..a7c1e890758e 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_base.h
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_base.h
@@ -39,6 +39,8 @@ struct sde_mdp_set_ot_params {
u32 reg_off_vbif_lim_conf;
u32 reg_off_mdp_clk_ctrl;
u32 bit_off_mdp_clk_ctrl;
+ char __iomem *rotsts_base;
+ u32 rotsts_busy_mask;
};
enum sde_bus_vote_type {
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
index 29215c1a5910..e9988400b729 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
@@ -1237,14 +1237,16 @@ static int sde_rotator_calc_perf(struct sde_rot_mgr *mgr,
perf->rdot_limit = sde_mdp_get_ot_limit(
config->input.width, config->input.height,
- config->input.format, max_fps, true);
+ config->input.format, config->frame_rate, true);
perf->wrot_limit = sde_mdp_get_ot_limit(
config->input.width, config->input.height,
- config->input.format, max_fps, false);
+ config->input.format, config->frame_rate, false);
SDEROT_DBG("clk:%lu, rdBW:%d, wrBW:%d, rdOT:%d, wrOT:%d\n",
perf->clk_rate, read_bw, write_bw, perf->rdot_limit,
perf->wrot_limit);
+ SDEROT_EVTLOG(perf->clk_rate, read_bw, write_bw, perf->rdot_limit,
+ perf->wrot_limit);
return 0;
}
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_pipe.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_pipe.c
index 3d84389513f1..5f886d7f1af2 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_pipe.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_pipe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012, 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -350,7 +350,7 @@ static int sde_mdp_src_addr_setup(struct sde_mdp_pipe *pipe,
static void sde_mdp_set_ot_limit_pipe(struct sde_mdp_pipe *pipe)
{
- struct sde_mdp_set_ot_params ot_params;
+ struct sde_mdp_set_ot_params ot_params = {0,};
ot_params.xin_id = pipe->xin_id;
ot_params.num = pipe->num;
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_wb.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_wb.c
index f9dc34167c59..863dfb09ad0f 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_wb.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r1_wb.c
@@ -402,7 +402,7 @@ static int sde_mdp_wb_wait4comp(struct sde_mdp_ctl *ctl, void *arg)
static void sde_mdp_set_ot_limit_wb(struct sde_mdp_writeback_ctx *ctx)
{
- struct sde_mdp_set_ot_params ot_params;
+ struct sde_mdp_set_ot_params ot_params = {0,};
ot_params.xin_id = ctx->xin_id;
ot_params.num = ctx->wb_num;
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
index 3bb8399da4bf..d7fb167ab49f 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
@@ -339,6 +339,8 @@ static void sde_hw_rotator_disable_irq(struct sde_hw_rotator *rot)
*/
static void sde_hw_rotator_dump_status(struct sde_hw_rotator *rot)
{
+ struct sde_rot_data_type *mdata = sde_rot_get_mdata();
+
SDEROT_ERR(
"op_mode = %x, int_en = %x, int_status = %x\n",
SDE_ROTREG_READ(rot->mdss_base,
@@ -370,6 +372,10 @@ static void sde_hw_rotator_dump_status(struct sde_hw_rotator *rot)
"UBWC decode status = %x, UBWC encode status = %x\n",
SDE_ROTREG_READ(rot->mdss_base, ROT_SSPP_UBWC_ERROR_STATUS),
SDE_ROTREG_READ(rot->mdss_base, ROT_WB_UBWC_ERROR_STATUS));
+
+ SDEROT_ERR("VBIF XIN HALT status = %x VBIF AXI HALT status = %x\n",
+ SDE_VBIF_READ(mdata, MMSS_VBIF_XIN_HALT_CTRL1),
+ SDE_VBIF_READ(mdata, MMSS_VBIF_AXI_HALT_CTRL1));
}
/**
@@ -1689,7 +1695,8 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
item->input.width, item->input.height,
item->output.width, item->output.height,
entry->src_buf.p[0].addr, entry->dst_buf.p[0].addr,
- item->input.format, item->output.format);
+ item->input.format, item->output.format,
+ entry->perf->config.frame_rate);
if (mdata->default_ot_rd_limit) {
struct sde_mdp_set_ot_params ot_params;
@@ -1708,6 +1715,8 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
ot_params.fmt = ctx->is_traffic_shaping ?
SDE_PIX_FMT_ABGR_8888 :
entry->perf->config.input.format;
+ ot_params.rotsts_base = rot->mdss_base + ROTTOP_STATUS;
+ ot_params.rotsts_busy_mask = ROT_BUSY_BIT;
sde_mdp_set_ot_limit(&ot_params);
}
@@ -1728,6 +1737,8 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
ot_params.fmt = ctx->is_traffic_shaping ?
SDE_PIX_FMT_ABGR_8888 :
entry->perf->config.input.format;
+ ot_params.rotsts_base = rot->mdss_base + ROTTOP_STATUS;
+ ot_params.rotsts_busy_mask = ROT_BUSY_BIT;
sde_mdp_set_ot_limit(&ot_params);
}
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index f958cf13f1e3..a20252f08f44 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1782,6 +1782,7 @@ static int msm_vdec_start_streaming(struct vb2_queue *q, unsigned int count)
struct msm_vidc_inst *inst;
int rc = 0;
struct hfi_device *hdev;
+ struct vb2_buf_entry *temp, *next;
if (!q || !q->drv_priv) {
dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q);
return -EINVAL;
@@ -1824,6 +1825,19 @@ static int msm_vdec_start_streaming(struct vb2_queue *q, unsigned int count)
}
stream_start_failed:
+ if (rc) {
+ mutex_lock(&inst->pendingq.lock);
+ list_for_each_entry_safe(temp, next, &inst->pendingq.list,
+ list) {
+ if (temp->vb->type == q->type) {
+ vb2_buffer_done(temp->vb,
+ VB2_BUF_STATE_QUEUED);
+ list_del(&temp->list);
+ kfree(temp);
+ }
+ }
+ mutex_unlock(&inst->pendingq.lock);
+ }
return rc;
}
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index 6127c03df581..c909511db251 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1048,9 +1048,9 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = {
.id = V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE,
.name = "Set Encoder performance mode",
.type = V4L2_CTRL_TYPE_INTEGER,
- .minimum = V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY,
+ .minimum = V4L2_MPEG_VIDC_VIDEO_PERF_UNINIT,
.maximum = V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE,
- .default_value = V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY,
+ .default_value = V4L2_MPEG_VIDC_VIDEO_PERF_UNINIT,
.step = 1,
.qmenu = NULL,
},
@@ -1666,9 +1666,10 @@ static int msm_venc_toggle_hier_p(struct msm_vidc_inst *inst, int layers)
static inline int msm_venc_power_save_mode_enable(struct msm_vidc_inst *inst)
{
- u32 rc = 0;
- u32 prop_id = 0, power_save_min = 0, power_save_max = 0, inst_load = 0;
+ u32 rc = 0, height = 0, width = 0;
+ u32 prop_id = 0, hq_max = 0, power_conf = 0, inst_load = 0;
void *pdata = NULL;
+ bool set_by_client = false, enable_low_power = false;
struct hfi_device *hdev = NULL;
enum hal_perf_mode venc_mode;
enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD |
@@ -1679,20 +1680,38 @@ static inline int msm_venc_power_save_mode_enable(struct msm_vidc_inst *inst)
return -EINVAL;
}
+ hdev = inst->core->device;
inst_load = msm_comm_get_inst_load(inst, quirks);
- power_save_min = inst->capability.mbs_per_sec_power_save.min;
- power_save_max = inst->capability.mbs_per_sec_power_save.max;
+ hq_max = inst->capability.mbs_per_sec.max;
+ power_conf = inst->core->resources.power_conf;
+ height = inst->prop.height[CAPTURE_PORT];
+ width = inst->prop.width[CAPTURE_PORT];
- if (!power_save_min || !power_save_max)
- return rc;
+ switch (msm_comm_g_ctrl_for_id(inst,
+ V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE)) {
+ case V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY:
+ case V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE:
+ set_by_client = true;
+ break;
+ }
- hdev = inst->core->device;
- if (inst_load >= power_save_min && inst_load <= power_save_max) {
+ if (inst_load > hq_max) {
+ dprintk(VIDC_INFO, "Setting low power w.r.t core limitation\n");
+ enable_low_power = true;
+ } else if (!set_by_client) {
+ if (power_conf && width * height >= power_conf) {
+ dprintk(VIDC_INFO,
+ "Setting low power w.r.t system power recommendation\n");
+ enable_low_power = true;
+ }
+ }
+
+ if (enable_low_power) {
prop_id = HAL_CONFIG_VENC_PERF_MODE;
venc_mode = HAL_PERF_MODE_POWER_SAVE;
pdata = &venc_mode;
rc = call_hfi_op(hdev, session_set_property,
- (void *)inst->session, prop_id, pdata);
+ (void *)inst->session, prop_id, pdata);
if (rc) {
dprintk(VIDC_ERR,
"%s: Failed to set power save mode for inst: %pK\n",
@@ -1758,6 +1777,7 @@ static int msm_venc_start_streaming(struct vb2_queue *q, unsigned int count)
{
struct msm_vidc_inst *inst;
int rc = 0;
+ struct vb2_buf_entry *temp, *next;
if (!q || !q->drv_priv) {
dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q);
return -EINVAL;
@@ -1795,6 +1815,19 @@ static int msm_venc_start_streaming(struct vb2_queue *q, unsigned int count)
}
stream_start_failed:
+ if (rc) {
+ mutex_lock(&inst->pendingq.lock);
+ list_for_each_entry_safe(temp, next, &inst->pendingq.list,
+ list) {
+ if (temp->vb->type == q->type) {
+ vb2_buffer_done(temp->vb,
+ VB2_BUF_STATE_QUEUED);
+ list_del(&temp->list);
+ kfree(temp);
+ }
+ }
+ mutex_unlock(&inst->pendingq.lock);
+ }
return rc;
}
@@ -3143,7 +3176,6 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
break;
}
pdata = &venc_mode;
-
break;
case V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS:
if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_HEVC) {
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index b36e3739e43b..662dcf7c8303 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -720,6 +720,7 @@ int msm_vidc_release_buffers(void *instance, int buffer_type)
struct buffer_info *bi, *dummy;
struct v4l2_buffer buffer_info;
struct v4l2_plane plane[VIDEO_MAX_PLANES];
+ struct vb2_buf_entry *temp, *next;
int i, rc = 0;
if (!inst)
@@ -807,6 +808,15 @@ free_and_unmap:
}
}
mutex_unlock(&inst->registeredbufs.lock);
+
+ mutex_lock(&inst->pendingq.lock);
+ list_for_each_entry_safe(temp, next, &inst->pendingq.list, list) {
+ if (temp->vb->type == buffer_type) {
+ list_del(&temp->list);
+ kfree(temp);
+ }
+ }
+ mutex_unlock(&inst->pendingq.lock);
return rc;
}
EXPORT_SYMBOL(msm_vidc_release_buffers);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c b/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c
index a3080be8cd7a..022c776a6096 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1084,6 +1084,13 @@ int read_platform_resources_from_dt(
goto err_load_max_hw_load;
}
+ rc = of_property_read_u32(pdev->dev.of_node, "qcom,power-conf",
+ &res->power_conf);
+ if (rc) {
+ dprintk(VIDC_DBG,
+ "Failed to read power configuration: %d\n", rc);
+ }
+
rc = msm_vidc_populate_legacy_context_bank(res);
if (rc) {
dprintk(VIDC_ERR,
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_resources.h b/drivers/media/platform/msm/vidc/msm_vidc_resources.h
index 734586a3f76c..03b31d7fd9d1 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_resources.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_resources.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -173,6 +173,7 @@ struct msm_vidc_platform_resources {
uint32_t imem_size;
enum imem_type imem_type;
uint32_t max_load;
+ uint32_t power_conf;
struct platform_device *pdev;
struct regulator_set regulator_set;
struct clock_set clock_set;
diff --git a/drivers/net/ethernet/msm/ecm_ipa.c b/drivers/net/ethernet/msm/ecm_ipa.c
index c7c4da22139d..0f25932d8855 100644
--- a/drivers/net/ethernet/msm/ecm_ipa.c
+++ b/drivers/net/ethernet/msm/ecm_ipa.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -9,7 +9,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
-
#include <linux/debugfs.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
@@ -106,10 +105,6 @@ enum ecm_ipa_operation {
* struct ecm_ipa_dev - main driver context parameters
* @net: network interface struct implemented by this driver
* @directory: debugfs directory for various debuging switches
- * @tx_enable: flag that enable/disable Tx path to continue to IPA
- * @rx_enable: flag that enable/disable Rx path to continue to IPA
- * @rm_enable: flag that enable/disable Resource manager request prior to Tx
- * @dma_enable: flag that allow on-the-fly DMA mode for IPA
* @eth_ipv4_hdr_hdl: saved handle for ipv4 header-insertion table
* @eth_ipv6_hdr_hdl: saved handle for ipv6 header-insertion table
* @usb_to_ipa_hdl: save handle for IPA pipe operations
@@ -129,10 +124,6 @@ enum ecm_ipa_operation {
*/
struct ecm_ipa_dev {
struct net_device *net;
- u32 tx_enable;
- u32 rx_enable;
- u32 rm_enable;
- bool dma_enable;
struct dentry *directory;
uint32_t eth_ipv4_hdr_hdl;
uint32_t eth_ipv6_hdr_hdl;
@@ -167,32 +158,16 @@ static void ecm_ipa_rm_notify(void *user_data, enum ipa_rm_event event,
static struct net_device_stats *ecm_ipa_get_stats(struct net_device *net);
static int ecm_ipa_create_rm_resource(struct ecm_ipa_dev *ecm_ipa_ctx);
static void ecm_ipa_destory_rm_resource(struct ecm_ipa_dev *ecm_ipa_ctx);
-static bool rx_filter(struct sk_buff *skb);
-static bool tx_filter(struct sk_buff *skb);
-static bool rm_enabled(struct ecm_ipa_dev *ecm_ipa_ctx);
static int resource_request(struct ecm_ipa_dev *ecm_ipa_ctx);
static void resource_release(struct ecm_ipa_dev *ecm_ipa_ctx);
static netdev_tx_t ecm_ipa_start_xmit(struct sk_buff *skb,
struct net_device *net);
-static int ecm_ipa_debugfs_stall_open(struct inode *inode,
- struct file *file);
-static ssize_t ecm_ipa_debugfs_stall_write(struct file *file,
- const char __user *buf, size_t count, loff_t *ppos);
static int ecm_ipa_debugfs_atomic_open(struct inode *inode, struct file *file);
-static ssize_t ecm_ipa_debugfs_enable_write_dma(struct file *file,
- const char __user *buf, size_t count, loff_t *ppos);
-static int ecm_ipa_debugfs_dma_open(struct inode *inode, struct file *file);
-static ssize_t ecm_ipa_debugfs_enable_write(struct file *file,
- const char __user *buf, size_t count, loff_t *ppos);
-static ssize_t ecm_ipa_debugfs_enable_read(struct file *file,
- char __user *ubuf, size_t count, loff_t *ppos);
static ssize_t ecm_ipa_debugfs_atomic_read(struct file *file,
char __user *ubuf, size_t count, loff_t *ppos);
static int ecm_ipa_debugfs_init(struct ecm_ipa_dev *ecm_ipa_ctx);
static void ecm_ipa_debugfs_destroy(struct ecm_ipa_dev *ecm_ipa_ctx);
static int ecm_ipa_ep_registers_cfg(u32 usb_to_ipa_hdl, u32 ipa_to_usb_hdl);
-static int ecm_ipa_ep_registers_dma_cfg(u32 usb_to_ipa_hdl,
- enum ipa_client_type prod_client);
static int ecm_ipa_set_device_ethernet_addr(u8 *dev_ethaddr,
u8 device_ethaddr[]);
static enum ecm_ipa_state ecm_ipa_next_state(enum ecm_ipa_state current_state,
@@ -210,22 +185,11 @@ static const struct net_device_ops ecm_ipa_netdev_ops = {
.ndo_get_stats = ecm_ipa_get_stats,
};
-const struct file_operations ecm_ipa_debugfs_dma_ops = {
- .open = ecm_ipa_debugfs_dma_open,
- .read = ecm_ipa_debugfs_enable_read,
- .write = ecm_ipa_debugfs_enable_write_dma,
-};
-
const struct file_operations ecm_ipa_debugfs_atomic_ops = {
.open = ecm_ipa_debugfs_atomic_open,
.read = ecm_ipa_debugfs_atomic_read,
};
-const struct file_operations ecm_ipa_debugfs_stall_ops = {
- .open = ecm_ipa_debugfs_stall_open,
- .write = ecm_ipa_debugfs_stall_write,
-};
-
static void ecm_ipa_msg_free_cb(void *buff, u32 len, u32 type)
{
kfree(buff);
@@ -286,9 +250,6 @@ int ecm_ipa_init(struct ecm_ipa_params *params)
ECM_IPA_DEBUG("ecm_ipa_ctx (private) = %p\n", ecm_ipa_ctx);
ecm_ipa_ctx->net = net;
- ecm_ipa_ctx->tx_enable = true;
- ecm_ipa_ctx->rx_enable = true;
- ecm_ipa_ctx->rm_enable = true;
ecm_ipa_ctx->outstanding_high = DEFAULT_OUTSTANDING_HIGH;
ecm_ipa_ctx->outstanding_low = DEFAULT_OUTSTANDING_LOW;
atomic_set(&ecm_ipa_ctx->outstanding_pkts, 0);
@@ -604,12 +565,6 @@ static netdev_tx_t ecm_ipa_start_xmit(struct sk_buff *skb,
return NETDEV_TX_BUSY;
}
- if (unlikely(tx_filter(skb))) {
- dev_kfree_skb_any(skb);
- ECM_IPA_DEBUG("packet got filtered out on Tx path\n");
- status = NETDEV_TX_OK;
- goto out;
- }
ret = resource_request(ecm_ipa_ctx);
if (ret) {
ECM_IPA_DEBUG("Waiting to resource\n");
@@ -683,11 +638,6 @@ static void ecm_ipa_packet_receive_notify(void *priv,
skb->dev = ecm_ipa_ctx->net;
skb->protocol = eth_type_trans(skb, ecm_ipa_ctx->net);
- if (rx_filter(skb)) {
- ECM_IPA_DEBUG("packet got filtered out on Rx path\n");
- dev_kfree_skb_any(skb);
- return;
- }
result = netif_rx(skb);
if (result)
@@ -1150,42 +1100,15 @@ static void ecm_ipa_destory_rm_resource(struct ecm_ipa_dev *ecm_ipa_ctx)
ECM_IPA_LOG_EXIT();
}
-static bool rx_filter(struct sk_buff *skb)
-{
- struct ecm_ipa_dev *ecm_ipa_ctx = netdev_priv(skb->dev);
- return !ecm_ipa_ctx->rx_enable;
-}
-
-static bool tx_filter(struct sk_buff *skb)
-{
- struct ecm_ipa_dev *ecm_ipa_ctx = netdev_priv(skb->dev);
- return !ecm_ipa_ctx->tx_enable;
-}
-
-static bool rm_enabled(struct ecm_ipa_dev *ecm_ipa_ctx)
-{
- return ecm_ipa_ctx->rm_enable;
-}
-
static int resource_request(struct ecm_ipa_dev *ecm_ipa_ctx)
{
- int result = 0;
-
- if (!rm_enabled(ecm_ipa_ctx))
- goto out;
- result = ipa_rm_inactivity_timer_request_resource(
- IPA_RM_RESOURCE_STD_ECM_PROD);
-out:
- return result;
+ return ipa_rm_inactivity_timer_request_resource(
+ IPA_RM_RESOURCE_STD_ECM_PROD);
}
static void resource_release(struct ecm_ipa_dev *ecm_ipa_ctx)
{
- if (!rm_enabled(ecm_ipa_ctx))
- goto out;
ipa_rm_inactivity_timer_release_resource(IPA_RM_RESOURCE_STD_ECM_PROD);
-out:
- return;
}
/**
@@ -1258,45 +1181,6 @@ static void ecm_ipa_tx_timeout(struct net_device *net)
net->stats.tx_errors++;
}
-static int ecm_ipa_debugfs_stall_open(struct inode *inode,
- struct file *file)
-{
- ECM_IPA_LOG_ENTRY();
-
- ECM_IPA_LOG_EXIT();
-
- return 0;
-}
-
-static ssize_t ecm_ipa_debugfs_stall_write(struct file *file,
- const char __user *buf, size_t count, loff_t *ppos)
-{
- u32 cmdq_cfg_mmio_phy = 0xFD4E3038;
- void *cmdq_cfg_mmio_virt;
- int result;
- bool val = 0;
-
- ECM_IPA_LOG_ENTRY();
-
- file->private_data = &val;
- result = ecm_ipa_debugfs_enable_write(file, buf, count, ppos);
-
- cmdq_cfg_mmio_virt = ioremap(cmdq_cfg_mmio_phy, sizeof(u32));
- if (!cmdq_cfg_mmio_virt) {
- ECM_IPA_ERROR("fail on mmio for cmdq_cfg_mmio_phy=0x%x",
- cmdq_cfg_mmio_phy);
- return result;
- }
-
- iowrite32(val, cmdq_cfg_mmio_virt);
- ECM_IPA_DEBUG("Value %d was written to cfgq", val);
-
- ECM_IPA_LOG_EXIT();
-
- return result;
-
-}
-
static int ecm_ipa_debugfs_atomic_open(struct inode *inode, struct file *file)
{
struct ecm_ipa_dev *ecm_ipa_ctx = inode->i_private;
@@ -1306,78 +1190,6 @@ static int ecm_ipa_debugfs_atomic_open(struct inode *inode, struct file *file)
return 0;
}
-static ssize_t ecm_ipa_debugfs_enable_write_dma(struct file *file,
- const char __user *buf, size_t count, loff_t *ppos)
-{
- struct ecm_ipa_dev *ecm_ipa_ctx = file->private_data;
- int result;
- ECM_IPA_LOG_ENTRY();
- file->private_data = &ecm_ipa_ctx->dma_enable;
- result = ecm_ipa_debugfs_enable_write(file, buf, count, ppos);
- if (ecm_ipa_ctx->dma_enable)
- ecm_ipa_ep_registers_dma_cfg(ecm_ipa_ctx->usb_to_ipa_hdl,
- ecm_ipa_ctx->ipa_to_usb_client);
- else
- ecm_ipa_ep_registers_cfg(ecm_ipa_ctx->usb_to_ipa_hdl,
- ecm_ipa_ctx->usb_to_ipa_hdl);
- ECM_IPA_LOG_EXIT();
- return result;
-}
-
-static int ecm_ipa_debugfs_dma_open(struct inode *inode, struct file *file)
-{
- struct ecm_ipa_dev *ecm_ipa_ctx = inode->i_private;
- ECM_IPA_LOG_ENTRY();
- file->private_data = ecm_ipa_ctx;
- ECM_IPA_LOG_EXIT();
- return 0;
-}
-
-static ssize_t ecm_ipa_debugfs_enable_write(struct file *file,
- const char __user *buf, size_t count, loff_t *ppos)
-{
- unsigned long missing;
- char input;
- bool *enable = file->private_data;
- if (count != sizeof(input) + 1) {
- ECM_IPA_ERROR("wrong input length(%zd)\n", count);
- return -EINVAL;
- }
- if (!buf) {
- ECM_IPA_ERROR("Bad argument\n");
- return -EINVAL;
- }
- missing = copy_from_user(&input, buf, 1);
- if (missing)
- return -EFAULT;
- ECM_IPA_DEBUG("input received %c\n", input);
- *enable = input - '0';
- ECM_IPA_DEBUG("value was set to %d\n", *enable);
- return count;
-}
-
-static ssize_t ecm_ipa_debugfs_enable_read(struct file *file,
- char __user *ubuf, size_t count, loff_t *ppos)
-{
- int nbytes;
- int size = 0;
- int ret;
- loff_t pos;
- u8 enable_str[sizeof(char)*3] = {0};
- bool *enable = file->private_data;
- pos = *ppos;
- nbytes = scnprintf(enable_str, sizeof(enable_str), "%d\n", *enable);
- ret = simple_read_from_buffer(ubuf, count, ppos, enable_str, nbytes);
- if (ret < 0) {
- ECM_IPA_ERROR("simple_read_from_buffer problem\n");
- return ret;
- }
- size += ret;
- count -= nbytes;
- *ppos = pos + size;
- return size;
-}
-
static ssize_t ecm_ipa_debugfs_atomic_read(struct file *file,
char __user *ubuf, size_t count, loff_t *ppos)
{
@@ -1394,7 +1206,6 @@ static int ecm_ipa_debugfs_init(struct ecm_ipa_dev *ecm_ipa_ctx)
{
const mode_t flags_read_write = S_IRUGO | S_IWUGO;
const mode_t flags_read_only = S_IRUGO;
- const mode_t flags_write_only = S_IWUGO;
struct dentry *file;
ECM_IPA_LOG_ENTRY();
@@ -1407,24 +1218,6 @@ static int ecm_ipa_debugfs_init(struct ecm_ipa_dev *ecm_ipa_ctx)
ECM_IPA_ERROR("could not create debugfs directory entry\n");
goto fail_directory;
}
- file = debugfs_create_bool("tx_enable", flags_read_write,
- ecm_ipa_ctx->directory, &ecm_ipa_ctx->tx_enable);
- if (!file) {
- ECM_IPA_ERROR("could not create debugfs tx file\n");
- goto fail_file;
- }
- file = debugfs_create_bool("rx_enable", flags_read_write,
- ecm_ipa_ctx->directory, &ecm_ipa_ctx->rx_enable);
- if (!file) {
- ECM_IPA_ERROR("could not create debugfs rx file\n");
- goto fail_file;
- }
- file = debugfs_create_bool("rm_enable", flags_read_write,
- ecm_ipa_ctx->directory, &ecm_ipa_ctx->rm_enable);
- if (!file) {
- ECM_IPA_ERROR("could not create debugfs rm file\n");
- goto fail_file;
- }
file = debugfs_create_u8("outstanding_high", flags_read_write,
ecm_ipa_ctx->directory, &ecm_ipa_ctx->outstanding_high);
if (!file) {
@@ -1437,13 +1230,6 @@ static int ecm_ipa_debugfs_init(struct ecm_ipa_dev *ecm_ipa_ctx)
ECM_IPA_ERROR("could not create outstanding_low file\n");
goto fail_file;
}
- file = debugfs_create_file("dma_enable", flags_read_write,
- ecm_ipa_ctx->directory,
- ecm_ipa_ctx, &ecm_ipa_debugfs_dma_ops);
- if (!file) {
- ECM_IPA_ERROR("could not create debugfs dma file\n");
- goto fail_file;
- }
file = debugfs_create_file("outstanding", flags_read_only,
ecm_ipa_ctx->directory,
ecm_ipa_ctx, &ecm_ipa_debugfs_atomic_ops);
@@ -1452,14 +1238,7 @@ static int ecm_ipa_debugfs_init(struct ecm_ipa_dev *ecm_ipa_ctx)
goto fail_file;
}
- file = debugfs_create_file("stall_ipa_rx_proc", flags_write_only,
- ecm_ipa_ctx->directory,
- ecm_ipa_ctx, &ecm_ipa_debugfs_stall_ops);
- if (!file) {
- ECM_IPA_ERROR("could not create stall_ipa_rx_proc file\n");
- goto fail_file;
- }
-
+ ECM_IPA_DEBUG("debugfs entries were created\n");
ECM_IPA_LOG_EXIT();
return 0;
@@ -1523,46 +1302,6 @@ out:
}
/**
- * ecm_ipa_ep_registers_dma_cfg() - configure the USB endpoints for ECM
- * DMA
- * @usb_to_ipa_hdl: handle received from ipa_connect
- *
- * This function will override the previous configuration
- * which is needed for cores that does not support blocks logic
- * Note that client handles are the actual pipe index
- */
-static int ecm_ipa_ep_registers_dma_cfg(u32 usb_to_ipa_hdl,
- enum ipa_client_type prod_client)
-{
- int result = 0;
- struct ipa_ep_cfg_mode cfg_mode;
- u32 apps_to_ipa_hdl = 2;
-
- ECM_IPA_LOG_ENTRY();
-
- memset(&cfg_mode, 0 , sizeof(cfg_mode));
- cfg_mode.mode = IPA_DMA;
- cfg_mode.dst = prod_client;
- result = ipa_cfg_ep_mode(apps_to_ipa_hdl, &cfg_mode);
- if (result) {
- ECM_IPA_ERROR("failed to configure Apps to IPA\n");
- goto out;
- }
- memset(&cfg_mode, 0 , sizeof(cfg_mode));
- cfg_mode.mode = IPA_DMA;
- cfg_mode.dst = IPA_CLIENT_A5_LAN_WAN_CONS;
- result = ipa_cfg_ep_mode(usb_to_ipa_hdl, &cfg_mode);
- if (result) {
- ECM_IPA_ERROR("failed to configure USB to IPA\n");
- goto out;
- }
- ECM_IPA_DEBUG("end-point registers successfully configured\n");
-out:
- ECM_IPA_LOG_EXIT();
- return result;
-}
-
-/**
* ecm_ipa_set_device_ethernet_addr() - set device etherenet address
* @dev_ethaddr: device etherenet address
*
diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig
index db1ca629cbd6..f0c831b4b3d9 100644
--- a/drivers/net/wireless/ath/ath10k/Kconfig
+++ b/drivers/net/wireless/ath/ath10k/Kconfig
@@ -21,6 +21,26 @@ config ATH10K_AHB
---help---
This module adds support for AHB bus
+config ATH10K_TARGET_SNOC
+ tristate "Atheros ath10k SNOC support"
+ depends on ATH10K
+ ---help---
+ This module adds support for the Integrated WCN3990 WLAN module,
+ WCN3990 has integrated 802.11ac chipset with SNOC bus interface.
+ This module also adds support to register the WCN3990 wlan module
+ with MAC80211 network subsystem.
+
+config ATH10K_SNOC
+ bool "Enable/disable Atheros ath10k SNOC bus interface support"
+ depends on ATH10K
+ depends on ATH10K_TARGET_SNOC
+ ---help---
+ This module add support for WLAN SNOC bus registration, WLAN
+ copy engine configuration for the WCN3990 chipset, WLAN hardware
+ shadow register configuration, create host to target communication
+ interface to interact with WLAN firmware, WLAN module interface
+ control and data receive(RX)/transmit(TX) control.
+
config ATH10K_DEBUG
bool "Atheros ath10k debugging"
depends on ATH10K
diff --git a/drivers/net/wireless/ath/ath10k/Makefile b/drivers/net/wireless/ath/ath10k/Makefile
index 930fadd940d8..25b23bf2c8e6 100644
--- a/drivers/net/wireless/ath/ath10k/Makefile
+++ b/drivers/net/wireless/ath/ath10k/Makefile
@@ -24,6 +24,9 @@ ath10k_core-$(CONFIG_PM) += wow.o
obj-$(CONFIG_ATH10K_PCI) += ath10k_pci.o
ath10k_pci-y += pci.o \
ce.o
+obj-$(CONFIG_ATH10K_TARGET_SNOC) += ath10k_snoc.o
+ath10k_snoc-y += snoc.o \
+ ce.o
ath10k_pci-$(CONFIG_ATH10K_AHB) += ahb.o
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 89b1dfcb89fd..871329c79a46 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -305,6 +305,21 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.hw_ops = &qca99x0_ops,
.decap_align_bytes = 1,
},
+ {
+ .id = ATH10K_HW_WCN3990,
+ .dev_id = 0,
+ .name = "wcn3990 hw1.0",
+ .continuous_frag_desc = true,
+ .tx_chain_mask = 0x7,
+ .rx_chain_mask = 0x7,
+ .max_spatial_stream = 4,
+ .fw = {
+ .dir = WCN3990_HW_1_0_FW_DIR,
+ },
+ .sw_decrypt_mcast_mgmt = true,
+ .hw_ops = &wcn3990_ops,
+ .decap_align_bytes = 1,
+ },
};
static const char *const ath10k_core_fw_feature_str[] = {
@@ -1263,12 +1278,14 @@ int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name,
data += ie_len;
}
- if (!fw_file->firmware_data ||
- !fw_file->firmware_len) {
- ath10k_warn(ar, "No ATH10K_FW_IE_FW_IMAGE found from '%s/%s', skipping\n",
- ar->hw_params.fw.dir, name);
- ret = -ENOMEDIUM;
- goto err;
+ if (ar->is_bmi) {
+ if (!fw_file->firmware_data ||
+ !fw_file->firmware_len) {
+ ath10k_warn(ar, "No ATH10K_FW_IE_FW_IMAGE found from '%s/%s', skipping\n",
+ ar->hw_params.fw.dir, name);
+ ret = -ENOMEDIUM;
+ goto err;
+ }
}
return 0;
@@ -1282,8 +1299,10 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
{
int ret;
- /* calibration file is optional, don't check for any errors */
- ath10k_fetch_cal_file(ar);
+ if (ar->is_bmi) {
+ /* calibration file is optional, don't check for any errors */
+ ath10k_fetch_cal_file(ar);
+ }
ar->fw_api = 5;
ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
@@ -1574,8 +1593,6 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
{
struct ath10k_fw_file *fw_file = &ar->normal_mode_fw.fw_file;
- init_fw_param(ar, &ar->normal_mode_fw.fw_file);
-
if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, fw_file->fw_features) &&
!test_bit(ATH10K_FW_FEATURE_WMI_10X, fw_file->fw_features)) {
ath10k_err(ar, "feature bits corrupted: 10.2 feature requires 10.x feature to be set as well");
@@ -1797,8 +1814,10 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
lockdep_assert_held(&ar->conf_mutex);
clear_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags);
- if (!ar->qmi.is_qmi) {
- ar->running_fw = fw;
+
+ ar->running_fw = fw;
+
+ if (ar->is_bmi) {
ath10k_bmi_start(ar);
@@ -1846,7 +1865,7 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
goto err;
}
- if (!ar->qmi.is_qmi) {
+ if (ar->is_bmi) {
status = ath10k_bmi_done(ar);
if (status)
goto err;
@@ -2083,38 +2102,37 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
return ret;
}
- if (!ar->qmi.is_qmi) {
+ if (ar->is_bmi) {
memset(&target_info, 0, sizeof(target_info));
ret = ath10k_bmi_get_target_info(ar, &target_info);
if (ret) {
ath10k_err(ar, "could not get target info (%d)\n", ret);
goto err_power_down;
}
-
ar->target_version = target_info.version;
ar->hw->wiphy->hw_version = target_info.version;
+ }
- ret = ath10k_init_hw_params(ar);
- if (ret) {
- ath10k_err(ar, "could not get hw params (%d)\n", ret);
- goto err_power_down;
- }
-
- ret = ath10k_core_fetch_firmware_files(ar);
- if (ret) {
- ath10k_err(ar, "could not fetch firmware files (%d)\n",
- ret);
- goto err_power_down;
- }
+ ret = ath10k_init_hw_params(ar);
+ if (ret) {
+ ath10k_err(ar, "could not get hw params (%d)\n", ret);
+ goto err_power_down;
+ }
- BUILD_BUG_ON(sizeof(ar->hw->wiphy->fw_version) !=
- sizeof(ar->normal_mode_fw.fw_file.fw_version));
- memcpy(ar->hw->wiphy->fw_version,
- ar->normal_mode_fw.fw_file.fw_version,
- sizeof(ar->hw->wiphy->fw_version));
+ ret = ath10k_core_fetch_firmware_files(ar);
+ if (ret) {
+ ath10k_err(ar, "could not fetch firmware files (%d)\n", ret);
+ goto err_power_down;
+ }
- ath10k_debug_print_hwfw_info(ar);
+ BUILD_BUG_ON(sizeof(ar->hw->wiphy->fw_version) !=
+ sizeof(ar->normal_mode_fw.fw_file.fw_version));
+ memcpy(ar->hw->wiphy->fw_version,
+ ar->normal_mode_fw.fw_file.fw_version,
+ sizeof(ar->hw->wiphy->fw_version));
+ ath10k_debug_print_hwfw_info(ar);
+ if (ar->is_bmi) {
ret = ath10k_core_pre_cal_download(ar);
if (ret) {
/* pre calibration data download is not necessary
@@ -2147,7 +2165,7 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
goto err_free_firmware_files;
}
- if (!ar->qmi.is_qmi) {
+ if (ar->is_bmi) {
ret = ath10k_swap_code_seg_init(ar,
&ar->normal_mode_fw.fw_file);
if (ret) {
@@ -2299,6 +2317,12 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
ar->hif.ops = hif_ops;
ar->hif.bus = bus;
+ /* By default, assume bmi is set, as most of the existing
+ * chip sets are based on this, set to false explicitly
+ * when current chip set does not support.
+ */
+ ar->is_bmi = true;
+
switch (hw_rev) {
case ATH10K_HW_QCA988X:
case ATH10K_HW_QCA9887:
@@ -2326,7 +2350,8 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
case ATH10K_HW_WCN3990:
ar->regs = &wcn3990_regs;
ar->hw_values = &wcn3990_values;
- ar->qmi.is_qmi = true;
+ /* WCN3990 chip set is non bmi based */
+ ar->is_bmi = false;
ar->fw_flags = &wcn3990_fw_flags;
break;
default:
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index bba51b939834..9310de85f2a0 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -138,11 +138,6 @@ struct ath10k_bmi {
bool done_sent;
};
-struct ath10k_qmi {
- bool fw_ready;
- bool is_qmi;
-};
-
struct ath10k_mem_chunk {
void *vaddr;
dma_addr_t paddr;
@@ -745,7 +740,6 @@ struct ath10k {
const struct ath10k_hw_regs *regs;
const struct ath10k_hw_values *hw_values;
struct ath10k_bmi bmi;
- struct ath10k_qmi qmi;
struct ath10k_wmi wmi;
struct ath10k_htc htc;
struct ath10k_htt htt;
@@ -930,6 +924,8 @@ struct ath10k {
spinlock_t ce_lock; /* lock for CE access */
void *ce_states;
struct fw_flag *fw_flags;
+ /* set for bmi chip sets */
+ bool is_bmi;
/* must be last */
u8 drv_priv[0] __aligned(sizeof(void *));
};
diff --git a/drivers/net/wireless/ath/ath10k/hw.c b/drivers/net/wireless/ath/ath10k/hw.c
index c9c43cd1ab95..0cd1068b0beb 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -271,3 +271,5 @@ static int ath10k_qca99x0_rx_desc_get_l3_pad_bytes(struct htt_rx_desc *rxd)
const struct ath10k_hw_ops qca99x0_ops = {
.rx_desc_get_l3_pad_bytes = ath10k_qca99x0_rx_desc_get_l3_pad_bytes,
};
+
+const struct ath10k_hw_ops wcn3990_ops = {0};
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 6a8765b4e358..2e7d90ef53f2 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -128,6 +128,10 @@ enum qca9377_chip_id_rev {
#define QCA4019_HW_1_0_BOARD_DATA_FILE "board.bin"
#define QCA4019_HW_1_0_PATCH_LOAD_ADDR 0x1234
+/* WCN3990 1.0 definitions */
+#define WCN3990_HW_1_0_DEV_VERSION ATH10K_HW_WCN3990
+#define WCN3990_HW_1_0_FW_DIR "/etc/firmware"
+
#define ATH10K_FW_API2_FILE "firmware-2.bin"
#define ATH10K_FW_API3_FILE "firmware-3.bin"
@@ -434,6 +438,7 @@ struct ath10k_hw_ops {
extern const struct ath10k_hw_ops qca988x_ops;
extern const struct ath10k_hw_ops qca99x0_ops;
+extern const struct ath10k_hw_ops wcn3990_ops;
static inline int
ath10k_rx_desc_get_l3_pad_bytes(struct ath10k_hw_params *hw,
diff --git a/drivers/platform/msm/Kconfig b/drivers/platform/msm/Kconfig
index 9c2697dde76d..024c66ac8e57 100644
--- a/drivers/platform/msm/Kconfig
+++ b/drivers/platform/msm/Kconfig
@@ -5,20 +5,20 @@ config QPNP_REVID
tristate "QPNP Revision ID Peripheral"
depends on SPMI
help
- Say 'y' here to include support for the Qualcomm QPNP REVID
- peripheral. REVID prints out the PMIC type and revision numbers
- in the kernel log along with the PMIC option status. The PMIC
- type is mapped to a Qualcomm chip part number and logged as well.
+ Say 'y' here to include support for the Qualcomm Technologies, Inc.
+ QPNP REVID peripheral. REVID prints out the PMIC type and revision
+ numbers in the kernel log along with the PMIC option status. The PMIC
+ type is mapped to a QTI chip part number and logged as well.
config QPNP_COINCELL
- tristate "Qualcomm QPNP coincell charger support"
+ tristate "QPNP coincell charger support"
depends on SPMI
help
This driver supports the QPNP coincell peripheral found inside of
- Qualcomm QPNP PMIC devices. The coincell charger provides a means to
- charge a coincell battery or backup capacitor which is used to
- maintain PMIC register state when the main battery is removed from the
- mobile device.
+ Qualcomm Technologies, Inc. QPNP PMIC devices. The coincell charger
+ provides a means to charge a coincell battery or backup capacitor
+ which is used to maintain PMIC register state when the main battery is
+ removed from the mobile device.
config SPS
bool "SPS support"
diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c
index fd241f6b62da..58c1704a875c 100644
--- a/drivers/platform/msm/gsi/gsi.c
+++ b/drivers/platform/msm/gsi/gsi.c
@@ -2733,6 +2733,16 @@ int gsi_enable_fw(phys_addr_t gsi_base_addr, u32 gsi_size)
}
EXPORT_SYMBOL(gsi_enable_fw);
+void gsi_get_inst_ram_offset_and_size(unsigned long *base_offset,
+ unsigned long *size)
+{
+ if (base_offset)
+ *base_offset = GSI_GSI_INST_RAM_BASE_OFFS;
+ if (size)
+ *size = GSI_GSI_INST_RAM_SIZE;
+}
+EXPORT_SYMBOL(gsi_get_inst_ram_offset_and_size);
+
static int msm_gsi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
diff --git a/drivers/platform/msm/gsi/gsi_reg.h b/drivers/platform/msm/gsi/gsi_reg.h
index fa1e84896f73..1acaf74a0968 100644
--- a/drivers/platform/msm/gsi/gsi_reg.h
+++ b/drivers/platform/msm/gsi/gsi_reg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1838,5 +1838,7 @@
#define GSI_INTER_EE_n_SRC_EV_CH_IRQ_CLR_EV_CH_BIT_MAP_BMSK 0xffffffff
#define GSI_INTER_EE_n_SRC_EV_CH_IRQ_CLR_EV_CH_BIT_MAP_SHFT 0x0
+#define GSI_GSI_INST_RAM_BASE_OFFS 0x4000
+#define GSI_GSI_INST_RAM_SIZE 0x4000
#endif /* __GSI_REG_H__ */
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index d64373327959..cd946fff31a9 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -4021,7 +4021,7 @@ static int ipa3_trigger_fw_loading_mdms(void)
IPADBG("FWs are available for loading\n");
- result = ipa3_load_fws(fw);
+ result = ipa3_load_fws(fw, ipa3_res.transport_mem_base);
if (result) {
IPAERR("IPA FWs loading has failed\n");
release_firmware(fw);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
index b3ce52424fec..7feb1c1ce178 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
@@ -2036,7 +2036,7 @@ int ipa3_uc_panic_notifier(struct notifier_block *this,
unsigned long event, void *ptr);
void ipa3_inc_acquire_wakelock(void);
void ipa3_dec_release_wakelock(void);
-int ipa3_load_fws(const struct firmware *firmware);
+int ipa3_load_fws(const struct firmware *firmware, phys_addr_t gsi_mem_base);
int ipa3_register_ipa_ready_cb(void (*ipa_ready_cb)(void *), void *user_data);
const char *ipa_hw_error_str(enum ipa3_hw_errors err_type);
int ipa_gsi_ch20_wa(void);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
index 683777d4cacd..3b909acdd823 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -3581,75 +3581,164 @@ end_sequence:
return res;
}
+static int ipa3_load_single_fw(const struct firmware *firmware,
+ const struct elf32_phdr *phdr)
+{
+ uint32_t *fw_mem_base;
+ int index;
+ const uint32_t *elf_data_ptr;
+
+ if (phdr->p_offset > firmware->size) {
+ IPAERR("Invalid ELF: offset=%u is beyond elf_size=%zu\n",
+ phdr->p_offset, firmware->size);
+ return -EINVAL;
+ }
+ if ((firmware->size - phdr->p_offset) < phdr->p_filesz) {
+ IPAERR("Invalid ELF: offset=%u filesz=%u elf_size=%zu\n",
+ phdr->p_offset, phdr->p_filesz, firmware->size);
+ return -EINVAL;
+ }
+
+ if (phdr->p_memsz % sizeof(uint32_t)) {
+ IPAERR("FW mem size %u doesn't align to 32bit\n",
+ phdr->p_memsz);
+ return -EFAULT;
+ }
+
+ if (phdr->p_filesz > phdr->p_memsz) {
+ IPAERR("FW image too big src_size=%u dst_size=%u\n",
+ phdr->p_filesz, phdr->p_memsz);
+ return -EFAULT;
+ }
+
+ fw_mem_base = ioremap(phdr->p_vaddr, phdr->p_memsz);
+ if (!fw_mem_base) {
+ IPAERR("Failed to map 0x%x for the size of %u\n",
+ phdr->p_vaddr, phdr->p_memsz);
+ return -ENOMEM;
+ }
+
+ /* Set the entire region to 0s */
+ memset(fw_mem_base, 0, phdr->p_memsz);
+
+ elf_data_ptr = (uint32_t *)(firmware->data + phdr->p_offset);
+
+ /* Write the FW */
+ for (index = 0; index < phdr->p_filesz/sizeof(uint32_t); index++) {
+ writel_relaxed(*elf_data_ptr, &fw_mem_base[index]);
+ elf_data_ptr++;
+ }
+
+ iounmap(fw_mem_base);
+
+ return 0;
+}
+
/**
* ipa3_load_fws() - Load the IPAv3 FWs into IPA&GSI SRAM.
*
* @firmware: Structure which contains the FW data from the user space.
+ * @gsi_mem_base: GSI base address
*
* Return value: 0 on success, negative otherwise
*
*/
-int ipa3_load_fws(const struct firmware *firmware)
+int ipa3_load_fws(const struct firmware *firmware, phys_addr_t gsi_mem_base)
{
const struct elf32_hdr *ehdr;
const struct elf32_phdr *phdr;
- const uint8_t *elf_phdr_ptr;
- uint32_t *elf_data_ptr;
- int phdr_idx, index;
- uint32_t *fw_mem_base;
-
- ehdr = (struct elf32_hdr *) firmware->data;
-
- elf_phdr_ptr = firmware->data + sizeof(*ehdr);
+ unsigned long gsi_iram_ofst;
+ unsigned long gsi_iram_size;
+ phys_addr_t ipa_reg_mem_base;
+ u32 ipa_reg_ofst;
+ int rc;
+
+ if (!gsi_mem_base) {
+ IPAERR("Invalid GSI base address\n");
+ return -EINVAL;
+ }
- for (phdr_idx = 0; phdr_idx < ehdr->e_phnum; phdr_idx++) {
- /*
- * The ELF program header will contain the starting
- * address to which the firmware needs to copied.
- */
- phdr = (struct elf32_phdr *)elf_phdr_ptr;
+ ipa_assert_on(!firmware);
+ /* One program header per FW image: GSI, DPS and HPS */
+ if (firmware->size < (sizeof(*ehdr) + 3 * sizeof(*phdr))) {
+ IPAERR("Missing ELF and Program headers firmware size=%zu\n",
+ firmware->size);
+ return -EINVAL;
+ }
- /*
- * p_vaddr will contain the starting address to which the
- * FW needs to be loaded.
- * p_memsz will contain the size of the IRAM.
- * p_filesz will contain the size of the FW image.
- */
- fw_mem_base = ioremap(phdr->p_vaddr, phdr->p_memsz);
- if (!fw_mem_base) {
- IPAERR("Failed to map 0x%x for the size of %u\n",
- phdr->p_vaddr, phdr->p_memsz);
- return -ENOMEM;
- }
+ ehdr = (struct elf32_hdr *) firmware->data;
+ ipa_assert_on(!ehdr);
+ if (ehdr->e_phnum != 3) {
+ IPAERR("Unexpected number of ELF program headers\n");
+ return -EINVAL;
+ }
+ phdr = (struct elf32_phdr *)(firmware->data + sizeof(*ehdr));
- /* Set the entire region to 0s */
- memset(fw_mem_base, 0, phdr->p_memsz);
+ /*
+ * Each ELF program header represents a FW image and contains:
+ * p_vaddr : The starting address to which the FW needs to loaded.
+ * p_memsz : The size of the IRAM (where the image loaded)
+ * p_filesz: The size of the FW image embedded inside the ELF
+ * p_offset: Absolute offset to the image from the head of the ELF
+ */
- /*
- * p_offset will contain and absolute offset from the beginning
- * of the ELF file.
- */
- elf_data_ptr = (uint32_t *)
- ((uint8_t *)firmware->data + phdr->p_offset);
+ /* Load GSI FW image */
+ gsi_get_inst_ram_offset_and_size(&gsi_iram_ofst, &gsi_iram_size);
+ if (phdr->p_vaddr != (gsi_mem_base + gsi_iram_ofst)) {
+ IPAERR(
+ "Invalid GSI FW img load addr vaddr=0x%x gsi_mem_base=%pa gsi_iram_ofst=0x%lx\n"
+ , phdr->p_vaddr, &gsi_mem_base, gsi_iram_ofst);
+ return -EINVAL;
+ }
+ if (phdr->p_memsz > gsi_iram_size) {
+ IPAERR("Invalid GSI FW img size memsz=%d gsi_iram_size=%lu\n",
+ phdr->p_memsz, gsi_iram_size);
+ return -EINVAL;
+ }
+ rc = ipa3_load_single_fw(firmware, phdr);
+ if (rc)
+ return rc;
- if (phdr->p_memsz % sizeof(uint32_t)) {
- IPAERR("FW size %u doesn't align to 32bit\n",
- phdr->p_memsz);
- return -EFAULT;
- }
+ phdr++;
+ ipa_reg_mem_base = ipa3_ctx->ipa_wrapper_base + ipahal_get_reg_base();
- /* Write the FW */
- for (index = 0; index < phdr->p_filesz/sizeof(uint32_t);
- index++) {
- writel_relaxed(*elf_data_ptr, &fw_mem_base[index]);
- elf_data_ptr++;
- }
+ /* Load IPA DPS FW image */
+ ipa_reg_ofst = ipahal_get_reg_ofst(IPA_DPS_SEQUENCER_FIRST);
+ if (phdr->p_vaddr != (ipa_reg_mem_base + ipa_reg_ofst)) {
+ IPAERR(
+ "Invalid IPA DPS img load addr vaddr=0x%x ipa_reg_mem_base=%pa ipa_reg_ofst=%u\n"
+ , phdr->p_vaddr, &ipa_reg_mem_base, ipa_reg_ofst);
+ return -EINVAL;
+ }
+ if (phdr->p_memsz > ipahal_get_dps_img_mem_size()) {
+ IPAERR("Invalid IPA DPS img size memsz=%d dps_mem_size=%u\n",
+ phdr->p_memsz, ipahal_get_dps_img_mem_size());
+ return -EINVAL;
+ }
+ rc = ipa3_load_single_fw(firmware, phdr);
+ if (rc)
+ return rc;
- iounmap(fw_mem_base);
+ phdr++;
- elf_phdr_ptr = elf_phdr_ptr + sizeof(*phdr);
+ /* Load IPA HPS FW image */
+ ipa_reg_ofst = ipahal_get_reg_ofst(IPA_HPS_SEQUENCER_FIRST);
+ if (phdr->p_vaddr != (ipa_reg_mem_base + ipa_reg_ofst)) {
+ IPAERR(
+ "Invalid IPA HPS img load addr vaddr=0x%x ipa_reg_mem_base=%pa ipa_reg_ofst=%u\n"
+ , phdr->p_vaddr, &ipa_reg_mem_base, ipa_reg_ofst);
+ return -EINVAL;
+ }
+ if (phdr->p_memsz > ipahal_get_hps_img_mem_size()) {
+ IPAERR("Invalid IPA HPS img size memsz=%d dps_mem_size=%u\n",
+ phdr->p_memsz, ipahal_get_hps_img_mem_size());
+ return -EINVAL;
}
- IPADBG("IPA FWs (GSI FW, HPS and DPS) were loaded\n");
+ rc = ipa3_load_single_fw(firmware, phdr);
+ if (rc)
+ return rc;
+
+ IPADBG("IPA FWs (GSI FW, DPS and HPS) loaded successfully\n");
return 0;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c
index 2bc179d5a33c..bc9d45b254b3 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1257,6 +1257,21 @@ int ipahal_get_proc_ctx_needed_len(enum ipa_hdr_proc_type type)
return res;
}
+/*
+ * Get IPA Data Processing Star image memory size at IPA SRAM
+ */
+u32 ipahal_get_dps_img_mem_size(void)
+{
+ return IPA_HW_DPS_IMG_MEM_SIZE_V3_0;
+}
+
+/*
+ * Get IPA Header Processing Star image memory size at IPA SRAM
+ */
+u32 ipahal_get_hps_img_mem_size(void)
+{
+ return IPA_HW_HPS_IMG_MEM_SIZE_V3_0;
+}
int ipahal_init(enum ipa_hw_type ipa_hw_type, void __iomem *base,
struct device *ipa_pdev)
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h
index 654977511814..154045fe4f56 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -634,6 +634,16 @@ int ipahal_cp_proc_ctx_to_hw_buff(enum ipa_hdr_proc_type type,
*/
int ipahal_get_proc_ctx_needed_len(enum ipa_hdr_proc_type type);
+/*
+ * Get IPA Data Processing Star image memory size at IPA SRAM
+ */
+u32 ipahal_get_dps_img_mem_size(void);
+
+/*
+ * Get IPA Header Processing Star image memory size at IPA SRAM
+ */
+u32 ipahal_get_hps_img_mem_size(void);
+
int ipahal_init(enum ipa_hw_type ipa_hw_type, void __iomem *base,
struct device *ipa_pdev);
void ipahal_destroy(void);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h
index 4c4b6661e8fc..d6a496e56861 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -546,4 +546,8 @@ struct ipa_hw_hdr_proc_ctx_add_hdr_cmd_seq {
struct ipa_hw_hdr_proc_ctx_tlv end;
};
+/* IPA HW DPS/HPS image memory sizes */
+#define IPA_HW_DPS_IMG_MEM_SIZE_V3_0 128
+#define IPA_HW_HPS_IMG_MEM_SIZE_V3_0 320
+
#endif /* _IPAHAL_I_H_ */
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
index 347a8c418ebb..ed0d0032af8d 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1119,6 +1119,12 @@ static struct ipahal_reg_obj ipahal_reg_objs[IPA_HW_MAX][IPA_REG_MAX] = {
[IPA_HW_v3_0][IPA_QSB_MAX_READS] = {
ipareg_construct_qsb_max_reads, ipareg_parse_dummy,
0x00000078, 0},
+ [IPA_HW_v3_0][IPA_DPS_SEQUENCER_FIRST] = {
+ ipareg_construct_dummy, ipareg_parse_dummy,
+ 0x0001e000, 0},
+ [IPA_HW_v3_0][IPA_HPS_SEQUENCER_FIRST] = {
+ ipareg_construct_dummy, ipareg_parse_dummy,
+ 0x0001e080, 0},
/* IPAv3.1 */
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h
index 5f1e3fe410b1..0fc2a65f5e99 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -83,6 +83,8 @@ enum ipahal_reg_name {
IPA_QSB_MAX_WRITES,
IPA_QSB_MAX_READS,
IPA_TX_CFG,
+ IPA_DPS_SEQUENCER_FIRST,
+ IPA_HPS_SEQUENCER_FIRST,
IPA_REG_MAX,
};
diff --git a/drivers/platform/msm/qpnp-coincell.c b/drivers/platform/msm/qpnp-coincell.c
index 6aaa53526868..b427f43e76df 100644
--- a/drivers/platform/msm/qpnp-coincell.c
+++ b/drivers/platform/msm/qpnp-coincell.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2015, 2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -244,7 +244,7 @@ static int qpnp_coincell_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id qpnp_coincell_match_table[] = {
+static const struct of_device_id qpnp_coincell_match_table[] = {
{ .compatible = QPNP_COINCELL_DRIVER_NAME, },
{}
};
diff --git a/drivers/platform/msm/qpnp-revid.c b/drivers/platform/msm/qpnp-revid.c
index 6b5db58f856a..9ea0b40304eb 100644
--- a/drivers/platform/msm/qpnp-revid.c
+++ b/drivers/platform/msm/qpnp-revid.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -70,7 +70,7 @@ struct revid_chip {
static LIST_HEAD(revid_chips);
static DEFINE_MUTEX(revid_chips_lock);
-static struct of_device_id qpnp_revid_match_table[] = {
+static const struct of_device_id qpnp_revid_match_table[] = {
{ .compatible = QPNP_REVID_DEV_NAME },
{}
};
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index 3b2ea6a6a5ed..55ab6177e6db 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -282,6 +282,7 @@ static struct device_attribute power_supply_attrs[] = {
POWER_SUPPLY_ATTR(fcc_delta),
POWER_SUPPLY_ATTR(icl_reduction),
POWER_SUPPLY_ATTR(parallel_mode),
+ POWER_SUPPLY_ATTR(connector_therm_zone),
/* Local extensions of type int64_t */
POWER_SUPPLY_ATTR(charge_counter_ext),
/* Properties of type `const char *' */
diff --git a/drivers/power/qcom/Kconfig b/drivers/power/qcom/Kconfig
index b7ca61d6c21d..efb9dd9628bb 100644
--- a/drivers/power/qcom/Kconfig
+++ b/drivers/power/qcom/Kconfig
@@ -23,12 +23,12 @@ config APSS_CORE_EA
and temperature information to the scheduler.
config MSM_APM
- bool "Qualcomm Technologies Inc platform specific APM driver"
- help
- Platform specific driver to manage the power source of
- memory arrays. Interfaces with regulator drivers to ensure
- SRAM Vmin requirements are met across different performance
- levels.
+ bool "Qualcomm Technologies, Inc. platform specific APM driver"
+ help
+ Platform specific driver to manage the power source of
+ memory arrays. Interfaces with regulator drivers to ensure
+ SRAM Vmin requirements are met across different performance
+ levels.
if MSM_PM
menuconfig MSM_IDLE_STATS
diff --git a/drivers/power/qcom/apm.c b/drivers/power/qcom/apm.c
index ffd0e3833b32..6181b08a41a5 100644
--- a/drivers/power/qcom/apm.c
+++ b/drivers/power/qcom/apm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -90,7 +90,7 @@ enum {
enum {
MSM8996_ID,
MSM8996PRO_ID,
- MSMTITANIUM_ID,
+ MSM8953_ID,
};
struct msm_apm_ctrl_dev {
@@ -239,8 +239,8 @@ free_events:
return ret;
}
-/* Titanium register offset definition */
-#define MSMTITANIUM_APM_DLY_CNTR 0x2ac
+/* MSM8953 register offset definition */
+#define MSM8953_APM_DLY_CNTR 0x2ac
/* Register field shift definitions */
#define APM_CTL_SEL_SWITCH_DLY_SHIFT 0
@@ -255,12 +255,12 @@ free_events:
#define APM_CTL_POST_HALT_DLY_MASK GENMASK(31, 24)
/*
- * Get the resources associated with the msmtitanium APM controller from
+ * Get the resources associated with the MSM8953 APM controller from
* device tree, remap all I/O addresses, and program the initial
- * register configuration required for the titanium APM controller device.
+ * register configuration required for the MSM8953 APM controller device.
*/
-static int msmtitanium_apm_ctrl_init(struct platform_device *pdev,
- struct msm_apm_ctrl_dev *ctrl)
+static int msm8953_apm_ctrl_init(struct platform_device *pdev,
+ struct msm_apm_ctrl_dev *ctrl)
{
struct device *dev = &pdev->dev;
struct resource *res;
@@ -282,7 +282,7 @@ static int msmtitanium_apm_ctrl_init(struct platform_device *pdev,
* Initial APM register configuration required before starting
* APM HW controller.
*/
- regval = readl_relaxed(ctrl->reg_base + MSMTITANIUM_APM_DLY_CNTR);
+ regval = readl_relaxed(ctrl->reg_base + MSM8953_APM_DLY_CNTR);
val = regval;
if (of_find_property(dev->of_node, "qcom,apm-post-halt-delay", NULL)) {
@@ -342,7 +342,7 @@ static int msmtitanium_apm_ctrl_init(struct platform_device *pdev,
}
if (val != regval) {
- writel_relaxed(val, ctrl->reg_base + MSMTITANIUM_APM_DLY_CNTR);
+ writel_relaxed(val, ctrl->reg_base + MSM8953_APM_DLY_CNTR);
/* make sure write completes before return */
mb();
}
@@ -619,17 +619,17 @@ done:
return ret;
}
-/* Titanium register value definitions */
-#define MSMTITANIUM_APM_MX_MODE_VAL 0x00
-#define MSMTITANIUM_APM_APCC_MODE_VAL 0x02
-#define MSMTITANIUM_APM_MX_DONE_VAL 0x00
-#define MSMTITANIUM_APM_APCC_DONE_VAL 0x03
+/* MSM8953 register value definitions */
+#define MSM8953_APM_MX_MODE_VAL 0x00
+#define MSM8953_APM_APCC_MODE_VAL 0x02
+#define MSM8953_APM_MX_DONE_VAL 0x00
+#define MSM8953_APM_APCC_DONE_VAL 0x03
-/* Titanium register offset definitions */
-#define MSMTITANIUM_APCC_APM_MODE 0x000002a8
-#define MSMTITANIUM_APCC_APM_CTL_STS 0x000002b0
+/* MSM8953 register offset definitions */
+#define MSM8953_APCC_APM_MODE 0x000002a8
+#define MSM8953_APCC_APM_CTL_STS 0x000002b0
-static int msmtitanium_apm_switch_to_mx(struct msm_apm_ctrl_dev *ctrl_dev)
+static int msm8953_apm_switch_to_mx(struct msm_apm_ctrl_dev *ctrl_dev)
{
int timeout = MSM_APM_SWITCH_TIMEOUT_US;
u32 regval;
@@ -639,17 +639,17 @@ static int msmtitanium_apm_switch_to_mx(struct msm_apm_ctrl_dev *ctrl_dev)
spin_lock_irqsave(&ctrl_dev->lock, flags);
/* Switch arrays to MX supply and wait for its completion */
- writel_relaxed(MSMTITANIUM_APM_MX_MODE_VAL, ctrl_dev->reg_base +
- MSMTITANIUM_APCC_APM_MODE);
+ writel_relaxed(MSM8953_APM_MX_MODE_VAL, ctrl_dev->reg_base +
+ MSM8953_APCC_APM_MODE);
/* Ensure write above completes before delaying */
mb();
while (timeout > 0) {
regval = readl_relaxed(ctrl_dev->reg_base +
- MSMTITANIUM_APCC_APM_CTL_STS);
+ MSM8953_APCC_APM_CTL_STS);
if ((regval & MSM_APM_CTL_STS_MASK) ==
- MSMTITANIUM_APM_MX_DONE_VAL)
+ MSM8953_APM_MX_DONE_VAL)
break;
udelay(1);
@@ -670,7 +670,7 @@ static int msmtitanium_apm_switch_to_mx(struct msm_apm_ctrl_dev *ctrl_dev)
return ret;
}
-static int msmtitanium_apm_switch_to_apcc(struct msm_apm_ctrl_dev *ctrl_dev)
+static int msm8953_apm_switch_to_apcc(struct msm_apm_ctrl_dev *ctrl_dev)
{
int timeout = MSM_APM_SWITCH_TIMEOUT_US;
u32 regval;
@@ -680,17 +680,17 @@ static int msmtitanium_apm_switch_to_apcc(struct msm_apm_ctrl_dev *ctrl_dev)
spin_lock_irqsave(&ctrl_dev->lock, flags);
/* Switch arrays to APCC supply and wait for its completion */
- writel_relaxed(MSMTITANIUM_APM_APCC_MODE_VAL, ctrl_dev->reg_base +
- MSMTITANIUM_APCC_APM_MODE);
+ writel_relaxed(MSM8953_APM_APCC_MODE_VAL, ctrl_dev->reg_base +
+ MSM8953_APCC_APM_MODE);
/* Ensure write above completes before delaying */
mb();
while (timeout > 0) {
regval = readl_relaxed(ctrl_dev->reg_base +
- MSMTITANIUM_APCC_APM_CTL_STS);
+ MSM8953_APCC_APM_CTL_STS);
if ((regval & MSM_APM_CTL_STS_MASK) ==
- MSMTITANIUM_APM_APCC_DONE_VAL)
+ MSM8953_APM_APCC_DONE_VAL)
break;
udelay(1);
@@ -722,8 +722,8 @@ static int msm_apm_switch_to_mx(struct msm_apm_ctrl_dev *ctrl_dev)
case MSM8996PRO_ID:
ret = msm8996pro_apm_switch_to_mx(ctrl_dev);
break;
- case MSMTITANIUM_ID:
- ret = msmtitanium_apm_switch_to_mx(ctrl_dev);
+ case MSM8953_ID:
+ ret = msm8953_apm_switch_to_mx(ctrl_dev);
break;
}
@@ -741,8 +741,8 @@ static int msm_apm_switch_to_apcc(struct msm_apm_ctrl_dev *ctrl_dev)
case MSM8996PRO_ID:
ret = msm8996pro_apm_switch_to_apcc(ctrl_dev);
break;
- case MSMTITANIUM_ID:
- ret = msmtitanium_apm_switch_to_apcc(ctrl_dev);
+ case MSM8953_ID:
+ ret = msm8953_apm_switch_to_apcc(ctrl_dev);
break;
}
@@ -898,7 +898,7 @@ static void apm_debugfs_init(struct msm_apm_ctrl_dev *ctrl_dev)
return;
}
- temp = debugfs_create_file("supply", S_IRUGO, ctrl_dev->debugfs,
+ temp = debugfs_create_file("supply", 0444, ctrl_dev->debugfs,
ctrl_dev, &apm_supply_fops);
if (IS_ERR_OR_NULL(temp)) {
pr_err("supply mode creation failed\n");
@@ -932,7 +932,7 @@ static void apm_debugfs_base_remove(void)
#endif
-static struct of_device_id msm_apm_match_table[] = {
+static const struct of_device_id msm_apm_match_table[] = {
{
.compatible = "qcom,msm-apm",
.data = (void *)(uintptr_t)MSM8996_ID,
@@ -942,8 +942,8 @@ static struct of_device_id msm_apm_match_table[] = {
.data = (void *)(uintptr_t)MSM8996PRO_ID,
},
{
- .compatible = "qcom,msmtitanium-apm",
- .data = (void *)(uintptr_t)MSMTITANIUM_ID,
+ .compatible = "qcom,msm8953-apm",
+ .data = (void *)(uintptr_t)MSM8953_ID,
},
{}
};
@@ -967,10 +967,8 @@ static int msm_apm_probe(struct platform_device *pdev)
return -ENODEV;
ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
- if (!ctrl) {
- dev_err(dev, "MSM APM controller memory allocation failed\n");
+ if (!ctrl)
return -ENOMEM;
- }
INIT_LIST_HEAD(&ctrl->list);
spin_lock_init(&ctrl->lock);
@@ -987,8 +985,8 @@ static int msm_apm_probe(struct platform_device *pdev)
return ret;
}
break;
- case MSMTITANIUM_ID:
- ret = msmtitanium_apm_ctrl_init(pdev, ctrl);
+ case MSM8953_ID:
+ ret = msm8953_apm_ctrl_init(pdev, ctrl);
if (ret) {
dev_err(dev, "Failed to initialize APM controller device: ret=%d\n",
ret);
diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c
index 38e822de34a7..a30ed90d6e92 100644
--- a/drivers/power/reset/msm-poweroff.c
+++ b/drivers/power/reset/msm-poweroff.c
@@ -530,7 +530,7 @@ static int msm_restart_probe(struct platform_device *pdev)
pr_err("unable to map imem KASLR offset\n");
}
- if (kaslr_imem_addr && scm_is_secure_device()) {
+ if (kaslr_imem_addr) {
__raw_writel(0xdead4ead, kaslr_imem_addr);
__raw_writel(KASLR_OFFSET_BIT_MASK &
(kimage_vaddr - KIMAGE_VADDR), kaslr_imem_addr + 4);
@@ -602,7 +602,6 @@ skip_sysfs_create:
scm_deassert_ps_hold_supported = true;
#ifdef CONFIG_QCOM_DLOAD_MODE
- download_mode = scm_is_secure_device();
set_dload_mode(download_mode);
if (!download_mode)
scm_disable_sdi();
diff --git a/drivers/power/supply/qcom/battery.c b/drivers/power/supply/qcom/battery.c
index 5f1b6b294b5f..34add97b55d2 100644
--- a/drivers/power/supply/qcom/battery.c
+++ b/drivers/power/supply/qcom/battery.c
@@ -42,6 +42,7 @@ struct pl_data {
struct votable *fcc_votable;
struct votable *fv_votable;
struct votable *pl_disable_votable;
+ struct votable *pl_awake_votable;
struct work_struct status_change_work;
struct delayed_work pl_taper_work;
struct power_supply *main_psy;
@@ -82,7 +83,7 @@ enum {
static void split_settled(struct pl_data *chip)
{
int slave_icl_pct;
- int slave_ua;
+ int slave_ua = 0;
union power_supply_propval pval = {0, };
int rc;
@@ -94,11 +95,9 @@ static void split_settled(struct pl_data *chip)
if (chip->pl_mode != POWER_SUPPLY_PARALLEL_USBIN_USBIN)
return;
- if (chip->main_psy)
+ if (!chip->main_psy)
return;
- slave_ua = 0;
-
if (!get_effective_result_locked(chip->pl_disable_votable)) {
/* read the aicl settled value */
rc = power_supply_get_property(chip->main_psy,
@@ -214,7 +213,7 @@ static void pl_taper_work(struct work_struct *work)
if (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER) {
pl_dbg(chip, PR_PARALLEL, "master is taper charging; reducing slave FCC\n");
- __pm_stay_awake(chip->pl_ws);
+ vote(chip->pl_awake_votable, TAPER_END_VOTER, true, 0);
/* Reduce the taper percent by 25 percent */
chip->taper_pct = chip->taper_pct * TAPER_RESIDUAL_PCT / 100;
rerun_election(chip->fcc_votable);
@@ -231,7 +230,7 @@ static void pl_taper_work(struct work_struct *work)
pl_dbg(chip, PR_PARALLEL, "master is fast charging; waiting for next taper\n");
done:
- __pm_relax(chip->pl_ws);
+ vote(chip->pl_awake_votable, TAPER_END_VOTER, false, 0);
}
/*********
@@ -375,15 +374,17 @@ static int pl_disable_vote_callback(struct votable *votable,
if (!pl_disable) { /* enable */
rerun_election(chip->fv_votable);
rerun_election(chip->fcc_votable);
-
- if (chip->pl_psy) {
- pval.intval = 0;
- rc = power_supply_set_property(chip->pl_psy,
- POWER_SUPPLY_PROP_INPUT_SUSPEND, &pval);
- if (rc < 0)
- pr_err("Couldn't change slave suspend state rc=%d\n",
- rc);
- }
+ /*
+ * Enable will be called with a valid pl_psy always. The
+ * PARALLEL_PSY_VOTER keeps it disabled unless a pl_psy
+ * is seen.
+ */
+ pval.intval = 0;
+ rc = power_supply_set_property(chip->pl_psy,
+ POWER_SUPPLY_PROP_INPUT_SUSPEND, &pval);
+ if (rc < 0)
+ pr_err("Couldn't change slave suspend state rc=%d\n",
+ rc);
if (chip->pl_mode == POWER_SUPPLY_PARALLEL_USBIN_USBIN)
split_settled(chip);
@@ -406,6 +407,7 @@ static int pl_disable_vote_callback(struct votable *votable,
if (chip->pl_mode == POWER_SUPPLY_PARALLEL_USBIN_USBIN)
split_settled(chip);
+ /* pl_psy may be NULL while in the disable branch */
if (chip->pl_psy) {
pval.intval = 1;
rc = power_supply_set_property(chip->pl_psy,
@@ -424,6 +426,20 @@ static int pl_disable_vote_callback(struct votable *votable,
return 0;
}
+static int pl_awake_vote_callback(struct votable *votable,
+ void *data, int awake, const char *client)
+{
+ struct pl_data *chip = data;
+
+ if (awake)
+ __pm_stay_awake(chip->pl_ws);
+ else
+ __pm_relax(chip->pl_ws);
+
+ pr_debug("client: %s awake: %d\n", client, awake);
+ return 0;
+}
+
static bool is_main_available(struct pl_data *chip)
{
if (!chip->main_psy)
@@ -500,15 +516,6 @@ static void handle_main_charge_type(struct pl_data *chip)
return;
}
- /* handle fast/taper charge entry */
- if (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER
- || pval.intval == POWER_SUPPLY_CHARGE_TYPE_FAST) {
- pl_dbg(chip, PR_PARALLEL, "chg_state enabling parallel\n");
- vote(chip->pl_disable_votable, CHG_STATE_VOTER, false, 0);
- chip->charge_type = pval.intval;
- return;
- }
-
/* handle taper charge entry */
if (chip->charge_type == POWER_SUPPLY_CHARGE_TYPE_FAST
&& (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER)) {
@@ -518,6 +525,15 @@ static void handle_main_charge_type(struct pl_data *chip)
return;
}
+ /* handle fast/taper charge entry */
+ if (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER
+ || pval.intval == POWER_SUPPLY_CHARGE_TYPE_FAST) {
+ pl_dbg(chip, PR_PARALLEL, "chg_state enabling parallel\n");
+ vote(chip->pl_disable_votable, CHG_STATE_VOTER, false, 0);
+ chip->charge_type = pval.intval;
+ return;
+ }
+
/* remember the new state only if it isn't any of the above */
chip->charge_type = pval.intval;
}
@@ -671,6 +687,14 @@ static int pl_init(void)
vote(chip->pl_disable_votable, TAPER_END_VOTER, false, 0);
vote(chip->pl_disable_votable, PARALLEL_PSY_VOTER, true, 0);
+ chip->pl_awake_votable = create_votable("PL_AWAKE", VOTE_SET_ANY,
+ pl_awake_vote_callback,
+ chip);
+ if (IS_ERR(chip->pl_awake_votable)) {
+ rc = PTR_ERR(chip->pl_disable_votable);
+ goto destroy_votable;
+ }
+
INIT_WORK(&chip->status_change_work, status_change_work);
INIT_DELAYED_WORK(&chip->pl_taper_work, pl_taper_work);
@@ -701,6 +725,7 @@ static int pl_init(void)
unreg_notifier:
power_supply_unreg_notifier(&chip->nb);
destroy_votable:
+ destroy_votable(chip->pl_awake_votable);
destroy_votable(chip->pl_disable_votable);
destroy_votable(chip->fv_votable);
destroy_votable(chip->fcc_votable);
@@ -716,6 +741,7 @@ static void pl_deinit(void)
struct pl_data *chip = the_chip;
power_supply_unreg_notifier(&chip->nb);
+ destroy_votable(chip->pl_awake_votable);
destroy_votable(chip->pl_disable_votable);
destroy_votable(chip->fv_votable);
destroy_votable(chip->fcc_votable);
diff --git a/drivers/power/supply/qcom/fg-core.h b/drivers/power/supply/qcom/fg-core.h
index d71e3afd8d42..0d3fcc2ede86 100644
--- a/drivers/power/supply/qcom/fg-core.h
+++ b/drivers/power/supply/qcom/fg-core.h
@@ -156,7 +156,8 @@ enum fg_sram_param_id {
FG_SRAM_ESR_TIMER_CHG_INIT,
FG_SRAM_SYS_TERM_CURR,
FG_SRAM_CHG_TERM_CURR,
- FG_SRAM_DELTA_SOC_THR,
+ FG_SRAM_DELTA_MSOC_THR,
+ FG_SRAM_DELTA_BSOC_THR,
FG_SRAM_RECHARGE_SOC_THR,
FG_SRAM_RECHARGE_VBATT_THR,
FG_SRAM_KI_COEFF_MED_DISCHG,
@@ -205,6 +206,7 @@ enum wa_flags {
struct fg_dt_props {
bool force_load_profile;
bool hold_soc_while_full;
+ bool auto_recharge_soc;
int cutoff_volt_mv;
int empty_volt_mv;
int vbatt_low_thr_mv;
@@ -322,6 +324,7 @@ struct fg_chip {
struct mutex bus_lock;
struct mutex sram_rw_lock;
struct mutex batt_avg_lock;
+ struct mutex charge_full_lock;
u32 batt_soc_base;
u32 batt_info_base;
u32 mem_if_base;
@@ -335,6 +338,9 @@ struct fg_chip {
int last_soc;
int last_batt_temp;
int health;
+ int maint_soc;
+ int delta_soc;
+ int last_msoc;
bool profile_available;
bool profile_loaded;
bool battery_missing;
@@ -345,6 +351,7 @@ struct fg_chip {
bool esr_fcc_ctrl_en;
bool soc_reporting_ready;
bool esr_flt_cold_temp_en;
+ bool bsoc_delta_irq_en;
struct completion soc_update;
struct completion soc_ready;
struct delayed_work profile_load_work;
diff --git a/drivers/power/supply/qcom/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c
index 7ffa583ca01d..12f3d448c891 100644
--- a/drivers/power/supply/qcom/qpnp-fg-gen3.c
+++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c
@@ -48,8 +48,10 @@
#define KI_COEFF_HI_DISCHG_OFFSET 0
#define KI_COEFF_LOW_DISCHG_WORD 10
#define KI_COEFF_LOW_DISCHG_OFFSET 2
-#define DELTA_SOC_THR_WORD 12
-#define DELTA_SOC_THR_OFFSET 3
+#define DELTA_MSOC_THR_WORD 12
+#define DELTA_MSOC_THR_OFFSET 3
+#define DELTA_BSOC_THR_WORD 13
+#define DELTA_BSOC_THR_OFFSET 2
#define RECHARGE_SOC_THR_WORD 14
#define RECHARGE_SOC_THR_OFFSET 0
#define CHG_TERM_CURR_WORD 14
@@ -113,8 +115,10 @@
#define KI_COEFF_MED_DISCHG_v2_OFFSET 0
#define KI_COEFF_HI_DISCHG_v2_WORD 10
#define KI_COEFF_HI_DISCHG_v2_OFFSET 1
-#define DELTA_SOC_THR_v2_WORD 13
-#define DELTA_SOC_THR_v2_OFFSET 0
+#define DELTA_BSOC_THR_v2_WORD 12
+#define DELTA_BSOC_THR_v2_OFFSET 3
+#define DELTA_MSOC_THR_v2_WORD 13
+#define DELTA_MSOC_THR_v2_OFFSET 0
#define RECHARGE_SOC_THR_v2_WORD 14
#define RECHARGE_SOC_THR_v2_OFFSET 1
#define CHG_TERM_CURR_v2_WORD 15
@@ -143,6 +147,8 @@ static void fg_encode_current(struct fg_sram_param *sp,
static void fg_encode_default(struct fg_sram_param *sp,
enum fg_sram_param_id id, int val, u8 *buf);
+static struct fg_irq_info fg_irqs[FG_IRQ_MAX];
+
#define PARAM(_id, _addr_word, _addr_byte, _len, _num, _den, _offset, \
_enc, _dec) \
[FG_SRAM_##_id] = { \
@@ -188,8 +194,10 @@ static struct fg_sram_param pmi8998_v1_sram_params[] = {
1000000, 122070, 0, fg_encode_current, NULL),
PARAM(CHG_TERM_CURR, CHG_TERM_CURR_WORD, CHG_TERM_CURR_OFFSET, 1,
100000, 390625, 0, fg_encode_current, NULL),
- PARAM(DELTA_SOC_THR, DELTA_SOC_THR_WORD, DELTA_SOC_THR_OFFSET, 1, 2048,
- 100, 0, fg_encode_default, NULL),
+ PARAM(DELTA_MSOC_THR, DELTA_MSOC_THR_WORD, DELTA_MSOC_THR_OFFSET, 1,
+ 2048, 100, 0, fg_encode_default, NULL),
+ PARAM(DELTA_BSOC_THR, DELTA_BSOC_THR_WORD, DELTA_BSOC_THR_OFFSET, 1,
+ 2048, 100, 0, fg_encode_default, NULL),
PARAM(RECHARGE_SOC_THR, RECHARGE_SOC_THR_WORD, RECHARGE_SOC_THR_OFFSET,
1, 256, 100, 0, fg_encode_default, NULL),
PARAM(ESR_TIMER_DISCHG_MAX, ESR_TIMER_DISCHG_MAX_WORD,
@@ -248,8 +256,10 @@ static struct fg_sram_param pmi8998_v2_sram_params[] = {
1000000, 122070, 0, fg_encode_current, NULL),
PARAM(CHG_TERM_CURR, CHG_TERM_CURR_v2_WORD, CHG_TERM_CURR_v2_OFFSET, 1,
100000, 390625, 0, fg_encode_current, NULL),
- PARAM(DELTA_SOC_THR, DELTA_SOC_THR_v2_WORD, DELTA_SOC_THR_v2_OFFSET, 1,
- 2048, 100, 0, fg_encode_default, NULL),
+ PARAM(DELTA_MSOC_THR, DELTA_MSOC_THR_v2_WORD, DELTA_MSOC_THR_v2_OFFSET,
+ 1, 2048, 100, 0, fg_encode_default, NULL),
+ PARAM(DELTA_BSOC_THR, DELTA_BSOC_THR_v2_WORD, DELTA_BSOC_THR_v2_OFFSET,
+ 1, 2048, 100, 0, fg_encode_default, NULL),
PARAM(RECHARGE_SOC_THR, RECHARGE_SOC_THR_v2_WORD,
RECHARGE_SOC_THR_v2_OFFSET, 1, 256, 100, 0, fg_encode_default,
NULL),
@@ -684,6 +694,20 @@ static int fg_get_msoc_raw(struct fg_chip *chip, int *val)
return 0;
}
+#define FULL_CAPACITY 100
+#define FULL_SOC_RAW 255
+static int fg_get_msoc(struct fg_chip *chip, int *msoc)
+{
+ int rc;
+
+ rc = fg_get_msoc_raw(chip, msoc);
+ if (rc < 0)
+ return rc;
+
+ *msoc = DIV_ROUND_CLOSEST(*msoc * FULL_CAPACITY, FULL_SOC_RAW);
+ return 0;
+}
+
static bool is_batt_empty(struct fg_chip *chip)
{
u8 status;
@@ -705,7 +729,7 @@ static bool is_batt_empty(struct fg_chip *chip)
return false;
}
- rc = fg_get_msoc_raw(chip, &msoc);
+ rc = fg_get_msoc(chip, &msoc);
if (!rc)
pr_warn("batt_soc_rt_sts: %x vbatt: %d uV msoc:%d\n", status,
vbatt_uv, msoc);
@@ -770,9 +794,8 @@ static bool is_debug_batt_id(struct fg_chip *chip)
return false;
}
-#define FULL_CAPACITY 100
-#define FULL_SOC_RAW 255
#define DEBUG_BATT_SOC 67
+#define BATT_MISS_SOC 50
#define EMPTY_SOC 0
static int fg_get_prop_capacity(struct fg_chip *chip, int *val)
{
@@ -783,6 +806,16 @@ static int fg_get_prop_capacity(struct fg_chip *chip, int *val)
return 0;
}
+ if (chip->fg_restarting) {
+ *val = chip->last_soc;
+ return 0;
+ }
+
+ if (chip->battery_missing) {
+ *val = BATT_MISS_SOC;
+ return 0;
+ }
+
if (is_batt_empty(chip)) {
*val = EMPTY_SOC;
return 0;
@@ -793,11 +826,14 @@ static int fg_get_prop_capacity(struct fg_chip *chip, int *val)
return 0;
}
- rc = fg_get_msoc_raw(chip, &msoc);
+ rc = fg_get_msoc(chip, &msoc);
if (rc < 0)
return rc;
- *val = DIV_ROUND_CLOSEST(msoc * FULL_CAPACITY, FULL_SOC_RAW);
+ if (chip->delta_soc > 0)
+ *val = chip->maint_soc;
+ else
+ *val = msoc;
return 0;
}
@@ -1386,6 +1422,36 @@ static int fg_adjust_ki_coeff_dischg(struct fg_chip *chip)
return 0;
}
+static int fg_set_recharge_voltage(struct fg_chip *chip, int voltage_mv)
+{
+ u8 buf;
+ int rc;
+
+ if (chip->dt.auto_recharge_soc)
+ return 0;
+
+ /* This configuration is available only for pmicobalt v2.0 and above */
+ if (chip->wa_flags & PMI8998_V1_REV_WA)
+ return 0;
+
+ fg_dbg(chip, FG_STATUS, "Setting recharge voltage to %dmV\n",
+ voltage_mv);
+ fg_encode(chip->sp, FG_SRAM_RECHARGE_VBATT_THR, voltage_mv, &buf);
+ rc = fg_sram_write(chip,
+ chip->sp[FG_SRAM_RECHARGE_VBATT_THR].addr_word,
+ chip->sp[FG_SRAM_RECHARGE_VBATT_THR].addr_byte,
+ &buf, chip->sp[FG_SRAM_RECHARGE_VBATT_THR].len,
+ FG_IMA_DEFAULT);
+ if (rc < 0) {
+ pr_err("Error in writing recharge_vbatt_thr, rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ return 0;
+}
+
+#define AUTO_RECHG_VOLT_LOW_LIMIT_MV 3700
static int fg_charge_full_update(struct fg_chip *chip)
{
union power_supply_propval prop = {0, };
@@ -1398,11 +1464,22 @@ static int fg_charge_full_update(struct fg_chip *chip)
if (!batt_psy_initialized(chip))
return 0;
+ mutex_lock(&chip->charge_full_lock);
+ if (!chip->charge_done && chip->bsoc_delta_irq_en) {
+ disable_irq_wake(fg_irqs[BSOC_DELTA_IRQ].irq);
+ disable_irq_nosync(fg_irqs[BSOC_DELTA_IRQ].irq);
+ chip->bsoc_delta_irq_en = false;
+ } else if (chip->charge_done && !chip->bsoc_delta_irq_en) {
+ enable_irq(fg_irqs[BSOC_DELTA_IRQ].irq);
+ enable_irq_wake(fg_irqs[BSOC_DELTA_IRQ].irq);
+ chip->bsoc_delta_irq_en = true;
+ }
+
rc = power_supply_get_property(chip->batt_psy, POWER_SUPPLY_PROP_HEALTH,
&prop);
if (rc < 0) {
pr_err("Error in getting battery health, rc=%d\n", rc);
- return rc;
+ goto out;
}
chip->health = prop.intval;
@@ -1412,33 +1489,77 @@ static int fg_charge_full_update(struct fg_chip *chip)
rc = fg_get_sram_prop(chip, FG_SRAM_BATT_SOC, &bsoc);
if (rc < 0) {
pr_err("Error in getting BATT_SOC, rc=%d\n", rc);
- return rc;
+ goto out;
}
/* We need 2 most significant bytes here */
bsoc = (u32)bsoc >> 16;
- rc = fg_get_prop_capacity(chip, &msoc);
+ rc = fg_get_msoc(chip, &msoc);
if (rc < 0) {
- pr_err("Error in getting capacity, rc=%d\n", rc);
- return rc;
+ pr_err("Error in getting msoc, rc=%d\n", rc);
+ goto out;
}
- fg_dbg(chip, FG_STATUS, "msoc: %d health: %d status: %d\n", msoc,
- chip->health, chip->charge_status);
- if (chip->charge_done) {
- if (msoc >= 99 && chip->health == POWER_SUPPLY_HEALTH_GOOD)
+ fg_dbg(chip, FG_STATUS, "msoc: %d bsoc: %x health: %d status: %d full: %d\n",
+ msoc, bsoc, chip->health, chip->charge_status,
+ chip->charge_full);
+ if (chip->charge_done && !chip->charge_full) {
+ if (msoc >= 99 && chip->health == POWER_SUPPLY_HEALTH_GOOD) {
+ fg_dbg(chip, FG_STATUS, "Setting charge_full to true\n");
chip->charge_full = true;
- else
+ /*
+ * Lower the recharge voltage so that VBAT_LT_RECHG
+ * signal will not be asserted soon.
+ */
+ rc = fg_set_recharge_voltage(chip,
+ AUTO_RECHG_VOLT_LOW_LIMIT_MV);
+ if (rc < 0) {
+ pr_err("Error in reducing recharge voltage, rc=%d\n",
+ rc);
+ goto out;
+ }
+ } else {
fg_dbg(chip, FG_STATUS, "Terminated charging @ SOC%d\n",
msoc);
- } else if ((bsoc >> 8) <= recharge_soc) {
- fg_dbg(chip, FG_STATUS, "bsoc: %d recharge_soc: %d\n",
- bsoc >> 8, recharge_soc);
+ }
+ } else if ((bsoc >> 8) <= recharge_soc && chip->charge_full) {
+ chip->delta_soc = FULL_CAPACITY - msoc;
+
+ /*
+ * We're spreading out the delta SOC over every 10% change
+ * in monotonic SOC. We cannot spread more than 9% in the
+ * range of 0-100 skipping the first 10%.
+ */
+ if (chip->delta_soc > 9) {
+ chip->delta_soc = 0;
+ chip->maint_soc = 0;
+ } else {
+ chip->maint_soc = FULL_CAPACITY;
+ chip->last_msoc = msoc;
+ }
+
chip->charge_full = false;
+
+ /*
+ * Raise the recharge voltage so that VBAT_LT_RECHG signal
+ * will be asserted soon as battery SOC had dropped below
+ * the recharge SOC threshold.
+ */
+ rc = fg_set_recharge_voltage(chip,
+ chip->dt.recharge_volt_thr_mv);
+ if (rc < 0) {
+ pr_err("Error in setting recharge voltage, rc=%d\n",
+ rc);
+ goto out;
+ }
+ fg_dbg(chip, FG_STATUS, "bsoc: %d recharge_soc: %d delta_soc: %d\n",
+ bsoc >> 8, recharge_soc, chip->delta_soc);
+ } else {
+ goto out;
}
if (!chip->charge_full)
- return 0;
+ goto out;
/*
* During JEITA conditions, charge_full can happen early. FULL_SOC
@@ -1449,18 +1570,20 @@ static int fg_charge_full_update(struct fg_chip *chip)
FG_IMA_ATOMIC);
if (rc < 0) {
pr_err("failed to write full_soc rc=%d\n", rc);
- return rc;
+ goto out;
}
rc = fg_sram_write(chip, MONOTONIC_SOC_WORD, MONOTONIC_SOC_OFFSET,
full_soc, 2, FG_IMA_ATOMIC);
if (rc < 0) {
pr_err("failed to write monotonic_soc rc=%d\n", rc);
- return rc;
+ goto out;
}
fg_dbg(chip, FG_STATUS, "Set charge_full to true @ soc %d\n", msoc);
- return 0;
+out:
+ mutex_unlock(&chip->charge_full_lock);
+ return rc;
}
#define RCONN_CONFIG_BIT BIT(0)
@@ -1539,13 +1662,16 @@ static int fg_rconn_config(struct fg_chip *chip)
static int fg_set_recharge_soc(struct fg_chip *chip, int recharge_soc)
{
- u8 buf[4];
+ u8 buf;
int rc;
- fg_encode(chip->sp, FG_SRAM_RECHARGE_SOC_THR, recharge_soc, buf);
+ if (!chip->dt.auto_recharge_soc)
+ return 0;
+
+ fg_encode(chip->sp, FG_SRAM_RECHARGE_SOC_THR, recharge_soc, &buf);
rc = fg_sram_write(chip,
chip->sp[FG_SRAM_RECHARGE_SOC_THR].addr_word,
- chip->sp[FG_SRAM_RECHARGE_SOC_THR].addr_byte, buf,
+ chip->sp[FG_SRAM_RECHARGE_SOC_THR].addr_byte, &buf,
chip->sp[FG_SRAM_RECHARGE_SOC_THR].len, FG_IMA_DEFAULT);
if (rc < 0) {
pr_err("Error in writing recharge_soc_thr, rc=%d\n", rc);
@@ -1559,6 +1685,9 @@ static int fg_adjust_recharge_soc(struct fg_chip *chip)
{
int rc, msoc, recharge_soc, new_recharge_soc = 0;
+ if (!chip->dt.auto_recharge_soc)
+ return 0;
+
recharge_soc = chip->dt.recharge_soc_thr;
/*
* If the input is present and charging had been terminated, adjust
@@ -1568,13 +1697,12 @@ static int fg_adjust_recharge_soc(struct fg_chip *chip)
if (is_input_present(chip) && !chip->recharge_soc_adjusted
&& chip->charge_done) {
/* Get raw monotonic SOC for calculation */
- rc = fg_get_msoc_raw(chip, &msoc);
+ rc = fg_get_msoc(chip, &msoc);
if (rc < 0) {
pr_err("Error in getting msoc, rc=%d\n", rc);
return rc;
}
- msoc = DIV_ROUND_CLOSEST(msoc * FULL_CAPACITY, FULL_SOC_RAW);
/* Adjust the recharge_soc threshold */
new_recharge_soc = msoc - (FULL_CAPACITY - recharge_soc);
} else if (chip->recharge_soc_adjusted && (!is_input_present(chip)
@@ -2062,7 +2190,6 @@ wait:
goto wait;
} else if (rc <= 0) {
pr_err("wait for soc_ready timed out rc=%d\n", rc);
- goto out;
}
rc = fg_masked_write(chip, BATT_SOC_RESTART(chip), RESTART_GO_BIT, 0);
@@ -2285,7 +2412,6 @@ reschedule:
msecs_to_jiffies(BATT_AVG_POLL_PERIOD_MS));
}
-#define DECI_TAU_SCALE 13
#define HOURS_TO_SECONDS 3600
#define OCV_SLOPE_UV 10869
#define MILLI_UNIT 1000
@@ -2294,7 +2420,7 @@ static int fg_get_time_to_full(struct fg_chip *chip, int *val)
{
int rc, ibatt_avg, vbatt_avg, rbatt, msoc, ocv_cc2cv, full_soc,
act_cap_uah;
- s32 i_cc2cv, soc_cc2cv, ln_val;
+ s32 i_cc2cv, soc_cc2cv, ln_val, centi_tau_scale;
s64 t_predicted_cc = 0, t_predicted_cv = 0;
if (chip->bp.float_volt_uv <= 0) {
@@ -2417,15 +2543,20 @@ skip_cc_estimate:
/* CV estimate starts here */
if (chip->charge_type >= POWER_SUPPLY_CHARGE_TYPE_TAPER)
- ln_val = ibatt_avg / abs(chip->dt.sys_term_curr_ma);
+ ln_val = ibatt_avg / (abs(chip->dt.sys_term_curr_ma) + 200);
+ else
+ ln_val = i_cc2cv / (abs(chip->dt.sys_term_curr_ma) + 200);
+
+ if (msoc < 95)
+ centi_tau_scale = 100;
else
- ln_val = i_cc2cv / abs(chip->dt.sys_term_curr_ma);
+ centi_tau_scale = 20 * (100 - msoc);
fg_dbg(chip, FG_TTF, "ln_in=%d\n", ln_val);
rc = fg_lerp(fg_ln_table, ARRAY_SIZE(fg_ln_table), ln_val, &ln_val);
fg_dbg(chip, FG_TTF, "ln_out=%d\n", ln_val);
t_predicted_cv = div_s64((s64)act_cap_uah * rbatt, MICRO_UNIT);
- t_predicted_cv = div_s64(t_predicted_cv * DECI_TAU_SCALE, 10);
+ t_predicted_cv = div_s64(t_predicted_cv * centi_tau_scale, 100);
t_predicted_cv = div_s64(t_predicted_cv * ln_val, MILLI_UNIT);
t_predicted_cv = div_s64(t_predicted_cv * HOURS_TO_SECONDS, MICRO_UNIT);
fg_dbg(chip, FG_TTF, "t_predicted_cv=%lld\n", t_predicted_cv);
@@ -2479,6 +2610,48 @@ static int fg_get_time_to_empty(struct fg_chip *chip, int *val)
return 0;
}
+static int fg_update_maint_soc(struct fg_chip *chip)
+{
+ int rc = 0, msoc;
+
+ mutex_lock(&chip->charge_full_lock);
+ if (chip->delta_soc <= 0)
+ goto out;
+
+ rc = fg_get_msoc(chip, &msoc);
+ if (rc < 0) {
+ pr_err("Error in getting msoc, rc=%d\n", rc);
+ goto out;
+ }
+
+ if (msoc > chip->maint_soc) {
+ /*
+ * When the monotonic SOC goes above maintenance SOC, we should
+ * stop showing the maintenance SOC.
+ */
+ chip->delta_soc = 0;
+ chip->maint_soc = 0;
+ } else if (msoc <= chip->last_msoc) {
+ /* MSOC is decreasing. Decrease maintenance SOC as well */
+ chip->maint_soc -= 1;
+ if (!(msoc % 10)) {
+ /*
+ * Reduce the maintenance SOC additionally by 1 whenever
+ * it crosses a SOC multiple of 10.
+ */
+ chip->maint_soc -= 1;
+ chip->delta_soc -= 1;
+ }
+ }
+
+ fg_dbg(chip, FG_IRQ, "msoc: %d last_msoc: %d maint_soc: %d delta_soc: %d\n",
+ msoc, chip->last_msoc, chip->maint_soc, chip->delta_soc);
+ chip->last_msoc = msoc;
+out:
+ mutex_unlock(&chip->charge_full_lock);
+ return rc;
+}
+
/* PSY CALLBACKS STAY HERE */
static int fg_psy_get_property(struct power_supply *psy,
@@ -2490,13 +2663,13 @@ static int fg_psy_get_property(struct power_supply *psy,
switch (psp) {
case POWER_SUPPLY_PROP_CAPACITY:
- if (chip->fg_restarting)
- pval->intval = chip->last_soc;
- else
- rc = fg_get_prop_capacity(chip, &pval->intval);
+ rc = fg_get_prop_capacity(chip, &pval->intval);
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- rc = fg_get_battery_voltage(chip, &pval->intval);
+ if (chip->battery_missing)
+ pval->intval = 3700000;
+ else
+ rc = fg_get_battery_voltage(chip, &pval->intval);
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
rc = fg_get_battery_current(chip, &pval->intval);
@@ -2749,15 +2922,27 @@ static int fg_hw_init(struct fg_chip *chip)
}
if (chip->dt.delta_soc_thr > 0 && chip->dt.delta_soc_thr < 100) {
- fg_encode(chip->sp, FG_SRAM_DELTA_SOC_THR,
+ fg_encode(chip->sp, FG_SRAM_DELTA_MSOC_THR,
+ chip->dt.delta_soc_thr, buf);
+ rc = fg_sram_write(chip,
+ chip->sp[FG_SRAM_DELTA_MSOC_THR].addr_word,
+ chip->sp[FG_SRAM_DELTA_MSOC_THR].addr_byte,
+ buf, chip->sp[FG_SRAM_DELTA_MSOC_THR].len,
+ FG_IMA_DEFAULT);
+ if (rc < 0) {
+ pr_err("Error in writing delta_msoc_thr, rc=%d\n", rc);
+ return rc;
+ }
+
+ fg_encode(chip->sp, FG_SRAM_DELTA_BSOC_THR,
chip->dt.delta_soc_thr, buf);
rc = fg_sram_write(chip,
- chip->sp[FG_SRAM_DELTA_SOC_THR].addr_word,
- chip->sp[FG_SRAM_DELTA_SOC_THR].addr_byte,
- buf, chip->sp[FG_SRAM_DELTA_SOC_THR].len,
+ chip->sp[FG_SRAM_DELTA_BSOC_THR].addr_word,
+ chip->sp[FG_SRAM_DELTA_BSOC_THR].addr_byte,
+ buf, chip->sp[FG_SRAM_DELTA_BSOC_THR].len,
FG_IMA_DEFAULT);
if (rc < 0) {
- pr_err("Error in writing delta_soc_thr, rc=%d\n", rc);
+ pr_err("Error in writing delta_bsoc_thr, rc=%d\n", rc);
return rc;
}
}
@@ -2770,18 +2955,11 @@ static int fg_hw_init(struct fg_chip *chip)
}
}
- /* This configuration is available only for pmicobalt v2.0 and above */
- if (!(chip->wa_flags & PMI8998_V1_REV_WA) &&
- chip->dt.recharge_volt_thr_mv > 0) {
- fg_encode(chip->sp, FG_SRAM_RECHARGE_VBATT_THR,
- chip->dt.recharge_volt_thr_mv, buf);
- rc = fg_sram_write(chip,
- chip->sp[FG_SRAM_RECHARGE_VBATT_THR].addr_word,
- chip->sp[FG_SRAM_RECHARGE_VBATT_THR].addr_byte,
- buf, chip->sp[FG_SRAM_RECHARGE_VBATT_THR].len,
- FG_IMA_DEFAULT);
+ if (chip->dt.recharge_volt_thr_mv > 0) {
+ rc = fg_set_recharge_voltage(chip,
+ chip->dt.recharge_volt_thr_mv);
if (rc < 0) {
- pr_err("Error in writing recharge_vbatt_thr, rc=%d\n",
+ pr_err("Error in setting recharge_voltage, rc=%d\n",
rc);
return rc;
}
@@ -3048,7 +3226,20 @@ static irqreturn_t fg_soc_update_irq_handler(int irq, void *data)
return IRQ_HANDLED;
}
-static irqreturn_t fg_delta_soc_irq_handler(int irq, void *data)
+static irqreturn_t fg_delta_bsoc_irq_handler(int irq, void *data)
+{
+ struct fg_chip *chip = data;
+ int rc;
+
+ fg_dbg(chip, FG_IRQ, "irq %d triggered\n", irq);
+ rc = fg_charge_full_update(chip);
+ if (rc < 0)
+ pr_err("Error in charge_full_update, rc=%d\n", rc);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t fg_delta_msoc_irq_handler(int irq, void *data)
{
struct fg_chip *chip = data;
int rc;
@@ -3068,6 +3259,10 @@ static irqreturn_t fg_delta_soc_irq_handler(int irq, void *data)
if (rc < 0)
pr_err("Error in adjusting ki_coeff_dischg, rc=%d\n", rc);
+ rc = fg_update_maint_soc(chip);
+ if (rc < 0)
+ pr_err("Error in updating maint_soc, rc=%d\n", rc);
+
if (batt_psy_initialized(chip))
power_supply_changed(chip->batt_psy);
@@ -3122,12 +3317,13 @@ static struct fg_irq_info fg_irqs[FG_IRQ_MAX] = {
},
[MSOC_DELTA_IRQ] = {
.name = "msoc-delta",
- .handler = fg_delta_soc_irq_handler,
+ .handler = fg_delta_msoc_irq_handler,
.wakeable = true,
},
[BSOC_DELTA_IRQ] = {
.name = "bsoc-delta",
- .handler = fg_dummy_irq_handler,
+ .handler = fg_delta_bsoc_irq_handler,
+ .wakeable = true,
},
[SOC_READY_IRQ] = {
.name = "soc-ready",
@@ -3485,6 +3681,9 @@ static int fg_parse_dt(struct fg_chip *chip)
else
chip->dt.recharge_volt_thr_mv = temp;
+ chip->dt.auto_recharge_soc = of_property_read_bool(node,
+ "qcom,fg-auto-recharge-soc");
+
rc = of_property_read_u32(node, "qcom,fg-rsense-sel", &temp);
if (rc < 0)
chip->dt.rsense_sel = SRC_SEL_BATFET_SMB;
@@ -3687,6 +3886,7 @@ static int fg_gen3_probe(struct platform_device *pdev)
mutex_init(&chip->cyc_ctr.lock);
mutex_init(&chip->cl.lock);
mutex_init(&chip->batt_avg_lock);
+ mutex_init(&chip->charge_full_lock);
init_completion(&chip->soc_update);
init_completion(&chip->soc_ready);
INIT_DELAYED_WORK(&chip->profile_load_work, profile_load_work);
@@ -3742,6 +3942,13 @@ static int fg_gen3_probe(struct platform_device *pdev)
if (fg_irqs[SOC_UPDATE_IRQ].irq)
disable_irq_nosync(fg_irqs[SOC_UPDATE_IRQ].irq);
+ /* Keep BSOC_DELTA_IRQ irq disabled until we require it */
+ if (fg_irqs[BSOC_DELTA_IRQ].irq) {
+ disable_irq_wake(fg_irqs[BSOC_DELTA_IRQ].irq);
+ disable_irq_nosync(fg_irqs[BSOC_DELTA_IRQ].irq);
+ chip->bsoc_delta_irq_en = false;
+ }
+
rc = fg_debugfs_create(chip);
if (rc < 0) {
dev_err(chip->dev, "Error in creating debugfs entries, rc:%d\n",
diff --git a/drivers/power/supply/qcom/qpnp-qnovo.c b/drivers/power/supply/qcom/qpnp-qnovo.c
index c4cc541a0a3e..078bbaaad5a2 100644
--- a/drivers/power/supply/qcom/qpnp-qnovo.c
+++ b/drivers/power/supply/qcom/qpnp-qnovo.c
@@ -110,8 +110,7 @@ struct qnovo_dt_props {
};
enum {
- QNOVO_ERASE_OFFSET_WA_BIT = BIT(0),
- QNOVO_NO_ERR_STS_BIT = BIT(1),
+ QNOVO_NO_ERR_STS_BIT = BIT(0),
};
struct chg_props {
@@ -315,7 +314,6 @@ static int qnovo_check_chg_version(struct qnovo *chip)
if ((chip->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE)
&& (chip->pmic_rev_id->rev4 < PMI8998_V2P0_REV4)) {
- chip->wa_flags |= QNOVO_ERASE_OFFSET_WA_BIT;
chip->wa_flags |= QNOVO_NO_ERR_STS_BIT;
}
@@ -447,6 +445,8 @@ static struct param_info params[] = {
.num_regs = 1,
.reg_to_unit_multiplier = 1,
.reg_to_unit_divider = 1,
+ .min_val = 0,
+ .max_val = 255,
.units_str = "pulses",
},
[VLIM1] = {
@@ -1187,7 +1187,7 @@ static int qnovo_hw_init(struct qnovo *chip)
u8 iadc_offset_external, iadc_offset_internal;
u8 iadc_gain_external, iadc_gain_internal;
u8 vadc_offset, vadc_gain;
- u8 buf[2] = {0, 0};
+ u8 val;
vote(chip->disable_votable, USER_VOTER, 1, 0);
@@ -1241,13 +1241,39 @@ static int qnovo_hw_init(struct qnovo *chip)
chip->v_gain_mega = 1000000000 + (s64)vadc_gain * GAIN_LSB_FACTOR;
chip->v_gain_mega = div_s64(chip->v_gain_mega, 1000);
- if (chip->wa_flags & QNOVO_ERASE_OFFSET_WA_BIT) {
- rc = qnovo_write(chip, QNOVO_TR_IADC_OFFSET_0, buf, 2);
- if (rc < 0) {
- pr_err("Couldn't erase offset rc = %d\n", rc);
- return rc;
- }
+ val = 0;
+ rc = qnovo_write(chip, QNOVO_STRM_CTRL, &val, 1);
+ if (rc < 0) {
+ pr_err("Couldn't write iadc bitsteam control rc = %d\n", rc);
+ return rc;
+ }
+
+ rc = qnovo_read(chip, QNOVO_TR_IADC_OFFSET_0, &val, 1);
+ if (rc < 0) {
+ pr_err("Couldn't read iadc offset rc = %d\n", rc);
+ return rc;
+ }
+
+ val *= -1;
+ rc = qnovo_write(chip, QNOVO_TR_IADC_OFFSET_0, &val, 1);
+ if (rc < 0) {
+ pr_err("Couldn't write iadc offset rc = %d\n", rc);
+ return rc;
+ }
+
+ rc = qnovo_read(chip, QNOVO_TR_IADC_OFFSET_1, &val, 1);
+ if (rc < 0) {
+ pr_err("Couldn't read iadc offset rc = %d\n", rc);
+ return rc;
}
+
+ val *= -1;
+ rc = qnovo_write(chip, QNOVO_TR_IADC_OFFSET_1, &val, 1);
+ if (rc < 0) {
+ pr_err("Couldn't write iadc offset rc = %d\n", rc);
+ return rc;
+ }
+
return 0;
}
diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c
index dea932ae37ad..f8171ecc47f3 100644
--- a/drivers/power/supply/qcom/qpnp-smb2.c
+++ b/drivers/power/supply/qcom/qpnp-smb2.c
@@ -620,7 +620,7 @@ static int smb2_usb_main_get_prop(struct power_supply *psy,
rc = smblib_get_prop_fcc_delta(chg, val);
break;
default:
- pr_err("get prop %d is not supported in usb-main\n", psp);
+ pr_debug("get prop %d is not supported in usb-main\n", psp);
rc = -EINVAL;
break;
}
@@ -1305,7 +1305,22 @@ static int smb2_init_hw(struct smb2 *chip)
smblib_get_charge_param(chg, &chg->param.dc_icl,
&chip->dt.dc_icl_ua);
- chg->otg_cl_ua = chip->dt.otg_cl_ua;
+ /* set a slower soft start setting for OTG */
+ rc = smblib_masked_write(chg, DC_ENG_SSUPPLY_CFG2_REG,
+ ENG_SSUPPLY_IVREF_OTG_SS_MASK, OTG_SS_SLOW);
+ if (rc < 0) {
+ pr_err("Couldn't set otg soft start rc=%d\n", rc);
+ return rc;
+ }
+
+ /* set OTG current limit */
+ rc = smblib_set_charge_param(chg, &chg->param.otg_cl,
+ chip->dt.otg_cl_ua);
+ if (rc < 0) {
+ pr_err("Couldn't set otg current limit rc=%d\n", rc);
+ return rc;
+ }
+
chg->dcp_icl_ua = chip->dt.usb_icl_ua;
chg->boost_threshold_ua = chip->dt.boost_threshold_ua;
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c
index 022ed49ce6eb..ee5b5a51465b 100644
--- a/drivers/power/supply/qcom/smb-lib.c
+++ b/drivers/power/supply/qcom/smb-lib.c
@@ -505,7 +505,7 @@ static int smblib_notifier_call(struct notifier_block *nb,
schedule_work(&chg->bms_update_work);
}
- if (!chg->pl.psy && !strcmp(psy->desc->name, "usb-parallel"))
+ if (!chg->pl.psy && !strcmp(psy->desc->name, "parallel"))
chg->pl.psy = psy;
return NOTIFY_OK;
@@ -762,20 +762,6 @@ out:
return rc;
}
-#define MICRO_250MA 250000
-static int smblib_otg_cl_config(struct smb_charger *chg, int otg_cl_ua)
-{
- int rc = 0;
-
- rc = smblib_set_charge_param(chg, &chg->param.otg_cl, otg_cl_ua);
- if (rc < 0) {
- smblib_err(chg, "Couldn't set otg current limit rc=%d\n", rc);
- return rc;
- }
-
- return rc;
-}
-
static int smblib_dc_icl_vote_callback(struct votable *votable, void *data,
int icl_ua, const char *client)
{
@@ -955,22 +941,33 @@ static int smblib_apsd_disable_vote_callback(struct votable *votable,
* VCONN REGULATOR *
* *****************/
+#define MAX_OTG_SS_TRIES 2
static int _smblib_vconn_regulator_enable(struct regulator_dev *rdev)
{
struct smb_charger *chg = rdev_get_drvdata(rdev);
u8 otg_stat, stat4;
- int rc = 0;
+ int rc = 0, i;
if (!chg->external_vconn) {
- rc = smblib_read(chg, OTG_STATUS_REG, &otg_stat);
- if (rc < 0) {
- smblib_err(chg, "Couldn't read OTG status rc=%d\n", rc);
- return rc;
+ /*
+ * Hardware based OTG soft start should complete within 1ms, so
+ * wait for 2ms in the worst case.
+ */
+ for (i = 0; i < MAX_OTG_SS_TRIES; ++i) {
+ usleep_range(1000, 1100);
+ rc = smblib_read(chg, OTG_STATUS_REG, &otg_stat);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't read OTG status rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ if (otg_stat & BOOST_SOFTSTART_DONE_BIT)
+ break;
}
- if ((otg_stat & OTG_STATE_MASK) != OTG_STATE_ENABLED) {
- smblib_err(chg, "Couldn't enable VCONN; OTG is not ready otg_stat=0x%02x\n",
- otg_stat);
+ if (!(otg_stat & BOOST_SOFTSTART_DONE_BIT)) {
+ smblib_err(chg, "Couldn't enable VCONN; OTG soft start failed\n");
return -EAGAIN;
}
}
@@ -985,6 +982,7 @@ static int _smblib_vconn_regulator_enable(struct regulator_dev *rdev)
return rc;
}
+ smblib_dbg(chg, PR_OTG, "enabling VCONN\n");
stat4 = stat4 & CC_ORIENTATION_BIT ? 0 : VCONN_EN_ORIENTATION_BIT;
rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
VCONN_EN_VALUE_BIT | VCONN_EN_ORIENTATION_BIT,
@@ -1002,7 +1000,7 @@ int smblib_vconn_regulator_enable(struct regulator_dev *rdev)
struct smb_charger *chg = rdev_get_drvdata(rdev);
int rc = 0;
- mutex_lock(&chg->otg_overcurrent_lock);
+ mutex_lock(&chg->otg_oc_lock);
if (chg->vconn_en)
goto unlock;
@@ -1011,7 +1009,7 @@ int smblib_vconn_regulator_enable(struct regulator_dev *rdev)
chg->vconn_en = true;
unlock:
- mutex_unlock(&chg->otg_overcurrent_lock);
+ mutex_unlock(&chg->otg_oc_lock);
return rc;
}
@@ -1020,6 +1018,7 @@ static int _smblib_vconn_regulator_disable(struct regulator_dev *rdev)
struct smb_charger *chg = rdev_get_drvdata(rdev);
int rc = 0;
+ smblib_dbg(chg, PR_OTG, "disabling VCONN\n");
rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
VCONN_EN_VALUE_BIT, 0);
if (rc < 0)
@@ -1033,7 +1032,7 @@ int smblib_vconn_regulator_disable(struct regulator_dev *rdev)
struct smb_charger *chg = rdev_get_drvdata(rdev);
int rc = 0;
- mutex_lock(&chg->otg_overcurrent_lock);
+ mutex_lock(&chg->otg_oc_lock);
if (!chg->vconn_en)
goto unlock;
@@ -1042,7 +1041,7 @@ int smblib_vconn_regulator_disable(struct regulator_dev *rdev)
chg->vconn_en = false;
unlock:
- mutex_unlock(&chg->otg_overcurrent_lock);
+ mutex_unlock(&chg->otg_oc_lock);
return rc;
}
@@ -1051,9 +1050,9 @@ int smblib_vconn_regulator_is_enabled(struct regulator_dev *rdev)
struct smb_charger *chg = rdev_get_drvdata(rdev);
int ret;
- mutex_lock(&chg->otg_overcurrent_lock);
+ mutex_lock(&chg->otg_oc_lock);
ret = chg->vconn_en;
- mutex_unlock(&chg->otg_overcurrent_lock);
+ mutex_unlock(&chg->otg_oc_lock);
return ret;
}
@@ -1061,14 +1060,12 @@ int smblib_vconn_regulator_is_enabled(struct regulator_dev *rdev)
* OTG REGULATOR *
*****************/
-#define MAX_SOFTSTART_TRIES 2
static int _smblib_vbus_regulator_enable(struct regulator_dev *rdev)
{
struct smb_charger *chg = rdev_get_drvdata(rdev);
- u8 stat;
- int rc = 0;
- int tries = MAX_SOFTSTART_TRIES;
+ int rc;
+ smblib_dbg(chg, PR_OTG, "halt 1 in 8 mode\n");
rc = smblib_masked_write(chg, OTG_ENG_OTG_CFG_REG,
ENG_BUCKBOOST_HALT1_8_MODE_BIT,
ENG_BUCKBOOST_HALT1_8_MODE_BIT);
@@ -1078,34 +1075,13 @@ static int _smblib_vbus_regulator_enable(struct regulator_dev *rdev)
return rc;
}
+ smblib_dbg(chg, PR_OTG, "enabling OTG\n");
rc = smblib_write(chg, CMD_OTG_REG, OTG_EN_BIT);
if (rc < 0) {
smblib_err(chg, "Couldn't enable OTG regulator rc=%d\n", rc);
return rc;
}
- /* waiting for boost readiness, usually ~1ms, 2ms in worst case */
- do {
- usleep_range(1000, 1100);
-
- rc = smblib_read(chg, OTG_STATUS_REG, &stat);
- if (rc < 0) {
- smblib_err(chg, "Couldn't read OTG_STATUS_REG rc=%d\n",
- rc);
- return rc;
- }
- if (stat & BOOST_SOFTSTART_DONE_BIT) {
- smblib_otg_cl_config(chg, chg->otg_cl_ua);
- break;
- }
- } while (--tries);
-
- if (tries == 0) {
- smblib_err(chg, "Timeout waiting for boost softstart rc=%d\n",
- rc);
- return -ETIMEDOUT;
- }
-
return rc;
}
@@ -1114,7 +1090,7 @@ int smblib_vbus_regulator_enable(struct regulator_dev *rdev)
struct smb_charger *chg = rdev_get_drvdata(rdev);
int rc = 0;
- mutex_lock(&chg->otg_overcurrent_lock);
+ mutex_lock(&chg->otg_oc_lock);
if (chg->otg_en)
goto unlock;
@@ -1123,7 +1099,7 @@ int smblib_vbus_regulator_enable(struct regulator_dev *rdev)
chg->otg_en = true;
unlock:
- mutex_unlock(&chg->otg_overcurrent_lock);
+ mutex_unlock(&chg->otg_oc_lock);
return rc;
}
@@ -1131,32 +1107,23 @@ static int _smblib_vbus_regulator_disable(struct regulator_dev *rdev)
{
struct smb_charger *chg = rdev_get_drvdata(rdev);
int rc;
- u8 stat;
- if (!chg->external_vconn) {
- rc = smblib_read(chg, RID_CC_CONTROL_7_0_REG, &stat);
+ if (!chg->external_vconn && chg->vconn_en) {
+ smblib_dbg(chg, PR_OTG, "Killing VCONN before disabling OTG\n");
+ rc = _smblib_vconn_regulator_disable(rdev);
if (rc < 0)
- smblib_err(chg, "Couldn't read RID_CC_CONTROL_7_0 rc=%d\n",
- rc);
-
- /* check if VCONN is enabled on either CC pin */
- if (stat & VCONN_EN_CC_MASK) {
- smblib_dbg(chg, PR_MISC, "Killing VCONN before disabling OTG\n");
- rc = _smblib_vconn_regulator_disable(rdev);
- if (rc < 0)
- smblib_err(chg, "Couldn't disable VCONN rc=%d\n",
- rc);
- }
+ smblib_err(chg, "Couldn't disable VCONN rc=%d\n", rc);
}
+ smblib_dbg(chg, PR_OTG, "disabling OTG\n");
rc = smblib_write(chg, CMD_OTG_REG, 0);
if (rc < 0) {
smblib_err(chg, "Couldn't disable OTG regulator rc=%d\n", rc);
return rc;
}
- smblib_otg_cl_config(chg, MICRO_250MA);
-
+ smblib_dbg(chg, PR_OTG, "start 1 in 8 mode\n");
+ rc = smblib_write(chg, CMD_OTG_REG, 0);
rc = smblib_masked_write(chg, OTG_ENG_OTG_CFG_REG,
ENG_BUCKBOOST_HALT1_8_MODE_BIT, 0);
if (rc < 0) {
@@ -1172,7 +1139,7 @@ int smblib_vbus_regulator_disable(struct regulator_dev *rdev)
struct smb_charger *chg = rdev_get_drvdata(rdev);
int rc = 0;
- mutex_lock(&chg->otg_overcurrent_lock);
+ mutex_lock(&chg->otg_oc_lock);
if (!chg->otg_en)
goto unlock;
@@ -1181,7 +1148,7 @@ int smblib_vbus_regulator_disable(struct regulator_dev *rdev)
chg->otg_en = false;
unlock:
- mutex_unlock(&chg->otg_overcurrent_lock);
+ mutex_unlock(&chg->otg_oc_lock);
return rc;
}
@@ -1190,9 +1157,9 @@ int smblib_vbus_regulator_is_enabled(struct regulator_dev *rdev)
struct smb_charger *chg = rdev_get_drvdata(rdev);
int ret;
- mutex_lock(&chg->otg_overcurrent_lock);
+ mutex_lock(&chg->otg_oc_lock);
ret = chg->otg_en;
- mutex_unlock(&chg->otg_overcurrent_lock);
+ mutex_unlock(&chg->otg_oc_lock);
return ret;
}
@@ -1955,6 +1922,29 @@ int smblib_get_pe_start(struct smb_charger *chg,
return 0;
}
+int smblib_get_prop_connector_therm_zone(struct smb_charger *chg,
+ union power_supply_propval *val)
+{
+ int rc, i;
+ u8 stat;
+
+ rc = smblib_read(chg, TEMP_RANGE_STATUS_REG, &stat);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't read TEMP_RANGE_STATUS_REG rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ i = fls((stat & TEMP_RANGE_MASK) >> TEMP_RANGE_SHIFT) - 1;
+ if (i < 0) {
+ smblib_err(chg, "TEMP_RANGE is invalid\n");
+ return -EINVAL;
+ }
+
+ val->intval = i;
+ return 0;
+}
+
/*******************
* USB PSY SETTERS *
* *****************/
@@ -2467,50 +2457,9 @@ irqreturn_t smblib_handle_otg_overcurrent(int irq, void *data)
return IRQ_HANDLED;
}
- if (!(stat & OTG_OVERCURRENT_RT_STS_BIT))
- return IRQ_HANDLED;
-
- smblib_err(chg, "over-current detected on VBUS\n");
- if (!chg->vbus_vreg || !chg->vbus_vreg->rdev)
- return IRQ_HANDLED;
-
- mutex_lock(&chg->otg_overcurrent_lock);
- if (!chg->external_vconn && chg->vconn_en) {
- rc = _smblib_vconn_regulator_disable(chg->vconn_vreg->rdev);
- if (rc < 0)
- smblib_err(chg, "Couldn't disable VCONN rc=%d\n", rc);
- }
-
- rc = _smblib_vbus_regulator_disable(chg->vbus_vreg->rdev);
- if (rc < 0)
- smblib_err(chg, "Couldn't disable VBUS rc=%d\n", rc);
+ if (stat & OTG_OVERCURRENT_RT_STS_BIT)
+ schedule_work(&chg->otg_oc_work);
- /*
- * VBUS must be disabled after OC to be ready for the next insertion.
- * If the maximum number of attempts have been reached then don't try
- * to re-enable.
- */
- if (++chg->otg_attempts > OTG_MAX_ATTEMPTS) {
- smblib_err(chg, "OTG failed to enable after %d attempts\n",
- chg->otg_attempts - 1);
- goto unlock;
- }
-
- /* allow the attached device to discharge */
- msleep(250);
-
- rc = _smblib_vbus_regulator_enable(chg->vbus_vreg->rdev);
- if (rc < 0)
- smblib_err(chg, "Couldn't enable VBUS rc=%d\n", rc);
-
- if (!chg->external_vconn && chg->vconn_en) {
- rc = _smblib_vconn_regulator_enable(chg->vconn_vreg->rdev);
- if (rc < 0)
- smblib_err(chg, "Couldn't enable VCONN rc=%d\n", rc);
- }
-
-unlock:
- mutex_unlock(&chg->otg_overcurrent_lock);
return IRQ_HANDLED;
}
@@ -3094,41 +3043,6 @@ irqreturn_t smblib_handle_usb_typec_change_for_uusb(struct smb_charger *chg)
return IRQ_HANDLED;
}
-static void smblib_handle_vconn_overcurrent(struct smb_charger *chg)
-{
- int rc;
-
- smblib_err(chg, "over-current detected on VCONN\n");
- if (!chg->vconn_vreg || !chg->vconn_vreg->rdev)
- return;
-
- mutex_lock(&chg->otg_overcurrent_lock);
- rc = _smblib_vconn_regulator_disable(chg->vconn_vreg->rdev);
- if (rc < 0)
- smblib_err(chg, "Couldn't disable VCONN rc=%d\n", rc);
-
- /*
- * VCONN must be disabled after OC to be ready for the next insertion.
- * If the maximum number of attempts have been reached then don't try
- * to re-enable.
- */
- if (++chg->vconn_attempts > VCONN_MAX_ATTEMPTS) {
- smblib_err(chg, "VCONN failed to enable after %d attempts\n",
- chg->vconn_attempts - 1);
- goto unlock;
- }
-
- /* allow the attached device to discharge */
- msleep(250);
-
- rc = _smblib_vconn_regulator_enable(chg->vconn_vreg->rdev);
- if (rc < 0)
- smblib_err(chg, "Couldn't enable VCONN rc=%d\n", rc);
-
-unlock:
- mutex_unlock(&chg->otg_overcurrent_lock);
-}
-
irqreturn_t smblib_handle_usb_typec_change(int irq, void *data)
{
struct smb_irq_data *irq_data = data;
@@ -3168,7 +3082,7 @@ irqreturn_t smblib_handle_usb_typec_change(int irq, void *data)
irq_data->name);
if (stat4 & TYPEC_VCONN_OVERCURR_STATUS_BIT)
- smblib_handle_vconn_overcurrent(chg);
+ schedule_work(&chg->vconn_oc_work);
power_supply_changed(chg->usb_psy);
smblib_dbg(chg, PR_REGISTER, "TYPE_C_STATUS_4 = 0x%02x\n", stat4);
@@ -3362,10 +3276,213 @@ rerun:
schedule_work(&chg->rdstd_cc2_detach_work);
}
+static void smblib_otg_oc_exit(struct smb_charger *chg, bool success)
+{
+ int rc;
+
+ chg->otg_attempts = 0;
+ if (!success) {
+ smblib_err(chg, "OTG soft start failed\n");
+ chg->otg_en = false;
+ }
+
+ smblib_dbg(chg, PR_OTG, "enabling VBUS < 1V check\n");
+ rc = smblib_masked_write(chg, OTG_CFG_REG,
+ QUICKSTART_OTG_FASTROLESWAP_BIT, 0);
+ if (rc < 0)
+ smblib_err(chg, "Couldn't enable VBUS < 1V check rc=%d\n", rc);
+
+ if (!chg->external_vconn && chg->vconn_en) {
+ chg->vconn_attempts = 0;
+ if (success) {
+ rc = _smblib_vconn_regulator_enable(
+ chg->vconn_vreg->rdev);
+ if (rc < 0)
+ smblib_err(chg, "Couldn't enable VCONN rc=%d\n",
+ rc);
+ } else {
+ chg->vconn_en = false;
+ }
+ }
+}
+
+#define MAX_OC_FALLING_TRIES 10
+static void smblib_otg_oc_work(struct work_struct *work)
+{
+ struct smb_charger *chg = container_of(work, struct smb_charger,
+ otg_oc_work);
+ int rc, i;
+ u8 stat;
+
+ if (!chg->vbus_vreg || !chg->vbus_vreg->rdev)
+ return;
+
+ smblib_err(chg, "over-current detected on VBUS\n");
+ mutex_lock(&chg->otg_oc_lock);
+ if (!chg->otg_en)
+ goto unlock;
+
+ smblib_dbg(chg, PR_OTG, "disabling VBUS < 1V check\n");
+ smblib_masked_write(chg, OTG_CFG_REG,
+ QUICKSTART_OTG_FASTROLESWAP_BIT,
+ QUICKSTART_OTG_FASTROLESWAP_BIT);
+
+ /*
+ * If 500ms has passed and another over-current interrupt has not
+ * triggered then it is likely that the software based soft start was
+ * successful and the VBUS < 1V restriction should be re-enabled.
+ */
+ schedule_delayed_work(&chg->otg_ss_done_work, msecs_to_jiffies(500));
+
+ rc = _smblib_vbus_regulator_disable(chg->vbus_vreg->rdev);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't disable VBUS rc=%d\n", rc);
+ goto unlock;
+ }
+
+ if (++chg->otg_attempts > OTG_MAX_ATTEMPTS) {
+ cancel_delayed_work_sync(&chg->otg_ss_done_work);
+ smblib_err(chg, "OTG failed to enable after %d attempts\n",
+ chg->otg_attempts - 1);
+ smblib_otg_oc_exit(chg, false);
+ goto unlock;
+ }
+
+ /*
+ * The real time status should go low within 10ms. Poll every 1-2ms to
+ * minimize the delay when re-enabling OTG.
+ */
+ for (i = 0; i < MAX_OC_FALLING_TRIES; ++i) {
+ usleep_range(1000, 2000);
+ rc = smblib_read(chg, OTG_BASE + INT_RT_STS_OFFSET, &stat);
+ if (rc >= 0 && !(stat & OTG_OVERCURRENT_RT_STS_BIT))
+ break;
+ }
+
+ if (i >= MAX_OC_FALLING_TRIES) {
+ cancel_delayed_work_sync(&chg->otg_ss_done_work);
+ smblib_err(chg, "OTG OC did not fall after %dms\n",
+ 2 * MAX_OC_FALLING_TRIES);
+ smblib_otg_oc_exit(chg, false);
+ goto unlock;
+ }
+
+ smblib_dbg(chg, PR_OTG, "OTG OC fell after %dms\n", 2 * i + 1);
+ rc = _smblib_vbus_regulator_enable(chg->vbus_vreg->rdev);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't enable VBUS rc=%d\n", rc);
+ goto unlock;
+ }
+
+unlock:
+ mutex_unlock(&chg->otg_oc_lock);
+}
+
+static void smblib_vconn_oc_work(struct work_struct *work)
+{
+ struct smb_charger *chg = container_of(work, struct smb_charger,
+ vconn_oc_work);
+ int rc, i;
+ u8 stat;
+
+ smblib_err(chg, "over-current detected on VCONN\n");
+ if (!chg->vconn_vreg || !chg->vconn_vreg->rdev)
+ return;
+
+ mutex_lock(&chg->otg_oc_lock);
+ rc = _smblib_vconn_regulator_disable(chg->vconn_vreg->rdev);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't disable VCONN rc=%d\n", rc);
+ goto unlock;
+ }
+
+ if (++chg->vconn_attempts > VCONN_MAX_ATTEMPTS) {
+ smblib_err(chg, "VCONN failed to enable after %d attempts\n",
+ chg->otg_attempts - 1);
+ chg->vconn_en = false;
+ chg->vconn_attempts = 0;
+ goto unlock;
+ }
+
+ /*
+ * The real time status should go low within 10ms. Poll every 1-2ms to
+ * minimize the delay when re-enabling OTG.
+ */
+ for (i = 0; i < MAX_OC_FALLING_TRIES; ++i) {
+ usleep_range(1000, 2000);
+ rc = smblib_read(chg, TYPE_C_STATUS_4_REG, &stat);
+ if (rc >= 0 && !(stat & TYPEC_VCONN_OVERCURR_STATUS_BIT))
+ break;
+ }
+
+ if (i >= MAX_OC_FALLING_TRIES) {
+ smblib_err(chg, "VCONN OC did not fall after %dms\n",
+ 2 * MAX_OC_FALLING_TRIES);
+ chg->vconn_en = false;
+ chg->vconn_attempts = 0;
+ goto unlock;
+ }
+
+ smblib_dbg(chg, PR_OTG, "VCONN OC fell after %dms\n", 2 * i + 1);
+ if (++chg->vconn_attempts > VCONN_MAX_ATTEMPTS) {
+ smblib_err(chg, "VCONN failed to enable after %d attempts\n",
+ chg->vconn_attempts - 1);
+ chg->vconn_en = false;
+ goto unlock;
+ }
+
+ rc = _smblib_vconn_regulator_enable(chg->vconn_vreg->rdev);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't enable VCONN rc=%d\n", rc);
+ goto unlock;
+ }
+
+unlock:
+ mutex_unlock(&chg->otg_oc_lock);
+}
+
+static void smblib_otg_ss_done_work(struct work_struct *work)
+{
+ struct smb_charger *chg = container_of(work, struct smb_charger,
+ otg_ss_done_work.work);
+ int rc;
+ bool success = false;
+ u8 stat;
+
+ mutex_lock(&chg->otg_oc_lock);
+ rc = smblib_read(chg, OTG_STATUS_REG, &stat);
+ if (rc < 0)
+ smblib_err(chg, "Couldn't read OTG status rc=%d\n", rc);
+ else if (stat & BOOST_SOFTSTART_DONE_BIT)
+ success = true;
+
+ smblib_otg_oc_exit(chg, success);
+ mutex_unlock(&chg->otg_oc_lock);
+}
+
static int smblib_create_votables(struct smb_charger *chg)
{
int rc = 0;
+ chg->fcc_votable = find_votable("FCC");
+ if (!chg->fcc_votable) {
+ rc = -EPROBE_DEFER;
+ return rc;
+ }
+
+ chg->fv_votable = find_votable("FV");
+ if (!chg->fv_votable) {
+ rc = -EPROBE_DEFER;
+ return rc;
+ }
+
+ chg->pl_disable_votable = find_votable("PL_DISABLE");
+ if (!chg->pl_disable_votable) {
+ rc = -EPROBE_DEFER;
+ return rc;
+ }
+ vote(chg->pl_disable_votable, PL_INDIRECT_VOTER, true, 0);
+
chg->usb_suspend_votable = create_votable("USB_SUSPEND", VOTE_SET_ANY,
smblib_usb_suspend_vote_callback,
chg);
@@ -3390,18 +3507,6 @@ static int smblib_create_votables(struct smb_charger *chg)
return rc;
}
- chg->fcc_votable = find_votable("FCC");
- if (!chg->fcc_votable) {
- rc = -EPROBE_DEFER;
- return rc;
- }
-
- chg->fv_votable = find_votable("FV");
- if (!chg->fv_votable) {
- rc = -EPROBE_DEFER;
- return rc;
- }
-
chg->usb_icl_votable = create_votable("USB_ICL", VOTE_MIN,
smblib_usb_icl_vote_callback,
chg);
@@ -3441,13 +3546,6 @@ static int smblib_create_votables(struct smb_charger *chg)
return rc;
}
- chg->pl_disable_votable = find_votable("PL_DISABLE");
- if (!chg->pl_disable_votable) {
- rc = -EPROBE_DEFER;
- return rc;
- }
- vote(chg->pl_disable_votable, PL_INDIRECT_VOTER, true, 0);
-
chg->chg_disable_votable = create_votable("CHG_DISABLE", VOTE_SET_ANY,
smblib_chg_disable_vote_callback,
chg);
@@ -3541,12 +3639,15 @@ int smblib_init(struct smb_charger *chg)
int rc = 0;
mutex_init(&chg->write_lock);
- mutex_init(&chg->otg_overcurrent_lock);
+ mutex_init(&chg->otg_oc_lock);
INIT_WORK(&chg->bms_update_work, bms_update_work);
INIT_WORK(&chg->rdstd_cc2_detach_work, rdstd_cc2_detach_work);
INIT_DELAYED_WORK(&chg->hvdcp_detect_work, smblib_hvdcp_detect_work);
INIT_DELAYED_WORK(&chg->step_soc_req_work, step_soc_req_work);
INIT_DELAYED_WORK(&chg->clear_hdc_work, clear_hdc_work);
+ INIT_WORK(&chg->otg_oc_work, smblib_otg_oc_work);
+ INIT_WORK(&chg->vconn_oc_work, smblib_vconn_oc_work);
+ INIT_DELAYED_WORK(&chg->otg_ss_done_work, smblib_otg_ss_done_work);
chg->fake_capacity = -EINVAL;
switch (chg->mode) {
@@ -3566,8 +3667,7 @@ int smblib_init(struct smb_charger *chg)
}
chg->bms_psy = power_supply_get_by_name("bms");
- chg->pl.psy = power_supply_get_by_name("usb-parallel");
-
+ chg->pl.psy = power_supply_get_by_name("parallel");
break;
case PARALLEL_SLAVE:
break;
diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h
index b3fce23c6508..cda4b80939ec 100644
--- a/drivers/power/supply/qcom/smb-lib.h
+++ b/drivers/power/supply/qcom/smb-lib.h
@@ -24,6 +24,7 @@ enum print_reason {
PR_REGISTER = BIT(1),
PR_MISC = BIT(2),
PR_PARALLEL = BIT(3),
+ PR_OTG = BIT(4),
};
#define DEFAULT_VOTER "DEFAULT_VOTER"
@@ -135,6 +136,9 @@ struct smb_iio {
struct iio_channel *usbin_i_chan;
struct iio_channel *usbin_v_chan;
struct iio_channel *batt_i_chan;
+ struct iio_channel *connector_temp_thr1_chan;
+ struct iio_channel *connector_temp_thr2_chan;
+ struct iio_channel *connector_temp_thr3_chan;
};
struct reg_info {
@@ -158,7 +162,7 @@ struct smb_charger {
/* locks */
struct mutex write_lock;
struct mutex ps_change_lock;
- struct mutex otg_overcurrent_lock;
+ struct mutex otg_oc_lock;
/* power supplies */
struct power_supply *batt_psy;
@@ -204,6 +208,9 @@ struct smb_charger {
struct delayed_work ps_change_timeout_work;
struct delayed_work step_soc_req_work;
struct delayed_work clear_hdc_work;
+ struct work_struct otg_oc_work;
+ struct work_struct vconn_oc_work;
+ struct delayed_work otg_ss_done_work;
/* cached status */
int voltage_min_uv;
@@ -214,7 +221,6 @@ struct smb_charger {
int system_temp_level;
int thermal_levels;
int *thermal_mitigation;
- int otg_cl_ua;
int dcp_icl_ua;
int fake_capacity;
bool step_chg_enabled;
@@ -360,6 +366,8 @@ int smblib_get_prop_charger_temp(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_charger_temp_max(struct smb_charger *chg,
union power_supply_propval *val);
+int smblib_get_prop_connector_therm_zone(struct smb_charger *chg,
+ union power_supply_propval *val);
int smblib_set_prop_pd_current_max(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_set_prop_usb_current_max(struct smb_charger *chg,
diff --git a/drivers/power/supply/qcom/smb-reg.h b/drivers/power/supply/qcom/smb-reg.h
index 5f74e27c7978..b5de39de995a 100644
--- a/drivers/power/supply/qcom/smb-reg.h
+++ b/drivers/power/supply/qcom/smb-reg.h
@@ -366,7 +366,9 @@ enum {
#define OTG_CURRENT_LIMIT_MASK GENMASK(2, 0)
#define OTG_CFG_REG (OTG_BASE + 0x53)
-#define OTG_RESERVED_MASK GENMASK(7, 4)
+#define OTG_RESERVED_MASK GENMASK(7, 6)
+#define DIS_OTG_ON_TLIM_BIT BIT(5)
+#define QUICKSTART_OTG_FASTROLESWAP_BIT BIT(4)
#define INCREASE_DFP_TIME_BIT BIT(3)
#define ENABLE_OTG_IN_DEBUG_MODE_BIT BIT(2)
#define OTG_EN_SRC_CFG_BIT BIT(1)
@@ -793,6 +795,10 @@ enum {
ZIN_ICL_HV_MAX_MV = 11000,
};
+#define DC_ENG_SSUPPLY_CFG2_REG (DCIN_BASE + 0xC1)
+#define ENG_SSUPPLY_IVREF_OTG_SS_MASK GENMASK(2, 0)
+#define OTG_SS_SLOW 0x3
+
#define DC_ENG_SSUPPLY_CFG3_REG (DCIN_BASE + 0xC2)
#define ENG_SSUPPLY_HI_CAP_BIT BIT(6)
#define ENG_SSUPPLY_HI_RES_BIT BIT(5)
@@ -817,6 +823,8 @@ enum {
#define TEMP_RANGE_STATUS_7_BIT BIT(7)
#define THERM_REG_ACTIVE_BIT BIT(6)
#define TLIM_BIT BIT(5)
+#define TEMP_RANGE_MASK GENMASK(4, 1)
+#define TEMP_RANGE_SHIFT 1
#define ALERT_LEVEL_BIT BIT(4)
#define TEMP_ABOVE_RANGE_BIT BIT(3)
#define TEMP_WITHIN_RANGE_BIT BIT(2)
diff --git a/drivers/power/supply/qcom/smb138x-charger.c b/drivers/power/supply/qcom/smb138x-charger.c
index ae15fef6c3a6..9287b7c37b97 100644
--- a/drivers/power/supply/qcom/smb138x-charger.c
+++ b/drivers/power/supply/qcom/smb138x-charger.c
@@ -10,18 +10,21 @@
* GNU General Public License for more details.
*/
+#define pr_fmt(fmt) "SMB138X: %s: " fmt, __func__
+
#include <linux/device.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/regmap.h>
-#include <linux/power_supply.h>
+#include <linux/iio/consumer.h>
#include <linux/interrupt.h>
+#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/regmap.h>
#include <linux/regulator/driver.h>
-#include <linux/regulator/of_regulator.h>
#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
#include <linux/qpnp/qpnp-revid.h>
#include "smb-reg.h"
#include "smb-lib.h"
@@ -89,6 +92,8 @@ struct smb_dt_props {
int fcc_ua;
int usb_icl_ua;
int dc_icl_ua;
+ int chg_temp_max_mdegc;
+ int connector_temp_max_mdegc;
};
struct smb138x {
@@ -132,6 +137,18 @@ static int smb138x_parse_dt(struct smb138x *chip)
if (rc < 0)
chip->dt.dc_icl_ua = SMB138X_DEFAULT_ICL_UA;
+ rc = of_property_read_u32(node,
+ "qcom,charger-temp-max-mdegc",
+ &chip->dt.chg_temp_max_mdegc);
+ if (rc < 0)
+ chip->dt.chg_temp_max_mdegc = 80000;
+
+ rc = of_property_read_u32(node,
+ "qcom,connector-temp-max-mdegc",
+ &chip->dt.chg_temp_max_mdegc);
+ if (rc < 0)
+ chip->dt.connector_temp_max_mdegc = 105000;
+
return 0;
}
@@ -415,6 +432,7 @@ static enum power_supply_property smb138x_parallel_props[] = {
POWER_SUPPLY_PROP_CHARGER_TEMP_MAX,
POWER_SUPPLY_PROP_MODEL_NAME,
POWER_SUPPLY_PROP_PARALLEL_MODE,
+ POWER_SUPPLY_PROP_CONNECTOR_THERM_ZONE,
};
static int smb138x_parallel_get_prop(struct power_supply *psy,
@@ -467,6 +485,9 @@ static int smb138x_parallel_get_prop(struct power_supply *psy,
case POWER_SUPPLY_PROP_PARALLEL_MODE:
val->intval = POWER_SUPPLY_PARALLEL_MID_MID;
break;
+ case POWER_SUPPLY_PROP_CONNECTOR_THERM_ZONE:
+ rc = smblib_get_prop_connector_therm_zone(chg, val);
+ break;
default:
pr_err("parallel power supply get prop %d not supported\n",
prop);
@@ -658,6 +679,138 @@ static int smb138x_init_vconn_regulator(struct smb138x *chip)
* HARDWARE INITIALIZATION *
***************************/
+#define MDEGC_3 3000
+#define MDEGC_15 15000
+static int smb138x_init_slave_hw(struct smb138x *chip)
+{
+ struct smb_charger *chg = &chip->chg;
+ int rc;
+
+ if (chip->wa_flags & OOB_COMP_WA_BIT) {
+ rc = smblib_masked_write(chg, SMB2CHG_MISC_ENG_SDCDC_CFG2,
+ ENG_SDCDC_SEL_OOB_VTH_BIT,
+ ENG_SDCDC_SEL_OOB_VTH_BIT);
+ if (rc < 0) {
+ pr_err("Couldn't configure the OOB comp threshold rc = %d\n",
+ rc);
+ return rc;
+ }
+
+ rc = smblib_masked_write(chg, SMB2CHG_MISC_ENG_SDCDC_CFG6,
+ DEAD_TIME_MASK, HIGH_DEAD_TIME_MASK);
+ if (rc < 0) {
+ pr_err("Couldn't configure the sdcdc cfg 6 reg rc = %d\n",
+ rc);
+ return rc;
+ }
+ }
+
+ /* enable watchdog bark and bite interrupts, and disable the watchdog */
+ rc = smblib_masked_write(chg, WD_CFG_REG, WDOG_TIMER_EN_BIT
+ | WDOG_TIMER_EN_ON_PLUGIN_BIT | BITE_WDOG_INT_EN_BIT
+ | BARK_WDOG_INT_EN_BIT,
+ BITE_WDOG_INT_EN_BIT | BARK_WDOG_INT_EN_BIT);
+ if (rc < 0) {
+ pr_err("Couldn't configure the watchdog rc=%d\n", rc);
+ return rc;
+ }
+
+ /* disable charging when watchdog bites */
+ rc = smblib_masked_write(chg, SNARL_BARK_BITE_WD_CFG_REG,
+ BITE_WDOG_DISABLE_CHARGING_CFG_BIT,
+ BITE_WDOG_DISABLE_CHARGING_CFG_BIT);
+ if (rc < 0) {
+ pr_err("Couldn't configure the watchdog bite rc=%d\n", rc);
+ return rc;
+ }
+
+ /* suspend parallel charging */
+ rc = smb138x_set_parallel_suspend(chip, true);
+ if (rc < 0) {
+ pr_err("Couldn't suspend parallel charging rc=%d\n", rc);
+ return rc;
+ }
+
+ /* initialize FCC to 0 */
+ rc = smblib_set_charge_param(chg, &chg->param.fcc, 0);
+ if (rc < 0) {
+ pr_err("Couldn't set 0 FCC rc=%d\n", rc);
+ return rc;
+ }
+
+ /* enable the charging path */
+ rc = smblib_masked_write(chg, CHARGING_ENABLE_CMD_REG,
+ CHARGING_ENABLE_CMD_BIT,
+ CHARGING_ENABLE_CMD_BIT);
+ if (rc < 0) {
+ pr_err("Couldn't enable charging rc=%d\n", rc);
+ return rc;
+ }
+
+ /* configure charge enable for software control; active high */
+ rc = smblib_masked_write(chg, CHGR_CFG2_REG,
+ CHG_EN_POLARITY_BIT | CHG_EN_SRC_BIT, 0);
+ if (rc < 0) {
+ pr_err("Couldn't configure charge enable source rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ /* enable parallel current sensing */
+ rc = smblib_masked_write(chg, CFG_REG,
+ VCHG_EN_CFG_BIT, VCHG_EN_CFG_BIT);
+ if (rc < 0) {
+ pr_err("Couldn't enable parallel current sensing rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ /* enable stacked diode */
+ rc = smblib_write(chg, SMB2CHG_DC_TM_SREFGEN, STACKED_DIODE_EN_BIT);
+ if (rc < 0) {
+ pr_err("Couldn't enable stacked diode rc=%d\n", rc);
+ return rc;
+ }
+
+ /* initialize charger temperature threshold */
+ rc = iio_write_channel_processed(chg->iio.temp_max_chan,
+ chip->dt.chg_temp_max_mdegc);
+ if (rc < 0) {
+ pr_err("Couldn't set charger temp threshold rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = iio_write_channel_processed(chg->iio.connector_temp_thr1_chan,
+ chip->dt.connector_temp_max_mdegc);
+ if (rc < 0) {
+ pr_err("Couldn't set connector temp threshold1 rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = iio_write_channel_processed(chg->iio.connector_temp_thr2_chan,
+ chip->dt.connector_temp_max_mdegc + MDEGC_3);
+ if (rc < 0) {
+ pr_err("Couldn't set connector temp threshold2 rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = iio_write_channel_processed(chg->iio.connector_temp_thr3_chan,
+ chip->dt.connector_temp_max_mdegc + MDEGC_15);
+ if (rc < 0) {
+ pr_err("Couldn't set connector temp threshold3 rc=%d\n", rc);
+ return rc;
+ }
+
+ rc = smblib_write(chg, THERMREG_SRC_CFG_REG,
+ THERMREG_SKIN_ADC_SRC_EN_BIT);
+ if (rc < 0) {
+ pr_err("Couldn't enable connector thermreg source rc=%d\n", rc);
+ return rc;
+ }
+
+ return 0;
+}
+
static int smb138x_init_hw(struct smb138x *chip)
{
struct smb_charger *chg = &chip->chg;
@@ -681,15 +834,14 @@ static int smb138x_init_hw(struct smb138x *chip)
rc = smblib_masked_write(chg, CHGR_CFG2_REG,
CHG_EN_POLARITY_BIT | CHG_EN_SRC_BIT, 0);
if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't configure charge enable source rc=%d\n", rc);
+ pr_err("Couldn't configure charge enable source rc=%d\n", rc);
return rc;
}
/* enable the charging path */
rc = vote(chg->chg_disable_votable, DEFAULT_VOTER, false, 0);
if (rc < 0) {
- dev_err(chg->dev, "Couldn't enable charging rc=%d\n", rc);
+ pr_err("Couldn't enable charging rc=%d\n", rc);
return rc;
}
@@ -701,8 +853,7 @@ static int smb138x_init_hw(struct smb138x *chip)
TYPEC_CCSTATE_CHANGE_INT_EN_BIT
| TYPEC_VBUS_ERROR_INT_EN_BIT);
if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't configure Type-C interrupts rc=%d\n", rc);
+ pr_err("Couldn't configure Type-C interrupts rc=%d\n", rc);
return rc;
}
@@ -711,16 +862,14 @@ static int smb138x_init_hw(struct smb138x *chip)
VCONN_EN_SRC_BIT | VCONN_EN_VALUE_BIT,
VCONN_EN_SRC_BIT);
if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't configure VCONN for SW control rc=%d\n", rc);
+ pr_err("Couldn't configure VCONN for SW control rc=%d\n", rc);
return rc;
}
/* configure VBUS for software control */
rc = smblib_masked_write(chg, OTG_CFG_REG, OTG_EN_SRC_CFG_BIT, 0);
if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't configure VBUS for SW control rc=%d\n", rc);
+ pr_err("Couldn't configure VBUS for SW control rc=%d\n", rc);
return rc;
}
@@ -728,8 +877,7 @@ static int smb138x_init_hw(struct smb138x *chip)
rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
TYPEC_POWER_ROLE_CMD_MASK, 0);
if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't configure power role for DRP rc=%d\n", rc);
+ pr_err("Couldn't configure power role for DRP rc=%d\n", rc);
return rc;
}
@@ -738,16 +886,16 @@ static int smb138x_init_hw(struct smb138x *chip)
ENG_SDCDC_SEL_OOB_VTH_BIT,
ENG_SDCDC_SEL_OOB_VTH_BIT);
if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't configure the oob comp threh rc = %d\n", rc);
+ pr_err("Couldn't configure the OOB comp threshold rc = %d\n",
+ rc);
return rc;
}
rc = smblib_masked_write(chg, SMB2CHG_MISC_ENG_SDCDC_CFG6,
DEAD_TIME_MASK, HIGH_DEAD_TIME_MASK);
if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't configure the sdcdc cfg 6 reg rc = %d\n", rc);
+ pr_err("Couldn't configure the sdcdc cfg 6 reg rc = %d\n",
+ rc);
return rc;
}
}
@@ -795,6 +943,23 @@ static int smb138x_setup_wa_flags(struct smb138x *chip)
* DETERMINE INITIAL STATUS *
****************************/
+static irqreturn_t smb138x_handle_temperature_change(int irq, void *data)
+{
+ struct smb_irq_data *irq_data = data;
+ struct smb138x *chip = irq_data->parent_data;
+
+ power_supply_changed(chip->parallel_psy);
+ return IRQ_HANDLED;
+}
+
+static int smb138x_determine_initial_slave_status(struct smb138x *chip)
+{
+ struct smb_irq_data irq_data = {chip, "determine-initial-status"};
+
+ smb138x_handle_temperature_change(0, &irq_data);
+ return 0;
+}
+
static int smb138x_determine_initial_status(struct smb138x *chip)
{
struct smb_irq_data irq_data = {chip, "determine-initial-status"};
@@ -802,7 +967,6 @@ static int smb138x_determine_initial_status(struct smb138x *chip)
smblib_handle_usb_plugin(0, &irq_data);
smblib_handle_usb_typec_change(0, &irq_data);
smblib_handle_usb_source_change(0, &irq_data);
-
return 0;
}
@@ -971,7 +1135,7 @@ static const struct smb138x_irq_info smb138x_irqs[] = {
},
{
.name = "temperature-change",
- .handler = smblib_handle_debug,
+ .handler = smb138x_handle_temperature_change,
},
{
.name = "switcher-power-ok",
@@ -1144,95 +1308,54 @@ static int smb138x_slave_probe(struct smb138x *chip)
goto cleanup;
}
- if (chip->wa_flags & OOB_COMP_WA_BIT) {
- rc = smblib_masked_write(chg, SMB2CHG_MISC_ENG_SDCDC_CFG2,
- ENG_SDCDC_SEL_OOB_VTH_BIT,
- ENG_SDCDC_SEL_OOB_VTH_BIT);
- if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't configure the oob comp threh rc = %d\n", rc);
- goto cleanup;
- }
-
- rc = smblib_masked_write(chg, SMB2CHG_MISC_ENG_SDCDC_CFG6,
- DEAD_TIME_MASK, HIGH_DEAD_TIME_MASK);
- if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't configure the sdcdc cfg 6 reg rc = %d\n", rc);
- goto cleanup;
- }
- }
-
- /* enable watchdog bark and bite interrupts, and disable the watchdog */
- rc = smblib_masked_write(chg, WD_CFG_REG, WDOG_TIMER_EN_BIT
- | WDOG_TIMER_EN_ON_PLUGIN_BIT | BITE_WDOG_INT_EN_BIT
- | BARK_WDOG_INT_EN_BIT,
- BITE_WDOG_INT_EN_BIT | BARK_WDOG_INT_EN_BIT);
- if (rc < 0) {
- pr_err("Couldn't configure the watchdog rc=%d\n", rc);
+ chg->iio.temp_max_chan = iio_channel_get(chg->dev, "charger_temp_max");
+ if (IS_ERR(chg->iio.temp_max_chan)) {
+ rc = PTR_ERR(chg->iio.temp_max_chan);
goto cleanup;
}
- /* disable charging when watchdog bites */
- rc = smblib_masked_write(chg, SNARL_BARK_BITE_WD_CFG_REG,
- BITE_WDOG_DISABLE_CHARGING_CFG_BIT,
- BITE_WDOG_DISABLE_CHARGING_CFG_BIT);
- if (rc < 0) {
- pr_err("Couldn't configure the watchdog bite rc=%d\n", rc);
+ chg->iio.connector_temp_thr1_chan = iio_channel_get(chg->dev,
+ "connector_temp_thr1");
+ if (IS_ERR(chg->iio.connector_temp_thr1_chan)) {
+ rc = PTR_ERR(chg->iio.connector_temp_thr1_chan);
goto cleanup;
}
- /* suspend parallel charging */
- rc = smb138x_set_parallel_suspend(chip, true);
- if (rc < 0) {
- pr_err("Couldn't suspend parallel charging rc=%d\n", rc);
+ chg->iio.connector_temp_thr2_chan = iio_channel_get(chg->dev,
+ "connector_temp_thr2");
+ if (IS_ERR(chg->iio.connector_temp_thr2_chan)) {
+ rc = PTR_ERR(chg->iio.connector_temp_thr2_chan);
goto cleanup;
}
- /* initialize FCC to 0 */
- rc = smblib_set_charge_param(chg, &chg->param.fcc, 0);
- if (rc < 0) {
- pr_err("Couldn't set 0 FCC rc=%d\n", rc);
+ chg->iio.connector_temp_thr3_chan = iio_channel_get(chg->dev,
+ "connector_temp_thr3");
+ if (IS_ERR(chg->iio.connector_temp_thr3_chan)) {
+ rc = PTR_ERR(chg->iio.connector_temp_thr3_chan);
goto cleanup;
}
- /* enable the charging path */
- rc = smblib_masked_write(chg, CHARGING_ENABLE_CMD_REG,
- CHARGING_ENABLE_CMD_BIT,
- CHARGING_ENABLE_CMD_BIT);
+ rc = smb138x_parse_dt(chip);
if (rc < 0) {
- dev_err(chg->dev, "Couldn't enable charging rc=%d\n", rc);
+ pr_err("Couldn't parse device tree rc=%d\n", rc);
goto cleanup;
}
- /* configure charge enable for software control; active high */
- rc = smblib_masked_write(chg, CHGR_CFG2_REG,
- CHG_EN_POLARITY_BIT | CHG_EN_SRC_BIT, 0);
+ rc = smb138x_init_slave_hw(chip);
if (rc < 0) {
- dev_err(chg->dev, "Couldn't configure charge enable source rc=%d\n",
- rc);
+ pr_err("Couldn't initialize hardware rc=%d\n", rc);
goto cleanup;
}
- /* enable parallel current sensing */
- rc = smblib_masked_write(chg, CFG_REG,
- VCHG_EN_CFG_BIT, VCHG_EN_CFG_BIT);
+ rc = smb138x_init_parallel_psy(chip);
if (rc < 0) {
- dev_err(chg->dev, "Couldn't enable parallel current sensing rc=%d\n",
- rc);
+ pr_err("Couldn't initialize parallel psy rc=%d\n", rc);
goto cleanup;
}
- /* enable stacked diode */
- rc = smblib_write(chg, SMB2CHG_DC_TM_SREFGEN, STACKED_DIODE_EN_BIT);
+ rc = smb138x_determine_initial_slave_status(chip);
if (rc < 0) {
- pr_err("Couldn't enable stacked diode rc=%d\n", rc);
- return rc;
- }
-
- rc = smb138x_init_parallel_psy(chip);
- if (rc < 0) {
- pr_err("Couldn't initialize parallel psy rc=%d\n", rc);
+ pr_err("Couldn't determine initial status rc=%d\n", rc);
goto cleanup;
}
@@ -1312,6 +1435,12 @@ static int smb138x_probe(struct platform_device *pdev)
goto cleanup;
}
+ if (rc < 0) {
+ if (rc != -EPROBE_DEFER)
+ pr_err("Couldn't probe SMB138X rc=%d\n", rc);
+ goto cleanup;
+ }
+
pr_info("SMB138X probed successfully mode=%d\n", chip->chg.mode);
return rc;
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 40e1afdfc286..b5e44b237ed8 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -310,13 +310,14 @@ config PWM_RCAR
will be called pwm-rcar.
config PWM_QPNP
+ tristate "Qualcomm Technologies, Inc. QPNP LPG/PWM support"
depends on SPMI
- tristate "Qualcomm QPNP LPG/PWM support"
- help
- This driver supports PWM/LPG devices in Qualcomm PMIC chips which
- comply with QPNP. QPNP is a SPMI based PMIC implementation. These
- devices support Pulse Width Modulation output with user generated
- patterns. They share a lookup table with size of 64 entries.
+ help
+ This driver supports PWM/LPG devices in Qualcomm Technologies, Inc.
+ PMIC chips which comply with QPNP. QPNP is an SPMI based PMIC
+ implementation. These devices support Pulse Width Modulation output
+ with user generated patterns. They share a lookup table with size of
+ 64 entries.
config PWM_RENESAS_TPU
tristate "Renesas TPU PWM support"
diff --git a/drivers/pwm/pwm-qpnp.c b/drivers/pwm/pwm-qpnp.c
index 6d0c1fbe566b..d57bf2f3b80c 100644
--- a/drivers/pwm/pwm-qpnp.c
+++ b/drivers/pwm/pwm-qpnp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -10,7 +10,7 @@
* GNU General Public License for more details.
*/
/*
- * Qualcomm QPNP Pulse Width Modulation (PWM) driver
+ * Qualcomm Technologies, Inc. QPNP Pulse Width Modulation (PWM) driver
*
* The HW module is also called LPG (Light Pattern Generator).
*/
@@ -382,6 +382,7 @@ static int qpnp_set_control(struct qpnp_pwm_chip *chip, bool pwm_hi,
bool pwm_lo, bool pwm_out, bool pwm_src, bool ramp_gen)
{
int value;
+
value = (ramp_gen << QPNP_PWM_EN_RAMP_GEN_SHIFT) |
(pwm_src << QPNP_PWM_SRC_SELECT_SHIFT) |
(pwm_lo << QPNP_EN_PWM_LO_SHIFT) |
@@ -476,7 +477,7 @@ static void qpnp_lpg_calc_period(enum time_level tm_lvl,
n = 6;
if (tm_lvl == LVL_USEC) {
- if (period_value < ((unsigned)(-1) / NSEC_PER_USEC)) {
+ if (period_value < ((unsigned int)(-1) / NSEC_PER_USEC)) {
period_n = (period_value * NSEC_PER_USEC) >> n;
} else {
if (supported_sizes == QPNP_PWM_SIZE_7_8_BIT)
@@ -499,7 +500,7 @@ static void qpnp_lpg_calc_period(enum time_level tm_lvl,
chip->channel_id, n);
}
- min_err = last_err = (unsigned)(-1);
+ min_err = last_err = (unsigned int)(-1);
best_m = 0;
best_clk = 0;
best_div = 0;
@@ -1233,7 +1234,7 @@ static int _pwm_config(struct qpnp_pwm_chip *chip,
}
pr_debug("duty/period=%u/%u %s: pwm_value=%d (of %d)\n",
- (unsigned)duty_value, (unsigned)period_value,
+ (unsigned int)duty_value, (unsigned int)period_value,
(tm_lvl == LVL_USEC) ? "usec" : "nsec",
pwm_config->pwm_value, 1 << period->pwm_size);
@@ -1290,7 +1291,7 @@ after_table_write:
QPNP_SET_PAUSE_CNT(lut_config->lut_pause_hi_cnt,
lut_params.lut_pause_hi, ramp_step_ms);
if (lut_config->lut_pause_hi_cnt > PM_PWM_MAX_PAUSE_CNT)
- lut_config->lut_pause_hi_cnt = PM_PWM_MAX_PAUSE_CNT;
+ lut_config->lut_pause_hi_cnt = PM_PWM_MAX_PAUSE_CNT;
lut_config->ramp_step_ms = ramp_step_ms;
@@ -1320,8 +1321,7 @@ static int _pwm_enable(struct qpnp_pwm_chip *chip)
chip->flags & QPNP_PWM_LUT_NOT_SUPPORTED) {
rc = qpnp_lpg_configure_pwm_state(chip, QPNP_PWM_ENABLE);
} else if (!(chip->flags & QPNP_PWM_LUT_NOT_SUPPORTED)) {
- rc = qpnp_lpg_configure_lut_state(chip,
- QPNP_LUT_ENABLE);
+ rc = qpnp_lpg_configure_lut_state(chip, QPNP_LUT_ENABLE);
}
if (!rc)
@@ -1368,7 +1368,7 @@ static int qpnp_pwm_config(struct pwm_chip *pwm_chip,
struct qpnp_pwm_chip *chip = qpnp_pwm_from_pwm_chip(pwm_chip);
int prev_period_us = chip->pwm_config.pwm_period;
- if ((unsigned)period_ns < PM_PWM_PERIOD_MIN * NSEC_PER_USEC) {
+ if ((unsigned int)period_ns < PM_PWM_PERIOD_MIN * NSEC_PER_USEC) {
pr_err("Invalid pwm handle or parameters\n");
return -EINVAL;
}
@@ -1403,6 +1403,7 @@ static int qpnp_pwm_enable(struct pwm_chip *pwm_chip,
{
int rc;
struct qpnp_pwm_chip *chip = qpnp_pwm_from_pwm_chip(pwm_chip);
+
rc = _pwm_enable(chip);
if (rc)
pr_err("Failed to enable PWM channel: %d\n", chip->channel_id);
@@ -1487,7 +1488,7 @@ int pwm_change_mode(struct pwm_device *pwm, enum pm_pwm_mode mode)
return rc;
}
-EXPORT_SYMBOL_GPL(pwm_change_mode);
+EXPORT_SYMBOL(pwm_change_mode);
/**
* pwm_config_period - change PWM period
@@ -1592,7 +1593,7 @@ out_unlock:
spin_unlock_irqrestore(&chip->lpg_lock, flags);
return rc;
}
-EXPORT_SYMBOL_GPL(pwm_config_pwm_value);
+EXPORT_SYMBOL(pwm_config_pwm_value);
/**
* pwm_config_us - change a PWM device configuration
@@ -1608,8 +1609,8 @@ int pwm_config_us(struct pwm_device *pwm, int duty_us, int period_us)
if (pwm == NULL || IS_ERR(pwm) ||
duty_us > period_us ||
- (unsigned)period_us > PM_PWM_PERIOD_MAX ||
- (unsigned)period_us < PM_PWM_PERIOD_MIN) {
+ (unsigned int)period_us > PM_PWM_PERIOD_MAX ||
+ (unsigned int)period_us < PM_PWM_PERIOD_MIN) {
pr_err("Invalid pwm handle or parameters\n");
return -EINVAL;
}
@@ -1622,10 +1623,11 @@ int pwm_config_us(struct pwm_device *pwm, int duty_us, int period_us)
qpnp_lpg_calc_period(LVL_USEC, period_us, chip);
qpnp_lpg_save_period(chip);
chip->pwm_config.pwm_period = period_us;
- if ((unsigned)period_us > (unsigned)(-1) / NSEC_PER_USEC)
+ if ((unsigned int)period_us >
+ (unsigned int)(-1) / NSEC_PER_USEC)
pwm->period = 0;
else
- pwm->period = (unsigned)period_us * NSEC_PER_USEC;
+ pwm->period = (unsigned int)period_us * NSEC_PER_USEC;
}
rc = _pwm_config(chip, LVL_USEC, duty_us, period_us);
@@ -1679,8 +1681,8 @@ int pwm_lut_config(struct pwm_device *pwm, int period_us,
return -EINVAL;
}
- if ((unsigned)period_us > PM_PWM_PERIOD_MAX ||
- (unsigned)period_us < PM_PWM_PERIOD_MIN) {
+ if ((unsigned int)period_us > PM_PWM_PERIOD_MAX ||
+ (unsigned int)period_us < PM_PWM_PERIOD_MIN) {
pr_err("Period out of range\n");
return -EINVAL;
}
@@ -1702,7 +1704,7 @@ int pwm_lut_config(struct pwm_device *pwm, int period_us,
return rc;
}
-EXPORT_SYMBOL_GPL(pwm_lut_config);
+EXPORT_SYMBOL(pwm_lut_config);
static int qpnp_parse_pwm_dt_config(struct device_node *of_pwm_node,
struct device_node *of_parent, struct qpnp_pwm_chip *chip)
@@ -1738,14 +1740,6 @@ static int qpnp_parse_pwm_dt_config(struct device_node *of_pwm_node,
return rc;
}
-#define qpnp_check_optional_dt_bindings(func) \
-do { \
- rc = func; \
- if (rc && rc != -EINVAL) \
- goto out; \
- rc = 0; \
-} while (0)
-
static int qpnp_parse_lpg_dt_config(struct device_node *of_lpg_node,
struct device_node *of_parent, struct qpnp_pwm_chip *chip)
{
@@ -1778,44 +1772,58 @@ static int qpnp_parse_lpg_dt_config(struct device_node *of_lpg_node,
return -EINVAL;
}
- duty_pct_list = kzalloc(sizeof(u32) * list_size, GFP_KERNEL);
-
- if (!duty_pct_list) {
- pr_err("kzalloc failed on duty_pct_list\n");
+ duty_pct_list = kcalloc(list_size, sizeof(*duty_pct_list), GFP_KERNEL);
+ if (!duty_pct_list)
return -ENOMEM;
- }
rc = of_property_read_u32_array(of_lpg_node, "qcom,duty-percents",
duty_pct_list, list_size);
if (rc) {
- pr_err("invalid or missing property:\n");
- pr_err("qcom,duty-pcts-list\n");
- kfree(duty_pct_list);
- return rc;
+ pr_err("invalid or missing property: qcom,duty-pcts-list\n");
+ goto out;
}
/* Read optional properties */
- qpnp_check_optional_dt_bindings(of_property_read_u32(of_lpg_node,
- "qcom,ramp-step-duration", &lut_config->ramp_step_ms));
- qpnp_check_optional_dt_bindings(of_property_read_u32(of_lpg_node,
- "qcom,lpg-lut-pause-hi", &lut_config->lut_pause_hi_cnt));
- qpnp_check_optional_dt_bindings(of_property_read_u32(of_lpg_node,
- "qcom,lpg-lut-pause-lo", &lut_config->lut_pause_lo_cnt));
- qpnp_check_optional_dt_bindings(of_property_read_u32(of_lpg_node,
- "qcom,lpg-lut-ramp-direction",
- (u32 *)&lut_config->ramp_direction));
- qpnp_check_optional_dt_bindings(of_property_read_u32(of_lpg_node,
- "qcom,lpg-lut-pattern-repeat",
- (u32 *)&lut_config->pattern_repeat));
- qpnp_check_optional_dt_bindings(of_property_read_u32(of_lpg_node,
- "qcom,lpg-lut-ramp-toggle",
- (u32 *)&lut_config->ramp_toggle));
- qpnp_check_optional_dt_bindings(of_property_read_u32(of_lpg_node,
- "qcom,lpg-lut-enable-pause-hi",
- (u32 *)&lut_config->enable_pause_hi));
- qpnp_check_optional_dt_bindings(of_property_read_u32(of_lpg_node,
- "qcom,lpg-lut-enable-pause-lo",
- (u32 *)&lut_config->enable_pause_lo));
+ rc = of_property_read_u32(of_lpg_node, "qcom,ramp-step-duration",
+ &lut_config->ramp_step_ms);
+ if (rc && rc != -EINVAL)
+ goto out;
+
+ rc = of_property_read_u32(of_lpg_node, "qcom,lpg-lut-pause-hi",
+ &lut_config->lut_pause_hi_cnt);
+ if (rc && rc != -EINVAL)
+ goto out;
+
+ rc = of_property_read_u32(of_lpg_node, "qcom,lpg-lut-pause-lo",
+ &lut_config->lut_pause_lo_cnt);
+ if (rc && rc != -EINVAL)
+ goto out;
+
+ rc = of_property_read_u32(of_lpg_node, "qcom,lpg-lut-ramp-direction",
+ (u32 *)&lut_config->ramp_direction);
+ if (rc && rc != -EINVAL)
+ goto out;
+
+ rc = of_property_read_u32(of_lpg_node, "qcom,lpg-lut-pattern-repeat",
+ (u32 *)&lut_config->pattern_repeat);
+ if (rc && rc != -EINVAL)
+ goto out;
+
+ rc = of_property_read_u32(of_lpg_node, "qcom,lpg-lut-ramp-toggle",
+ (u32 *)&lut_config->ramp_toggle);
+ if (rc && rc != -EINVAL)
+ goto out;
+
+ rc = of_property_read_u32(of_lpg_node, "qcom,lpg-lut-enable-pause-hi",
+ (u32 *)&lut_config->enable_pause_hi);
+ if (rc && rc != -EINVAL)
+ goto out;
+
+ rc = of_property_read_u32(of_lpg_node, "qcom,lpg-lut-enable-pause-lo",
+ (u32 *)&lut_config->enable_pause_lo);
+ if (rc && rc != -EINVAL)
+ goto out;
+ rc = 0;
qpnp_set_lut_params(&lut_params, lut_config, start_idx, list_size);
@@ -1877,7 +1885,7 @@ static int qpnp_parse_dt_config(struct platform_device *pdev,
struct qpnp_pwm_chip *chip)
{
int rc, enable, lut_entry_size, list_size, i;
- const char *lable;
+ const char *label;
const __be32 *prop;
u32 size;
struct device_node *node;
@@ -1992,12 +2000,10 @@ static int qpnp_parse_dt_config(struct platform_device *pdev,
lut_entry_size = sizeof(u8);
}
- lut_config->duty_pct_list = kzalloc(lpg_config->lut_size *
+ lut_config->duty_pct_list = kcalloc(lpg_config->lut_size,
lut_entry_size, GFP_KERNEL);
- if (!lut_config->duty_pct_list) {
- pr_err("can not allocate duty pct list\n");
+ if (!lut_config->duty_pct_list)
return -ENOMEM;
- }
rc = of_property_read_u32(of_node, "qcom,ramp-index",
&lut_config->ramp_index);
@@ -2038,18 +2044,18 @@ static int qpnp_parse_dt_config(struct platform_device *pdev,
}
for_each_child_of_node(of_node, node) {
- rc = of_property_read_string(node, "label", &lable);
+ rc = of_property_read_string(node, "label", &label);
if (rc) {
- dev_err(&pdev->dev, "%s: Missing lable property\n",
+ dev_err(&pdev->dev, "%s: Missing label property\n",
__func__);
goto out;
}
- if (!strncmp(lable, "pwm", 3)) {
+ if (!strcmp(label, "pwm")) {
rc = qpnp_parse_pwm_dt_config(node, of_node, chip);
if (rc)
goto out;
found_pwm_subnode = 1;
- } else if (!strncmp(lable, "lpg", 3) &&
+ } else if (!strcmp(label, "lpg") &&
!(chip->flags & QPNP_PWM_LUT_NOT_SUPPORTED)) {
rc = qpnp_parse_lpg_dt_config(node, of_node, chip);
if (rc)
@@ -2102,10 +2108,9 @@ static int qpnp_pwm_probe(struct platform_device *pdev)
int rc;
pwm_chip = kzalloc(sizeof(*pwm_chip), GFP_KERNEL);
- if (pwm_chip == NULL) {
- pr_err("kzalloc() failed.\n");
+ if (pwm_chip == NULL)
return -ENOMEM;
- }
+
pwm_chip->regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!pwm_chip->regmap) {
dev_err(&pdev->dev, "Couldn't get parent's regmap\n");
@@ -2169,7 +2174,7 @@ static int qpnp_pwm_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id spmi_match_table[] = {
+static const struct of_device_id spmi_match_table[] = {
{ .compatible = QPNP_LPG_DRIVER_NAME, },
{}
};
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 8d54ece776e2..e5ba63171eba 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -807,42 +807,43 @@ config REGULATOR_RPM_SMD
application processor over SMD.
config REGULATOR_QPNP
+ tristate "Qualcomm Technologies, Inc. QPNP regulator support"
depends on SPMI
- tristate "Qualcomm QPNP regulator support"
help
- This driver supports voltage regulators in Qualcomm PMIC chips which
- comply with QPNP. QPNP is a SPMI based PMIC implementation. These
- chips provide several different varieties of LDO and switching
- regulators. They also provide voltage switches and boost regulators.
+ This driver supports voltage regulators in Qualcomm Technologies, Inc.
+ PMIC chips which comply with QPNP. QPNP is a SPMI based PMIC
+ implementation. These chips provide several different varieties of
+ LDO and switching regulators. They also provide voltage switches and
+ boost regulators.
config REGULATOR_QPNP_LABIBB
+ tristate "Qualcomm Technologies, Inc. QPNP LAB/IBB regulator support"
depends on SPMI
- tristate "Qualcomm Technologies, Inc QPNP LAB/IBB regulator support"
help
- This driver supports voltage regulators in Qualcomm Technologies, Inc
+ This driver supports voltage regulators in Qualcomm Technologies, Inc.
PMIC chips which comply with QPNP LAB/IBB regulators. QPNP LAB and IBB
- are SPMI based PMIC implementation. LAB regulator can be used as a
+ are SPMI based PMIC implementations. LAB regulator can be used as a
regular positive boost regulator. IBB can be used as a regular
negative boost regulator. LAB/IBB regulators can also be used
together for LCD or AMOLED.
config REGULATOR_QPNP_LCDB
+ tristate "Qualcomm Technologies, Inc. QPNP LCDB support"
depends on SPMI
- tristate "Qualcomm Technologies, Inc QPNP LCDB support"
help
- Supports the LCDB module in the Qualcomm Technologies, Inc
- QPNP PMIC. Exposes regulators to control the positive and
+ Supports the LCDB module in the Qualcomm Technologies, Inc.
+ QPNP PMICs. Exposes regulators to control the positive and
negative voltage bias for the LCD display panel. It also
allows configurability for the various bias-voltage parameters.
config REGULATOR_QPNP_OLEDB
+ tristate "Qualcomm Technologies, Inc. QPNP OLEDB regulator support"
depends on SPMI
- tristate "Qualcomm Technologies, Inc QPNP OLEDB regulator support"
help
- This driver supports the OLEDB(AVDD bias) signal for AMOLED panel in Qualcomm
- Technologies, Inc QPNP PMIC. It exposes the OLED voltage configuration
- via the regulator framework. The configurable range of this bias is
- 5V to 8.1V.
+ This driver supports the OLEDB (AVDD bias) signal for AMOLED panel in
+ Qualcomm Technologies, Inc. QPNP PMICs. It exposes the OLED voltage
+ configuration via the regulator framework. The configurable range of
+ this bias is 5 V to 8.1 V.
config REGULATOR_SPM
bool "SPM regulator driver"
@@ -950,19 +951,18 @@ config REGULATOR_KRYO
depends on OF
help
Some MSM designs have CPUs that can be directly powered from a common
- voltage rail via a Block Head Switch (BHS) or an LDO whose output voltage
- can be configured for use when certain power constraints are met.
- Say yes to support management of LDO and BHS modes for the clusters in the
- CPU subsystem.
+ voltage rail via a Block Head Switch (BHS) or an LDO whose output
+ voltage can be configured for use when certain power constraints are
+ met. Say yes to support management of LDO and BHS modes for the
+ clusters in the CPU subsystem.
config REGULATOR_MEM_ACC
- tristate "QTI Memory accelerator regulator driver"
- help
- Say y here to enable the memory accelerator driver for Qualcomm
- Technologies (QTI) chips. The accelerator controls delays applied
- for memory accesses.
- This driver configures the power-mode (corner) for the memory
- accelerator.
+ tristate "QTI Memory accelerator regulator driver"
+ help
+ Say y here to enable the memory accelerator driver for Qualcomm
+ Technologies, Inc. (QTI) chips. The accelerator controls delays
+ applied for memory accesses. This driver configures the power-mode
+ (corner) for the memory accelerator.
config REGULATOR_PROXY_CONSUMER
bool "Boot time regulator proxy consumer support"
diff --git a/drivers/regulator/cpr3-hmss-regulator.c b/drivers/regulator/cpr3-hmss-regulator.c
index 091780525207..77e8bf4b9895 100644
--- a/drivers/regulator/cpr3-hmss-regulator.c
+++ b/drivers/regulator/cpr3-hmss-regulator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1232,7 +1232,7 @@ static int cpr3_hmss_kvreg_init(struct cpr3_regulator *vreg)
scnprintf(kvreg_name_buf, MAX_VREG_NAME_SIZE,
"vdd-thread%d-ldo-supply", id);
- if (!of_find_property(ctrl->dev->of_node, kvreg_name_buf , NULL))
+ if (!of_find_property(ctrl->dev->of_node, kvreg_name_buf, NULL))
return 0;
else if (!of_find_property(node, "qcom,ldo-min-headroom-voltage", NULL))
return 0;
@@ -1675,7 +1675,7 @@ static int cpr3_hmss_regulator_resume(struct platform_device *pdev)
}
/* Data corresponds to the SoC revision */
-static struct of_device_id cpr_regulator_match_table[] = {
+static const struct of_device_id cpr_regulator_match_table[] = {
{
.compatible = "qcom,cpr3-msm8996-v1-hmss-regulator",
.data = (void *)(uintptr_t)1
diff --git a/drivers/regulator/cpr3-mmss-regulator.c b/drivers/regulator/cpr3-mmss-regulator.c
index 1070a34073e4..41032dd3c15a 100644
--- a/drivers/regulator/cpr3-mmss-regulator.c
+++ b/drivers/regulator/cpr3-mmss-regulator.c
@@ -1088,7 +1088,7 @@ static int cpr3_mmss_regulator_resume(struct platform_device *pdev)
}
/* Data corresponds to the SoC revision */
-static struct of_device_id cpr_regulator_match_table[] = {
+static const struct of_device_id cpr_regulator_match_table[] = {
{
.compatible = "qcom,cpr3-msm8996-v1-mmss-regulator",
.data = (void *)(uintptr_t)1,
diff --git a/drivers/regulator/cpr3-regulator.c b/drivers/regulator/cpr3-regulator.c
index 6775152f2623..c51ed182ba96 100644
--- a/drivers/regulator/cpr3-regulator.c
+++ b/drivers/regulator/cpr3-regulator.c
@@ -1622,8 +1622,6 @@ static void cpr3_regulator_set_target_quot(struct cpr3_thread *thread)
}
thread->last_closed_loop_aggr_corner = thread->aggr_corner;
-
- return;
}
/**
@@ -1647,8 +1645,8 @@ static void cpr3_update_vreg_closed_loop_volt(struct cpr3_regulator *vreg,
if (vreg->last_closed_loop_corner == CPR3_REGULATOR_CORNER_INVALID)
return;
- else
- corner = &vreg->corner[vreg->last_closed_loop_corner];
+
+ corner = &vreg->corner[vreg->last_closed_loop_corner];
if (vreg->thread->last_closed_loop_aggr_corner.ro_mask
== CPR3_RO_MASK || !vreg->aggregated) {
@@ -4195,7 +4193,7 @@ static int cpr3_regulator_update_ctrl_state(struct cpr3_controller *ctrl)
* Return: 0 on success, errno on failure
*/
static int cpr3_regulator_set_voltage(struct regulator_dev *rdev,
- int corner, int corner_max, unsigned *selector)
+ int corner, int corner_max, unsigned int *selector)
{
struct cpr3_regulator *vreg = rdev_get_drvdata(rdev);
struct cpr3_controller *ctrl = vreg->thread->ctrl;
@@ -4264,7 +4262,7 @@ static int cpr3_regulator_get_voltage(struct regulator_dev *rdev)
* Return: voltage corner value offset by CPR3_CORNER_OFFSET
*/
static int cpr3_regulator_list_voltage(struct regulator_dev *rdev,
- unsigned selector)
+ unsigned int selector)
{
struct cpr3_regulator *vreg = rdev_get_drvdata(rdev);
@@ -4964,11 +4962,11 @@ static struct dentry *debugfs_create_int(const char *name, umode_t mode,
struct dentry *parent, int *value)
{
/* if there are no write bits set, make read only */
- if (!(mode & S_IWUGO))
+ if (!(mode & 0222))
return debugfs_create_file(name, mode, parent, value,
&fops_int_ro);
/* if there are no read bits set, make write only */
- if (!(mode & S_IRUGO))
+ if (!(mode & 0444))
return debugfs_create_file(name, mode, parent, value,
&fops_int_wo);
@@ -5225,21 +5223,21 @@ static void cpr3_regulator_debugfs_corner_add(struct cpr3_regulator *vreg,
struct cpr3_debug_corner_info *info;
struct dentry *temp;
- temp = cpr3_debugfs_create_corner_int(vreg, "floor_volt", S_IRUGO,
+ temp = cpr3_debugfs_create_corner_int(vreg, "floor_volt", 0444,
corner_dir, index, offsetof(struct cpr3_corner, floor_volt));
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(vreg, "floor_volt debugfs file creation failed\n");
return;
}
- temp = cpr3_debugfs_create_corner_int(vreg, "ceiling_volt", S_IRUGO,
+ temp = cpr3_debugfs_create_corner_int(vreg, "ceiling_volt", 0444,
corner_dir, index, offsetof(struct cpr3_corner, ceiling_volt));
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(vreg, "ceiling_volt debugfs file creation failed\n");
return;
}
- temp = cpr3_debugfs_create_corner_int(vreg, "open_loop_volt", S_IRUGO,
+ temp = cpr3_debugfs_create_corner_int(vreg, "open_loop_volt", 0444,
corner_dir, index,
offsetof(struct cpr3_corner, open_loop_volt));
if (IS_ERR_OR_NULL(temp)) {
@@ -5247,7 +5245,7 @@ static void cpr3_regulator_debugfs_corner_add(struct cpr3_regulator *vreg,
return;
}
- temp = cpr3_debugfs_create_corner_int(vreg, "last_volt", S_IRUGO,
+ temp = cpr3_debugfs_create_corner_int(vreg, "last_volt", 0444,
corner_dir, index, offsetof(struct cpr3_corner, last_volt));
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(vreg, "last_volt debugfs file creation failed\n");
@@ -5262,8 +5260,8 @@ static void cpr3_regulator_debugfs_corner_add(struct cpr3_regulator *vreg,
info->index = index;
info->corner = vreg->corner;
- temp = debugfs_create_file("target_quots", S_IRUGO, corner_dir,
- info, &cpr3_debug_quot_fops);
+ temp = debugfs_create_file("target_quots", 0444, corner_dir, info,
+ &cpr3_debug_quot_fops);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(vreg, "target_quots debugfs file creation failed\n");
return;
@@ -5361,21 +5359,21 @@ static void cpr3_regulator_debugfs_vreg_add(struct cpr3_regulator *vreg,
return;
}
- temp = debugfs_create_int("speed_bin_fuse", S_IRUGO, vreg_dir,
+ temp = debugfs_create_int("speed_bin_fuse", 0444, vreg_dir,
&vreg->speed_bin_fuse);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(vreg, "speed_bin_fuse debugfs file creation failed\n");
return;
}
- temp = debugfs_create_int("cpr_rev_fuse", S_IRUGO, vreg_dir,
+ temp = debugfs_create_int("cpr_rev_fuse", 0444, vreg_dir,
&vreg->cpr_rev_fuse);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(vreg, "cpr_rev_fuse debugfs file creation failed\n");
return;
}
- temp = debugfs_create_int("fuse_combo", S_IRUGO, vreg_dir,
+ temp = debugfs_create_int("fuse_combo", 0444, vreg_dir,
&vreg->fuse_combo);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(vreg, "fuse_combo debugfs file creation failed\n");
@@ -5383,15 +5381,15 @@ static void cpr3_regulator_debugfs_vreg_add(struct cpr3_regulator *vreg,
}
if (vreg->ldo_regulator) {
- temp = debugfs_create_file("ldo_mode", S_IRUGO, vreg_dir,
- vreg, &cpr3_debug_ldo_mode_fops);
+ temp = debugfs_create_file("ldo_mode", 0444, vreg_dir, vreg,
+ &cpr3_debug_ldo_mode_fops);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(vreg, "ldo_mode debugfs file creation failed\n");
return;
}
temp = debugfs_create_file("ldo_mode_allowed",
- S_IRUGO | S_IWUSR, vreg_dir, vreg,
+ 0644, vreg_dir, vreg,
&cpr3_debug_ldo_mode_allowed_fops);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(vreg, "ldo_mode_allowed debugfs file creation failed\n");
@@ -5399,7 +5397,7 @@ static void cpr3_regulator_debugfs_vreg_add(struct cpr3_regulator *vreg,
}
}
- temp = debugfs_create_int("corner_count", S_IRUGO, vreg_dir,
+ temp = debugfs_create_int("corner_count", 0444, vreg_dir,
&vreg->corner_count);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(vreg, "corner_count debugfs file creation failed\n");
@@ -5412,8 +5410,8 @@ static void cpr3_regulator_debugfs_vreg_add(struct cpr3_regulator *vreg,
return;
}
- temp = debugfs_create_file("index", S_IRUGO | S_IWUSR, corner_dir,
- vreg, &cpr3_debug_corner_index_fops);
+ temp = debugfs_create_file("index", 0644, corner_dir, vreg,
+ &cpr3_debug_corner_index_fops);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(vreg, "index debugfs file creation failed\n");
return;
@@ -5428,8 +5426,8 @@ static void cpr3_regulator_debugfs_vreg_add(struct cpr3_regulator *vreg,
return;
}
- temp = debugfs_create_file("index", S_IRUGO, corner_dir,
- vreg, &cpr3_debug_current_corner_index_fops);
+ temp = debugfs_create_file("index", 0444, corner_dir, vreg,
+ &cpr3_debug_current_corner_index_fops);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(vreg, "index debugfs file creation failed\n");
return;
@@ -5470,7 +5468,7 @@ static void cpr3_regulator_debugfs_thread_add(struct cpr3_thread *thread)
return;
}
- temp = debugfs_create_int("floor_volt", S_IRUGO, aggr_dir,
+ temp = debugfs_create_int("floor_volt", 0444, aggr_dir,
&thread->aggr_corner.floor_volt);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(ctrl, "thread %u aggr floor_volt debugfs file creation failed\n",
@@ -5478,7 +5476,7 @@ static void cpr3_regulator_debugfs_thread_add(struct cpr3_thread *thread)
return;
}
- temp = debugfs_create_int("ceiling_volt", S_IRUGO, aggr_dir,
+ temp = debugfs_create_int("ceiling_volt", 0444, aggr_dir,
&thread->aggr_corner.ceiling_volt);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(ctrl, "thread %u aggr ceiling_volt debugfs file creation failed\n",
@@ -5486,7 +5484,7 @@ static void cpr3_regulator_debugfs_thread_add(struct cpr3_thread *thread)
return;
}
- temp = debugfs_create_int("open_loop_volt", S_IRUGO, aggr_dir,
+ temp = debugfs_create_int("open_loop_volt", 0444, aggr_dir,
&thread->aggr_corner.open_loop_volt);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(ctrl, "thread %u aggr open_loop_volt debugfs file creation failed\n",
@@ -5494,7 +5492,7 @@ static void cpr3_regulator_debugfs_thread_add(struct cpr3_thread *thread)
return;
}
- temp = debugfs_create_int("last_volt", S_IRUGO, aggr_dir,
+ temp = debugfs_create_int("last_volt", 0444, aggr_dir,
&thread->aggr_corner.last_volt);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(ctrl, "thread %u aggr last_volt debugfs file creation failed\n",
@@ -5511,8 +5509,8 @@ static void cpr3_regulator_debugfs_thread_add(struct cpr3_thread *thread)
info->index = index;
info->corner = &thread->aggr_corner;
- temp = debugfs_create_file("target_quots", S_IRUGO, aggr_dir,
- info, &cpr3_debug_quot_fops);
+ temp = debugfs_create_file("target_quots", 0444, aggr_dir, info,
+ &cpr3_debug_quot_fops);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(ctrl, "thread %u target_quots debugfs file creation failed\n",
thread->thread_id);
@@ -5869,7 +5867,7 @@ static void cpr3_regulator_debugfs_ctrl_add(struct cpr3_controller *ctrl)
return;
}
- temp = debugfs_create_file("cpr_closed_loop_enable", S_IRUGO | S_IWUSR,
+ temp = debugfs_create_file("cpr_closed_loop_enable", 0644,
ctrl->debugfs, ctrl,
&cpr3_debug_closed_loop_enable_fops);
if (IS_ERR_OR_NULL(temp)) {
@@ -5878,8 +5876,8 @@ static void cpr3_regulator_debugfs_ctrl_add(struct cpr3_controller *ctrl)
}
if (ctrl->supports_hw_closed_loop) {
- temp = debugfs_create_file("use_hw_closed_loop",
- S_IRUGO | S_IWUSR, ctrl->debugfs, ctrl,
+ temp = debugfs_create_file("use_hw_closed_loop", 0644,
+ ctrl->debugfs, ctrl,
&cpr3_debug_hw_closed_loop_enable_fops);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(ctrl, "use_hw_closed_loop debugfs file creation failed\n");
@@ -5887,7 +5885,7 @@ static void cpr3_regulator_debugfs_ctrl_add(struct cpr3_controller *ctrl)
}
}
- temp = debugfs_create_int("thread_count", S_IRUGO, ctrl->debugfs,
+ temp = debugfs_create_int("thread_count", 0444, ctrl->debugfs,
&ctrl->thread_count);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(ctrl, "thread_count debugfs file creation failed\n");
@@ -5895,7 +5893,7 @@ static void cpr3_regulator_debugfs_ctrl_add(struct cpr3_controller *ctrl)
}
if (ctrl->apm) {
- temp = debugfs_create_int("apm_threshold_volt", S_IRUGO,
+ temp = debugfs_create_int("apm_threshold_volt", 0444,
ctrl->debugfs, &ctrl->apm_threshold_volt);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(ctrl, "apm_threshold_volt debugfs file creation failed\n");
@@ -5905,28 +5903,28 @@ static void cpr3_regulator_debugfs_ctrl_add(struct cpr3_controller *ctrl)
if (ctrl->aging_required || ctrl->aging_succeeded
|| ctrl->aging_failed) {
- temp = debugfs_create_int("aging_adj_volt", S_IRUGO,
+ temp = debugfs_create_int("aging_adj_volt", 0444,
ctrl->debugfs, &ctrl->aging_ref_adjust_volt);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(ctrl, "aging_adj_volt debugfs file creation failed\n");
return;
}
- temp = debugfs_create_file("aging_succeeded", S_IRUGO,
+ temp = debugfs_create_file("aging_succeeded", 0444,
ctrl->debugfs, &ctrl->aging_succeeded, &fops_bool_ro);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(ctrl, "aging_succeeded debugfs file creation failed\n");
return;
}
- temp = debugfs_create_file("aging_failed", S_IRUGO,
+ temp = debugfs_create_file("aging_failed", 0444,
ctrl->debugfs, &ctrl->aging_failed, &fops_bool_ro);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(ctrl, "aging_failed debugfs file creation failed\n");
return;
}
- temp = debugfs_create_file("aging_trigger", S_IWUSR,
+ temp = debugfs_create_file("aging_trigger", 0200,
ctrl->debugfs, ctrl,
&cpr3_debug_trigger_aging_measurement_fops);
if (IS_ERR_OR_NULL(temp)) {
@@ -5941,28 +5939,28 @@ static void cpr3_regulator_debugfs_ctrl_add(struct cpr3_controller *ctrl)
return;
}
- temp = debugfs_create_int("floor_volt", S_IRUGO, aggr_dir,
+ temp = debugfs_create_int("floor_volt", 0444, aggr_dir,
&ctrl->aggr_corner.floor_volt);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(ctrl, "aggr floor_volt debugfs file creation failed\n");
return;
}
- temp = debugfs_create_int("ceiling_volt", S_IRUGO, aggr_dir,
+ temp = debugfs_create_int("ceiling_volt", 0444, aggr_dir,
&ctrl->aggr_corner.ceiling_volt);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(ctrl, "aggr ceiling_volt debugfs file creation failed\n");
return;
}
- temp = debugfs_create_int("open_loop_volt", S_IRUGO, aggr_dir,
+ temp = debugfs_create_int("open_loop_volt", 0444, aggr_dir,
&ctrl->aggr_corner.open_loop_volt);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(ctrl, "aggr open_loop_volt debugfs file creation failed\n");
return;
}
- temp = debugfs_create_int("last_volt", S_IRUGO, aggr_dir,
+ temp = debugfs_create_int("last_volt", 0444, aggr_dir,
&ctrl->aggr_corner.last_volt);
if (IS_ERR_OR_NULL(temp)) {
cpr3_err(ctrl, "aggr last_volt debugfs file creation failed\n");
diff --git a/drivers/regulator/cpr3-regulator.h b/drivers/regulator/cpr3-regulator.h
index f0230b8ae2e5..7dae23ca0e70 100644
--- a/drivers/regulator/cpr3-regulator.h
+++ b/drivers/regulator/cpr3-regulator.h
@@ -36,9 +36,9 @@ struct cpr3_thread;
* from 0 to 63. bit_start must be less than or equal to bit_end.
*/
struct cpr3_fuse_param {
- unsigned row;
- unsigned bit_start;
- unsigned bit_end;
+ unsigned int row;
+ unsigned int bit_start;
+ unsigned int bit_end;
};
/* Each CPR3 sensor has 16 ring oscillators */
@@ -1021,7 +1021,6 @@ static inline int cpr3_limit_open_loop_voltages(struct cpr3_regulator *vreg)
static inline void cpr3_open_loop_voltage_as_ceiling(
struct cpr3_regulator *vreg)
{
- return;
}
static inline int cpr3_limit_floor_voltages(struct cpr3_regulator *vreg)
@@ -1031,7 +1030,6 @@ static inline int cpr3_limit_floor_voltages(struct cpr3_regulator *vreg)
static inline void cpr3_print_quots(struct cpr3_regulator *vreg)
{
- return;
}
static inline int cpr3_adjust_fused_open_loop_voltages(
diff --git a/drivers/regulator/cpr4-apss-regulator.c b/drivers/regulator/cpr4-apss-regulator.c
index 737511e250f1..cfc09ba9f8da 100644
--- a/drivers/regulator/cpr4-apss-regulator.c
+++ b/drivers/regulator/cpr4-apss-regulator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1402,7 +1402,7 @@ static int cpr4_apss_regulator_remove(struct platform_device *pdev)
return cpr3_regulator_unregister(ctrl);
}
-static struct of_device_id cpr4_regulator_match_table[] = {
+static const struct of_device_id cpr4_regulator_match_table[] = {
{ .compatible = "qcom,cpr4-msm8953-apss-regulator", },
{}
};
diff --git a/drivers/regulator/cprh-kbss-regulator.c b/drivers/regulator/cprh-kbss-regulator.c
index 0472ce13197b..f21800e00d80 100644
--- a/drivers/regulator/cprh-kbss-regulator.c
+++ b/drivers/regulator/cprh-kbss-regulator.c
@@ -2007,7 +2007,7 @@ static int cprh_kbss_regulator_resume(struct platform_device *pdev)
}
/* Data corresponds to the SoC revision */
-static struct of_device_id cprh_regulator_match_table[] = {
+static const struct of_device_id cprh_regulator_match_table[] = {
{
.compatible = "qcom,cprh-msm8998-v1-kbss-regulator",
.data = (void *)(uintptr_t)MSM8998_V1_SOC_ID,
diff --git a/drivers/regulator/kryo-regulator.c b/drivers/regulator/kryo-regulator.c
index cf7830469db5..fd853e7323bb 100644
--- a/drivers/regulator/kryo-regulator.c
+++ b/drivers/regulator/kryo-regulator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -333,7 +333,7 @@ static int kryo_regulator_is_enabled(struct regulator_dev *rdev)
}
static int kryo_regulator_set_voltage(struct regulator_dev *rdev,
- int min_volt, int max_volt, unsigned *selector)
+ int min_volt, int max_volt, unsigned int *selector)
{
struct kryo_regulator *kvreg = rdev_get_drvdata(rdev);
int rc;
@@ -400,7 +400,7 @@ static int kryo_regulator_get_bypass(struct regulator_dev *rdev,
}
static int kryo_regulator_list_voltage(struct regulator_dev *rdev,
- unsigned selector)
+ unsigned int selector)
{
struct kryo_regulator *kvreg = rdev_get_drvdata(rdev);
@@ -411,7 +411,7 @@ static int kryo_regulator_list_voltage(struct regulator_dev *rdev,
}
static int kryo_regulator_retention_set_voltage(struct regulator_dev *rdev,
- int min_volt, int max_volt, unsigned *selector)
+ int min_volt, int max_volt, unsigned int *selector)
{
struct kryo_regulator *kvreg = rdev_get_drvdata(rdev);
int rc;
@@ -499,7 +499,7 @@ static int kryo_regulator_retention_get_bypass(struct regulator_dev *rdev,
}
static int kryo_regulator_retention_list_voltage(struct regulator_dev *rdev,
- unsigned selector)
+ unsigned int selector)
{
struct kryo_regulator *kvreg = rdev_get_drvdata(rdev);
@@ -624,7 +624,7 @@ static void kryo_debugfs_init(struct kryo_regulator *kvreg)
return;
}
- temp = debugfs_create_file("mode", S_IRUGO, kvreg->debugfs,
+ temp = debugfs_create_file("mode", 0444, kvreg->debugfs,
kvreg, &kryo_dbg_mode_fops);
if (IS_ERR_OR_NULL(temp)) {
@@ -989,10 +989,8 @@ static int kryo_regulator_probe(struct platform_device *pdev)
init_data->constraints.input_uV = init_data->constraints.max_uV;
kvreg = devm_kzalloc(dev, sizeof(*kvreg), GFP_KERNEL);
- if (!kvreg) {
- dev_err(dev, "memory allocation failed\n");
+ if (!kvreg)
return -ENOMEM;
- }
rc = kryo_regulator_init_data(pdev, kvreg);
if (rc) {
@@ -1073,7 +1071,7 @@ static int kryo_regulator_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id kryo_regulator_match_table[] = {
+static const struct of_device_id kryo_regulator_match_table[] = {
{ .compatible = "qcom,kryo-regulator", },
{}
};
diff --git a/drivers/regulator/mem-acc-regulator.c b/drivers/regulator/mem-acc-regulator.c
index c693969b19b6..4c03decda95a 100644
--- a/drivers/regulator/mem-acc-regulator.c
+++ b/drivers/regulator/mem-acc-regulator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -269,7 +269,7 @@ static void update_acc_reg(struct mem_acc_regulator *mem_acc_vreg, int corner)
}
static int mem_acc_regulator_set_voltage(struct regulator_dev *rdev,
- int corner, int corner_max, unsigned *selector)
+ int corner, int corner_max, unsigned int *selector)
{
struct mem_acc_regulator *mem_acc_vreg = rdev_get_drvdata(rdev);
int i;
@@ -333,10 +333,8 @@ static int __mem_acc_sel_init(struct mem_acc_regulator *mem_acc_vreg,
mem_acc_vreg->acc_sel_mask[mem_type] = devm_kzalloc(mem_acc_vreg->dev,
mem_acc_vreg->num_acc_sel[mem_type] * sizeof(u32), GFP_KERNEL);
- if (!mem_acc_vreg->acc_sel_mask[mem_type]) {
- pr_err("Unable to allocate memory for mem_type=%d\n", mem_type);
+ if (!mem_acc_vreg->acc_sel_mask[mem_type])
return -ENOMEM;
- }
for (i = 0; i < mem_acc_vreg->num_acc_sel[mem_type]; i++) {
bit = mem_acc_vreg->acc_sel_bit_pos[mem_type][i];
@@ -355,8 +353,8 @@ static int mem_acc_sel_init(struct mem_acc_regulator *mem_acc_vreg)
if (mem_acc_vreg->mem_acc_supported[i]) {
rc = __mem_acc_sel_init(mem_acc_vreg, i);
if (rc) {
- pr_err("Unable to intialize mem_type=%d rc=%d\n",
- i, rc);
+ pr_err("Unable to initialize mem_type=%d rc=%d\n",
+ i, rc);
return rc;
}
}
@@ -523,15 +521,15 @@ static int mem_acc_custom_data_init(struct platform_device *pdev,
if (!res || !res->start) {
pr_debug("%s resource missing\n", custom_apc_addr_str);
return -EINVAL;
- } else {
- len = res->end - res->start + 1;
- mem_acc_vreg->acc_custom_addr[mem_type] =
- devm_ioremap(mem_acc_vreg->dev, res->start, len);
- if (!mem_acc_vreg->acc_custom_addr[mem_type]) {
- pr_err("Unable to map %s %pa\n", custom_apc_addr_str,
- &res->start);
- return -EINVAL;
- }
+ }
+
+ len = res->end - res->start + 1;
+ mem_acc_vreg->acc_custom_addr[mem_type] =
+ devm_ioremap(mem_acc_vreg->dev, res->start, len);
+ if (!mem_acc_vreg->acc_custom_addr[mem_type]) {
+ pr_err("Unable to map %s %pa\n",
+ custom_apc_addr_str, &res->start);
+ return -EINVAL;
}
rc = populate_acc_data(mem_acc_vreg, custom_apc_data_str,
@@ -1190,7 +1188,7 @@ static int mem_acc_init(struct platform_device *pdev,
rc = mem_acc_sel_init(mem_acc_vreg);
if (rc) {
- pr_err("Unable to intialize mem_acc_sel reg rc=%d\n", rc);
+ pr_err("Unable to initialize mem_acc_sel reg rc=%d\n", rc);
return rc;
}
@@ -1307,19 +1305,16 @@ static int mem_acc_regulator_probe(struct platform_device *pdev)
if (!init_data) {
pr_err("regulator init data is missing\n");
return -EINVAL;
- } else {
- init_data->constraints.input_uV
- = init_data->constraints.max_uV;
- init_data->constraints.valid_ops_mask
- |= REGULATOR_CHANGE_VOLTAGE;
}
+ init_data->constraints.input_uV = init_data->constraints.max_uV;
+ init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE;
+
mem_acc_vreg = devm_kzalloc(&pdev->dev, sizeof(*mem_acc_vreg),
GFP_KERNEL);
- if (!mem_acc_vreg) {
- pr_err("Can't allocate mem_acc_vreg memory\n");
+ if (!mem_acc_vreg)
return -ENOMEM;
- }
+
mem_acc_vreg->dev = &pdev->dev;
rc = mem_acc_init(pdev, mem_acc_vreg);
@@ -1361,7 +1356,7 @@ static int mem_acc_regulator_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id mem_acc_regulator_match_table[] = {
+static const struct of_device_id mem_acc_regulator_match_table[] = {
{ .compatible = "qcom,mem-acc-regulator", },
{}
};
diff --git a/drivers/regulator/msm_gfx_ldo.c b/drivers/regulator/msm_gfx_ldo.c
index 265ca9ed5258..2800607b5b31 100644
--- a/drivers/regulator/msm_gfx_ldo.c
+++ b/drivers/regulator/msm_gfx_ldo.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -42,7 +42,7 @@
#define LDO_VREF_SET_REG 0x18
#define UPDATE_VREF_BIT BIT(31)
#define SEL_RST_BIT BIT(16)
-#define VREF_VAL_MASK GENMASK(6 , 0)
+#define VREF_VAL_MASK GENMASK(6, 0)
#define PWRSWITCH_CTRL_REG 0x1C
#define LDO_CLAMP_IO_BIT BIT(31)
@@ -95,9 +95,9 @@ enum voltage_handling {
};
struct fuse_param {
- unsigned row;
- unsigned bit_start;
- unsigned bit_end;
+ unsigned int row;
+ unsigned int bit_start;
+ unsigned int bit_end;
};
struct ldo_config {
@@ -665,7 +665,7 @@ static int switch_mode_to_bhs(struct msm_gfx_ldo *ldo_vreg)
}
static int msm_gfx_ldo_set_corner(struct regulator_dev *rdev,
- int corner, int corner_max, unsigned *selector)
+ int corner, int corner_max, unsigned int *selector)
{
struct msm_gfx_ldo *ldo_vreg = rdev_get_drvdata(rdev);
int rc = 0, mem_acc_corner, new_uv;
@@ -860,7 +860,7 @@ fail:
}
static int msm_gfx_ldo_set_voltage(struct regulator_dev *rdev,
- int new_uv, int max_uv, unsigned *selector)
+ int new_uv, int max_uv, unsigned int *selector)
{
struct msm_gfx_ldo *ldo_vreg = rdev_get_drvdata(rdev);
int rc = 0;
@@ -1444,22 +1444,22 @@ static void msm_gfx_ldo_debugfs_init(struct msm_gfx_ldo *ldo_vreg)
return;
}
- temp = debugfs_create_file("debug_info", S_IRUGO, ldo_vreg->debugfs,
+ temp = debugfs_create_file("debug_info", 0444, ldo_vreg->debugfs,
ldo_vreg, &msm_gfx_ldo_debug_info_fops);
if (IS_ERR_OR_NULL(temp)) {
pr_err("debug_info node creation failed\n");
return;
}
- temp = debugfs_create_file("ldo_voltage", S_IRUGO | S_IWUSR,
- ldo_vreg->debugfs, ldo_vreg, &ldo_voltage_fops);
+ temp = debugfs_create_file("ldo_voltage", 0644, ldo_vreg->debugfs,
+ ldo_vreg, &ldo_voltage_fops);
if (IS_ERR_OR_NULL(temp)) {
pr_err("ldo_voltage node creation failed\n");
return;
}
- temp = debugfs_create_file("ldo_mode_disable", S_IRUGO | S_IWUSR,
- ldo_vreg->debugfs, ldo_vreg, &ldo_mode_disable_fops);
+ temp = debugfs_create_file("ldo_mode_disable", 0644, ldo_vreg->debugfs,
+ ldo_vreg, &ldo_mode_disable_fops);
if (IS_ERR_OR_NULL(temp)) {
pr_err("ldo_mode_disable node creation failed\n");
return;
diff --git a/drivers/regulator/qpnp-labibb-regulator.c b/drivers/regulator/qpnp-labibb-regulator.c
index 40c62c355188..cf8f00085a0c 100644
--- a/drivers/regulator/qpnp-labibb-regulator.c
+++ b/drivers/regulator/qpnp-labibb-regulator.c
@@ -2365,7 +2365,7 @@ static int qpnp_lab_regulator_is_enabled(struct regulator_dev *rdev)
}
static int qpnp_lab_regulator_set_voltage(struct regulator_dev *rdev,
- int min_uV, int max_uV, unsigned *selector)
+ int min_uV, int max_uV, unsigned int *selector)
{
int rc, new_uV;
u8 val;
@@ -3282,7 +3282,7 @@ static int qpnp_ibb_regulator_is_enabled(struct regulator_dev *rdev)
}
static int qpnp_ibb_regulator_set_voltage(struct regulator_dev *rdev,
- int min_uV, int max_uV, unsigned *selector)
+ int min_uV, int max_uV, unsigned int *selector)
{
int rc = 0;
@@ -3648,12 +3648,10 @@ static int qpnp_labibb_regulator_probe(struct platform_device *pdev)
u8 type, revision;
int rc = 0;
- labibb = devm_kzalloc(&pdev->dev,
- sizeof(struct qpnp_labibb), GFP_KERNEL);
- if (labibb == NULL) {
- pr_err("labibb allocation failed.\n");
+ labibb = devm_kzalloc(&pdev->dev, sizeof(*labibb), GFP_KERNEL);
+ if (labibb == NULL)
return -ENOMEM;
- }
+
labibb->regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!labibb->regmap) {
dev_err(&pdev->dev, "Couldn't get parent's regmap\n");
@@ -3849,7 +3847,7 @@ static int qpnp_labibb_regulator_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id spmi_match_table[] = {
+static const struct of_device_id spmi_match_table[] = {
{ .compatible = QPNP_LABIBB_REGULATOR_DRIVER_NAME, },
{ },
};
diff --git a/drivers/regulator/qpnp-lcdb-regulator.c b/drivers/regulator/qpnp-lcdb-regulator.c
index daa4e8e74d5b..a08ade61e057 100644
--- a/drivers/regulator/qpnp-lcdb-regulator.c
+++ b/drivers/regulator/qpnp-lcdb-regulator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -863,7 +863,7 @@ static int qpnp_lcdb_ldo_regulator_is_enabled(struct regulator_dev *rdev)
}
static int qpnp_lcdb_ldo_regulator_set_voltage(struct regulator_dev *rdev,
- int min_uV, int max_uV, unsigned *selector)
+ int min_uV, int max_uV, unsigned int *selector)
{
int rc = 0;
struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
@@ -934,7 +934,7 @@ static int qpnp_lcdb_ncp_regulator_is_enabled(struct regulator_dev *rdev)
}
static int qpnp_lcdb_ncp_regulator_set_voltage(struct regulator_dev *rdev,
- int min_uV, int max_uV, unsigned *selector)
+ int min_uV, int max_uV, unsigned int *selector)
{
int rc = 0;
struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
diff --git a/drivers/regulator/qpnp-oledb-regulator.c b/drivers/regulator/qpnp-oledb-regulator.c
index 587538cca474..8d017fb55a3f 100644
--- a/drivers/regulator/qpnp-oledb-regulator.c
+++ b/drivers/regulator/qpnp-oledb-regulator.c
@@ -327,7 +327,7 @@ static int qpnp_oledb_regulator_is_enabled(struct regulator_dev *rdev)
}
static int qpnp_oledb_regulator_set_voltage(struct regulator_dev *rdev,
- int min_uV, int max_uV, unsigned *selector)
+ int min_uV, int max_uV, unsigned int *selector)
{
u8 val;
int rc = 0;
diff --git a/drivers/regulator/qpnp-regulator.c b/drivers/regulator/qpnp-regulator.c
index 17865857df03..bd706658348d 100644
--- a/drivers/regulator/qpnp-regulator.c
+++ b/drivers/regulator/qpnp-regulator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -45,7 +45,7 @@ enum {
static int qpnp_vreg_debug_mask;
module_param_named(
- debug_mask, qpnp_vreg_debug_mask, int, S_IRUSR | S_IWUSR
+ debug_mask, qpnp_vreg_debug_mask, int, 0600
);
#define vreg_err(vreg, fmt, ...) \
@@ -302,7 +302,7 @@ struct qpnp_voltage_range {
int step_uV;
int set_point_min_uV;
int set_point_max_uV;
- unsigned n_voltages;
+ unsigned int n_voltages;
u8 range_sel;
};
@@ -313,7 +313,7 @@ struct qpnp_voltage_range {
struct qpnp_voltage_set_points {
struct qpnp_voltage_range *range;
int count;
- unsigned n_voltages;
+ unsigned int n_voltages;
};
struct qpnp_regulator_mapping {
@@ -381,7 +381,7 @@ struct qpnp_regulator {
{ \
.range = _ranges, \
.count = ARRAY_SIZE(_ranges), \
-};
+}
/*
* These tables contain the physically available PMIC regulator voltage setpoint
@@ -730,7 +730,7 @@ static int qpnp_regulator_common_disable(struct regulator_dev *rdev)
*/
static int qpnp_regulator_select_voltage_same_range(struct qpnp_regulator *vreg,
int min_uV, int max_uV, int *range_sel, int *voltage_sel,
- unsigned *selector)
+ unsigned int *selector)
{
struct qpnp_voltage_range *range = NULL;
int uV = min_uV;
@@ -781,9 +781,9 @@ static int qpnp_regulator_select_voltage_same_range(struct qpnp_regulator *vreg,
(uV - vreg->set_points->range[i].set_point_min_uV)
/ vreg->set_points->range[i].step_uV;
break;
- } else {
- *selector += vreg->set_points->range[i].n_voltages;
}
+
+ *selector += vreg->set_points->range[i].n_voltages;
}
if (*selector >= vreg->set_points->n_voltages)
@@ -794,7 +794,7 @@ static int qpnp_regulator_select_voltage_same_range(struct qpnp_regulator *vreg,
static int qpnp_regulator_select_voltage(struct qpnp_regulator *vreg,
int min_uV, int max_uV, int *range_sel, int *voltage_sel,
- unsigned *selector)
+ unsigned int *selector)
{
struct qpnp_voltage_range *range;
int uV = min_uV;
@@ -872,7 +872,7 @@ static int qpnp_regulator_delay_for_slewing(struct qpnp_regulator *vreg,
}
static int qpnp_regulator_common_set_voltage(struct regulator_dev *rdev,
- int min_uV, int max_uV, unsigned *selector)
+ int min_uV, int max_uV, unsigned int *selector)
{
struct qpnp_regulator *vreg = rdev_get_drvdata(rdev);
int rc, range_sel, voltage_sel, voltage_old = 0;
@@ -958,7 +958,7 @@ static int qpnp_regulator_common_get_voltage(struct regulator_dev *rdev)
}
static int qpnp_regulator_single_range_set_voltage(struct regulator_dev *rdev,
- int min_uV, int max_uV, unsigned *selector)
+ int min_uV, int max_uV, unsigned int *selector)
{
struct qpnp_regulator *vreg = rdev_get_drvdata(rdev);
int rc, range_sel, voltage_sel;
@@ -995,7 +995,7 @@ static int qpnp_regulator_single_range_get_voltage(struct regulator_dev *rdev)
}
static int qpnp_regulator_ult_lo_smps_set_voltage(struct regulator_dev *rdev,
- int min_uV, int max_uV, unsigned *selector)
+ int min_uV, int max_uV, unsigned int *selector)
{
struct qpnp_regulator *vreg = rdev_get_drvdata(rdev);
int rc, range_sel, voltage_sel;
@@ -1065,7 +1065,7 @@ static int qpnp_regulator_ult_lo_smps_get_voltage(struct regulator_dev *rdev)
}
static int qpnp_regulator_common_list_voltage(struct regulator_dev *rdev,
- unsigned selector)
+ unsigned int selector)
{
struct qpnp_regulator *vreg = rdev_get_drvdata(rdev);
int uV = 0;
@@ -1079,16 +1079,16 @@ static int qpnp_regulator_common_list_voltage(struct regulator_dev *rdev,
uV = selector * vreg->set_points->range[i].step_uV
+ vreg->set_points->range[i].set_point_min_uV;
break;
- } else {
- selector -= vreg->set_points->range[i].n_voltages;
}
+
+ selector -= vreg->set_points->range[i].n_voltages;
}
return uV;
}
static int qpnp_regulator_common2_set_voltage(struct regulator_dev *rdev,
- int min_uV, int max_uV, unsigned *selector)
+ int min_uV, int max_uV, unsigned int *selector)
{
struct qpnp_regulator *vreg = rdev_get_drvdata(rdev);
int rc, range_sel, voltage_sel, voltage_old = 0;
@@ -1280,8 +1280,6 @@ static void qpnp_regulator_vs_ocp_work(struct work_struct *work)
= container_of(dwork, struct qpnp_regulator, ocp_work);
qpnp_regulator_vs_clear_ocp(vreg);
-
- return;
}
static irqreturn_t qpnp_regulator_vs_ocp_isr(int irq, void *data)
@@ -1418,8 +1416,7 @@ static void qpnp_vreg_show_state(struct regulator_dev *rdev,
pc_mode_label[5] =
mode_reg & QPNP_COMMON_MODE_FOLLOW_HW_EN0_MASK ? '0' : '_';
- pr_info("%s %-11s: %s, v=%7d uV, mode=%s, pc_en=%s, "
- "alt_mode=%s\n",
+ pr_info("%s %-11s: %s, v=%7d uV, mode=%s, pc_en=%s, alt_mode=%s\n",
action_label, vreg->rdesc.name, enable_label, uV,
mode_label, pc_enable_label, pc_mode_label);
break;
@@ -1440,8 +1437,7 @@ static void qpnp_vreg_show_state(struct regulator_dev *rdev,
pc_mode_label[6] =
mode_reg & QPNP_COMMON_MODE_FOLLOW_HW_EN0_MASK ? '0' : '_';
- pr_info("%s %-11s: %s, v=%7d uV, mode=%s, pc_en=%s, "
- "alt_mode=%s\n",
+ pr_info("%s %-11s: %s, v=%7d uV, mode=%s, pc_en=%s, alt_mode=%s\n",
action_label, vreg->rdesc.name, enable_label, uV,
mode_label, pc_enable_label, pc_mode_label);
break;
@@ -2165,7 +2161,7 @@ static int qpnp_regulator_get_dt_config(struct platform_device *pdev,
return rc;
}
-static struct of_device_id spmi_match_table[];
+static const struct of_device_id spmi_match_table[];
#define MAX_NAME_LEN 127
@@ -2256,8 +2252,6 @@ static int qpnp_regulator_probe(struct platform_device *pdev)
reg_name = kzalloc(strnlen(pdata->init_data.constraints.name,
MAX_NAME_LEN) + 1, GFP_KERNEL);
if (!reg_name) {
- dev_err(&pdev->dev, "%s: Can't allocate regulator name\n",
- __func__);
kfree(vreg);
return -ENOMEM;
}
@@ -2362,7 +2356,7 @@ static int qpnp_regulator_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id spmi_match_table[] = {
+static const struct of_device_id spmi_match_table[] = {
{ .compatible = QPNP_REGULATOR_DRIVER_NAME, },
{}
};
@@ -2422,8 +2416,7 @@ int __init qpnp_regulator_init(void)
if (has_registered)
return 0;
- else
- has_registered = true;
+ has_registered = true;
qpnp_regulator_set_point_init();
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index ef3ff5e16e86..50ca3c33f942 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1592,13 +1592,13 @@ config RTC_DRV_MOXART
will be called rtc-moxart
config RTC_DRV_QPNP
- tristate "Qualcomm QPNP PMIC RTC"
- depends on SPMI && OF_SPMI && MSM_QPNP_INT
+ tristate "Qualcomm Technologies, Inc. QPNP PMIC RTC"
+ depends on SPMI
help
- Say Y here if you want to support the Qualcomm QPNP PMIC RTC.
-
- To compile this driver as a module, choose M here: the
- module will be called qpnp-rtc.
+ This enables support for the RTC found on Qualcomm Technologies, Inc.
+ QPNP PMIC chips. This driver supports using the PMIC RTC peripheral
+ to wake a mobile device up from suspend or to wake it up from power-
+ off.
config RTC_DRV_MT6397
tristate "Mediatek Real Time Clock driver"
@@ -1610,15 +1610,6 @@ config RTC_DRV_MT6397
If you want to use Mediatek(R) RTC interface, select Y or M here.
-config RTC_DRV_QPNP
- tristate "Qualcomm QPNP PMIC RTC"
- depends on SPMI
- help
- Say Y here if you want to support the Qualcomm QPNP PMIC RTC.
-
- To compile this driver as a module, choose M here: the
- module will be called qpnp-rtc.
-
config RTC_DRV_XGENE
tristate "APM X-Gene RTC"
depends on HAS_IOMEM
diff --git a/drivers/rtc/qpnp-rtc.c b/drivers/rtc/qpnp-rtc.c
index 1b74b94796ba..a2c004e0f7fd 100644
--- a/drivers/rtc/qpnp-rtc.c
+++ b/drivers/rtc/qpnp-rtc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, 2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -50,9 +50,9 @@
/* Module parameter to control power-on-alarm */
bool poweron_alarm;
+EXPORT_SYMBOL(poweron_alarm);
module_param(poweron_alarm, bool, 0644);
MODULE_PARM_DESC(poweron_alarm, "Enable/Disable power-on alarm");
-EXPORT_SYMBOL(poweron_alarm);
/* rtc driver internal structure */
struct qpnp_rtc {
@@ -138,7 +138,7 @@ qpnp_rtc_set_time(struct device *dev, struct rtc_time *tm)
* | BYTE[3] | BYTE[2] | BYTE[1] | BYTE[0] |
* ----------------------------------------------
*
- * RTC has four 8 bit registers for writting time in seconds:
+ * RTC has four 8 bit registers for writing time in seconds:
* WDATA[3], WDATA[2], WDATA[1], WDATA[0]
*
* Write to the RTC registers should be done in following order
@@ -149,7 +149,7 @@ qpnp_rtc_set_time(struct device *dev, struct rtc_time *tm)
*
* Write BYTE[0] of time to RTC WDATA[0] register
*
- * Clearing BYTE[0] and writting in the end will prevent any
+ * Clearing BYTE[0] and writing in the end will prevent any
* unintentional overflow from WDATA[0] to higher bytes during the
* write operation
*/
@@ -162,9 +162,8 @@ qpnp_rtc_set_time(struct device *dev, struct rtc_time *tm)
rc = qpnp_write_wrapper(rtc_dd, &rtc_ctrl_reg,
rtc_dd->rtc_base + REG_OFFSET_RTC_CTRL, 1);
if (rc) {
- dev_err(dev,
- "Disabling of RTC control reg failed"
- " with error:%d\n", rc);
+ dev_err(dev, "Disabling of RTC control reg failed with error:%d\n",
+ rc);
goto rtc_rw_fail;
}
rtc_dd->rtc_ctrl_reg = rtc_ctrl_reg;
@@ -201,9 +200,8 @@ qpnp_rtc_set_time(struct device *dev, struct rtc_time *tm)
rc = qpnp_write_wrapper(rtc_dd, &rtc_ctrl_reg,
rtc_dd->rtc_base + REG_OFFSET_RTC_CTRL, 1);
if (rc) {
- dev_err(dev,
- "Enabling of RTC control reg failed"
- " with error:%d\n", rc);
+ dev_err(dev, "Enabling of RTC control reg failed with error:%d\n",
+ rc);
goto rtc_rw_fail;
}
rtc_dd->rtc_ctrl_reg = rtc_ctrl_reg;
@@ -417,11 +415,19 @@ rtc_rw_fail:
return rc;
}
-static struct rtc_class_ops qpnp_rtc_ops = {
+static const struct rtc_class_ops qpnp_rtc_ro_ops = {
+ .read_time = qpnp_rtc_read_time,
+ .set_alarm = qpnp_rtc_set_alarm,
+ .read_alarm = qpnp_rtc_read_alarm,
+ .alarm_irq_enable = qpnp_rtc_alarm_irq_enable,
+};
+
+static const struct rtc_class_ops qpnp_rtc_rw_ops = {
.read_time = qpnp_rtc_read_time,
.set_alarm = qpnp_rtc_set_alarm,
.read_alarm = qpnp_rtc_read_alarm,
.alarm_irq_enable = qpnp_rtc_alarm_irq_enable,
+ .set_time = qpnp_rtc_set_time,
};
static irqreturn_t qpnp_alarm_trigger(int irq, void *dev_id)
@@ -465,6 +471,7 @@ rtc_alarm_handled:
static int qpnp_rtc_probe(struct platform_device *pdev)
{
+ const struct rtc_class_ops *rtc_ops = &qpnp_rtc_ro_ops;
int rc;
u8 subtype;
struct qpnp_rtc *rtc_dd;
@@ -578,13 +585,13 @@ static int qpnp_rtc_probe(struct platform_device *pdev)
}
if (rtc_dd->rtc_write_enable == true)
- qpnp_rtc_ops.set_time = qpnp_rtc_set_time;
+ rtc_ops = &qpnp_rtc_rw_ops;
dev_set_drvdata(&pdev->dev, rtc_dd);
/* Register the RTC device */
rtc_dd->rtc = rtc_device_register("qpnp_rtc", &pdev->dev,
- &qpnp_rtc_ops, THIS_MODULE);
+ rtc_ops, THIS_MODULE);
if (IS_ERR(rtc_dd->rtc)) {
dev_err(&pdev->dev, "%s: RTC registration failed (%ld)\n",
__func__, PTR_ERR(rtc_dd->rtc));
@@ -676,7 +683,7 @@ fail_alarm_disable:
}
}
-static struct of_device_id spmi_match_table[] = {
+static const struct of_device_id spmi_match_table[] = {
{
.compatible = "qcom,qpnp-rtc",
},
@@ -707,4 +714,4 @@ static void __exit qpnp_rtc_exit(void)
module_exit(qpnp_rtc_exit);
MODULE_DESCRIPTION("SMPI PMIC RTC driver");
-MODULE_LICENSE("GPL V2");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 4a315d8f5534..1e5970b31404 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -37,12 +37,14 @@ config MSM_SMEM
inter-processor communication.
config QPNP_HAPTIC
- tristate "Haptic support for QPNP PMIC"
+ tristate "Haptic support for QPNP PMIC"
depends on ARCH_QCOM
- help
- This option enables device driver support for the Haptic
- on the Qualcomm Technologies' QPNP PMICs. It uses the android
- timed-output framework.
+ help
+ This option enables device driver support for the haptic peripheral
+ found on Qualcomm Technologies, Inc. QPNP PMICs. The haptic
+ peripheral is capable of driving both LRA and ERM vibrators. This
+ module provides haptic feedback for user actions such as a long press
+ on the touch screen. It uses the Android timed-output framework.
config MSM_SMD
depends on MSM_SMEM
diff --git a/drivers/soc/qcom/glink_smem_native_xprt.c b/drivers/soc/qcom/glink_smem_native_xprt.c
index f2d2aece6846..14cf10b92122 100644
--- a/drivers/soc/qcom/glink_smem_native_xprt.c
+++ b/drivers/soc/qcom/glink_smem_native_xprt.c
@@ -678,10 +678,15 @@ static void process_rx_data(struct edge_info *einfo, uint16_t cmd_id,
} else if (intent->data == NULL) {
if (einfo->intentless) {
intent->data = kmalloc(cmd.frag_size, GFP_ATOMIC);
- if (!intent->data)
+ if (!intent->data) {
err = true;
- else
+ GLINK_ERR(
+ "%s: atomic alloc fail ch %d liid %d size %d\n",
+ __func__, rcid, intent_id,
+ cmd.frag_size);
+ } else {
intent->intent_size = cmd.frag_size;
+ }
} else {
GLINK_ERR(
"%s: intent for ch %d liid %d has no data buff\n",
diff --git a/drivers/soc/qcom/glink_ssr.c b/drivers/soc/qcom/glink_ssr.c
index 4d94e6446505..5e2dbc8b1d20 100644
--- a/drivers/soc/qcom/glink_ssr.c
+++ b/drivers/soc/qcom/glink_ssr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -339,6 +339,7 @@ void close_ch_worker(struct work_struct *work)
BUG_ON(!ss_info->cb_data);
kfree(ss_info->cb_data);
+ ss_info->cb_data = NULL;
kfree(close_work);
}
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index 16ee98d8e4e0..7c08c28aeda8 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -1724,19 +1724,21 @@ static int icnss_call_driver_probe(struct icnss_priv *priv)
out:
icnss_hw_power_off(priv);
- penv->ops = NULL;
return ret;
}
-static int icnss_call_driver_reinit(struct icnss_priv *priv)
+static int icnss_pd_restart_complete(struct icnss_priv *priv)
{
- int ret = 0;
+ int ret;
+
+ clear_bit(ICNSS_PD_RESTART, &priv->state);
+ icnss_pm_relax(priv);
if (!priv->ops || !priv->ops->reinit)
goto out;
if (!test_bit(ICNSS_DRIVER_PROBED, &penv->state))
- goto out;
+ goto call_probe;
icnss_pr_dbg("Calling driver reinit state: 0x%lx\n", priv->state);
@@ -1751,18 +1753,14 @@ static int icnss_call_driver_reinit(struct icnss_priv *priv)
}
out:
- clear_bit(ICNSS_PD_RESTART, &priv->state);
-
- icnss_pm_relax(priv);
-
return 0;
+call_probe:
+ return icnss_call_driver_probe(priv);
+
out_power_off:
icnss_hw_power_off(priv);
- clear_bit(ICNSS_PD_RESTART, &priv->state);
-
- icnss_pm_relax(priv);
return ret;
}
@@ -1787,7 +1785,7 @@ static int icnss_driver_event_fw_ready_ind(void *data)
}
if (test_bit(ICNSS_PD_RESTART, &penv->state))
- ret = icnss_call_driver_reinit(penv);
+ ret = icnss_pd_restart_complete(penv);
else
ret = icnss_call_driver_probe(penv);
diff --git a/drivers/soc/qcom/peripheral-loader.c b/drivers/soc/qcom/peripheral-loader.c
index eaeb8d4776fe..2244c64d28af 100644
--- a/drivers/soc/qcom/peripheral-loader.c
+++ b/drivers/soc/qcom/peripheral-loader.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -171,7 +171,11 @@ int pil_do_ramdump(struct pil_desc *desc, void *ramdump_dev)
ret = do_elf_ramdump(ramdump_dev, ramdump_segs, count);
kfree(ramdump_segs);
- if (!ret && desc->subsys_vmid > 0)
+ if (ret)
+ pil_err(desc, "%s: Ramdump collection failed for subsys %s rc:%d\n",
+ __func__, desc->name, ret);
+
+ if (desc->subsys_vmid > 0)
ret = pil_assign_mem_to_subsys(desc, priv->region_start,
(priv->region_end - priv->region_start));
diff --git a/drivers/soc/qcom/qdsp6v2/apr_tal_glink.c b/drivers/soc/qcom/qdsp6v2/apr_tal_glink.c
index 45ac48eb2241..19974b61ec1c 100644
--- a/drivers/soc/qcom/qdsp6v2/apr_tal_glink.c
+++ b/drivers/soc/qcom/qdsp6v2/apr_tal_glink.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016 The Linux Foundation.
+/* Copyright (c) 2016-2017 The Linux Foundation.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -17,7 +17,6 @@
#include <linux/uaccess.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
-#include <linux/list.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/errno.h>
@@ -34,16 +33,10 @@
#define APR_MAXIMUM_NUM_OF_RETRIES 2
struct apr_tx_buf {
- struct list_head list;
struct apr_pkt_priv pkt_priv;
char buf[APR_MAX_BUF];
};
-struct apr_buf_list {
- struct list_head list;
- spinlock_t lock;
-};
-
struct link_state {
uint32_t dest;
void *handle;
@@ -52,7 +45,6 @@ struct link_state {
};
static struct link_state link_state[APR_DEST_MAX];
-static struct apr_buf_list buf_list;
static char *svc_names[APR_DEST_MAX][APR_CLIENT_MAX] = {
{
@@ -68,44 +60,37 @@ static char *svc_names[APR_DEST_MAX][APR_CLIENT_MAX] = {
static struct apr_svc_ch_dev
apr_svc_ch[APR_DL_MAX][APR_DEST_MAX][APR_CLIENT_MAX];
-static struct apr_tx_buf *apr_get_free_buf(int len)
+static struct apr_tx_buf *apr_alloc_buf(int len)
{
- struct apr_tx_buf *tx_buf;
- unsigned long flags;
if (len > APR_MAX_BUF) {
pr_err("%s: buf too large [%d]\n", __func__, len);
return ERR_PTR(-EINVAL);
}
- spin_lock_irqsave(&buf_list.lock, flags);
- if (list_empty(&buf_list.list)) {
- spin_unlock_irqrestore(&buf_list.lock, flags);
- pr_err("%s: No buf available\n", __func__);
- return ERR_PTR(-ENOMEM);
- }
-
- tx_buf = list_first_entry(&buf_list.list, struct apr_tx_buf, list);
- list_del(&tx_buf->list);
- spin_unlock_irqrestore(&buf_list.lock, flags);
-
- return tx_buf;
+ return kzalloc(sizeof(struct apr_tx_buf), GFP_ATOMIC);
}
-static void apr_buf_add_tail(const void *buf)
+static void apr_free_buf(const void *ptr)
{
- struct apr_tx_buf *list;
- unsigned long flags;
- if (!buf)
+ struct apr_pkt_priv *apr_pkt_priv = (struct apr_pkt_priv *)ptr;
+ struct apr_tx_buf *tx_buf;
+
+ if (!apr_pkt_priv) {
+ pr_err("%s: Invalid apr_pkt_priv\n", __func__);
return;
+ }
- spin_lock_irqsave(&buf_list.lock, flags);
- list = container_of((void *)buf, struct apr_tx_buf, buf);
- list_add_tail(&list->list, &buf_list.list);
- spin_unlock_irqrestore(&buf_list.lock, flags);
+ if (apr_pkt_priv->pkt_owner == APR_PKT_OWNER_DRIVER) {
+ tx_buf = container_of((void *)apr_pkt_priv,
+ struct apr_tx_buf, pkt_priv);
+ pr_debug("%s: Freeing buffer %pK", __func__, tx_buf);
+ kfree(tx_buf);
+ }
}
+
static int __apr_tal_write(struct apr_svc_ch_dev *apr_ch, void *data,
struct apr_pkt_priv *pkt_priv, int len)
{
@@ -137,7 +122,7 @@ int apr_tal_write(struct apr_svc_ch_dev *apr_ch, void *data,
return -EINVAL;
if (pkt_priv->pkt_owner == APR_PKT_OWNER_DRIVER) {
- tx_buf = apr_get_free_buf(len);
+ tx_buf = apr_alloc_buf(len);
if (IS_ERR_OR_NULL(tx_buf)) {
rc = -EINVAL;
goto exit;
@@ -160,7 +145,7 @@ int apr_tal_write(struct apr_svc_ch_dev *apr_ch, void *data,
if (rc < 0) {
pr_err("%s: Unable to send the packet, rc:%d\n", __func__, rc);
if (pkt_priv->pkt_owner == APR_PKT_OWNER_DRIVER)
- apr_buf_add_tail(pkt_data);
+ kfree(tx_buf);
}
exit:
return rc;
@@ -189,39 +174,17 @@ void apr_tal_notify_rx(void *handle, const void *priv, const void *pkt_priv,
static void apr_tal_notify_tx_abort(void *handle, const void *priv,
const void *pkt_priv)
{
- struct apr_pkt_priv *apr_pkt_priv_ptr =
- (struct apr_pkt_priv *)pkt_priv;
- struct apr_tx_buf *list_node;
-
- if (!apr_pkt_priv_ptr) {
- pr_err("%s: Invalid pkt_priv\n", __func__);
- return;
- }
-
- pr_debug("%s: tx_abort received for apr_pkt_priv_ptr:%pK\n",
- __func__, apr_pkt_priv_ptr);
-
- if (apr_pkt_priv_ptr->pkt_owner == APR_PKT_OWNER_DRIVER) {
- list_node = container_of(apr_pkt_priv_ptr,
- struct apr_tx_buf, pkt_priv);
- apr_buf_add_tail(list_node->buf);
- }
+ pr_debug("%s: tx_abort received for pkt_priv:%pK\n",
+ __func__, pkt_priv);
+ apr_free_buf(pkt_priv);
}
void apr_tal_notify_tx_done(void *handle, const void *priv,
const void *pkt_priv, const void *ptr)
{
- struct apr_pkt_priv *apr_pkt_priv = (struct apr_pkt_priv *)pkt_priv;
-
- if (!pkt_priv || !ptr) {
- pr_err("%s: Invalid pkt_priv or ptr\n", __func__);
- return;
- }
-
- pr_debug("%s: tx_done received\n", __func__);
-
- if (apr_pkt_priv->pkt_owner == APR_PKT_OWNER_DRIVER)
- apr_buf_add_tail(ptr);
+ pr_debug("%s: tx_done received for pkt_priv:%pK\n",
+ __func__, pkt_priv);
+ apr_free_buf(pkt_priv);
}
bool apr_tal_notify_rx_intent_req(void *handle, const void *priv,
@@ -457,8 +420,6 @@ static struct glink_link_info lpass_link_info = {
static int __init apr_tal_init(void)
{
int i, j, k;
- struct apr_tx_buf *buf;
- struct list_head *ptr, *next;
for (i = 0; i < APR_DL_MAX; i++) {
for (j = 0; j < APR_DEST_MAX; j++) {
@@ -474,21 +435,6 @@ static int __init apr_tal_init(void)
for (i = 0; i < APR_DEST_MAX; i++)
init_waitqueue_head(&link_state[i].wait);
- spin_lock_init(&buf_list.lock);
- INIT_LIST_HEAD(&buf_list.list);
- for (i = 0; i < APR_NUM_OF_TX_BUF; i++) {
- buf = kzalloc(sizeof(struct apr_tx_buf), GFP_KERNEL);
- if (!buf) {
- pr_err("%s: Unable to allocate tx buf\n", __func__);
- goto tx_buf_alloc_fail;
- }
-
- INIT_LIST_HEAD(&buf->list);
- spin_lock(&buf_list.lock);
- list_add_tail(&buf->list, &buf_list.list);
- spin_unlock(&buf_list.lock);
- }
-
link_state[APR_DEST_MODEM].link_state = GLINK_LINK_STATE_DOWN;
link_state[APR_DEST_MODEM].handle =
glink_register_link_state_cb(&mpss_link_info, NULL);
@@ -502,13 +448,5 @@ static int __init apr_tal_init(void)
pr_err("%s: Unable to register lpass link state\n", __func__);
return 0;
-
-tx_buf_alloc_fail:
- list_for_each_safe(ptr, next, &buf_list.list) {
- buf = list_entry(ptr, struct apr_tx_buf, list);
- list_del(&buf->list);
- kfree(buf);
- }
- return -ENOMEM;
}
device_initcall(apr_tal_init);
diff --git a/drivers/soc/qcom/qpnp-haptic.c b/drivers/soc/qcom/qpnp-haptic.c
index 21387568fe53..39070561d7e4 100644
--- a/drivers/soc/qcom/qpnp-haptic.c
+++ b/drivers/soc/qcom/qpnp-haptic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, 2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -918,15 +918,16 @@ static ssize_t qpnp_hap_wf_samp_store(struct device *dev,
struct timed_output_dev *timed_dev = dev_get_drvdata(dev);
struct qpnp_hap *hap = container_of(timed_dev, struct qpnp_hap,
timed_dev);
- int data;
+ int data, rc;
if (index < 0 || index >= QPNP_HAP_WAV_SAMP_LEN) {
dev_err(dev, "Invalid sample index(%d)\n", index);
return -EINVAL;
}
- if (sscanf(buf, "%x", &data) != 1)
- return -EINVAL;
+ rc = kstrtoint(buf, 16, &data);
+ if (rc)
+ return rc;
if (data < 0 || data > 0xff) {
dev_err(dev, "Invalid sample wf_%d (%d)\n", index, data);
@@ -1032,8 +1033,9 @@ static ssize_t qpnp_hap_wf_rep_store(struct device *dev,
int data, rc, temp;
u8 reg;
- if (sscanf(buf, "%d", &data) != 1)
- return -EINVAL;
+ rc = kstrtoint(buf, 10, &data);
+ if (rc)
+ return rc;
if (data < QPNP_HAP_WAV_REP_MIN)
data = QPNP_HAP_WAV_REP_MIN;
@@ -1078,8 +1080,9 @@ static ssize_t qpnp_hap_wf_s_rep_store(struct device *dev,
int data, rc, temp;
u8 reg;
- if (sscanf(buf, "%d", &data) != 1)
- return -EINVAL;
+ rc = kstrtoint(buf, 10, &data);
+ if (rc)
+ return rc;
if (data < QPNP_HAP_WAV_S_REP_MIN)
data = QPNP_HAP_WAV_S_REP_MIN;
@@ -1290,51 +1293,25 @@ static ssize_t qpnp_hap_ramp_test_data_show(struct device *dev,
/* sysfs attributes */
static struct device_attribute qpnp_hap_attrs[] = {
- __ATTR(wf_s0, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_hap_wf_s0_show,
- qpnp_hap_wf_s0_store),
- __ATTR(wf_s1, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_hap_wf_s1_show,
- qpnp_hap_wf_s1_store),
- __ATTR(wf_s2, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_hap_wf_s2_show,
- qpnp_hap_wf_s2_store),
- __ATTR(wf_s3, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_hap_wf_s3_show,
- qpnp_hap_wf_s3_store),
- __ATTR(wf_s4, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_hap_wf_s4_show,
- qpnp_hap_wf_s4_store),
- __ATTR(wf_s5, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_hap_wf_s5_show,
- qpnp_hap_wf_s5_store),
- __ATTR(wf_s6, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_hap_wf_s6_show,
- qpnp_hap_wf_s6_store),
- __ATTR(wf_s7, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_hap_wf_s7_show,
- qpnp_hap_wf_s7_store),
- __ATTR(wf_update, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_hap_wf_update_show,
- qpnp_hap_wf_update_store),
- __ATTR(wf_rep, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_hap_wf_rep_show,
- qpnp_hap_wf_rep_store),
- __ATTR(wf_s_rep, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_hap_wf_s_rep_show,
- qpnp_hap_wf_s_rep_store),
- __ATTR(play_mode, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_hap_play_mode_show,
- qpnp_hap_play_mode_store),
- __ATTR(dump_regs, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_hap_dump_regs_show,
- NULL),
- __ATTR(ramp_test, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_hap_ramp_test_data_show,
- qpnp_hap_ramp_test_data_store),
- __ATTR(min_max_test, (S_IRUGO | S_IWUSR | S_IWGRP),
- qpnp_hap_min_max_test_data_show,
- qpnp_hap_min_max_test_data_store),
+ __ATTR(wf_s0, 0664, qpnp_hap_wf_s0_show, qpnp_hap_wf_s0_store),
+ __ATTR(wf_s1, 0664, qpnp_hap_wf_s1_show, qpnp_hap_wf_s1_store),
+ __ATTR(wf_s2, 0664, qpnp_hap_wf_s2_show, qpnp_hap_wf_s2_store),
+ __ATTR(wf_s3, 0664, qpnp_hap_wf_s3_show, qpnp_hap_wf_s3_store),
+ __ATTR(wf_s4, 0664, qpnp_hap_wf_s4_show, qpnp_hap_wf_s4_store),
+ __ATTR(wf_s5, 0664, qpnp_hap_wf_s5_show, qpnp_hap_wf_s5_store),
+ __ATTR(wf_s6, 0664, qpnp_hap_wf_s6_show, qpnp_hap_wf_s6_store),
+ __ATTR(wf_s7, 0664, qpnp_hap_wf_s7_show, qpnp_hap_wf_s7_store),
+ __ATTR(wf_update, 0664, qpnp_hap_wf_update_show,
+ qpnp_hap_wf_update_store),
+ __ATTR(wf_rep, 0664, qpnp_hap_wf_rep_show, qpnp_hap_wf_rep_store),
+ __ATTR(wf_s_rep, 0664, qpnp_hap_wf_s_rep_show, qpnp_hap_wf_s_rep_store),
+ __ATTR(play_mode, 0664, qpnp_hap_play_mode_show,
+ qpnp_hap_play_mode_store),
+ __ATTR(dump_regs, 0664, qpnp_hap_dump_regs_show, NULL),
+ __ATTR(ramp_test, 0664, qpnp_hap_ramp_test_data_show,
+ qpnp_hap_ramp_test_data_store),
+ __ATTR(min_max_test, 0664, qpnp_hap_min_max_test_data_show,
+ qpnp_hap_min_max_test_data_store),
};
static void calculate_lra_code(struct qpnp_hap *hap)
@@ -1420,13 +1397,13 @@ static enum hrtimer_restart detect_auto_res_error(struct hrtimer *timer)
if (val & AUTO_RES_ERR_BIT) {
schedule_work(&hap->auto_res_err_work);
return HRTIMER_NORESTART;
- } else {
- update_lra_frequency(hap);
- currtime = ktime_get();
- hrtimer_forward(&hap->auto_res_err_poll_timer, currtime,
- ktime_set(0, POLL_TIME_AUTO_RES_ERR_NS));
- return HRTIMER_RESTART;
}
+
+ update_lra_frequency(hap);
+ currtime = ktime_get();
+ hrtimer_forward(&hap->auto_res_err_poll_timer, currtime,
+ ktime_set(0, POLL_TIME_AUTO_RES_ERR_NS));
+ return HRTIMER_RESTART;
}
static void correct_auto_res_error(struct work_struct *auto_res_err_work)
@@ -1595,19 +1572,23 @@ int qpnp_hap_play_byte(u8 data, bool on)
return rc;
if (!on) {
- /* set the pwm back to original duty for normal operations */
- /* this is not required if standard interface is not used */
+ /*
+ * Set the pwm back to original duty for normal operations.
+ * This is not required if standard interface is not used.
+ */
rc = pwm_config(hap->pwm_info.pwm_dev,
hap->pwm_info.duty_us * NSEC_PER_USEC,
hap->pwm_info.period_us * NSEC_PER_USEC);
return rc;
}
- /* pwm values range from 0x00 to 0xff. The range from 0x00 to 0x7f
- provides a postive amplitude in the sin wave form for 0 to 100%.
- The range from 0x80 to 0xff provides a negative amplitude in the
- sin wave form for 0 to 100%. Here the duty percentage is calculated
- based on the incoming data to accommodate this. */
+ /*
+ * pwm values range from 0x00 to 0xff. The range from 0x00 to 0x7f
+ * provides a postive amplitude in the sin wave form for 0 to 100%.
+ * The range from 0x80 to 0xff provides a negative amplitude in the
+ * sin wave form for 0 to 100%. Here the duty percentage is calculated
+ * based on the incoming data to accommodate this.
+ */
if (data <= QPNP_HAP_EXT_PWM_PEAK_DATA)
duty_percent = QPNP_HAP_EXT_PWM_HALF_DUTY +
((data * QPNP_HAP_EXT_PWM_DATA_FACTOR) / 100);
@@ -1675,6 +1656,7 @@ static int qpnp_hap_get_time(struct timed_output_dev *dev)
if (hrtimer_active(&hap->hap_timer)) {
ktime_t r = hrtimer_get_remaining(&hap->hap_timer);
+
return (int)ktime_to_us(r);
} else {
return 0;
@@ -1709,6 +1691,7 @@ static enum hrtimer_restart qpnp_hap_test_timer(struct hrtimer *timer)
static int qpnp_haptic_suspend(struct device *dev)
{
struct qpnp_hap *hap = dev_get_drvdata(dev);
+
hrtimer_cancel(&hap->hap_timer);
cancel_work_sync(&hap->work);
/* turn-off haptic */
@@ -1845,9 +1828,11 @@ static int qpnp_hap_config(struct qpnp_hap *hap)
if (rc)
return rc;
- /* Configure RATE_CFG1 and RATE_CFG2 registers */
- /* Note: For ERM these registers act as play rate and
- for LRA these represent resonance period */
+ /*
+ * Configure RATE_CFG1 and RATE_CFG2 registers.
+ * Note: For ERM these registers act as play rate and
+ * for LRA these represent resonance period
+ */
if (hap->wave_play_rate_us < QPNP_HAP_WAV_PLAY_RATE_US_MIN)
hap->wave_play_rate_us = QPNP_HAP_WAV_PLAY_RATE_US_MIN;
else if (hap->wave_play_rate_us > QPNP_HAP_WAV_PLAY_RATE_US_MAX)
@@ -2314,7 +2299,7 @@ static int qpnp_haptic_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id spmi_match_table[] = {
+static const struct of_device_id spmi_match_table[] = {
{ .compatible = "qcom,qpnp-haptic", },
{ },
};
diff --git a/drivers/soc/qcom/spcom.c b/drivers/soc/qcom/spcom.c
index 9b71083e4f27..d91daa6a3456 100644
--- a/drivers/soc/qcom/spcom.c
+++ b/drivers/soc/qcom/spcom.c
@@ -316,6 +316,10 @@ static int spcom_create_predefined_channels_chardev(void)
{
int i;
int ret;
+ static bool is_predefined_created;
+
+ if (is_predefined_created)
+ return 0;
for (i = 0; i < SPCOM_MAX_CHANNELS; i++) {
const char *name = spcom_dev->predefined_ch_name[i];
@@ -330,6 +334,8 @@ static int spcom_create_predefined_channels_chardev(void)
}
}
+ is_predefined_created = true;
+
return 0;
}
@@ -1633,12 +1639,13 @@ static int spcom_handle_lock_ion_buf_command(struct spcom_channel *ch,
pr_err("fail to get ion handle.\n");
return -EINVAL;
}
+
pr_debug("ion handle ok.\n");
/* Check if this ION buffer is already locked */
for (i = 0 ; i < ARRAY_SIZE(ch->ion_handle_table) ; i++) {
if (ch->ion_handle_table[i] == ion_handle) {
- pr_debug("fd [%d] ion buf is already locked.\n", fd);
+ pr_err("fd [%d] ion buf is already locked.\n", fd);
/* decrement back the ref count */
ion_free(spcom_dev->ion_client, ion_handle);
return -EINVAL;
@@ -1650,11 +1657,14 @@ static int spcom_handle_lock_ion_buf_command(struct spcom_channel *ch,
if (ch->ion_handle_table[i] == NULL) {
ch->ion_handle_table[i] = ion_handle;
ch->ion_fd_table[i] = fd;
- pr_debug("locked ion buf#[%d], fd [%d].\n", i, fd);
+ pr_debug("ch [%s] locked ion buf #%d, fd [%d].\n",
+ ch->name, i, fd);
return 0;
}
}
+ pr_err("fd [%d] ion buf not found.\n", fd);
+
return -EFAULT;
}
@@ -1684,20 +1694,22 @@ static int spcom_unlock_ion_buf(struct spcom_channel *ch, int fd)
/* unlock all ION buf */
for (i = 0 ; i < ARRAY_SIZE(ch->ion_handle_table) ; i++) {
if (ch->ion_handle_table[i] != NULL) {
+ pr_debug("unlocked ion buf #%d fd [%d].\n",
+ i, ch->ion_fd_table[i]);
ion_free(ion_client, ch->ion_handle_table[i]);
ch->ion_handle_table[i] = NULL;
ch->ion_fd_table[i] = -1;
- pr_debug("unlocked ion buf#[%d].\n", i);
}
}
} else {
/* unlock specific ION buf */
for (i = 0 ; i < ARRAY_SIZE(ch->ion_handle_table) ; i++) {
if (ch->ion_fd_table[i] == fd) {
+ pr_debug("unlocked ion buf #%d fd [%d].\n",
+ i, ch->ion_fd_table[i]);
ion_free(ion_client, ch->ion_handle_table[i]);
ch->ion_handle_table[i] = NULL;
ch->ion_fd_table[i] = -1;
- pr_debug("unlocked ion buf#[%d].\n", i);
found = true;
break;
}
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index b8360383a6d2..aa122340c717 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -406,19 +406,18 @@ config INTEL_PCH_THERMAL
programmable trip points and other information.
config THERMAL_QPNP
- tristate "Qualcomm Plug-and-Play PMIC Temperature Alarm"
- depends on THERMAL
- depends on OF
- depends on SPMI
- help
- This enables a thermal Sysfs driver for Qualcomm plug-and-play (QPNP)
- PMIC devices. It shows up in Sysfs as a thermal zone with multiple
- trip points. The temperature reported by the thermal zone reflects the
- real time die temperature if an ADC is present or an estimate of the
- temperature based upon the over temperature stage value if no ADC is
- available. If allowed via compile time configuration; enabling the
- thermal zone device via the mode file results in shifting PMIC over
- temperature shutdown control from hardware to software.
+ tristate "Qualcomm Technologies, Inc. QPNP PMIC Temperature Alarm"
+ depends on OF && SPMI
+ help
+ This enables a thermal Sysfs driver for Qualcomm Technologies, Inc.
+ QPNP PMIC devices. It shows up in Sysfs as a thermal zone with
+ multiple trip points. The temperature reported by the thermal zone
+ reflects the real time die temperature if an ADC is present or an
+ estimate of the temperature based upon the over temperature stage
+ value if no ADC is available. If allowed via compile time
+ configuration; enabling the thermal zone device via the mode file
+ results in shifting PMIC over temperature shutdown control from
+ hardware to software.
config THERMAL_QPNP_ADC_TM
tristate "Qualcomm 8974 Thermal Monitor ADC Driver"
diff --git a/drivers/thermal/msm-tsens.c b/drivers/thermal/msm-tsens.c
index 82a8e4e200ba..d59b9736c570 100644
--- a/drivers/thermal/msm-tsens.c
+++ b/drivers/thermal/msm-tsens.c
@@ -364,6 +364,7 @@ static int32_t get_tsens_sensor_for_client_id(struct tsens_tm_device *tmdev,
if (!strcmp(id->compatible, "qcom,msm8996-tsens") ||
(!strcmp(id->compatible, "qcom,msm8998-tsens")) ||
(!strcmp(id->compatible, "qcom,sdm660-tsens")) ||
+ (!strcmp(id->compatible, "qcom,sdm630-tsens")) ||
(!strcmp(id->compatible, "qcom,msmhamster-tsens"))) {
while (i < tmdev->tsens_num_sensor && !id_found) {
if (tmdev->sensor[i].sensor_client_id ==
@@ -494,6 +495,7 @@ int tsens_get_hw_id_mapping(int thermal_sensor_num, int *sensor_client_id)
if (!strcmp(id->compatible, "qcom,msm8996-tsens") ||
(!strcmp(id->compatible, "qcom,msm8998-tsens")) ||
(!strcmp(id->compatible, "qcom,sdm660-tsens")) ||
+ (!strcmp(id->compatible, "qcom,sdm630-tsens")) ||
(!strcmp(id->compatible, "qcom,msmhamster-tsens"))) {
/* Assign client id's that is used to get the
* controller and hw_sensor details
diff --git a/drivers/thermal/msm_lmh_dcvs.c b/drivers/thermal/msm_lmh_dcvs.c
index 7758750516f8..4ebfc713cb28 100644
--- a/drivers/thermal/msm_lmh_dcvs.c
+++ b/drivers/thermal/msm_lmh_dcvs.c
@@ -68,6 +68,8 @@
_max = (_val) & 0x3FF; \
_max *= 19200; \
} while (0)
+#define FREQ_KHZ_TO_HZ(_val) ((_val) * 1000)
+#define FREQ_HZ_TO_KHZ(_val) ((_val) / 1000)
enum lmh_hw_trips {
LIMITS_TRIP_LO,
@@ -114,6 +116,7 @@ static uint32_t msm_lmh_mitigation_notify(struct msm_lmh_dcvs_hw *hw)
uint32_t max_limit = 0, val = 0;
struct device *cpu_dev = NULL;
unsigned long freq_val;
+ struct dev_pm_opp *opp_entry;
val = readl_relaxed(hw->osm_hw_reg);
dcvsh_get_frequency(val, max_limit);
@@ -124,11 +127,23 @@ static uint32_t msm_lmh_mitigation_notify(struct msm_lmh_dcvs_hw *hw)
goto notify_exit;
}
- freq_val = max_limit;
+ freq_val = FREQ_KHZ_TO_HZ(max_limit);
rcu_read_lock();
- dev_pm_opp_find_freq_floor(cpu_dev, &freq_val);
+ opp_entry = dev_pm_opp_find_freq_floor(cpu_dev, &freq_val);
+ /*
+ * Hardware mitigation frequency can be lower than the lowest
+ * possible CPU frequency. In that case freq floor call will
+ * fail with -ERANGE and we need to match to the lowest
+ * frequency using freq_ceil.
+ */
+ if (IS_ERR(opp_entry) && PTR_ERR(opp_entry) == -ERANGE) {
+ opp_entry = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_val);
+ if (IS_ERR(opp_entry))
+ dev_err(cpu_dev, "frequency:%lu. opp error:%ld\n",
+ freq_val, PTR_ERR(opp_entry));
+ }
rcu_read_unlock();
- max_limit = freq_val;
+ max_limit = FREQ_HZ_TO_KHZ(freq_val);
sched_update_cpu_freq_min_max(&hw->core_map, 0, max_limit);
trace_lmh_dcvs_freq(cpumask_first(&hw->core_map), max_limit);
diff --git a/drivers/thermal/qpnp-temp-alarm.c b/drivers/thermal/qpnp-temp-alarm.c
index 691c6c16532d..8c516da1d9ab 100644
--- a/drivers/thermal/qpnp-temp-alarm.c
+++ b/drivers/thermal/qpnp-temp-alarm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -773,7 +773,7 @@ static const struct dev_pm_ops qpnp_tm_pm_ops = {
#define QPNP_TM_PM_OPS NULL
#endif
-static struct of_device_id qpnp_tm_match_table[] = {
+static const struct of_device_id qpnp_tm_match_table[] = {
{ .compatible = QPNP_TM_DRIVER_NAME, },
{}
};
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 0e73026711d6..9de5e06430e1 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -1021,6 +1021,8 @@ struct dwc3 {
unsigned irq_event_count[MAX_INTR_STATS];
unsigned irq_dbg_index;
+ unsigned long l1_remote_wakeup_cnt;
+
wait_queue_head_t wait_linkstate;
};
diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c
index 4b4978043d50..068b03a35bd5 100644
--- a/drivers/usb/dwc3/debugfs.c
+++ b/drivers/usb/dwc3/debugfs.c
@@ -1180,9 +1180,12 @@ static int dwc3_gadget_int_events_show(struct seq_file *s, void *unused)
seq_printf(s, "%d\t", dwc->bh_completion_time[i]);
seq_putc(s, '\n');
- seq_printf(s, "t_pwr evt irq : %lld\t",
+ seq_printf(s, "t_pwr evt irq : %lld\n",
ktime_to_us(dwc->t_pwr_evt_irq));
+ seq_printf(s, "l1_remote_wakeup_cnt : %lu\n",
+ dwc->l1_remote_wakeup_cnt);
+
spin_unlock_irqrestore(&dwc->lock, flags);
return 0;
}
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 2b910e09a80a..9cd87513619c 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -236,6 +236,8 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
unsigned long flags;
int ret;
+ enum dwc3_link_state link_state;
+ u32 reg;
spin_lock_irqsave(&dwc->lock, flags);
if (!dep->endpoint.desc) {
@@ -252,6 +254,18 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
goto out;
}
+ /* if link stats is in L1 initiate remote wakeup before queuing req */
+ if (dwc->speed != DWC3_DSTS_SUPERSPEED) {
+ link_state = dwc3_get_link_state(dwc);
+ /* in HS this link state is same as L1 */
+ if (link_state == DWC3_LINK_STATE_U2) {
+ dwc->l1_remote_wakeup_cnt++;
+ reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+ reg |= DWC3_DCTL_ULSTCHNG_RECOVERY;
+ dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+ }
+ }
+
dwc3_trace(trace_dwc3_ep0,
"queueing request %pK to %s length %d state '%s'",
request, dep->name, request->length,
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index e2440b7efc58..88350e61f3bd 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1317,13 +1317,6 @@ static int dwc3_gadget_wakeup(struct usb_gadget *g)
return 0;
}
-static inline enum dwc3_link_state dwc3_get_link_state(struct dwc3 *dwc)
-{
- u32 reg;
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
- return DWC3_DSTS_USBLNKST(reg);
-}
-
static bool dwc3_gadget_is_suspended(struct dwc3 *dwc)
{
if (atomic_read(&dwc->in_lpm) ||
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h
index 3abd6379164e..a21962c8f513 100644
--- a/drivers/usb/dwc3/gadget.h
+++ b/drivers/usb/dwc3/gadget.h
@@ -84,6 +84,14 @@ static inline void dwc3_gadget_move_request_queued(struct dwc3_request *req)
list_move_tail(&req->list, &dep->req_queued);
}
+static inline enum dwc3_link_state dwc3_get_link_state(struct dwc3 *dwc)
+{
+ u32 reg;
+
+ reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+ return DWC3_DSTS_USBLNKST(reg);
+}
+
void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
int status);
diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
index d03678a02185..7f1ae5cf9909 100644
--- a/drivers/usb/dwc3/host.c
+++ b/drivers/usb/dwc3/host.c
@@ -25,6 +25,7 @@ int dwc3_host_init(struct dwc3 *dwc)
struct platform_device *xhci;
struct usb_xhci_pdata pdata;
int ret;
+ struct device_node *node = dwc->dev->of_node;
xhci = platform_device_alloc("xhci-hcd", PLATFORM_DEVID_AUTO);
if (!xhci) {
@@ -52,6 +53,11 @@ int dwc3_host_init(struct dwc3 *dwc)
pdata.usb3_lpm_capable = dwc->usb3_lpm_capable;
+ ret = of_property_read_u32(node, "xhci-imod-value",
+ &pdata.imod_interval);
+ if (ret)
+ pdata.imod_interval = 0; /* use default xhci.c value */
+
ret = platform_device_add_data(xhci, &pdata, sizeof(pdata));
if (ret) {
dev_err(dwc->dev, "couldn't add platform data to xHCI device\n");
diff --git a/drivers/usb/gadget/function/u_data_ipa.c b/drivers/usb/gadget/function/u_data_ipa.c
index 6c18a04f6c1c..83a98f1196f8 100644
--- a/drivers/usb/gadget/function/u_data_ipa.c
+++ b/drivers/usb/gadget/function/u_data_ipa.c
@@ -402,6 +402,7 @@ static void ipa_data_connect_work(struct work_struct *w)
if (!port->port_usb) {
spin_unlock_irqrestore(&port->port_lock, flags);
+ usb_gadget_autopm_put_async(port->gadget);
pr_err("%s(): port_usb is NULL.\n", __func__);
return;
}
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 1221a80e0bdc..05d96fd8c07c 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -138,6 +138,8 @@ static int xhci_plat_probe(struct platform_device *pdev)
struct clk *clk;
int ret;
int irq;
+ u32 temp, imod;
+ unsigned long flags;
if (usb_disabled())
return -ENODEV;
@@ -256,6 +258,18 @@ static int xhci_plat_probe(struct platform_device *pdev)
device_wakeup_enable(&xhci->shared_hcd->self.root_hub->dev);
+ /* override imod interval if specified */
+ if (pdata && pdata->imod_interval) {
+ imod = pdata->imod_interval & ER_IRQ_INTERVAL_MASK;
+ spin_lock_irqsave(&xhci->lock, flags);
+ temp = readl_relaxed(&xhci->ir_set->irq_control);
+ temp &= ~ER_IRQ_INTERVAL_MASK;
+ temp |= imod;
+ writel_relaxed(temp, &xhci->ir_set->irq_control);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ dev_dbg(&pdev->dev, "%s: imod set to %u\n", __func__, imod);
+ }
+
ret = device_create_file(&pdev->dev, &dev_attr_config_imod);
if (ret)
dev_err(&pdev->dev, "%s: unable to create imod sysfs entry\n",
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c
index ed33743c9062..611750e209f9 100644
--- a/drivers/usb/pd/policy_engine.c
+++ b/drivers/usb/pd/policy_engine.c
@@ -243,6 +243,10 @@ static void *usbpd_ipc_log;
#define MAX_VDM_RESPONSE_TIME 60 /* 2 * tVDMSenderResponse_max(30ms) */
#define MAX_VDM_BUSY_TIME 100 /* 2 * tVDMBusy (50ms) */
+#define PD_SNK_PDO_FIXED(prs, hc, uc, usb_comm, drs, volt, curr) \
+ (((prs) << 29) | ((hc) << 28) | ((uc) << 27) | ((usb_comm) << 26) | \
+ ((drs) << 25) | ((volt) << 10) | (curr))
+
/* VDM header is the first 32-bit object following the 16-bit PD header */
#define VDM_HDR_SVID(hdr) ((hdr) >> 16)
#define VDM_IS_SVDM(hdr) ((hdr) & 0x8000)
@@ -273,7 +277,7 @@ static int min_sink_current = 900;
module_param(min_sink_current, int, S_IRUSR | S_IWUSR);
static const u32 default_src_caps[] = { 0x36019096 }; /* VSafe5V @ 1.5A */
-static const u32 default_snk_caps[] = { 0x2601905A }; /* 5V @ 900mA */
+static const u32 default_snk_caps[] = { 0x2601912C }; /* VSafe5V @ 3A */
struct vdm_tx {
u32 data[7];
@@ -318,6 +322,9 @@ struct usbpd {
bool peer_pr_swap;
bool peer_dr_swap;
+ u32 sink_caps[7];
+ int num_sink_caps;
+
struct power_supply *usb_psy;
struct notifier_block psy_nb;
@@ -1718,8 +1725,8 @@ static void usbpd_sm(struct work_struct *w)
}
} else if (IS_CTRL(rx_msg, MSG_GET_SINK_CAP)) {
ret = pd_send_msg(pd, MSG_SINK_CAPABILITIES,
- default_snk_caps,
- ARRAY_SIZE(default_snk_caps), SOP_MSG);
+ pd->sink_caps, pd->num_sink_caps,
+ SOP_MSG);
if (ret) {
usbpd_err(&pd->dev, "Error sending Sink Caps\n");
usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
@@ -1996,8 +2003,8 @@ static void usbpd_sm(struct work_struct *w)
usbpd_set_state(pd, PE_SNK_EVALUATE_CAPABILITY);
} else if (IS_CTRL(rx_msg, MSG_GET_SINK_CAP)) {
ret = pd_send_msg(pd, MSG_SINK_CAPABILITIES,
- default_snk_caps,
- ARRAY_SIZE(default_snk_caps), SOP_MSG);
+ pd->sink_caps, pd->num_sink_caps,
+ SOP_MSG);
if (ret) {
usbpd_err(&pd->dev, "Error sending Sink Caps\n");
usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
@@ -3157,6 +3164,44 @@ struct usbpd *usbpd_create(struct device *parent)
pd->vconn_is_external = device_property_present(parent,
"qcom,vconn-uses-external-source");
+ pd->num_sink_caps = device_property_read_u32_array(parent,
+ "qcom,default-sink-caps", NULL, 0);
+ if (pd->num_sink_caps) {
+ int i;
+ u32 sink_caps[14];
+
+ if (pd->num_sink_caps % 2 || pd->num_sink_caps > 14) {
+ ret = -EINVAL;
+ usbpd_err(&pd->dev, "default-sink-caps must be be specified as voltage/current, max 7 pairs\n");
+ goto put_psy;
+ }
+
+ ret = device_property_read_u32_array(parent,
+ "qcom,default-sink-caps", sink_caps,
+ pd->num_sink_caps);
+ if (ret) {
+ usbpd_err(&pd->dev, "Error reading default-sink-caps\n");
+ goto put_psy;
+ }
+
+ pd->num_sink_caps /= 2;
+
+ for (i = 0; i < pd->num_sink_caps; i++) {
+ int v = sink_caps[i * 2] / 50;
+ int c = sink_caps[i * 2 + 1] / 10;
+
+ pd->sink_caps[i] =
+ PD_SNK_PDO_FIXED(0, 0, 0, 0, 0, v, c);
+ }
+
+ /* First PDO includes additional capabilities */
+ pd->sink_caps[0] |= PD_SNK_PDO_FIXED(1, 0, 0, 1, 1, 0, 0);
+ } else {
+ memcpy(pd->sink_caps, default_snk_caps,
+ sizeof(default_snk_caps));
+ pd->num_sink_caps = ARRAY_SIZE(default_snk_caps);
+ }
+
/*
* Register the Android dual-role class (/sys/class/dual_role_usb/).
* The first instance should be named "otg_default" as that's what
diff --git a/drivers/video/fbdev/msm/mdp3_ctrl.c b/drivers/video/fbdev/msm/mdp3_ctrl.c
index da6c68d43b53..fc89a2ea772e 100644
--- a/drivers/video/fbdev/msm/mdp3_ctrl.c
+++ b/drivers/video/fbdev/msm/mdp3_ctrl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -2147,8 +2147,10 @@ static int mdp3_ctrl_lut_config(struct msm_fb_data_type *mfd,
dma = mdp3_session->dma;
- if (cfg->cmap.start + cfg->cmap.len > MDP_LUT_SIZE) {
- pr_err("Invalid arguments\n");
+ if ((cfg->cmap.start > MDP_LUT_SIZE) ||
+ (cfg->cmap.len > MDP_LUT_SIZE) ||
+ (cfg->cmap.start + cfg->cmap.len > MDP_LUT_SIZE)) {
+ pr_err("Invalid arguments.\n");
return -EINVAL;
}
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c
index f3c36c5c6b5a..af9dc7ce1730 100644
--- a/drivers/video/fbdev/msm/mdss_dp.c
+++ b/drivers/video/fbdev/msm/mdss_dp.c
@@ -129,6 +129,40 @@ static int mdss_dp_is_clk_prefix(const char *clk_prefix, const char *clk_name)
return !strncmp(clk_name, clk_prefix, strlen(clk_prefix));
}
+static int mdss_dp_parse_prop(struct platform_device *pdev,
+ struct mdss_dp_drv_pdata *dp_drv)
+{
+ int len = 0, i = 0;
+ const char *data;
+
+ data = of_get_property(pdev->dev.of_node,
+ "qcom,aux-cfg-settings", &len);
+ if ((!data) || (len != AUX_CFG_LEN)) {
+ pr_err("%s:%d, Unable to read DP AUX CFG settings",
+ __func__, __LINE__);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < len; i++)
+ dp_drv->aux_cfg[i] = data[i];
+
+ data = of_get_property(pdev->dev.of_node,
+ "qcom,logical2physical-lane-map", &len);
+ if ((!data) || (len != DP_MAX_PHY_LN)) {
+ pr_debug("%s:%d, lane mapping not defined, use default",
+ __func__, __LINE__);
+ dp_drv->l_map[DP_PHY_LN0] = DP_ML0;
+ dp_drv->l_map[DP_PHY_LN1] = DP_ML1;
+ dp_drv->l_map[DP_PHY_LN2] = DP_ML2;
+ dp_drv->l_map[DP_PHY_LN3] = DP_ML3;
+ } else {
+ for (i = 0; i < len; i++)
+ dp_drv->l_map[i] = data[i];
+ }
+
+ return 0;
+}
+
static int mdss_dp_init_clk_power_data(struct device *dev,
struct mdss_dp_drv_pdata *pdata)
{
@@ -304,7 +338,25 @@ static int mdss_dp_clk_init(struct mdss_dp_drv_pdata *dp_drv,
goto ctrl_get_error;
}
+ dp_drv->pixel_clk_rcg = devm_clk_get(dev, "pixel_clk_rcg");
+ if (IS_ERR(dp_drv->pixel_clk_rcg)) {
+ pr_debug("%s: Unable to get DP pixel clk RCG\n",
+ __func__);
+ dp_drv->pixel_clk_rcg = NULL;
+ }
+
+ dp_drv->pixel_parent = devm_clk_get(dev,
+ "pixel_parent");
+ if (IS_ERR(dp_drv->pixel_parent)) {
+ pr_debug("%s: Unable to get DP pixel RCG parent\n",
+ __func__);
+ dp_drv->pixel_parent = NULL;
+ }
} else {
+ if (dp_drv->pixel_parent)
+ devm_clk_put(dev, dp_drv->pixel_parent);
+ if (dp_drv->pixel_clk_rcg)
+ devm_clk_put(dev, dp_drv->pixel_clk_rcg);
msm_dss_put_clk(ctrl_power_data->clk_config,
ctrl_power_data->num_clk);
msm_dss_put_clk(core_power_data->clk_config,
@@ -1151,10 +1203,9 @@ static inline void mdss_dp_ack_state(struct mdss_dp_drv_pdata *dp, int val)
* given usb plug orientation.
*/
static int mdss_dp_get_lane_mapping(struct mdss_dp_drv_pdata *dp,
- enum plug_orientation orientation,
- struct lane_mapping *lane_map)
+ enum plug_orientation orientation, char *lane_map)
{
- int ret = 0;
+ int ret = 0, i = 0, j = 0;
pr_debug("enter: orientation = %d\n", orientation);
@@ -1164,22 +1215,35 @@ static int mdss_dp_get_lane_mapping(struct mdss_dp_drv_pdata *dp,
goto exit;
}
- /* Set the default lane mapping */
- lane_map->lane0 = 2;
- lane_map->lane1 = 3;
- lane_map->lane2 = 1;
- lane_map->lane3 = 0;
-
+ /* For flip case, swap phy lanes with ML0 and ML3, ML1 and ML2 */
if (orientation == ORIENTATION_CC2) {
- lane_map->lane0 = 1;
- lane_map->lane1 = 0;
- lane_map->lane2 = 2;
- lane_map->lane3 = 3;
+ for (i = 0; i < DP_MAX_PHY_LN; i++) {
+ if (dp->l_map[i] == DP_ML0) {
+ for (j = 0; j < DP_MAX_PHY_LN; j++) {
+ if (dp->l_map[j] == DP_ML3) {
+ lane_map[i] = DP_ML3;
+ lane_map[j] = DP_ML0;
+ break;
+ }
+ }
+ } else if (dp->l_map[i] == DP_ML1) {
+ for (j = 0; j < DP_MAX_PHY_LN; j++) {
+ if (dp->l_map[j] == DP_ML2) {
+ lane_map[i] = DP_ML2;
+ lane_map[j] = DP_ML1;
+ break;
+ }
+ }
+ }
+ }
+ } else {
+ /* Normal orientation */
+ for (i = 0; i < DP_MAX_PHY_LN; i++)
+ lane_map[i] = dp->l_map[i];
}
pr_debug("lane0 = %d, lane1 = %d, lane2 =%d, lane3 =%d\n",
- lane_map->lane0, lane_map->lane1, lane_map->lane2,
- lane_map->lane3);
+ lane_map[0], lane_map[1], lane_map[2], lane_map[3]);
exit:
return ret;
@@ -1212,6 +1276,9 @@ static int mdss_dp_enable_mainlink_clocks(struct mdss_dp_drv_pdata *dp)
{
int ret = 0;
+ if (dp->pixel_clk_rcg && dp->pixel_parent)
+ clk_set_parent(dp->pixel_clk_rcg, dp->pixel_parent);
+
mdss_dp_set_clock_rate(dp, "ctrl_link_clk",
(dp->link_rate * DP_LINK_RATE_MULTIPLIER) / DP_KHZ_TO_HZ);
@@ -1248,9 +1315,9 @@ static void mdss_dp_disable_mainlink_clocks(struct mdss_dp_drv_pdata *dp_drv)
* configuration, output format and sink/panel timing information.
*/
static void mdss_dp_configure_source_params(struct mdss_dp_drv_pdata *dp,
- struct lane_mapping *lane_map)
+ char *lane_map)
{
- mdss_dp_ctrl_lane_mapping(&dp->ctrl_io, *lane_map);
+ mdss_dp_ctrl_lane_mapping(&dp->ctrl_io, lane_map);
mdss_dp_fill_link_cfg(dp);
mdss_dp_mainlink_ctrl(&dp->ctrl_io, true);
mdss_dp_config_ctrl(dp);
@@ -1318,7 +1385,7 @@ end:
static int mdss_dp_on_irq(struct mdss_dp_drv_pdata *dp_drv, bool lt_needed)
{
int ret = 0;
- struct lane_mapping ln_map;
+ char ln_map[4];
/* wait until link training is completed */
pr_debug("enter, lt_needed=%s\n", lt_needed ? "true" : "false");
@@ -1331,13 +1398,14 @@ static int mdss_dp_on_irq(struct mdss_dp_drv_pdata *dp_drv, bool lt_needed)
dp_init_panel_info(dp_drv, dp_drv->vic);
ret = mdss_dp_get_lane_mapping(dp_drv, dp_drv->orientation,
- &ln_map);
+ ln_map);
if (ret)
goto exit_loop;
mdss_dp_phy_share_lane_config(&dp_drv->phy_io,
dp_drv->orientation,
- dp_drv->dpcd.max_lane_count);
+ dp_drv->dpcd.max_lane_count,
+ dp_drv->phy_reg_offset);
if (lt_needed) {
/*
@@ -1352,7 +1420,7 @@ static int mdss_dp_on_irq(struct mdss_dp_drv_pdata *dp_drv, bool lt_needed)
goto exit_loop;
}
- mdss_dp_configure_source_params(dp_drv, &ln_map);
+ mdss_dp_configure_source_params(dp_drv, ln_map);
reinit_completion(&dp_drv->idle_comp);
@@ -1385,7 +1453,7 @@ exit_loop:
int mdss_dp_on_hpd(struct mdss_dp_drv_pdata *dp_drv)
{
int ret = 0;
- struct lane_mapping ln_map;
+ char ln_map[4];
/* wait until link training is completed */
mutex_lock(&dp_drv->train_mutex);
@@ -1404,7 +1472,7 @@ int mdss_dp_on_hpd(struct mdss_dp_drv_pdata *dp_drv)
}
mdss_dp_hpd_configure(&dp_drv->ctrl_io, true);
- ret = mdss_dp_get_lane_mapping(dp_drv, dp_drv->orientation, &ln_map);
+ ret = mdss_dp_get_lane_mapping(dp_drv, dp_drv->orientation, ln_map);
if (ret)
goto exit;
@@ -1419,7 +1487,7 @@ int mdss_dp_on_hpd(struct mdss_dp_drv_pdata *dp_drv)
}
mdss_dp_phy_share_lane_config(&dp_drv->phy_io, dp_drv->orientation,
- dp_drv->dpcd.max_lane_count);
+ dp_drv->dpcd.max_lane_count, dp_drv->phy_reg_offset);
ret = mdss_dp_enable_mainlink_clocks(dp_drv);
if (ret)
@@ -1427,7 +1495,7 @@ int mdss_dp_on_hpd(struct mdss_dp_drv_pdata *dp_drv)
reinit_completion(&dp_drv->idle_comp);
- mdss_dp_configure_source_params(dp_drv, &ln_map);
+ mdss_dp_configure_source_params(dp_drv, ln_map);
if (dp_drv->psm_enabled) {
ret = mdss_dp_aux_send_psm_request(dp_drv, false);
@@ -1689,7 +1757,8 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata)
mdss_dp_get_ctrl_hw_version(&dp_drv->ctrl_io),
mdss_dp_get_phy_hw_version(&dp_drv->phy_io));
- mdss_dp_phy_aux_setup(&dp_drv->phy_io);
+ mdss_dp_phy_aux_setup(&dp_drv->phy_io, dp_drv->aux_cfg,
+ dp_drv->phy_reg_offset);
mdss_dp_irq_enable(dp_drv);
dp_drv->dp_initialized = true;
@@ -2743,6 +2812,11 @@ static int mdss_retrieve_dp_ctrl_resources(struct platform_device *pdev,
return rc;
}
+ rc = of_property_read_u32(pdev->dev.of_node,
+ "qcom,phy-register-offset", &dp_drv->phy_reg_offset);
+ if (rc)
+ dp_drv->phy_reg_offset = 0;
+
rc = msm_dss_ioremap_byname(pdev, &dp_drv->tcsr_reg_io,
"tcsr_regs");
if (rc) {
@@ -3704,6 +3778,13 @@ static int mdss_dp_probe(struct platform_device *pdev)
goto probe_err;
}
+ ret = mdss_dp_parse_prop(pdev, dp_drv);
+ if (ret) {
+ DEV_ERR("DP properties parsing failed.ret=%d\n",
+ ret);
+ goto probe_err;
+ }
+
ret = mdss_dp_irq_setup(dp_drv);
if (ret)
goto probe_err;
@@ -3759,18 +3840,33 @@ probe_err:
void *mdss_dp_get_hdcp_data(struct device *dev)
{
- struct mdss_dp_drv_pdata *dp_drv = NULL;
+ struct mdss_dp_drv_pdata *dp;
+ struct msm_fb_data_type *mfd;
+ struct mdss_panel_data *pd;
+ struct fb_info *fbi = dev_get_drvdata(dev);
- if (!dev) {
- pr_err("%s:Invalid input\n", __func__);
- return NULL;
+ if (!fbi) {
+ pr_err("invalid fbi\n");
+ goto error;
}
- dp_drv = dev_get_drvdata(dev);
- if (!dp_drv) {
- pr_err("%s:Invalid dp driver\n", __func__);
- return NULL;
+
+ mfd = (struct msm_fb_data_type *)fbi->par;
+ if (!mfd) {
+ pr_err("invalid mfd\n");
+ goto error;
}
- return dp_drv->hdcp.data;
+
+ pd = dev_get_platdata(&mfd->pdev->dev);
+ if (!pd) {
+ pr_err("invalid panel_data\n");
+ goto error;
+ }
+
+ dp = container_of(pd, struct mdss_dp_drv_pdata, panel_data);
+
+ return dp->hdcp.data;
+error:
+ return NULL;
}
static inline bool dp_is_stream_shareable(struct mdss_dp_drv_pdata *dp_drv)
diff --git a/drivers/video/fbdev/msm/mdss_dp.h b/drivers/video/fbdev/msm/mdss_dp.h
index bf74a8a4d7df..d6f5d160aef2 100644
--- a/drivers/video/fbdev/msm/mdss_dp.h
+++ b/drivers/video/fbdev/msm/mdss_dp.h
@@ -36,6 +36,8 @@
#define AUX_CMD_MAX 16
#define AUX_CMD_I2C_MAX 128
+#define AUX_CFG_LEN 10
+
#define EDP_PORT_MAX 1
#define EDP_SINK_CAP_LEN 16
@@ -460,6 +462,7 @@ struct mdss_dp_drv_pdata {
struct dss_io_data dp_cc_io;
struct dss_io_data qfprom_io;
struct dss_io_data hdcp_io;
+ u32 phy_reg_offset;
int base_size;
unsigned char *mmss_cc_base;
bool override_config;
@@ -486,6 +489,10 @@ struct mdss_dp_drv_pdata {
struct edp_edid edid;
struct dpcd_cap dpcd;
+ /* DP Pixel clock RCG and PLL parent */
+ struct clk *pixel_clk_rcg;
+ struct clk *pixel_parent;
+
/* regulators */
struct dss_module_power power_data[DP_MAX_PM];
struct dp_pinctrl_res pin_res;
@@ -536,6 +543,10 @@ struct mdss_dp_drv_pdata {
struct mdss_dp_event_data dp_event;
struct task_struct *ev_thread;
+ /* dt settings */
+ char l_map[4];
+ u32 aux_cfg[AUX_CFG_LEN];
+
struct workqueue_struct *workq;
struct delayed_work hdcp_cb_work;
spinlock_t lock;
@@ -554,6 +565,21 @@ struct mdss_dp_drv_pdata {
struct list_head attention_head;
};
+enum dp_phy_lane_num {
+ DP_PHY_LN0 = 0,
+ DP_PHY_LN1 = 1,
+ DP_PHY_LN2 = 2,
+ DP_PHY_LN3 = 3,
+ DP_MAX_PHY_LN = 4,
+};
+
+enum dp_mainlink_lane_num {
+ DP_ML0 = 0,
+ DP_ML1 = 1,
+ DP_ML2 = 2,
+ DP_ML3 = 3,
+};
+
enum dp_lane_count {
DP_LANE_COUNT_1 = 1,
DP_LANE_COUNT_2 = 2,
diff --git a/drivers/video/fbdev/msm/mdss_dp_util.c b/drivers/video/fbdev/msm/mdss_dp_util.c
index 1dcf83f094c1..3b9242448198 100644
--- a/drivers/video/fbdev/msm/mdss_dp_util.c
+++ b/drivers/video/fbdev/msm/mdss_dp_util.c
@@ -859,31 +859,38 @@ void mdss_dp_setup_tr_unit(struct dss_io_data *ctrl_io, u8 link_rate,
pr_debug("dp_tu=0x%x\n", dp_tu);
}
-void mdss_dp_ctrl_lane_mapping(struct dss_io_data *ctrl_io,
- struct lane_mapping l_map)
+void mdss_dp_ctrl_lane_mapping(struct dss_io_data *ctrl_io, char *l_map)
{
u8 bits_per_lane = 2;
- u32 lane_map = ((l_map.lane0 << (bits_per_lane * 0))
- | (l_map.lane1 << (bits_per_lane * 1))
- | (l_map.lane2 << (bits_per_lane * 2))
- | (l_map.lane3 << (bits_per_lane * 3)));
+ u32 lane_map = ((l_map[0] << (bits_per_lane * 0))
+ | (l_map[1] << (bits_per_lane * 1))
+ | (l_map[2] << (bits_per_lane * 2))
+ | (l_map[3] << (bits_per_lane * 3)));
pr_debug("%s: lane mapping reg = 0x%x\n", __func__, lane_map);
writel_relaxed(lane_map,
ctrl_io->base + DP_LOGICAL2PHYSCIAL_LANE_MAPPING);
}
-void mdss_dp_phy_aux_setup(struct dss_io_data *phy_io)
+void mdss_dp_phy_aux_setup(struct dss_io_data *phy_io, u32 *aux_cfg,
+ u32 phy_reg_offset)
{
- writel_relaxed(0x3d, phy_io->base + DP_PHY_PD_CTL);
- writel_relaxed(0x13, phy_io->base + DP_PHY_AUX_CFG1);
- writel_relaxed(0x10, phy_io->base + DP_PHY_AUX_CFG3);
- writel_relaxed(0x0a, phy_io->base + DP_PHY_AUX_CFG4);
- writel_relaxed(0x26, phy_io->base + DP_PHY_AUX_CFG5);
- writel_relaxed(0x0a, phy_io->base + DP_PHY_AUX_CFG6);
- writel_relaxed(0x03, phy_io->base + DP_PHY_AUX_CFG7);
- writel_relaxed(0x8b, phy_io->base + DP_PHY_AUX_CFG8);
- writel_relaxed(0x03, phy_io->base + DP_PHY_AUX_CFG9);
- writel_relaxed(0x1f, phy_io->base + DP_PHY_AUX_INTERRUPT_MASK);
+ void __iomem *adjusted_phy_io_base = phy_io->base + phy_reg_offset;
+
+ writel_relaxed(0x3d, adjusted_phy_io_base + DP_PHY_PD_CTL);
+
+ /* DP AUX CFG register programming */
+ writel_relaxed(aux_cfg[0], adjusted_phy_io_base + DP_PHY_AUX_CFG0);
+ writel_relaxed(aux_cfg[1], adjusted_phy_io_base + DP_PHY_AUX_CFG1);
+ writel_relaxed(aux_cfg[2], adjusted_phy_io_base + DP_PHY_AUX_CFG2);
+ writel_relaxed(aux_cfg[3], adjusted_phy_io_base + DP_PHY_AUX_CFG3);
+ writel_relaxed(aux_cfg[4], adjusted_phy_io_base + DP_PHY_AUX_CFG4);
+ writel_relaxed(aux_cfg[5], adjusted_phy_io_base + DP_PHY_AUX_CFG5);
+ writel_relaxed(aux_cfg[6], adjusted_phy_io_base + DP_PHY_AUX_CFG6);
+ writel_relaxed(aux_cfg[7], adjusted_phy_io_base + DP_PHY_AUX_CFG7);
+ writel_relaxed(aux_cfg[8], adjusted_phy_io_base + DP_PHY_AUX_CFG8);
+ writel_relaxed(aux_cfg[9], adjusted_phy_io_base + DP_PHY_AUX_CFG9);
+
+ writel_relaxed(0x1f, adjusted_phy_io_base + DP_PHY_AUX_INTERRUPT_MASK);
}
int mdss_dp_irq_setup(struct mdss_dp_drv_pdata *dp_drv)
@@ -1036,14 +1043,14 @@ u32 mdss_dp_usbpd_gen_config_pkt(struct mdss_dp_drv_pdata *dp)
}
void mdss_dp_phy_share_lane_config(struct dss_io_data *phy_io,
- u8 orientation, u8 ln_cnt)
+ u8 orientation, u8 ln_cnt, u32 phy_reg_offset)
{
u32 info = 0x0;
info |= (ln_cnt & 0x0F);
info |= ((orientation & 0x0F) << 4);
pr_debug("Shared Info = 0x%x\n", info);
- writel_relaxed(info, phy_io->base + DP_PHY_SPARE0);
+ writel_relaxed(info, phy_io->base + phy_reg_offset + DP_PHY_SPARE0);
}
void mdss_dp_config_audio_acr_ctrl(struct dss_io_data *ctrl_io, char link_rate)
@@ -1051,8 +1058,6 @@ void mdss_dp_config_audio_acr_ctrl(struct dss_io_data *ctrl_io, char link_rate)
u32 acr_ctrl = 0;
u32 select = 0;
- acr_ctrl = readl_relaxed(ctrl_io->base + MMSS_DP_AUDIO_ACR_CTRL);
-
switch (link_rate) {
case DP_LINK_RATE_162:
select = 0;
diff --git a/drivers/video/fbdev/msm/mdss_dp_util.h b/drivers/video/fbdev/msm/mdss_dp_util.h
index cb62d145960f..b3b15a3579fa 100644
--- a/drivers/video/fbdev/msm/mdss_dp_util.h
+++ b/drivers/video/fbdev/msm/mdss_dp_util.h
@@ -206,13 +206,6 @@
#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA11 (0x01C)
#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA12 (0x020)
-struct lane_mapping {
- char lane0;
- char lane1;
- char lane2;
- char lane3;
-};
-
struct edp_cmd {
char read; /* 1 == read, 0 == write */
char i2c; /* 1 == i2c cmd, 0 == native cmd */
@@ -292,12 +285,12 @@ void mdss_dp_assert_phy_reset(struct dss_io_data *ctrl_io, bool assert);
void mdss_dp_setup_tr_unit(struct dss_io_data *ctrl_io, u8 link_rate,
u8 ln_cnt, u32 res, struct mdss_panel_info *pinfo);
void mdss_dp_config_misc(struct mdss_dp_drv_pdata *dp, u32 bd, u32 cc);
-void mdss_dp_phy_aux_setup(struct dss_io_data *phy_io);
+void mdss_dp_phy_aux_setup(struct dss_io_data *phy_io, u32 *aux_cfg,
+ u32 phy_reg_offset);
void mdss_dp_hpd_configure(struct dss_io_data *ctrl_io, bool enable);
void mdss_dp_aux_ctrl(struct dss_io_data *ctrl_io, bool enable);
void mdss_dp_mainlink_ctrl(struct dss_io_data *ctrl_io, bool enable);
-void mdss_dp_ctrl_lane_mapping(struct dss_io_data *ctrl_io,
- struct lane_mapping l_map);
+void mdss_dp_ctrl_lane_mapping(struct dss_io_data *ctrl_io, char *l_map);
int mdss_dp_mainlink_ready(struct mdss_dp_drv_pdata *dp, u32 which);
void mdss_dp_timing_cfg(struct dss_io_data *ctrl_io,
struct mdss_panel_info *pinfo);
@@ -311,10 +304,8 @@ void mdss_dp_sw_config_msa(struct dss_io_data *ctrl_io,
void mdss_dp_usbpd_ext_capabilities(struct usbpd_dp_capabilities *dp_cap);
void mdss_dp_usbpd_ext_dp_status(struct usbpd_dp_status *dp_status);
u32 mdss_dp_usbpd_gen_config_pkt(struct mdss_dp_drv_pdata *dp);
-void mdss_dp_ctrl_lane_mapping(struct dss_io_data *ctrl_io,
- struct lane_mapping l_map);
void mdss_dp_phy_share_lane_config(struct dss_io_data *phy_io,
- u8 orientation, u8 ln_cnt);
+ u8 orientation, u8 ln_cnt, u32 phy_reg_offset);
void mdss_dp_config_audio_acr_ctrl(struct dss_io_data *ctrl_io,
char link_rate);
void mdss_dp_audio_setup_sdps(struct dss_io_data *ctrl_io, u32 num_of_channels);
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c
index 51745a9a59ac..c66d9f3b3a65 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.c
+++ b/drivers/video/fbdev/msm/mdss_dsi.c
@@ -2183,6 +2183,21 @@ static int mdss_dsi_check_params(struct mdss_dsi_ctrl_pdata *ctrl, void *arg)
return rc;
}
+static void mdss_dsi_avr_config(struct mdss_dsi_ctrl_pdata *ctrl_pdata,
+ int enabled)
+{
+ u32 data = MIPI_INP((ctrl_pdata->ctrl_base) + 0x10);
+
+ /* DSI_VIDEO_MODE_CTRL */
+ if (enabled)
+ data |= BIT(29); /* AVR_SUPPORT_ENABLED */
+ else
+ data &= ~BIT(29);
+
+ MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x10, data);
+ MDSS_XLOG(ctrl_pdata->ndx, enabled, data);
+}
+
static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps)
{
int rc = 0;
@@ -2700,6 +2715,9 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata,
case MDSS_EVENT_DSI_TIMING_DB_CTRL:
mdss_dsi_timing_db_ctrl(ctrl_pdata, (int)(unsigned long)arg);
break;
+ case MDSS_EVENT_AVR_MODE:
+ mdss_dsi_avr_config(ctrl_pdata, (int)(unsigned long) arg);
+ break;
default:
pr_debug("%s: unhandled event=%d\n", __func__, event);
break;
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
index abc56f5f352d..5804d88e5af5 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
@@ -22,6 +22,7 @@
#include <linux/types.h>
#include <linux/hdcp_qseecom.h>
#include <linux/msm_mdp.h>
+#include <linux/msm_ext_display.h>
#define REG_DUMP 0
@@ -414,7 +415,6 @@ static inline void hdmi_tx_cec_device_suspend(struct hdmi_tx_ctrl *hdmi_ctrl)
hdmi_cec_device_suspend(fd, hdmi_ctrl->panel_suspend);
}
-
static inline void hdmi_tx_send_cable_notification(
struct hdmi_tx_ctrl *hdmi_ctrl, int val)
{
@@ -431,7 +431,7 @@ static inline void hdmi_tx_send_cable_notification(
}
}
-static inline void hdmi_tx_set_audio_switch_node(
+static inline void hdmi_tx_ack_state(
struct hdmi_tx_ctrl *hdmi_ctrl, int val)
{
if (hdmi_ctrl && hdmi_ctrl->ext_audio_data.intf_ops.notify &&
@@ -440,47 +440,6 @@ static inline void hdmi_tx_set_audio_switch_node(
val);
}
-static void hdmi_tx_wait_for_audio_engine(struct hdmi_tx_ctrl *hdmi_ctrl)
-{
- u64 status = 0;
- u32 wait_for_vote = 50;
- struct dss_io_data *io = NULL;
-
- if (!hdmi_ctrl) {
- DEV_ERR("%s: invalid input\n", __func__);
- return;
- }
-
- io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
- if (!io->base) {
- DEV_ERR("%s: core io not inititalized\n", __func__);
- return;
- }
-
- /*
- * wait for 5 sec max for audio engine to acknowledge if hdmi tx core
- * can be safely turned off. Sleep for a reasonable time to make sure
- * vote_hdmi_core_on variable is updated properly by audio.
- */
- while (hdmi_ctrl->vote_hdmi_core_on && --wait_for_vote)
- msleep(100);
-
-
- if (!wait_for_vote)
- DEV_ERR("%s: HDMI core still voted for power on\n", __func__);
-
- if (readl_poll_timeout(io->base + HDMI_AUDIO_PKT_CTRL, status,
- (status & BIT(0)) == 0, AUDIO_POLL_SLEEP_US,
- AUDIO_POLL_TIMEOUT_US))
- DEV_ERR("%s: Error turning off audio packet transmission.\n",
- __func__);
-
- if (readl_poll_timeout(io->base + HDMI_AUDIO_CFG, status,
- (status & BIT(0)) == 0, AUDIO_POLL_SLEEP_US,
- AUDIO_POLL_TIMEOUT_US))
- DEV_ERR("%s: Error turning off audio engine.\n", __func__);
-}
-
static struct hdmi_tx_ctrl *hdmi_tx_get_drvdata_from_panel_data(
struct mdss_panel_data *mpd)
{
@@ -900,8 +859,7 @@ static ssize_t hdmi_tx_sysfs_wta_hpd(struct device *dev,
hdmi_tx_config_5v(hdmi_ctrl, false);
} else {
hdmi_tx_hpd_off(hdmi_ctrl);
-
- hdmi_tx_set_audio_switch_node(hdmi_ctrl, 0);
+ hdmi_tx_send_cable_notification(hdmi_ctrl, 0);
}
break;
@@ -1589,7 +1547,6 @@ static void hdmi_tx_hdcp_cb_work(struct work_struct *work)
if (hdmi_tx_is_panel_on(hdmi_ctrl) &&
hdmi_tx_is_stream_shareable(hdmi_ctrl)) {
rc = hdmi_tx_config_avmute(hdmi_ctrl, false);
- hdmi_tx_set_audio_switch_node(hdmi_ctrl, 1);
}
if (hdmi_ctrl->hdcp1_use_sw_keys && hdmi_ctrl->hdcp14_present)
@@ -1605,7 +1562,6 @@ static void hdmi_tx_hdcp_cb_work(struct work_struct *work)
if (hdmi_tx_is_encryption_set(hdmi_ctrl) ||
!hdmi_tx_is_stream_shareable(hdmi_ctrl)) {
- hdmi_tx_set_audio_switch_node(hdmi_ctrl, 0);
rc = hdmi_tx_config_avmute(hdmi_ctrl, true);
}
@@ -1631,7 +1587,6 @@ static void hdmi_tx_hdcp_cb_work(struct work_struct *work)
if (hdmi_tx_is_panel_on(hdmi_ctrl)) {
rc = hdmi_tx_config_avmute(hdmi_ctrl, false);
- hdmi_tx_set_audio_switch_node(hdmi_ctrl, 1);
}
break;
case HDCP_STATE_AUTH_ENC_1X:
@@ -1641,9 +1596,7 @@ static void hdmi_tx_hdcp_cb_work(struct work_struct *work)
if (hdmi_tx_is_panel_on(hdmi_ctrl) &&
hdmi_tx_is_stream_shareable(hdmi_ctrl)) {
rc = hdmi_tx_config_avmute(hdmi_ctrl, false);
- hdmi_tx_set_audio_switch_node(hdmi_ctrl, 1);
} else {
- hdmi_tx_set_audio_switch_node(hdmi_ctrl, 0);
rc = hdmi_tx_config_avmute(hdmi_ctrl, true);
}
break;
@@ -2373,7 +2326,8 @@ static void hdmi_tx_hpd_int_work(struct work_struct *work)
if (!hdmi_ctrl->hpd_initialized) {
DEV_DBG("hpd not initialized\n");
- goto end;
+ mutex_unlock(&hdmi_ctrl->tx_lock);
+ return;
}
DEV_DBG("%s: %s\n", __func__,
@@ -2386,16 +2340,11 @@ static void hdmi_tx_hpd_int_work(struct work_struct *work)
pr_warn_ratelimited("%s: EDID read failed\n", __func__);
hdmi_tx_update_deep_color(hdmi_ctrl);
hdmi_tx_update_hdr_info(hdmi_ctrl);
-
- hdmi_tx_send_cable_notification(hdmi_ctrl, true);
- } else {
- hdmi_tx_set_audio_switch_node(hdmi_ctrl, 0);
- hdmi_tx_wait_for_audio_engine(hdmi_ctrl);
-
- hdmi_tx_send_cable_notification(hdmi_ctrl, false);
}
-end:
+
mutex_unlock(&hdmi_ctrl->tx_lock);
+
+ hdmi_tx_send_cable_notification(hdmi_ctrl, hdmi_ctrl->hpd_state);
} /* hdmi_tx_hpd_int_work */
static int hdmi_tx_check_capability(struct hdmi_tx_ctrl *hdmi_ctrl)
@@ -3239,7 +3188,6 @@ static int hdmi_tx_power_on(struct hdmi_tx_ctrl *hdmi_ctrl)
if (hdmi_ctrl->panel.infoframe &&
!hdmi_tx_is_encryption_set(hdmi_ctrl) &&
hdmi_tx_is_stream_shareable(hdmi_ctrl)) {
- hdmi_tx_set_audio_switch_node(hdmi_ctrl, 1);
hdmi_tx_config_avmute(hdmi_ctrl, false);
}
@@ -3845,20 +3793,6 @@ static int hdmi_tx_evt_handle_resume(struct hdmi_tx_ctrl *hdmi_ctrl)
goto end;
}
- if (hdmi_ctrl->sdev.state &&
- !hdmi_tx_hw_is_cable_connected(hdmi_ctrl)) {
- u32 timeout;
-
- reinit_completion(&hdmi_ctrl->hpd_int_done);
- timeout = wait_for_completion_timeout(
- &hdmi_ctrl->hpd_int_done, HZ/10);
- if (!timeout && !hdmi_ctrl->hpd_state) {
- DEV_DBG("%s: cable removed during suspend\n", __func__);
- hdmi_tx_set_audio_switch_node(hdmi_ctrl, 0);
- hdmi_tx_wait_for_audio_engine(hdmi_ctrl);
- hdmi_tx_send_cable_notification(hdmi_ctrl, 0);
- }
- }
end:
return rc;
}
@@ -3906,14 +3840,6 @@ static int hdmi_tx_evt_handle_panel_on(struct hdmi_tx_ctrl *hdmi_ctrl)
hdmi_ctrl->timing_gen_on = true;
- if (hdmi_ctrl->panel_suspend) {
- DEV_DBG("%s: panel suspend has triggered\n", __func__);
-
- hdmi_tx_set_audio_switch_node(hdmi_ctrl, 0);
- hdmi_tx_wait_for_audio_engine(hdmi_ctrl);
- hdmi_tx_send_cable_notification(hdmi_ctrl, 0);
- }
-
return rc;
}
@@ -4003,6 +3929,55 @@ static int hdmi_tx_evt_handle_hdmi_ppm(struct hdmi_tx_ctrl *hdmi_ctrl)
return hdmi_tx_update_ppm(hdmi_ctrl, ppm);
}
+static int hdmi_tx_pre_evt_handle_panel_off(struct hdmi_tx_ctrl *hdmi_ctrl)
+{
+ hdmi_tx_ack_state(hdmi_ctrl, false);
+ return 0;
+}
+
+static int hdmi_tx_pre_evt_handle_update_fps(struct hdmi_tx_ctrl *hdmi_ctrl)
+{
+ hdmi_ctrl->dynamic_fps = (u32) (unsigned long)hdmi_ctrl->evt_arg;
+ queue_work(hdmi_ctrl->workq, &hdmi_ctrl->fps_work);
+ return 0;
+}
+
+static int hdmi_tx_post_evt_handle_unblank(struct hdmi_tx_ctrl *hdmi_ctrl)
+{
+ hdmi_tx_ack_state(hdmi_ctrl, true);
+ return 0;
+}
+
+static int hdmi_tx_post_evt_handle_resume(struct hdmi_tx_ctrl *hdmi_ctrl)
+{
+ if (!hdmi_ctrl->hpd_feature_on)
+ return 0;
+
+ if (!hdmi_tx_hw_is_cable_connected(hdmi_ctrl)) {
+ u32 timeout;
+
+ reinit_completion(&hdmi_ctrl->hpd_int_done);
+ timeout = wait_for_completion_timeout(
+ &hdmi_ctrl->hpd_int_done, HZ/10);
+ if (!timeout) {
+ pr_debug("cable removed during suspend\n");
+ hdmi_tx_send_cable_notification(hdmi_ctrl, 0);
+ }
+ }
+
+ return 0;
+}
+
+static int hdmi_tx_post_evt_handle_panel_on(struct hdmi_tx_ctrl *hdmi_ctrl)
+{
+ if (hdmi_ctrl->panel_suspend) {
+ pr_debug("panel suspend has triggered\n");
+ hdmi_tx_send_cable_notification(hdmi_ctrl, 0);
+ }
+
+ return 0;
+}
+
static int hdmi_tx_event_handler(struct mdss_panel_data *panel_data,
int event, void *arg)
{
@@ -4012,33 +3987,52 @@ static int hdmi_tx_event_handler(struct mdss_panel_data *panel_data,
hdmi_tx_get_drvdata_from_panel_data(panel_data);
if (!hdmi_ctrl) {
- DEV_ERR("%s: invalid input\n", __func__);
- rc = -EINVAL;
- goto end;
- }
-
- /* UPDATE FPS is called from atomic context */
- if (event == MDSS_EVENT_PANEL_UPDATE_FPS) {
- hdmi_ctrl->dynamic_fps = (u32) (unsigned long)arg;
- queue_work(hdmi_ctrl->workq, &hdmi_ctrl->fps_work);
- return rc;
+ pr_err("%s: invalid input\n", __func__);
+ return -EINVAL;
}
- mutex_lock(&hdmi_ctrl->tx_lock);
-
hdmi_ctrl->evt_arg = arg;
- DEV_DBG("%s: event = %s suspend=%d, hpd_feature=%d\n", __func__,
+ pr_debug("event = %s suspend=%d, hpd_feature=%d\n",
mdss_panel_intf_event_to_string(event),
hdmi_ctrl->panel_suspend,
hdmi_ctrl->hpd_feature_on);
+ /* event handlers prior to tx_lock */
+ handler = hdmi_ctrl->pre_evt_handler[event];
+ if (handler) {
+ rc = handler(hdmi_ctrl);
+ if (rc) {
+ pr_err("pre handler failed: event = %s, rc = %d\n",
+ mdss_panel_intf_event_to_string(event), rc);
+ return rc;
+ }
+ }
+
+ mutex_lock(&hdmi_ctrl->tx_lock);
+
handler = hdmi_ctrl->evt_handler[event];
- if (handler)
+ if (handler) {
rc = handler(hdmi_ctrl);
+ if (rc) {
+ pr_err("handler failed: event = %s, rc = %d\n",
+ mdss_panel_intf_event_to_string(event), rc);
+ mutex_unlock(&hdmi_ctrl->tx_lock);
+ return rc;
+ }
+ }
mutex_unlock(&hdmi_ctrl->tx_lock);
-end:
+
+ /* event handlers post to tx_lock */
+ handler = hdmi_ctrl->post_evt_handler[event];
+ if (handler) {
+ rc = handler(hdmi_ctrl);
+ if (rc)
+ pr_err("post handler failed: event = %s, rc = %d\n",
+ mdss_panel_intf_event_to_string(event), rc);
+ }
+
return rc;
}
@@ -4692,7 +4686,6 @@ static int hdmi_tx_init_event_handler(struct hdmi_tx_ctrl *hdmi_ctrl)
return -EINVAL;
handler = hdmi_ctrl->evt_handler;
-
handler[MDSS_EVENT_FB_REGISTERED] = hdmi_tx_evt_handle_register;
handler[MDSS_EVENT_CHECK_PARAMS] = hdmi_tx_evt_handle_check_param;
handler[MDSS_EVENT_RESUME] = hdmi_tx_evt_handle_resume;
@@ -4704,7 +4697,17 @@ static int hdmi_tx_init_event_handler(struct hdmi_tx_ctrl *hdmi_ctrl)
handler[MDSS_EVENT_PANEL_OFF] = hdmi_tx_evt_handle_panel_off;
handler[MDSS_EVENT_CLOSE] = hdmi_tx_evt_handle_close;
handler[MDSS_EVENT_DEEP_COLOR] = hdmi_tx_evt_handle_deep_color;
- handler[MDSS_EVENT_UPDATE_PANEL_PPM] = hdmi_tx_evt_handle_hdmi_ppm;
+ handler[MDSS_EVENT_UPDATE_PANEL_PPM] = hdmi_tx_evt_handle_hdmi_ppm;
+
+ handler = hdmi_ctrl->pre_evt_handler;
+ handler[MDSS_EVENT_PANEL_UPDATE_FPS] =
+ hdmi_tx_pre_evt_handle_update_fps;
+ handler[MDSS_EVENT_PANEL_OFF] = hdmi_tx_pre_evt_handle_panel_off;
+
+ handler = hdmi_ctrl->post_evt_handler;
+ handler[MDSS_EVENT_UNBLANK] = hdmi_tx_post_evt_handle_unblank;
+ handler[MDSS_EVENT_RESUME] = hdmi_tx_post_evt_handle_resume;
+ handler[MDSS_EVENT_PANEL_ON] = hdmi_tx_post_evt_handle_panel_on;
return 0;
}
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.h b/drivers/video/fbdev/msm/mdss_hdmi_tx.h
index 2a6a48a4e473..ca316a350238 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_tx.h
+++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.h
@@ -98,7 +98,6 @@ struct hdmi_tx_ctrl {
struct mutex tx_lock;
struct list_head cable_notify_handlers;
struct kobject *kobj;
- struct switch_dev sdev;
struct workqueue_struct *workq;
struct hdmi_util_ds_data ds_data;
struct completion hpd_int_done;
@@ -166,7 +165,10 @@ struct hdmi_tx_ctrl {
char disp_switch_name[MAX_SWITCH_NAME_SIZE];
+ /* pre/post is done in the context without tx_lock */
+ hdmi_tx_evt_handler pre_evt_handler[MDSS_EVENT_MAX - 1];
hdmi_tx_evt_handler evt_handler[MDSS_EVENT_MAX - 1];
+ hdmi_tx_evt_handler post_evt_handler[MDSS_EVENT_MAX - 1];
};
#endif /* __MDSS_HDMI_TX_H__ */
diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c
index fbbcc16f48b5..b65582f8e042 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp.c
@@ -2138,6 +2138,7 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata)
set_bit(MDSS_CAPS_3D_MUX_UNDERRUN_RECOVERY_SUPPORTED,
mdata->mdss_caps_map);
set_bit(MDSS_CAPS_QSEED3, mdata->mdss_caps_map);
+ set_bit(MDSS_CAPS_DEST_SCALER, mdata->mdss_caps_map);
set_bit(MDSS_CAPS_MDP_VOTE_CLK_NOT_SUPPORTED,
mdata->mdss_caps_map);
mdss_mdp_init_default_prefill_factors(mdata);
@@ -4158,6 +4159,7 @@ static int mdss_mdp_parse_dt_prefill(struct platform_device *pdev)
static void mdss_mdp_parse_vbif_qos(struct platform_device *pdev)
{
struct mdss_data_type *mdata = platform_get_drvdata(pdev);
+ u32 npriority_lvl_nrt;
int rc;
mdata->npriority_lvl = mdss_mdp_parse_dt_prop_len(pdev,
@@ -4183,8 +4185,20 @@ static void mdss_mdp_parse_vbif_qos(struct platform_device *pdev)
return;
}
- mdata->npriority_lvl = mdss_mdp_parse_dt_prop_len(pdev,
+ npriority_lvl_nrt = mdss_mdp_parse_dt_prop_len(pdev,
"qcom,mdss-vbif-qos-nrt-setting");
+
+ if (!npriority_lvl_nrt) {
+ pr_debug("no vbif nrt priorities found rt:%d\n",
+ mdata->npriority_lvl);
+ return;
+ } else if (npriority_lvl_nrt != mdata->npriority_lvl) {
+ /* driver expects same number for both nrt and rt */
+ pr_err("invalid nrt settings nrt(%d) != rt(%d)\n",
+ npriority_lvl_nrt, mdata->npriority_lvl);
+ return;
+ }
+
if (mdata->npriority_lvl == MDSS_VBIF_QOS_REMAP_ENTRIES) {
mdata->vbif_nrt_qos = kzalloc(sizeof(u32) *
mdata->npriority_lvl, GFP_KERNEL);
@@ -4202,7 +4216,7 @@ static void mdss_mdp_parse_vbif_qos(struct platform_device *pdev)
}
} else {
mdata->npriority_lvl = 0;
- pr_debug("Invalid or no vbif qos nrt seting\n");
+ pr_debug("Invalid or no vbif qos nrt setting\n");
}
}
diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
index ffbf156e9eed..acb356fc681a 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
@@ -3614,6 +3614,7 @@ int mdss_mdp_ctl_setup(struct mdss_mdp_ctl *ctl)
u32 width, height;
int split_fb, rc = 0;
u32 max_mixer_width;
+ bool dsc_merge_enabled = 0;
struct mdss_panel_info *pinfo;
if (!ctl || !ctl->panel_data) {
@@ -3738,15 +3739,15 @@ int mdss_mdp_ctl_setup(struct mdss_mdp_ctl *ctl)
ctl->mixer_right = NULL;
}
- if (ctl->mixer_right) {
- if (!is_dsc_compression(pinfo) ||
- (pinfo->dsc_enc_total == 1))
- ctl->opmode |= MDSS_MDP_CTL_OP_PACK_3D_ENABLE |
- MDSS_MDP_CTL_OP_PACK_3D_H_ROW_INT;
- } else {
+ dsc_merge_enabled = is_dsc_compression(pinfo) &&
+ (pinfo->dsc_enc_total == 2);
+
+ if (ctl->mixer_right && (!dsc_merge_enabled))
+ ctl->opmode |= MDSS_MDP_CTL_OP_PACK_3D_ENABLE |
+ MDSS_MDP_CTL_OP_PACK_3D_H_ROW_INT;
+ else
ctl->opmode &= ~(MDSS_MDP_CTL_OP_PACK_3D_ENABLE |
MDSS_MDP_CTL_OP_PACK_3D_H_ROW_INT);
- }
return 0;
}
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
index b7f27b818eda..2a62ae5881b3 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
@@ -2031,6 +2031,19 @@ static int __mdss_mdp_wait4pingpong(struct mdss_mdp_cmd_ctx *ctx)
return rc;
}
+static void __clear_ping_pong_callback(struct mdss_mdp_ctl *ctl,
+ struct mdss_mdp_cmd_ctx *ctx)
+{
+ mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_TYPE_PING_PONG_COMP,
+ ctx->current_pp_num);
+ mdss_mdp_set_intr_callback_nosync(
+ MDSS_MDP_IRQ_TYPE_PING_PONG_COMP,
+ ctx->current_pp_num, NULL, NULL);
+ if (atomic_add_unless(&ctx->koff_cnt, -1, 0)
+ && mdss_mdp_cmd_do_notifier(ctx))
+ mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_TIMEOUT);
+}
+
static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg)
{
struct mdss_mdp_cmd_ctx *ctx;
@@ -2047,7 +2060,7 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg)
pdata = ctl->panel_data;
MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), ctl->roi_bkup.w,
- ctl->roi_bkup.h);
+ ctl->roi_bkup.h, pdata->panel_info.panel_dead);
pr_debug("%s: intf_num=%d ctx=%pK koff_cnt=%d\n", __func__,
ctl->intf_num, ctx, atomic_read(&ctx->koff_cnt));
@@ -2073,6 +2086,13 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg)
mdss_mdp_cmd_pingpong_done(ctl);
local_irq_restore(flags);
rc = 1;
+ } else if (pdata->panel_info.panel_dead) {
+ /*
+ * if panel is reported dead, no need to wait for
+ * pingpong done, and don't report timeout
+ */
+ MDSS_XLOG(0xdead);
+ __clear_ping_pong_callback(ctl, ctx);
}
rc = atomic_read(&ctx->koff_cnt) == 0;
@@ -2098,15 +2118,7 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg)
ctx->pp_timeout_report_cnt++;
rc = -EPERM;
- mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_TYPE_PING_PONG_COMP,
- ctx->current_pp_num);
- mdss_mdp_set_intr_callback_nosync(
- MDSS_MDP_IRQ_TYPE_PING_PONG_COMP,
- ctx->current_pp_num, NULL, NULL);
- if (atomic_add_unless(&ctx->koff_cnt, -1, 0)
- && mdss_mdp_cmd_do_notifier(ctx))
- mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_TIMEOUT);
-
+ __clear_ping_pong_callback(ctl, ctx);
} else {
rc = 0;
ctx->pp_timeout_report_cnt = 0;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
index 4efa38093557..663d63092ebf 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
@@ -106,6 +106,9 @@ static void mdss_mdp_fetch_start_config(struct mdss_mdp_video_ctx *ctx,
static void mdss_mdp_fetch_end_config(struct mdss_mdp_video_ctx *ctx,
struct mdss_mdp_ctl *ctl);
+static void mdss_mdp_video_timegen_flush(struct mdss_mdp_ctl *ctl,
+ struct mdss_mdp_video_ctx *sctx);
+
static void early_wakeup_dfps_update_work(struct work_struct *work);
static int mdss_mdp_video_avr_ctrl(struct mdss_mdp_ctl *ctl, bool enable);
@@ -411,6 +414,8 @@ static void mdss_mdp_video_avr_vtotal_setup(struct mdss_mdp_ctl *ctl,
struct mdss_mdp_video_ctx *ctx)
{
struct mdss_data_type *mdata = ctl->mdata;
+ struct mdss_mdp_ctl *sctl = NULL;
+ struct mdss_mdp_video_ctx *sctx = NULL;
if (test_bit(MDSS_CAPS_AVR_SUPPORTED, mdata->mdss_caps_map)) {
struct mdss_panel_data *pdata = ctl->panel_data;
@@ -435,6 +440,17 @@ static void mdss_mdp_video_avr_vtotal_setup(struct mdss_mdp_ctl *ctl,
mdp_video_write(ctx, MDSS_MDP_REG_INTF_AVR_VTOTAL, avr_vtotal);
+ /*
+ * Make sure config goes through
+ */
+ wmb();
+
+ sctl = mdss_mdp_get_split_ctl(ctl);
+ if (sctl)
+ sctx = (struct mdss_mdp_video_ctx *)
+ sctl->intf_ctx[MASTER_CTX];
+ mdss_mdp_video_timegen_flush(ctl, ctx);
+
MDSS_XLOG(pinfo->min_fps, pinfo->default_fps, avr_vtotal);
}
}
@@ -461,8 +477,9 @@ static int mdss_mdp_video_avr_trigger_setup(struct mdss_mdp_ctl *ctl)
}
static void mdss_mdp_video_avr_ctrl_setup(struct mdss_mdp_video_ctx *ctx,
- struct mdss_mdp_avr_info *avr_info, bool is_master, bool enable)
+ struct mdss_mdp_ctl *ctl, bool is_master, bool enable)
{
+ struct mdss_mdp_avr_info *avr_info = &ctl->avr_info;
u32 avr_ctrl = 0;
u32 avr_mode = 0;
@@ -475,9 +492,18 @@ static void mdss_mdp_video_avr_ctrl_setup(struct mdss_mdp_video_ctx *ctx,
if (avr_mode == MDSS_MDP_AVR_ONE_SHOT)
avr_mode |= (1 << 8);
- if (is_master)
+ if (is_master) {
mdp_video_write(ctx, MDSS_MDP_REG_INTF_AVR_CONTROL, avr_ctrl);
+ /*
+ * When AVR is enabled, need to setup DSI Video mode control
+ */
+ mdss_mdp_ctl_intf_event(ctl,
+ MDSS_EVENT_AVR_MODE,
+ (void *)(unsigned long) avr_ctrl,
+ CTL_INTF_EVENT_FLAG_DEFAULT);
+ }
+
mdp_video_write(ctx, MDSS_MDP_REG_INTF_AVR_MODE, avr_mode);
pr_debug("intf:%d avr_mode:%x avr_ctrl:%x\n",
@@ -1435,7 +1461,6 @@ static int mdss_mdp_video_config_fps(struct mdss_mdp_ctl *ctl, int new_fps)
}
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
-
/*
* Need to disable AVR during DFPS update period.
* Next commit will restore the AVR settings.
@@ -1844,6 +1869,7 @@ static void mdss_mdp_handoff_programmable_fetch(struct mdss_mdp_ctl *ctl,
struct mdss_mdp_video_ctx *ctx)
{
struct mdss_panel_info *pinfo = &ctl->panel_data->panel_info;
+
u32 fetch_start_handoff, v_total_handoff, h_total_handoff;
pinfo->prg_fet = 0;
if (mdp_video_read(ctx, MDSS_MDP_REG_INTF_CONFIG) & BIT(31)) {
@@ -2269,7 +2295,7 @@ static int mdss_mdp_video_avr_ctrl(struct mdss_mdp_ctl *ctl, bool enable)
pr_err("invalid master ctx\n");
return -EINVAL;
}
- mdss_mdp_video_avr_ctrl_setup(ctx, &ctl->avr_info, ctl->is_master,
+ mdss_mdp_video_avr_ctrl_setup(ctx, ctl, ctl->is_master,
enable);
if (is_pingpong_split(ctl->mfd)) {
@@ -2278,7 +2304,7 @@ static int mdss_mdp_video_avr_ctrl(struct mdss_mdp_ctl *ctl, bool enable)
pr_err("invalid slave ctx\n");
return -EINVAL;
}
- mdss_mdp_video_avr_ctrl_setup(sctx, &ctl->avr_info, false,
+ mdss_mdp_video_avr_ctrl_setup(sctx, ctl, false,
enable);
}
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c
index e1d2a947a77f..5b284e624c7f 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c
@@ -125,6 +125,48 @@ static inline void mdp_wb_write(struct mdss_mdp_writeback_ctx *ctx,
writel_relaxed(val, ctx->base + reg);
}
+static void mdss_mdp_qos_vbif_remapper_setup_wb(struct mdss_mdp_ctl *ctl,
+ struct mdss_mdp_writeback_ctx *ctx)
+{
+ u32 mask, reg_val, reg_val_lvl, reg_high, i, vbif_qos;
+ struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+ bool is_nrt_vbif = (ctl->mixer_left && ctl->mixer_left->rotator_mode);
+
+ if (!mdata->vbif_nrt_qos)
+ return;
+
+ if (test_bit(MDSS_QOS_REMAPPER, mdata->mdss_qos_map)) {
+ mutex_lock(&mdata->reg_lock);
+ for (i = 0; i < mdata->npriority_lvl; i++) {
+ reg_high = ((ctx->xin_id & 0x8) >> 3) * 4 + (i * 8);
+
+ reg_val = MDSS_VBIF_READ(mdata,
+ MDSS_VBIF_QOS_RP_REMAP_BASE +
+ reg_high, is_nrt_vbif);
+ reg_val_lvl = MDSS_VBIF_READ(mdata,
+ MDSS_VBIF_QOS_LVL_REMAP_BASE + reg_high,
+ is_nrt_vbif);
+
+ mask = 0x3 << (ctx->xin_id * 4);
+ vbif_qos = mdata->vbif_nrt_qos[i];
+
+ reg_val &= ~(mask);
+ reg_val |= vbif_qos << (ctx->xin_id * 4);
+
+ reg_val_lvl &= ~(mask);
+ reg_val_lvl |= vbif_qos << (ctx->xin_id * 4);
+
+ pr_debug("idx:%d xin:%d reg:0x%x val:0x%x lvl:0x%x\n",
+ i, ctx->xin_id, reg_high, reg_val, reg_val_lvl);
+ MDSS_VBIF_WRITE(mdata, MDSS_VBIF_QOS_RP_REMAP_BASE +
+ reg_high, reg_val, is_nrt_vbif);
+ MDSS_VBIF_WRITE(mdata, MDSS_VBIF_QOS_LVL_REMAP_BASE +
+ reg_high, reg_val_lvl, is_nrt_vbif);
+ }
+ mutex_unlock(&mdata->reg_lock);
+ }
+}
+
static void mdss_mdp_set_qos_wb(struct mdss_mdp_ctl *ctl,
struct mdss_mdp_writeback_ctx *ctx)
{
@@ -133,12 +175,15 @@ static void mdss_mdp_set_qos_wb(struct mdss_mdp_ctl *ctl,
struct mdss_overlay_private *mdp5_data;
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
- if (false == test_bit(MDSS_QOS_WB_QOS, mdata->mdss_qos_map))
- return;
-
mdp5_data = mfd_to_mdp5_data(ctl->mfd);
cwb = &mdp5_data->cwb;
+ if (!cwb->valid)
+ mdss_mdp_qos_vbif_remapper_setup_wb(ctl, ctx);
+
+ if (false == test_bit(MDSS_QOS_WB_QOS, mdata->mdss_qos_map))
+ return;
+
if (cwb->valid)
wb_qos_setup = QOS_LUT_CWB_READ;
else
diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
index 9864d611e8e4..c49f4f2a4ad6 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
@@ -4495,8 +4495,10 @@ static int mdss_bl_scale_config(struct msm_fb_data_type *mfd,
mfd->bl_scale = data->scale;
pr_debug("update scale = %d\n", mfd->bl_scale);
- /* update current backlight to use new scaling*/
- mdss_fb_set_backlight(mfd, curr_bl);
+ /* Update current backlight to use new scaling, if it is not zero */
+ if (curr_bl)
+ mdss_fb_set_backlight(mfd, curr_bl);
+
mutex_unlock(&mfd->bl_lock);
return ret;
}
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pipe.c b/drivers/video/fbdev/msm/mdss_mdp_pipe.c
index 563cb8be1a04..bd41cb9e025c 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pipe.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pipe.c
@@ -1011,8 +1011,10 @@ static void mdss_mdp_qos_vbif_remapper_setup(struct mdss_data_type *mdata,
u32 mask, reg_val, reg_val_lvl, i, vbif_qos;
u32 reg_high;
bool is_nrt_vbif = mdss_mdp_is_nrt_vbif_client(mdata, pipe);
+ u32 *vbif_qos_ptr = is_realtime ? mdata->vbif_rt_qos :
+ mdata->vbif_nrt_qos;
- if (mdata->npriority_lvl == 0)
+ if ((mdata->npriority_lvl == 0) || !vbif_qos_ptr)
return;
if (test_bit(MDSS_QOS_REMAPPER, mdata->mdss_qos_map)) {
@@ -1028,8 +1030,7 @@ static void mdss_mdp_qos_vbif_remapper_setup(struct mdss_data_type *mdata,
is_nrt_vbif);
mask = 0x3 << (pipe->xin_id * 4);
- vbif_qos = is_realtime ?
- mdata->vbif_rt_qos[i] : mdata->vbif_nrt_qos[i];
+ vbif_qos = vbif_qos_ptr[i];
reg_val &= ~(mask);
reg_val |= vbif_qos << (pipe->xin_id * 4);
@@ -1053,8 +1054,7 @@ static void mdss_mdp_qos_vbif_remapper_setup(struct mdss_data_type *mdata,
mask = 0x3 << (pipe->xin_id * 2);
reg_val &= ~(mask);
- vbif_qos = is_realtime ?
- mdata->vbif_rt_qos[i] : mdata->vbif_nrt_qos[i];
+ vbif_qos = vbif_qos_ptr[i];
reg_val |= vbif_qos << (pipe->xin_id * 2);
MDSS_VBIF_WRITE(mdata, MDSS_VBIF_QOS_REMAP_BASE + i*4,
reg_val, is_nrt_vbif);
diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h
index 3fc5b2226b3e..d73416e311b5 100644
--- a/drivers/video/fbdev/msm/mdss_panel.h
+++ b/drivers/video/fbdev/msm/mdss_panel.h
@@ -265,6 +265,10 @@ struct mdss_intf_recovery {
* Argument provided is bits per pixel (8/10/12)
* @MDSS_EVENT_UPDATE_PANEL_PPM: update pixel clock by input PPM.
* Argument provided is parts per million.
+ * @MDSS_EVENT_AVR_MODE: Setup DSI Video mode to support AVR based on the
+ * avr mode passed as argument
+ * 0 - disable AVR support
+ * 1 - enable AVR support
*/
enum mdss_intf_events {
MDSS_EVENT_RESET = 1,
@@ -299,6 +303,7 @@ enum mdss_intf_events {
MDSS_EVENT_DISABLE_PANEL,
MDSS_EVENT_UPDATE_PANEL_PPM,
MDSS_EVENT_DSI_TIMING_DB_CTRL,
+ MDSS_EVENT_AVR_MODE,
MDSS_EVENT_MAX,
};
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 624a57a9c4aa..c6a499b7547e 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -275,11 +275,11 @@ loop:
goto loop;
end_loop:
- write_unlock(&journal->j_state_lock);
del_timer_sync(&journal->j_commit_timer);
journal->j_task = NULL;
wake_up(&journal->j_wait_done_commit);
jbd_debug(1, "Journal thread exiting.\n");
+ write_unlock(&journal->j_state_lock);
return 0;
}
diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h
index fad58671c49e..62acf17a894b 100644
--- a/include/linux/iio/consumer.h
+++ b/include/linux/iio/consumer.h
@@ -161,6 +161,16 @@ int iio_read_channel_processed(struct iio_channel *chan, int *val);
int iio_write_channel_raw(struct iio_channel *chan, int val);
/**
+ * iio_write_channel_processed() - write to a given channel
+ * @chan: The channel being queried.
+ * @val: Value being written.
+ *
+ * Note processed writes to iio channels are converted to raw
+ * values before being written.
+ */
+int iio_write_channel_processed(struct iio_channel *chan, int val);
+
+/**
* iio_get_channel_type() - get the type of a channel
* @channel: The channel being queried.
* @type: The type of the channel.
diff --git a/include/linux/msm_ext_display.h b/include/linux/msm_ext_display.h
index 44a04b5c2fcd..4378080da0d9 100644
--- a/include/linux/msm_ext_display.h
+++ b/include/linux/msm_ext_display.h
@@ -91,7 +91,7 @@ enum msm_ext_disp_power_state {
/**
* struct msm_ext_disp_intf_ops - operations exposed to display interface
* @hpd: updates external display interface state
- * @notify: updates audio framework with interface state
+ * @notify: acknowledgment to power on or off
*/
struct msm_ext_disp_intf_ops {
int (*hpd)(struct platform_device *pdev,
@@ -100,8 +100,7 @@ struct msm_ext_disp_intf_ops {
u32 flags);
int (*notify)(struct platform_device *pdev,
enum msm_ext_disp_cable_state state);
- int (*ack)(struct platform_device *pdev,
- u32 ack);
+ int (*ack)(struct platform_device *pdev, u32 ack);
};
/**
diff --git a/include/linux/msm_gsi.h b/include/linux/msm_gsi.h
index fb2607dd365b..6037fbf00a23 100644
--- a/include/linux/msm_gsi.h
+++ b/include/linux/msm_gsi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1040,6 +1040,19 @@ int gsi_configure_regs(phys_addr_t gsi_base_addr, u32 gsi_size,
*/
int gsi_enable_fw(phys_addr_t gsi_base_addr, u32 gsi_size);
+/**
+ * gsi_get_inst_ram_offset_and_size - Peripheral should call this function
+ * to get instruction RAM base address offset and size. Peripheral typically
+ * uses this info to load GSI FW into the IRAM.
+ *
+ * @base_offset:[OUT] - IRAM base offset address
+ * @size: [OUT] - IRAM size
+
+ * @Return none
+ */
+void gsi_get_inst_ram_offset_and_size(unsigned long *base_offset,
+ unsigned long *size);
+
/*
* Here is a typical sequence of calls
*
@@ -1227,9 +1240,15 @@ static inline int gsi_configure_regs(phys_addr_t gsi_base_addr, u32 gsi_size,
{
return -GSI_STATUS_UNSUPPORTED_OP;
}
+
static inline int gsi_enable_fw(phys_addr_t gsi_base_addr, u32 gsi_size)
{
return -GSI_STATUS_UNSUPPORTED_OP;
}
+
+static inline void gsi_get_inst_ram_offset_and_size(unsigned long *base_offset,
+ unsigned long *size)
+{
+}
#endif
#endif
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 8f95c91c059a..64f5c4ca09d5 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -237,6 +237,7 @@ enum power_supply_property {
POWER_SUPPLY_PROP_FCC_DELTA,
POWER_SUPPLY_PROP_ICL_REDUCTION,
POWER_SUPPLY_PROP_PARALLEL_MODE,
+ POWER_SUPPLY_PROP_CONNECTOR_THERM_ZONE,
/* Local extensions of type int64_t */
POWER_SUPPLY_PROP_CHARGE_COUNTER_EXT,
/* Properties of type `const char *' */
diff --git a/include/linux/qdsp6v2/apr_tal.h b/include/linux/qdsp6v2/apr_tal.h
index c2c49dd748de..bf324064960b 100644
--- a/include/linux/qdsp6v2/apr_tal.h
+++ b/include/linux/qdsp6v2/apr_tal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, 2016 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2011, 2016-2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -32,7 +32,6 @@
#if defined(CONFIG_MSM_QDSP6_APRV2_GLINK) || \
defined(CONFIG_MSM_QDSP6_APRV3_GLINK)
#define APR_MAX_BUF 512
-#define APR_NUM_OF_TX_BUF 30
#else
#define APR_MAX_BUF 8092
#endif
diff --git a/include/linux/regulator/qpnp-regulator.h b/include/linux/regulator/qpnp-regulator.h
index c7afeb50f244..36288c068ac3 100644
--- a/include/linux/regulator/qpnp-regulator.h
+++ b/include/linux/regulator/qpnp-regulator.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -158,8 +158,8 @@ enum qpnp_boost_current_limit {
struct qpnp_regulator_platform_data {
struct regulator_init_data init_data;
int pull_down_enable;
- unsigned pin_ctrl_enable;
- unsigned pin_ctrl_hpm;
+ unsigned int pin_ctrl_enable;
+ unsigned int pin_ctrl_hpm;
int system_load;
int enable_time;
int ocp_enable;
diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h
index 418eb97110a3..ef8a092251aa 100644
--- a/include/linux/sched/sysctl.h
+++ b/include/linux/sched/sysctl.h
@@ -45,6 +45,14 @@ extern unsigned int sysctl_sched_initial_task_util;
extern unsigned int sysctl_sched_cstate_aware;
#ifdef CONFIG_SCHED_HMP
+
+enum freq_reporting_policy {
+ FREQ_REPORT_MAX_CPU_LOAD_TOP_TASK,
+ FREQ_REPORT_CPU_LOAD,
+ FREQ_REPORT_TOP_TASK,
+ FREQ_REPORT_INVALID_POLICY
+};
+
extern int sysctl_sched_freq_inc_notify;
extern int sysctl_sched_freq_dec_notify;
extern unsigned int sysctl_sched_freq_reporting_policy;
diff --git a/include/linux/usb/xhci_pdriver.h b/include/linux/usb/xhci_pdriver.h
index 376654b5b0f7..a44b53c33e75 100644
--- a/include/linux/usb/xhci_pdriver.h
+++ b/include/linux/usb/xhci_pdriver.h
@@ -19,9 +19,13 @@
* @usb3_lpm_capable: determines if this xhci platform supports USB3
* LPM capability
*
+ * @imod_interval: minimum inter-interrupt interval. Specified in
+ * 250nsec increments.
+ *
*/
struct usb_xhci_pdata {
unsigned usb3_lpm_capable:1;
+ unsigned imod_interval;
};
#endif /* __USB_CORE_XHCI_PDRIVER_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index e5930177c96a..1ce3ea1fd917 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5474,6 +5474,21 @@ int cfg80211_iter_combinations(struct wiphy *wiphy,
void *data),
void *data);
+/*
+ * cfg80211_stop_iface - trigger interface disconnection
+ *
+ * @wiphy: the wiphy
+ * @wdev: wireless device
+ * @gfp: context flags
+ *
+ * Trigger interface to be stopped as if AP was stopped, IBSS/mesh left, STA
+ * disconnected.
+ *
+ * Note: This doesn't need any locks and is asynchronous.
+ */
+void cfg80211_stop_iface(struct wiphy *wiphy, struct wireless_dev *wdev,
+ gfp_t gfp);
+
/**
* cfg80211_shutdown_all_interfaces - shut down all interfaces for a wiphy
* @wiphy: the wiphy to shut down
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index a047a33334d2..1f8bba7e9ab7 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -42,6 +42,8 @@ struct param_outband {
#define ADM_MATRIX_ID_AUDIO_TX 1
#define ADM_MATRIX_ID_COMPRESSED_AUDIO_RX 2
+
+#define ADM_MATRIX_ID_LISTEN_TX 4
/* Enumeration for an audio Tx matrix ID.*/
#define ADM_MATRIX_ID_AUDIOX 1
@@ -9044,6 +9046,7 @@ struct asm_aptx_dec_fmt_blk_v2 {
#define LSM_SESSION_EVENT_DETECTION_STATUS_V2 (0x00012B01)
#define LSM_DATA_EVENT_READ_DONE (0x00012B02)
#define LSM_DATA_EVENT_STATUS (0x00012B03)
+#define LSM_SESSION_EVENT_DETECTION_STATUS_V3 (0x00012B04)
#define LSM_MODULE_ID_VOICE_WAKEUP (0x00012C00)
#define LSM_PARAM_ID_ENDPOINT_DETECT_THRESHOLD (0x00012C01)
@@ -9056,6 +9059,12 @@ struct asm_aptx_dec_fmt_blk_v2 {
#define LSM_PARAM_ID_LAB_ENABLE (0x00012C09)
#define LSM_PARAM_ID_LAB_CONFIG (0x00012C0A)
#define LSM_MODULE_ID_FRAMEWORK (0x00012C0E)
+#define LSM_PARAM_ID_SWMAD_CFG (0x00012C18)
+#define LSM_PARAM_ID_SWMAD_MODEL (0x00012C19)
+#define LSM_PARAM_ID_SWMAD_ENABLE (0x00012C1A)
+#define LSM_PARAM_ID_POLLING_ENABLE (0x00012C1B)
+#define LSM_PARAM_ID_MEDIA_FMT (0x00012C1E)
+#define LSM_PARAM_ID_FWK_MODE_CONFIG (0x00012C27)
/* HW MAD specific */
#define AFE_MODULE_HW_MAD (0x00010230)
@@ -10172,6 +10181,7 @@ enum {
COMPRESSED_PASSTHROUGH,
COMPRESSED_PASSTHROUGH_CONVERT,
COMPRESSED_PASSTHROUGH_DSD,
+ LISTEN,
};
#define AUDPROC_MODULE_ID_COMPRESSED_MUTE 0x00010770
diff --git a/include/sound/cpe_core.h b/include/sound/cpe_core.h
index 323a63fd6238..846cf819b9e5 100644
--- a/include/sound/cpe_core.h
+++ b/include/sound/cpe_core.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016, Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -162,7 +162,7 @@ struct wcd_cpe_lsm_ops {
int (*lsm_set_one_param)(void *core_handle,
struct cpe_lsm_session *session,
struct lsm_params_info *p_info,
- void *data, enum LSM_PARAM_TYPE param_type);
+ void *data, uint32_t param_type);
void (*lsm_get_snd_model_offset)
(void *core_handle, struct cpe_lsm_session *,
size_t *offset);
diff --git a/include/sound/q6adm-v2.h b/include/sound/q6adm-v2.h
index 8c7da3b9838d..25376315dd20 100644
--- a/include/sound/q6adm-v2.h
+++ b/include/sound/q6adm-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -96,7 +96,7 @@ int adm_unmap_rtac_block(uint32_t *mem_map_handle);
int adm_close(int port, int topology, int perf_mode);
int adm_matrix_map(int path, struct route_payload payload_map,
- int perf_mode);
+ int perf_mode, uint32_t passthr_mode);
int adm_connect_afe_port(int mode, int session_id, int port_id);
diff --git a/include/sound/q6lsm.h b/include/sound/q6lsm.h
index fb848bc70873..4805246766d6 100644
--- a/include/sound/q6lsm.h
+++ b/include/sound/q6lsm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015, Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -21,6 +21,10 @@
#define MAX_NUM_CONFIDENCE 20
+#define ADM_LSM_PORT_ID 0xADCB
+
+#define LSM_MAX_NUM_CHANNELS 8
+
typedef void (*lsm_app_cb)(uint32_t opcode, uint32_t token,
uint32_t *payload, void *priv);
@@ -49,11 +53,12 @@ struct lsm_lab_buffer {
uint32_t mem_map_handle;
};
-struct lsm_lab_hw_params {
+struct lsm_hw_params {
u16 sample_rate;
u16 sample_size;
u32 buf_sz;
u32 period_count;
+ u16 num_chs;
};
struct lsm_client {
@@ -79,8 +84,12 @@ struct lsm_client {
bool lab_enable;
bool lab_started;
struct lsm_lab_buffer *lab_buffer;
- struct lsm_lab_hw_params hw_params;
+ struct lsm_hw_params hw_params;
bool use_topology;
+ int session_state;
+ bool poll_enable;
+ int perf_mode;
+ uint32_t event_mode;
};
struct lsm_stream_cmd_open_tx {
@@ -134,6 +143,27 @@ struct lsm_param_connect_to_port {
uint16_t reserved;
} __packed;
+struct lsm_param_poll_enable {
+ struct lsm_param_payload_common common;
+ uint32_t minor_version;
+ /* indicates to voice wakeup that HW MAD/SW polling is enabled or not */
+ uint32_t polling_enable;
+} __packed;
+
+struct lsm_param_fwk_mode_cfg {
+ struct lsm_param_payload_common common;
+ uint32_t minor_version;
+ uint32_t mode;
+} __packed;
+
+struct lsm_param_media_fmt {
+ struct lsm_param_payload_common common;
+ uint32_t minor_version;
+ uint32_t sample_rate;
+ uint16_t num_channels;
+ uint16_t bit_width;
+ uint8_t channel_mapping[LSM_MAX_NUM_CHANNELS];
+} __packed;
/*
* This param cannot be sent in this format.
@@ -163,11 +193,22 @@ struct lsm_cmd_set_params_conf {
struct lsm_param_min_confidence_levels conf_payload;
} __packed;
-struct lsm_cmd_set_opmode_connectport {
+struct lsm_cmd_set_params_opmode {
+ struct apr_hdr msg_hdr;
+ struct lsm_set_params_hdr params_hdr;
+ struct lsm_param_op_mode op_mode;
+} __packed;
+
+struct lsm_cmd_set_connectport {
+ struct apr_hdr msg_hdr;
+ struct lsm_set_params_hdr params_hdr;
+ struct lsm_param_connect_to_port connect_to_port;
+} __packed;
+
+struct lsm_cmd_poll_enable {
struct apr_hdr msg_hdr;
struct lsm_set_params_hdr params_hdr;
- struct lsm_param_connect_to_port connect_to_port;
- struct lsm_param_op_mode op_mode;
+ struct lsm_param_poll_enable poll_enable;
} __packed;
struct lsm_param_epd_thres {
@@ -250,6 +291,19 @@ struct lsm_cmd_read_done {
uint32_t flags;
} __packed;
+struct lsm_cmd_set_fwk_mode_cfg {
+ struct apr_hdr msg_hdr;
+ struct lsm_set_params_hdr params_hdr;
+ struct lsm_param_fwk_mode_cfg fwk_mode_cfg;
+} __packed;
+
+struct lsm_cmd_set_media_fmt {
+ struct apr_hdr msg_hdr;
+ struct lsm_set_params_hdr params_hdr;
+ struct lsm_param_media_fmt media_fmt;
+} __packed;
+
+
struct lsm_client *q6lsm_client_alloc(lsm_app_cb cb, void *priv);
void q6lsm_client_free(struct lsm_client *client);
int q6lsm_open(struct lsm_client *client, uint16_t app_id);
@@ -274,8 +328,11 @@ int q6lsm_read(struct lsm_client *client, struct lsm_cmd_read *read);
int q6lsm_lab_buffer_alloc(struct lsm_client *client, bool alloc);
int q6lsm_set_one_param(struct lsm_client *client,
struct lsm_params_info *p_info, void *data,
- enum LSM_PARAM_TYPE param_type);
+ uint32_t param_type);
void q6lsm_sm_set_param_data(struct lsm_client *client,
struct lsm_params_info *p_info,
size_t *offset);
+int q6lsm_set_port_connected(struct lsm_client *client);
+int q6lsm_set_fwk_mode_cfg(struct lsm_client *client, uint32_t event_mode);
+int q6lsm_set_media_fmt_params(struct lsm_client *client);
#endif /* __Q6LSM_H__ */
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index 8fdf57504ab6..c8653a9f0e9e 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -1058,6 +1058,9 @@ enum vl42_mpeg_vidc_video_h264_svc_nal {
(V4L2_CID_MPEG_MSM_VIDC_BASE + 68)
enum v4l2_mpeg_vidc_video_perf_mode {
+#define V4L2_MPEG_VIDC_VIDEO_PERF_UNINIT \
+ V4L2_MPEG_VIDC_VIDEO_PERF_UNINIT
+ V4L2_MPEG_VIDC_VIDEO_PERF_UNINIT = 0,
V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY = 1,
V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE = 2
};
diff --git a/include/uapi/media/msm_vidc.h b/include/uapi/media/msm_vidc.h
index b259bdef8a93..e9370cb660b2 100644
--- a/include/uapi/media/msm_vidc.h
+++ b/include/uapi/media/msm_vidc.h
@@ -245,7 +245,7 @@ enum msm_vidc_extradata_type {
MSM_VIDC_EXTRADATA_DIGITAL_ZOOM = 0x07000010,
#define MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO \
MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO
- MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO = 0x070000011,
+ MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO = 0x00000014,
MSM_VIDC_EXTRADATA_MULTISLICE_INFO = 0x7F100000,
MSM_VIDC_EXTRADATA_NUM_CONCEALED_MB = 0x7F100001,
MSM_VIDC_EXTRADATA_INDEX = 0x7F100002,
diff --git a/include/uapi/sound/lsm_params.h b/include/uapi/sound/lsm_params.h
index eafdc117413a..9ca5930475ba 100644
--- a/include/uapi/sound/lsm_params.h
+++ b/include/uapi/sound/lsm_params.h
@@ -1,6 +1,9 @@
#ifndef _UAPI_LSM_PARAMS_H__
#define _UAPI_LSM_PARAMS_H__
+#define LSM_POLLING_ENABLE_SUPPORT
+#define LSM_EVENT_TIMESTAMP_MODE_SUPPORT
+
#include <linux/types.h>
#include <sound/asound.h>
@@ -18,6 +21,19 @@
#define LSM_OUT_TRANSFER_MODE_RT (0)
#define LSM_OUT_TRANSFER_MODE_FTRT (1)
+#define LSM_ENDPOINT_DETECT_THRESHOLD (0)
+#define LSM_OPERATION_MODE (1)
+#define LSM_GAIN (2)
+#define LSM_MIN_CONFIDENCE_LEVELS (3)
+#define LSM_REG_SND_MODEL (4)
+#define LSM_DEREG_SND_MODEL (5)
+#define LSM_CUSTOM_PARAMS (6)
+#define LSM_POLLING_ENABLE (7)
+#define LSM_PARAMS_MAX (LSM_POLLING_ENABLE + 1)
+
+#define LSM_EVENT_NON_TIME_STAMP_MODE (0)
+#define LSM_EVENT_TIME_STAMP_MODE (1)
+
enum lsm_app_id {
LSM_VOICE_WAKEUP_APP_ID = 1,
LSM_VOICE_WAKEUP_APP_ID_V2 = 2,
@@ -35,18 +51,6 @@ enum lsm_vw_status {
LSM_VOICE_WAKEUP_STATUS_REJECTED
};
-enum LSM_PARAM_TYPE {
- LSM_ENDPOINT_DETECT_THRESHOLD = 0,
- LSM_OPERATION_MODE,
- LSM_GAIN,
- LSM_MIN_CONFIDENCE_LEVELS,
- LSM_REG_SND_MODEL,
- LSM_DEREG_SND_MODEL,
- LSM_CUSTOM_PARAMS,
- /* driver ioctl will parse only so many params */
- LSM_PARAMS_MAX,
-};
-
/*
* Data for LSM_ENDPOINT_DETECT_THRESHOLD param_type
* @epd_begin: Begin threshold
@@ -75,6 +79,14 @@ struct snd_lsm_gain {
__u16 gain;
};
+/*
+ * Data for LSM_POLLING_ENABLE param_type
+ * @poll_en: Polling enable or disable
+ */
+struct snd_lsm_poll_enable {
+ bool poll_en;
+};
+
struct snd_lsm_sound_model_v2 {
__u8 __user *data;
@@ -95,11 +107,20 @@ struct snd_lsm_event_status {
__u8 payload[0];
};
+struct snd_lsm_event_status_v3 {
+ __u32 timestamp_lsw;
+ __u32 timestamp_msw;
+ __u16 status;
+ __u16 payload_size;
+ __u8 payload[0];
+};
+
struct snd_lsm_detection_params {
__u8 *conf_level;
enum lsm_detection_mode detect_mode;
__u8 num_confidence_levels;
bool detect_failure;
+ bool poll_enable;
};
/*
@@ -122,7 +143,7 @@ struct lsm_params_info {
__u32 param_id;
__u32 param_size;
__u8 __user *param_data;
- enum LSM_PARAM_TYPE param_type;
+ uint32_t param_type;
};
/*
@@ -171,5 +192,9 @@ struct snd_lsm_output_format_cfg {
struct snd_lsm_module_params)
#define SNDRV_LSM_OUT_FORMAT_CFG _IOW('U', 0x0C, \
struct snd_lsm_output_format_cfg)
+#define SNDRV_LSM_SET_PORT _IO('U', 0x0D)
+#define SNDRV_LSM_SET_FWK_MODE_CONFIG _IOW('U', 0x0E, uint32_t)
+#define SNDRV_LSM_EVENT_STATUS_V3 _IOW('U', 0x0F, \
+ struct snd_lsm_event_status_v3)
#endif
diff --git a/kernel/sched/boost.c b/kernel/sched/boost.c
index fcfda385b74a..5bdd51b1e55e 100644
--- a/kernel/sched/boost.c
+++ b/kernel/sched/boost.c
@@ -156,9 +156,6 @@ void sched_boost_parse_dt(void)
struct device_node *sn;
const char *boost_policy;
- if (!sched_enable_hmp)
- return;
-
sn = of_find_node_by_path("/sched-hmp");
if (!sn)
return;
@@ -175,9 +172,6 @@ int sched_set_boost(int type)
{
int ret = 0;
- if (!sched_enable_hmp)
- return -EINVAL;
-
mutex_lock(&boost_mutex);
if (verify_boost_params(sysctl_sched_boost, type))
@@ -197,9 +191,6 @@ int sched_boost_handler(struct ctl_table *table, int write,
unsigned int *data = (unsigned int *)table->data;
unsigned int old_val;
- if (!sched_enable_hmp)
- return -EINVAL;
-
mutex_lock(&boost_mutex);
old_val = *data;
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 672ed90fc879..3fcadbae663d 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -3025,8 +3025,9 @@ void sched_exec(void)
unsigned long flags;
int dest_cpu, curr_cpu;
- if (sched_enable_hmp)
- return;
+#ifdef CONFIG_SCHED_HMP
+ return;
+#endif
raw_spin_lock_irqsave(&p->pi_lock, flags);
curr_cpu = task_cpu(p);
@@ -8215,8 +8216,9 @@ void __init sched_init(void)
int i, j;
unsigned long alloc_size = 0, ptr;
- if (sched_enable_hmp)
- pr_info("HMP scheduling enabled.\n");
+#ifdef CONFIG_SCHED_HMP
+ pr_info("HMP scheduling enabled.\n");
+#endif
BUG_ON(num_possible_cpus() > BITS_PER_LONG);
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index ac4c3f1d144a..6f68b0e19c4a 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -3332,9 +3332,9 @@ void _inc_hmp_sched_stats_fair(struct rq *rq,
* inc/dec_nr_big_task and inc/dec_cumulative_runnable_avg called
* from inc_cfs_rq_hmp_stats() have similar checks), we gain a bit on
* efficiency by short-circuiting for_each_sched_entity() loop when
- * !sched_enable_hmp || sched_disable_window_stats
+ * sched_disable_window_stats
*/
- if (!sched_enable_hmp || sched_disable_window_stats)
+ if (sched_disable_window_stats)
return;
for_each_sched_entity(se) {
@@ -3357,7 +3357,7 @@ _dec_hmp_sched_stats_fair(struct rq *rq, struct task_struct *p, int change_cra)
struct sched_entity *se = &p->se;
/* See comment on efficiency in _inc_hmp_sched_stats_fair */
- if (!sched_enable_hmp || sched_disable_window_stats)
+ if (sched_disable_window_stats)
return;
for_each_sched_entity(se) {
@@ -3482,8 +3482,7 @@ static inline int migration_needed(struct task_struct *p, int cpu)
int nice;
struct related_thread_group *grp;
- if (!sched_enable_hmp || p->state != TASK_RUNNING ||
- p->nr_cpus_allowed == 1)
+ if (p->state != TASK_RUNNING || p->nr_cpus_allowed == 1)
return 0;
/* No need to migrate task that is about to be throttled */
@@ -7024,8 +7023,9 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int sd_flag, int wake_f
int want_affine = 0;
int sync = wake_flags & WF_SYNC;
- if (sched_enable_hmp)
- return select_best_cpu(p, prev_cpu, 0, sync);
+#ifdef CONFIG_SCHED_HMP
+ return select_best_cpu(p, prev_cpu, 0, sync);
+#endif
if (sd_flag & SD_BALANCE_WAKE)
want_affine = (!wake_wide(p) && task_fits_max(p, cpu) &&
@@ -9313,8 +9313,9 @@ static struct rq *find_busiest_queue(struct lb_env *env,
unsigned long busiest_load = 0, busiest_capacity = 1;
int i;
- if (sched_enable_hmp)
- return find_busiest_queue_hmp(env, group);
+#ifdef CONFIG_SCHED_HMP
+ return find_busiest_queue_hmp(env, group);
+#endif
for_each_cpu_and(i, sched_group_cpus(group), env->cpus) {
unsigned long capacity, wl;
@@ -10120,8 +10121,9 @@ static inline int find_new_ilb(int type)
{
int ilb;
- if (sched_enable_hmp)
- return find_new_hmp_ilb(type);
+#ifdef CONFIG_SCHED_HMP
+ return find_new_hmp_ilb(type);
+#endif
ilb = cpumask_first(nohz.idle_cpus_mask);
@@ -10496,8 +10498,9 @@ static inline int _nohz_kick_needed(struct rq *rq, int cpu, int *type)
if (likely(!atomic_read(&nohz.nr_cpus)))
return 0;
- if (sched_enable_hmp)
- return _nohz_kick_needed_hmp(rq, cpu, type);
+#ifdef CONFIG_SCHED_HMP
+ return _nohz_kick_needed_hmp(rq, cpu, type);
+#endif
if (time_before(now, nohz.next_balance))
return 0;
diff --git a/kernel/sched/hmp.c b/kernel/sched/hmp.c
index 0a74c8d23552..6379de764236 100644
--- a/kernel/sched/hmp.c
+++ b/kernel/sched/hmp.c
@@ -615,19 +615,6 @@ int register_cpu_cycle_counter_cb(struct cpu_cycle_counter_cb *cb)
return 0;
}
-int __init set_sched_enable_hmp(char *str)
-{
- int enable_hmp = 0;
-
- get_option(&str, &enable_hmp);
-
- sched_enable_hmp = !!enable_hmp;
-
- return 0;
-}
-
-early_param("sched_enable_hmp", set_sched_enable_hmp);
-
/* Clear any HMP scheduler related requests pending from or on cpu */
void clear_hmp_request(int cpu)
{
@@ -869,9 +856,6 @@ unsigned int max_task_load(void)
return sched_ravg_window;
}
-/* Use this knob to turn on or off HMP-aware task placement logic */
-unsigned int __read_mostly sched_enable_hmp;
-
/* A cpu can no longer accommodate more tasks if:
*
* rq->nr_running > sysctl_sched_spill_nr_run ||
@@ -1244,7 +1228,7 @@ unlock:
void inc_nr_big_task(struct hmp_sched_stats *stats, struct task_struct *p)
{
- if (!sched_enable_hmp || sched_disable_window_stats)
+ if (sched_disable_window_stats)
return;
if (is_big_task(p))
@@ -1253,7 +1237,7 @@ void inc_nr_big_task(struct hmp_sched_stats *stats, struct task_struct *p)
void dec_nr_big_task(struct hmp_sched_stats *stats, struct task_struct *p)
{
- if (!sched_enable_hmp || sched_disable_window_stats)
+ if (sched_disable_window_stats)
return;
if (is_big_task(p))
@@ -1322,7 +1306,7 @@ void fixup_nr_big_tasks(struct hmp_sched_stats *stats,
u64 new_task_load;
u64 old_task_load;
- if (!sched_enable_hmp || sched_disable_window_stats)
+ if (sched_disable_window_stats)
return;
old_task_load = scale_load_to_cpu(task_load(p), task_cpu(p));
@@ -1432,9 +1416,6 @@ int sched_window_update_handler(struct ctl_table *table, int write,
unsigned int *data = (unsigned int *)table->data;
unsigned int old_val;
- if (!sched_enable_hmp)
- return -EINVAL;
-
mutex_lock(&policy_mutex);
old_val = *data;
@@ -1470,9 +1451,6 @@ int sched_hmp_proc_update_handler(struct ctl_table *table, int write,
unsigned int *data = (unsigned int *)table->data;
int update_task_count = 0;
- if (!sched_enable_hmp)
- return 0;
-
/*
* The policy mutex is acquired with cpu_hotplug.lock
* held from cpu_up()->cpufreq_governor_interactive()->
@@ -1749,9 +1727,6 @@ static int send_notification(struct rq *rq, int check_pred, int check_groups)
int rc = 0;
u64 group_load = 0, new_load = 0;
- if (!sched_enable_hmp)
- return 0;
-
if (check_pred) {
u64 prev = rq->old_busy_time;
u64 predicted = rq->hmp_stats.pred_demands_sum;
@@ -2812,7 +2787,7 @@ static u64 update_task_demand(struct task_struct *p, struct rq *rq,
}
static inline void
-update_task_burst(struct task_struct *p, struct rq *rq, int event, int runtime)
+update_task_burst(struct task_struct *p, struct rq *rq, int event, u64 runtime)
{
/*
* update_task_demand() has checks for idle task and
@@ -2960,7 +2935,7 @@ void set_window_start(struct rq *rq)
{
static int sync_cpu_available;
- if (rq->window_start || !sched_enable_hmp)
+ if (rq->window_start)
return;
if (!sync_cpu_available) {
@@ -3133,7 +3108,7 @@ static inline u64 freq_policy_load(struct rq *rq, u64 load)
case FREQ_REPORT_CPU_LOAD:
break;
default:
- WARN_ON_ONCE(1);
+ break;
}
return load;
@@ -3539,7 +3514,7 @@ void fixup_busy_time(struct task_struct *p, int new_cpu)
bool new_task;
struct related_thread_group *grp;
- if (!sched_enable_hmp || (!p->on_rq && p->state != TASK_WAKING))
+ if (!p->on_rq && p->state != TASK_WAKING)
return;
if (exiting_task(p)) {
@@ -4246,9 +4221,6 @@ static int register_sched_callback(void)
{
int ret;
- if (!sched_enable_hmp)
- return 0;
-
ret = cpufreq_register_notifier(&notifier_policy_block,
CPUFREQ_POLICY_NOTIFIER);
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 3fe00d6fa335..b72352bbd752 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1406,6 +1406,7 @@ static void yield_task_rt(struct rq *rq)
#ifdef CONFIG_SMP
static int find_lowest_rq(struct task_struct *task);
+#ifdef CONFIG_SCHED_HMP
static int
select_task_rq_rt_hmp(struct task_struct *p, int cpu, int sd_flag, int flags)
{
@@ -1419,6 +1420,7 @@ select_task_rq_rt_hmp(struct task_struct *p, int cpu, int sd_flag, int flags)
return cpu;
}
+#endif
static int
select_task_rq_rt(struct task_struct *p, int cpu, int sd_flag, int flags)
@@ -1426,8 +1428,9 @@ select_task_rq_rt(struct task_struct *p, int cpu, int sd_flag, int flags)
struct task_struct *curr;
struct rq *rq;
- if (sched_enable_hmp)
- return select_task_rq_rt_hmp(p, cpu, sd_flag, flags);
+#ifdef CONFIG_SCHED_HMP
+ return select_task_rq_rt_hmp(p, cpu, sd_flag, flags);
+#endif
/* For anything but wake ups, just return the task_cpu */
if (sd_flag != SD_BALANCE_WAKE && sd_flag != SD_BALANCE_FORK)
@@ -1796,14 +1799,6 @@ static int find_lowest_rq_hmp(struct task_struct *task)
return best_cpu;
}
-
-#else /* CONFIG_SCHED_HMP */
-
-static int find_lowest_rq_hmp(struct task_struct *task)
-{
- return -1;
-}
-
#endif /* CONFIG_SCHED_HMP */
static int find_lowest_rq(struct task_struct *task)
@@ -1813,8 +1808,9 @@ static int find_lowest_rq(struct task_struct *task)
int this_cpu = smp_processor_id();
int cpu = task_cpu(task);
- if (sched_enable_hmp)
- return find_lowest_rq_hmp(task);
+#ifdef CONFIG_SCHED_HMP
+ return find_lowest_rq_hmp(task);
+#endif
/* Make sure the mask is initialized first */
if (unlikely(!lowest_mask))
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 3e2ef7b0df3e..360e298398fb 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1071,10 +1071,6 @@ enum sched_boost_policy {
#define WINDOW_STATS_AVG 3
#define WINDOW_STATS_INVALID_POLICY 4
-#define FREQ_REPORT_MAX_CPU_LOAD_TOP_TASK 0
-#define FREQ_REPORT_CPU_LOAD 1
-#define FREQ_REPORT_TOP_TASK 2
-
#define SCHED_UPMIGRATE_MIN_NICE 15
#define EXITING_TASK_MARKER 0xdeaddead
@@ -1085,7 +1081,6 @@ enum sched_boost_policy {
extern struct mutex policy_mutex;
extern unsigned int sched_ravg_window;
extern unsigned int sched_disable_window_stats;
-extern unsigned int sched_enable_hmp;
extern unsigned int max_possible_freq;
extern unsigned int min_max_freq;
extern unsigned int pct_task_load(struct task_struct *p);
@@ -1129,7 +1124,6 @@ extern void update_cluster_topology(void);
extern void note_task_waking(struct task_struct *p, u64 wallclock);
extern void set_task_last_switch_out(struct task_struct *p, u64 wallclock);
extern void init_clusters(void);
-extern int __init set_sched_enable_hmp(char *str);
extern void reset_cpu_hmp_stats(int cpu, int reset_cra);
extern unsigned int max_task_load(void);
extern void sched_account_irqtime(int cpu, struct task_struct *curr,
@@ -1259,7 +1253,7 @@ inc_cumulative_runnable_avg(struct hmp_sched_stats *stats,
{
u32 task_load;
- if (!sched_enable_hmp || sched_disable_window_stats)
+ if (sched_disable_window_stats)
return;
task_load = sched_disable_window_stats ? 0 : p->ravg.demand;
@@ -1274,7 +1268,7 @@ dec_cumulative_runnable_avg(struct hmp_sched_stats *stats,
{
u32 task_load;
- if (!sched_enable_hmp || sched_disable_window_stats)
+ if (sched_disable_window_stats)
return;
task_load = sched_disable_window_stats ? 0 : p->ravg.demand;
@@ -1292,7 +1286,7 @@ fixup_cumulative_runnable_avg(struct hmp_sched_stats *stats,
struct task_struct *p, s64 task_load_delta,
s64 pred_demand_delta)
{
- if (!sched_enable_hmp || sched_disable_window_stats)
+ if (sched_disable_window_stats)
return;
stats->cumulative_runnable_avg += task_load_delta;
@@ -1661,7 +1655,6 @@ static inline int update_preferred_cluster(struct related_thread_group *grp,
static inline void add_new_task_to_grp(struct task_struct *new) {}
-#define sched_enable_hmp 0
#define PRED_DEMAND_DELTA (0)
static inline void
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index a2a87c3ad44e..7112dc54d88e 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -133,6 +133,7 @@ static int ten_thousand = 10000;
#endif
#ifdef CONFIG_SCHED_HMP
static int one_thousand = 1000;
+static int max_freq_reporting_policy = FREQ_REPORT_INVALID_POLICY - 1;
#endif
/* this is needed for the proc_doulongvec_minmax of vm_dirty_bytes */
@@ -297,6 +298,7 @@ static struct ctl_table kern_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec_minmax,
.extra1 = &zero,
+ .extra2 = &max_freq_reporting_policy,
},
{
.procname = "sched_freq_inc_notify",
@@ -591,7 +593,8 @@ static struct ctl_table kern_table[] = {
.data = &sysctl_sched_time_avg,
.maxlen = sizeof(unsigned int),
.mode = 0644,
- .proc_handler = proc_dointvec,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &one,
},
{
.procname = "sched_shares_window_ns",
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 46e60923221f..6f7985e6f129 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -208,6 +208,9 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
u8 *data;
bool pfmemalloc;
+ if (IS_ENABLED(CONFIG_FORCE_ALLOC_FROM_DMA_ZONE))
+ gfp_mask |= GFP_DMA;
+
cache = (flags & SKB_ALLOC_FCLONE)
? skbuff_fclone_cache : skbuff_head_cache;
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 800f1aff472f..00a43a70e1fc 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -132,7 +132,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
IEEE80211_MAX_QUEUE_MAP,
IEEE80211_QUEUE_STOP_REASON_SUSPEND,
false);
- local->wowlan = false;
+ return err;
} else {
goto suspend;
}
diff --git a/net/wireless/ap.c b/net/wireless/ap.c
index f09f5683cb30..91d02ac0f42f 100644
--- a/net/wireless/ap.c
+++ b/net/wireless/ap.c
@@ -6,8 +6,8 @@
#include "rdev-ops.h"
-static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
- struct net_device *dev, bool notify)
+int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
+ struct net_device *dev, bool notify)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
int err;
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 14868e42f3ca..01d0c4eb06fc 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -927,6 +927,92 @@ void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
rdev->num_running_monitor_ifaces += num;
}
+void __cfg80211_leave(struct cfg80211_registered_device *rdev,
+ struct wireless_dev *wdev)
+{
+ struct net_device *dev = wdev->netdev;
+ struct cfg80211_sched_scan_request *sched_scan_req;
+
+ ASSERT_RTNL();
+ ASSERT_WDEV_LOCK(wdev);
+
+ switch (wdev->iftype) {
+ case NL80211_IFTYPE_ADHOC:
+ __cfg80211_leave_ibss(rdev, dev, true);
+ break;
+ case NL80211_IFTYPE_P2P_CLIENT:
+ case NL80211_IFTYPE_STATION:
+ sched_scan_req = rtnl_dereference(rdev->sched_scan_req);
+ if (sched_scan_req && dev == sched_scan_req->dev)
+ __cfg80211_stop_sched_scan(rdev, false);
+#ifdef CONFIG_CFG80211_WEXT
+ kfree(wdev->wext.ie);
+ wdev->wext.ie = NULL;
+ wdev->wext.ie_len = 0;
+ wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
+#endif
+ cfg80211_disconnect(rdev, dev,
+ WLAN_REASON_DEAUTH_LEAVING, true);
+ cfg80211_mlme_down(rdev, dev);
+ break;
+ case NL80211_IFTYPE_MESH_POINT:
+ __cfg80211_leave_mesh(rdev, dev);
+ break;
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_P2P_GO:
+ __cfg80211_stop_ap(rdev, dev, true);
+ break;
+ case NL80211_IFTYPE_OCB:
+ __cfg80211_leave_ocb(rdev, dev);
+ break;
+ case NL80211_IFTYPE_WDS:
+ /* must be handled by mac80211/driver, has no APIs */
+ break;
+ case NL80211_IFTYPE_P2P_DEVICE:
+ /* cannot happen, has no netdev */
+ break;
+ case NL80211_IFTYPE_AP_VLAN:
+ case NL80211_IFTYPE_MONITOR:
+ /* nothing to do */
+ break;
+ case NL80211_IFTYPE_UNSPECIFIED:
+ case NUM_NL80211_IFTYPES:
+ /* invalid */
+ break;
+ }
+ wdev->beacon_interval = 0;
+}
+
+void cfg80211_leave(struct cfg80211_registered_device *rdev,
+ struct wireless_dev *wdev)
+{
+ wdev_lock(wdev);
+ __cfg80211_leave(rdev, wdev);
+ wdev_unlock(wdev);
+}
+
+void cfg80211_stop_iface(struct wiphy *wiphy, struct wireless_dev *wdev,
+ gfp_t gfp)
+{
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+ struct cfg80211_event *ev;
+ unsigned long flags;
+
+ trace_cfg80211_stop_iface(wiphy, wdev);
+
+ ev = kzalloc(sizeof(*ev), gfp);
+ if (!ev)
+ return;
+
+ ev->type = EVENT_STOPPED;
+
+ spin_lock_irqsave(&wdev->event_lock, flags);
+ list_add_tail(&ev->list, &wdev->event_list);
+ spin_unlock_irqrestore(&wdev->event_lock, flags);
+ queue_work(cfg80211_wq, &rdev->event_work);
+}
+EXPORT_SYMBOL(cfg80211_stop_iface);
+
static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
unsigned long state, void *ptr)
{
@@ -988,40 +1074,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
dev->priv_flags |= IFF_DONT_BRIDGE;
break;
case NETDEV_GOING_DOWN:
- switch (wdev->iftype) {
- case NL80211_IFTYPE_ADHOC:
- cfg80211_leave_ibss(rdev, dev, true);
- break;
- case NL80211_IFTYPE_P2P_CLIENT:
- case NL80211_IFTYPE_STATION:
- ASSERT_RTNL();
- sched_scan_req = rtnl_dereference(rdev->sched_scan_req);
- if (sched_scan_req && dev == sched_scan_req->dev)
- __cfg80211_stop_sched_scan(rdev, false);
-
- wdev_lock(wdev);
-#ifdef CONFIG_CFG80211_WEXT
- kfree(wdev->wext.ie);
- wdev->wext.ie = NULL;
- wdev->wext.ie_len = 0;
- wdev->wext.connect.auth_type =
- NL80211_AUTHTYPE_AUTOMATIC;
-#endif
- cfg80211_disconnect(rdev, dev,
- WLAN_REASON_DEAUTH_LEAVING, true);
- cfg80211_mlme_down(rdev, dev);
- wdev_unlock(wdev);
- break;
- case NL80211_IFTYPE_MESH_POINT:
- cfg80211_leave_mesh(rdev, dev);
- break;
- case NL80211_IFTYPE_AP:
- cfg80211_stop_ap(rdev, dev, false);
- break;
- default:
- break;
- }
- wdev->beacon_interval = 0;
+ cfg80211_leave(rdev, wdev);
break;
case NETDEV_DOWN:
cfg80211_update_iface_num(rdev, wdev->iftype, -1);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index a06a1056f726..a972e386ad7f 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -199,6 +199,7 @@ enum cfg80211_event_type {
EVENT_ROAMED,
EVENT_DISCONNECTED,
EVENT_IBSS_JOINED,
+ EVENT_STOPPED,
};
struct cfg80211_event {
@@ -297,6 +298,8 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
struct net_device *dev,
struct mesh_setup *setup,
const struct mesh_config *conf);
+int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
+ struct net_device *dev);
int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
struct net_device *dev);
int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
@@ -316,6 +319,8 @@ int cfg80211_leave_ocb(struct cfg80211_registered_device *rdev,
struct net_device *dev);
/* AP */
+int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
+ struct net_device *dev, bool notify);
int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
struct net_device *dev, bool notify);
@@ -470,6 +475,11 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
enum nl80211_iftype iftype, int num);
+void __cfg80211_leave(struct cfg80211_registered_device *rdev,
+ struct wireless_dev *wdev);
+void cfg80211_leave(struct cfg80211_registered_device *rdev,
+ struct wireless_dev *wdev);
+
void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev);
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 929795af643f..092300b30c37 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -238,8 +238,8 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
return 0;
}
-static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
- struct net_device *dev)
+int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
+ struct net_device *dev)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
int err;
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index b3675ce67a8b..6bde2241bffa 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -6,11 +6,12 @@
#include "core.h"
#include "trace.h"
-static inline int rdev_suspend(struct cfg80211_registered_device *rdev)
+static inline int rdev_suspend(struct cfg80211_registered_device *rdev,
+ struct cfg80211_wowlan *wowlan)
{
int ret;
- trace_rdev_suspend(&rdev->wiphy, rdev->wiphy.wowlan_config);
- ret = rdev->ops->suspend(&rdev->wiphy, rdev->wiphy.wowlan_config);
+ trace_rdev_suspend(&rdev->wiphy, wowlan);
+ ret = rdev->ops->suspend(&rdev->wiphy, wowlan);
trace_rdev_return_int(&rdev->wiphy, ret);
return ret;
}
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 0178de1fc9aa..460c4b0e343c 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -94,12 +94,11 @@ static int wiphy_suspend(struct device *dev)
rdev->suspend_at = get_seconds();
- if (rdev->ops->suspend) {
- rtnl_lock();
- if (rdev->wiphy.registered)
- ret = rdev_suspend(rdev);
- rtnl_unlock();
- }
+ rtnl_lock();
+ if (rdev->wiphy.registered)
+ if (rdev->ops->suspend)
+ ret = rdev_suspend(rdev, NULL);
+ rtnl_unlock();
return ret;
}
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 500d72ac719a..b7bf5ba63555 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -2827,6 +2827,22 @@ DEFINE_EVENT(wiphy_wdev_evt, rdev_abort_scan,
TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev),
TP_ARGS(wiphy, wdev)
);
+
+TRACE_EVENT(cfg80211_stop_iface,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev),
+ TP_ARGS(wiphy, wdev),
+ TP_STRUCT__entry(
+ WIPHY_ENTRY
+ WDEV_ENTRY
+ ),
+ TP_fast_assign(
+ WIPHY_ASSIGN;
+ WDEV_ASSIGN;
+ ),
+ TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT,
+ WIPHY_PR_ARG, WDEV_PR_ARG)
+);
+
#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
#undef TRACE_INCLUDE_PATH
diff --git a/net/wireless/util.c b/net/wireless/util.c
index ef394e8a42bc..dfd0766abd6f 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -895,6 +895,9 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev)
__cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid,
ev->ij.channel);
break;
+ case EVENT_STOPPED:
+ __cfg80211_leave(wiphy_to_rdev(wdev->wiphy), wdev);
+ break;
}
wdev_unlock(wdev);
@@ -1080,7 +1083,7 @@ static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate)
58500000,
65000000,
78000000,
- 0,
+ 86500000,
},
{ 13500000,
27000000,
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 328b4a43f09a..b73133885384 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -375,7 +375,8 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
* the elapsed time to detect xruns.
*/
jdelta = curr_jiffies - runtime->hw_ptr_jiffies;
- if (jdelta < runtime->hw_ptr_buffer_jiffies / 2)
+ if ((jdelta < runtime->hw_ptr_buffer_jiffies / 2) ||
+ (runtime->hw_ptr_buffer_jiffies <= 0))
goto no_delta_check;
hdelta = jdelta - delta * HZ / runtime->rate;
xrun_threshold = runtime->hw_ptr_buffer_jiffies / 2 + 1;
diff --git a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c
index 5c210dc2176e..df0bdf666ba1 100644
--- a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c
+++ b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c
@@ -50,6 +50,9 @@ static unsigned long rx_digital_gain_reg[] = {
static unsigned long tx_digital_gain_reg[] = {
MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN,
MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN,
+ MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN,
+ MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN,
+ MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN,
};
static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
@@ -729,6 +732,7 @@ static int msm_dig_cdc_hw_params(struct snd_pcm_substream *substream,
MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 0x20, 0x20);
break;
case SNDRV_PCM_FORMAT_S24_LE:
+ case SNDRV_PCM_FORMAT_S24_3LE:
snd_soc_update_bits(dai->codec,
MSM89XX_CDC_CORE_CLK_RX_I2S_CTL, 0x20, 0x00);
break;
@@ -799,13 +803,8 @@ static int msm_dig_cdc_codec_enable_dmic(struct snd_soc_dapm_widget *w,
dmic_clk_en, dmic_clk_en);
}
snd_soc_update_bits(codec,
- MSM89XX_CDC_CORE_TX1_DMIC_CTL, 0x07, 0x02);
- snd_soc_update_bits(codec,
- MSM89XX_CDC_CORE_TX2_DMIC_CTL, 0x07, 0x02);
- snd_soc_update_bits(codec,
- MSM89XX_CDC_CORE_TX3_DMIC_CTL, 0x07, 0x02);
- snd_soc_update_bits(codec,
- MSM89XX_CDC_CORE_TX4_DMIC_CTL, 0x07, 0x02);
+ MSM89XX_CDC_CORE_TX1_DMIC_CTL + (dmic - 1) * 0x20,
+ 0x07, 0x02);
break;
case SND_SOC_DAPM_POST_PMD:
(*dmic_clk_cnt)--;
@@ -884,6 +883,10 @@ static int msm_dig_cdc_codec_enable_dec(struct snd_soc_dapm_widget *w,
32 * (decimator - 1);
tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX1_MUX_CTL +
32 * (decimator - 1);
+ if (decimator == 5) {
+ tx_vol_ctl_reg = MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG;
+ tx_mux_ctl_reg = MSM89XX_CDC_CORE_TX5_MUX_CTL;
+ }
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@@ -1225,11 +1228,18 @@ static const struct snd_soc_dapm_route audio_dig_map[] = {
{"I2S TX1", NULL, "DEC1 MUX"},
{"I2S TX2", NULL, "DEC2 MUX"},
- {"I2S TX3", NULL, "DEC3 MUX"},
- {"I2S TX4", NULL, "DEC4 MUX"},
+ {"I2S TX3", NULL, "I2S TX2 INP1"},
+ {"I2S TX4", NULL, "I2S TX2 INP2"},
{"I2S TX5", NULL, "DEC3 MUX"},
- {"I2S TX6", NULL, "DEC4 MUX"},
- {"I2S TX6", NULL, "DEC5 MUX"},
+ {"I2S TX6", NULL, "I2S TX3 INP2"},
+
+ {"I2S TX2 INP1", "RX_MIX1", "RX1 MIX2"},
+ {"I2S TX2 INP1", "DEC3", "DEC3 MUX"},
+ {"I2S TX2 INP2", "RX_MIX2", "RX2 MIX2"},
+ {"I2S TX2 INP2", "RX_MIX3", "RX3 MIX1"},
+ {"I2S TX2 INP2", "DEC4", "DEC4 MUX"},
+ {"I2S TX3 INP2", "DEC4", "DEC4 MUX"},
+ {"I2S TX3 INP2", "DEC5", "DEC5 MUX"},
{"PDM_OUT_RX1", NULL, "RX1 CHAIN"},
{"PDM_OUT_RX2", NULL, "RX2 CHAIN"},
@@ -1350,6 +1360,19 @@ static const struct snd_soc_dapm_route audio_dig_map[] = {
{"IIR1 INP1 MUX", "DEC4", "DEC4 MUX"},
};
+
+static const char * const i2s_tx2_inp1_text[] = {
+ "ZERO", "RX_MIX1", "DEC3"
+};
+
+static const char * const i2s_tx2_inp2_text[] = {
+ "ZERO", "RX_MIX2", "RX_MIX3", "DEC4"
+};
+
+static const char * const i2s_tx3_inp2_text[] = {
+ "DEC4", "DEC5"
+};
+
static const char * const rx_mix1_text[] = {
"ZERO", "IIR1", "IIR2", "RX1", "RX2", "RX3"
};
@@ -1365,6 +1388,20 @@ static const char * const dec_mux_text[] = {
static const char * const iir_inp1_text[] = {
"ZERO", "DEC1", "DEC2", "RX1", "RX2", "RX3", "DEC3", "DEC4"
};
+
+/* I2S TX MUXes */
+static const struct soc_enum i2s_tx2_inp1_chain_enum =
+ SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL,
+ 2, 3, i2s_tx2_inp1_text);
+
+static const struct soc_enum i2s_tx2_inp2_chain_enum =
+ SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL,
+ 0, 4, i2s_tx2_inp2_text);
+
+static const struct soc_enum i2s_tx3_inp2_chain_enum =
+ SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL,
+ 4, 2, i2s_tx3_inp2_text);
+
/* RX1 MIX1 */
static const struct soc_enum rx_mix1_inp1_chain_enum =
SOC_ENUM_SINGLE(MSM89XX_CDC_CORE_CONN_RX1_B1_CTL,
@@ -1482,6 +1519,15 @@ static const struct snd_kcontrol_new dec4_mux =
static const struct snd_kcontrol_new decsva_mux =
MSM89XX_DEC_ENUM("DEC5 MUX Mux", decsva_mux_enum);
+static const struct snd_kcontrol_new i2s_tx2_inp1_mux =
+ SOC_DAPM_ENUM("I2S TX2 INP1 Mux", i2s_tx2_inp1_chain_enum);
+
+static const struct snd_kcontrol_new i2s_tx2_inp2_mux =
+ SOC_DAPM_ENUM("I2S TX2 INP2 Mux", i2s_tx2_inp2_chain_enum);
+
+static const struct snd_kcontrol_new i2s_tx3_inp2_mux =
+ SOC_DAPM_ENUM("I2S TX3 INP2 Mux", i2s_tx3_inp2_chain_enum);
+
static const struct snd_kcontrol_new iir1_inp1_mux =
SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum);
@@ -1623,6 +1669,14 @@ static const struct snd_soc_dapm_widget msm_dig_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("TX_I2S_CLK",
MSM89XX_CDC_CORE_CLK_TX_I2S_CTL, 4, 0, NULL, 0),
+
+ SND_SOC_DAPM_MUX("I2S TX2 INP1", SND_SOC_NOPM, 0, 0,
+ &i2s_tx2_inp1_mux),
+ SND_SOC_DAPM_MUX("I2S TX2 INP2", SND_SOC_NOPM, 0, 0,
+ &i2s_tx2_inp2_mux),
+ SND_SOC_DAPM_MUX("I2S TX3 INP2", SND_SOC_NOPM, 0, 0,
+ &i2s_tx3_inp2_mux),
+
/* Digital Mic Inputs */
SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
msm_dig_cdc_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
diff --git a/sound/soc/codecs/wcd-dsp-mgr.c b/sound/soc/codecs/wcd-dsp-mgr.c
index f51301d1ab08..71a2052f1089 100644
--- a/sound/soc/codecs/wcd-dsp-mgr.c
+++ b/sound/soc/codecs/wcd-dsp-mgr.c
@@ -1,5 +1,4 @@
-/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -881,12 +880,50 @@ done:
static int wdsp_suspend(struct device *wdsp_dev)
{
- return 0;
+ struct wdsp_mgr_priv *wdsp;
+ int rc = 0, i;
+
+ if (!wdsp_dev) {
+ pr_err("%s: Invalid handle to device\n", __func__);
+ return -EINVAL;
+ }
+
+ wdsp = dev_get_drvdata(wdsp_dev);
+
+ for (i = WDSP_CMPNT_TYPE_MAX - 1; i >= 0; i--) {
+ rc = wdsp_unicast_event(wdsp, i, WDSP_EVENT_SUSPEND, NULL);
+ if (rc < 0) {
+ WDSP_ERR(wdsp, "component %s failed to suspend\n",
+ WDSP_GET_CMPNT_TYPE_STR(i));
+ break;
+ }
+ }
+
+ return rc;
}
static int wdsp_resume(struct device *wdsp_dev)
{
- return 0;
+ struct wdsp_mgr_priv *wdsp;
+ int rc = 0, i;
+
+ if (!wdsp_dev) {
+ pr_err("%s: Invalid handle to device\n", __func__);
+ return -EINVAL;
+ }
+
+ wdsp = dev_get_drvdata(wdsp_dev);
+
+ for (i = 0; i < WDSP_CMPNT_TYPE_MAX; i++) {
+ rc = wdsp_unicast_event(wdsp, i, WDSP_EVENT_RESUME, NULL);
+ if (rc < 0) {
+ WDSP_ERR(wdsp, "component %s failed to resume\n",
+ WDSP_GET_CMPNT_TYPE_STR(i));
+ break;
+ }
+ }
+
+ return rc;
}
static struct wdsp_mgr_ops wdsp_ops = {
diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c
index cb201899b4b8..8454ebfc6216 100644
--- a/sound/soc/codecs/wcd-mbhc-v2.c
+++ b/sound/soc/codecs/wcd-mbhc-v2.c
@@ -1610,12 +1610,8 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc)
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, 0);
wcd_mbhc_report_plug(mbhc, 0, SND_JACK_LINEOUT);
} else if (mbhc->current_plug == MBHC_PLUG_TYPE_ANC_HEADPHONE) {
- mbhc->mbhc_cb->irq_control(codec,
- mbhc->intr_ids->mbhc_hs_rem_intr,
- false);
- mbhc->mbhc_cb->irq_control(codec,
- mbhc->intr_ids->mbhc_hs_ins_intr,
- false);
+ wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_REM, false);
+ wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS, false);
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_DETECTION_TYPE,
0);
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, 0);
diff --git a/sound/soc/codecs/wcd-spi.c b/sound/soc/codecs/wcd-spi.c
index 614410c26a91..b03a8a9caed7 100644
--- a/sound/soc/codecs/wcd-spi.c
+++ b/sound/soc/codecs/wcd-spi.c
@@ -1,5 +1,4 @@
-/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -60,7 +59,8 @@
/* Command delays */
#define WCD_SPI_CLKREQ_DELAY_USECS (500)
-#define WCD_SPI_CLK_OFF_TIMER_MS (3000)
+#define WCD_SPI_CLK_OFF_TIMER_MS (500)
+#define WCD_SPI_RESUME_TIMEOUT_MS 100
/* Command masks */
#define WCD_CMD_ADDR_MASK \
@@ -90,6 +90,7 @@
/* Status mask bits */
#define WCD_SPI_CLK_STATE_ENABLED BIT(0)
+#define WCD_SPI_IS_SUSPENDED BIT(1)
/* Locking related */
#define WCD_SPI_MUTEX_LOCK(spi, lock) \
@@ -144,6 +145,9 @@ struct wcd_spi_priv {
/* Debugfs related information */
struct wcd_spi_debug_data debug_data;
+
+ /* Completion object to indicate system resume completion */
+ struct completion resume_comp;
};
enum xfer_request {
@@ -170,6 +174,55 @@ static void wcd_spi_reinit_xfer(struct spi_transfer *xfer)
xfer->len = 0;
}
+static bool wcd_spi_is_suspended(struct wcd_spi_priv *wcd_spi)
+{
+ return test_bit(WCD_SPI_IS_SUSPENDED, &wcd_spi->status_mask);
+}
+
+static bool wcd_spi_can_suspend(struct wcd_spi_priv *wcd_spi)
+{
+ struct spi_device *spi = wcd_spi->spi;
+
+ if (wcd_spi->clk_users > 0 ||
+ test_bit(WCD_SPI_CLK_STATE_ENABLED, &wcd_spi->status_mask)) {
+ dev_err(&spi->dev, "%s: cannot suspend, clk_users = %d\n",
+ __func__, wcd_spi->clk_users);
+ return false;
+ }
+
+ return true;
+}
+
+static int wcd_spi_wait_for_resume(struct wcd_spi_priv *wcd_spi)
+{
+ struct spi_device *spi = wcd_spi->spi;
+ int rc = 0;
+
+ WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex);
+ /* If the system is already in resumed state, return right away */
+ if (!wcd_spi_is_suspended(wcd_spi))
+ goto done;
+
+ /* If suspended then wait for resume to happen */
+ reinit_completion(&wcd_spi->resume_comp);
+ WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex);
+ rc = wait_for_completion_timeout(&wcd_spi->resume_comp,
+ msecs_to_jiffies(WCD_SPI_RESUME_TIMEOUT_MS));
+ WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex);
+ if (rc == 0) {
+ dev_err(&spi->dev, "%s: failed to resume in %u msec\n",
+ __func__, WCD_SPI_RESUME_TIMEOUT_MS);
+ rc = -EIO;
+ goto done;
+ }
+
+ dev_dbg(&spi->dev, "%s: resume successful\n", __func__);
+ rc = 0;
+done:
+ WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex);
+ return rc;
+}
+
static int wcd_spi_read_single(struct spi_device *spi,
u32 remote_addr, u32 *val)
{
@@ -579,6 +632,18 @@ static int wcd_spi_clk_ctrl(struct spi_device *spi,
}
if (request == WCD_SPI_CLK_ENABLE) {
+ /*
+ * If the SPI bus is suspended, then return error
+ * as the transaction cannot be completed.
+ */
+ if (wcd_spi_is_suspended(wcd_spi)) {
+ dev_err(&spi->dev,
+ "%s: SPI suspended, cannot enable clk\n",
+ __func__);
+ ret = -EIO;
+ goto done;
+ }
+
/* Cancel the disable clk work */
WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex);
cancel_delayed_work_sync(&wcd_spi->clk_dwork);
@@ -899,6 +964,17 @@ static int wdsp_spi_event_handler(struct device *dev, void *priv_data,
ret = wdsp_spi_read_section(spi, data);
break;
+ case WDSP_EVENT_SUSPEND:
+ WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex);
+ if (!wcd_spi_can_suspend(wcd_spi))
+ ret = -EBUSY;
+ WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex);
+ break;
+
+ case WDSP_EVENT_RESUME:
+ ret = wcd_spi_wait_for_resume(wcd_spi);
+ break;
+
default:
dev_dbg(&spi->dev, "%s: Unhandled event %d\n",
__func__, event);
@@ -1303,6 +1379,7 @@ static int wcd_spi_probe(struct spi_device *spi)
mutex_init(&wcd_spi->clk_mutex);
mutex_init(&wcd_spi->xfer_mutex);
INIT_DELAYED_WORK(&wcd_spi->clk_dwork, wcd_spi_clk_work);
+ init_completion(&wcd_spi->resume_comp);
wcd_spi->spi = spi;
spi_set_drvdata(spi, wcd_spi);
@@ -1340,6 +1417,61 @@ static int wcd_spi_remove(struct spi_device *spi)
return 0;
}
+#ifdef CONFIG_PM
+static int wcd_spi_suspend(struct device *dev)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi);
+ int rc = 0;
+
+ WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex);
+ if (!wcd_spi_can_suspend(wcd_spi)) {
+ rc = -EBUSY;
+ goto done;
+ }
+
+ /*
+ * If we are here, it is okay to let the suspend go
+ * through for this driver. But, still need to notify
+ * the master to make sure all other components can suspend
+ * as well.
+ */
+ if (wcd_spi->m_dev && wcd_spi->m_ops &&
+ wcd_spi->m_ops->suspend) {
+ WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex);
+ rc = wcd_spi->m_ops->suspend(wcd_spi->m_dev);
+ WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex);
+ }
+
+ if (rc == 0)
+ set_bit(WCD_SPI_IS_SUSPENDED, &wcd_spi->status_mask);
+ else
+ dev_dbg(&spi->dev, "%s: cannot suspend, err = %d\n",
+ __func__, rc);
+done:
+ WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex);
+ return rc;
+}
+
+static int wcd_spi_resume(struct device *dev)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ struct wcd_spi_priv *wcd_spi = spi_get_drvdata(spi);
+
+ WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex);
+ clear_bit(WCD_SPI_IS_SUSPENDED, &wcd_spi->status_mask);
+ complete(&wcd_spi->resume_comp);
+ WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex);
+
+ return 0;
+}
+
+static const struct dev_pm_ops wcd_spi_pm_ops = {
+ .suspend = wcd_spi_suspend,
+ .resume = wcd_spi_resume,
+};
+#endif
+
static const struct of_device_id wcd_spi_of_match[] = {
{ .compatible = "qcom,wcd-spi-v2", },
{ }
@@ -1350,6 +1482,9 @@ static struct spi_driver wcd_spi_driver = {
.driver = {
.name = "wcd-spi-v2",
.of_match_table = wcd_spi_of_match,
+#ifdef CONFIG_PM
+ .pm = &wcd_spi_pm_ops,
+#endif
},
.probe = wcd_spi_probe,
.remove = wcd_spi_remove,
diff --git a/sound/soc/codecs/wcd934x/wcd934x-routing.h b/sound/soc/codecs/wcd934x/wcd934x-routing.h
index 8ca4c07a3327..cd165af43eab 100644
--- a/sound/soc/codecs/wcd934x/wcd934x-routing.h
+++ b/sound/soc/codecs/wcd934x/wcd934x-routing.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -914,9 +914,23 @@ const struct snd_soc_dapm_route tavil_audio_map[] = {
{"ANC OUT EAR Enable", "Switch", "ADC MUX11"},
{"RX INT0 MIX2", NULL, "ANC OUT EAR Enable"},
+ {"ANC OUT HPHL Enable", "Switch", "ADC MUX10"},
+ {"ANC OUT HPHL Enable", "Switch", "ADC MUX11"},
+ {"RX INT1 MIX2", NULL, "ANC OUT HPHL Enable"},
+
+ {"ANC OUT HPHR Enable", "Switch", "ADC MUX12"},
+ {"ANC OUT HPHR Enable", "Switch", "ADC MUX13"},
+ {"RX INT2 MIX2", NULL, "ANC OUT HPHR Enable"},
+
{"ANC EAR PA", NULL, "RX INT0 DAC"},
{"ANC EAR", NULL, "ANC EAR PA"},
+ {"ANC HPHL PA", NULL, "RX INT1 DAC"},
+ {"ANC HPHL", NULL, "ANC HPHL PA"},
+
+ {"ANC HPHR PA", NULL, "RX INT2 DAC"},
+ {"ANC HPHR", NULL, "ANC HPHR PA"},
+
{"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX10"},
{"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX11"},
{"RX INT7 MIX2", NULL, "ANC OUT EAR SPKR Enable"},
diff --git a/sound/soc/codecs/wcd934x/wcd934x.c b/sound/soc/codecs/wcd934x/wcd934x.c
index c5d2b1ce8151..5b300a668489 100644
--- a/sound/soc/codecs/wcd934x/wcd934x.c
+++ b/sound/soc/codecs/wcd934x/wcd934x.c
@@ -176,6 +176,10 @@ enum {
AUDIO_NOMINAL,
HPH_PA_DELAY,
CLSH_Z_CONFIG,
+ ANC_MIC_AMIC1,
+ ANC_MIC_AMIC2,
+ ANC_MIC_AMIC3,
+ ANC_MIC_AMIC4,
};
enum {
@@ -510,6 +514,7 @@ module_param(tx_unmute_delay, int,
S_IRUGO | S_IWUSR | S_IWGRP);
MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path");
+static void tavil_codec_set_tx_hold(struct snd_soc_codec *, u16, bool);
/* Hold instance to soundwire platform device */
struct tavil_swr_ctrl_data {
@@ -998,14 +1003,30 @@ static int tavil_put_anc_func(struct snd_kcontrol *kcontrol,
snd_soc_dapm_enable_pin(dapm, "ANC EAR PA");
snd_soc_dapm_enable_pin(dapm, "ANC EAR");
snd_soc_dapm_enable_pin(dapm, "ANC SPK1 PA");
+ snd_soc_dapm_enable_pin(dapm, "ANC HPHL PA");
+ snd_soc_dapm_enable_pin(dapm, "ANC HPHR PA");
+ snd_soc_dapm_enable_pin(dapm, "ANC HPHL");
+ snd_soc_dapm_enable_pin(dapm, "ANC HPHR");
snd_soc_dapm_disable_pin(dapm, "EAR PA");
snd_soc_dapm_disable_pin(dapm, "EAR");
+ snd_soc_dapm_disable_pin(dapm, "HPHL PA");
+ snd_soc_dapm_disable_pin(dapm, "HPHR PA");
+ snd_soc_dapm_disable_pin(dapm, "HPHL");
+ snd_soc_dapm_disable_pin(dapm, "HPHR");
} else {
snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
snd_soc_dapm_disable_pin(dapm, "ANC EAR");
snd_soc_dapm_disable_pin(dapm, "ANC SPK1 PA");
+ snd_soc_dapm_disable_pin(dapm, "ANC HPHL PA");
+ snd_soc_dapm_disable_pin(dapm, "ANC HPHR PA");
+ snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
+ snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
snd_soc_dapm_enable_pin(dapm, "EAR PA");
snd_soc_dapm_enable_pin(dapm, "EAR");
+ snd_soc_dapm_enable_pin(dapm, "HPHL");
+ snd_soc_dapm_enable_pin(dapm, "HPHR");
+ snd_soc_dapm_enable_pin(dapm, "HPHL PA");
+ snd_soc_dapm_enable_pin(dapm, "HPHR PA");
}
mutex_unlock(&tavil->codec_mutex);
@@ -1122,16 +1143,56 @@ static int tavil_codec_enable_anc(struct snd_soc_dapm_widget *w,
}
/* Rate converter clk enable and set bypass mode */
- snd_soc_update_bits(codec, WCD934X_CDC_ANC0_RC_COMMON_CTL,
- 0x05, 0x05);
+ if (!strcmp(w->name, "RX INT0 DAC") ||
+ !strcmp(w->name, "RX INT1 DAC") ||
+ !strcmp(w->name, "ANC SPK1 PA")) {
+ snd_soc_update_bits(codec,
+ WCD934X_CDC_ANC0_RC_COMMON_CTL,
+ 0x05, 0x05);
+ if (!strcmp(w->name, "RX INT1 DAC")) {
+ snd_soc_update_bits(codec,
+ WCD934X_CDC_ANC0_FIFO_COMMON_CTL,
+ 0x66, 0x66);
+ }
+ } else if (!strcmp(w->name, "RX INT2 DAC")) {
+ snd_soc_update_bits(codec,
+ WCD934X_CDC_ANC1_RC_COMMON_CTL,
+ 0x05, 0x05);
+ snd_soc_update_bits(codec,
+ WCD934X_CDC_ANC1_FIFO_COMMON_CTL,
+ 0x66, 0x66);
+ }
+ if (!strcmp(w->name, "RX INT1 DAC"))
+ snd_soc_update_bits(codec,
+ WCD934X_CDC_ANC0_CLK_RESET_CTL, 0x08, 0x08);
+ else if (!strcmp(w->name, "RX INT2 DAC"))
+ snd_soc_update_bits(codec,
+ WCD934X_CDC_ANC1_CLK_RESET_CTL, 0x08, 0x08);
+
if (!hwdep_cal)
release_firmware(fw);
break;
+
+ case SND_SOC_DAPM_POST_PMU:
+ if (!strcmp(w->name, "ANC HPHL PA") ||
+ !strcmp(w->name, "ANC HPHR PA")) {
+ /* Remove ANC Rx from reset */
+ snd_soc_update_bits(codec,
+ WCD934X_CDC_ANC0_CLK_RESET_CTL,
+ 0x08, 0x00);
+ snd_soc_update_bits(codec,
+ WCD934X_CDC_ANC1_CLK_RESET_CTL,
+ 0x08, 0x00);
+ }
+
+ break;
+
case SND_SOC_DAPM_POST_PMD:
snd_soc_update_bits(codec, WCD934X_CDC_ANC0_RC_COMMON_CTL,
0x05, 0x00);
if (!strcmp(w->name, "ANC EAR PA") ||
- !strcmp(w->name, "ANC SPK1 PA")) {
+ !strcmp(w->name, "ANC SPK1 PA") ||
+ !strcmp(w->name, "ANC HPHL PA")) {
snd_soc_update_bits(codec, WCD934X_CDC_ANC0_MODE_1_CTL,
0x30, 0x00);
msleep(50);
@@ -1146,6 +1207,21 @@ static int tavil_codec_enable_anc(struct snd_soc_dapm_widget *w,
snd_soc_update_bits(codec,
WCD934X_CDC_ANC0_CLK_RESET_CTL,
0x38, 0x00);
+ } else if (!strcmp(w->name, "ANC HPHR PA")) {
+ snd_soc_update_bits(codec, WCD934X_CDC_ANC1_MODE_1_CTL,
+ 0x30, 0x00);
+ msleep(50);
+ snd_soc_update_bits(codec, WCD934X_CDC_ANC1_MODE_1_CTL,
+ 0x01, 0x00);
+ snd_soc_update_bits(codec,
+ WCD934X_CDC_ANC1_CLK_RESET_CTL,
+ 0x38, 0x38);
+ snd_soc_update_bits(codec,
+ WCD934X_CDC_ANC1_CLK_RESET_CTL,
+ 0x07, 0x00);
+ snd_soc_update_bits(codec,
+ WCD934X_CDC_ANC1_CLK_RESET_CTL,
+ 0x38, 0x00);
}
break;
}
@@ -1893,6 +1969,18 @@ static void tavil_codec_override(struct snd_soc_codec *codec, int mode,
}
}
+static void tavil_codec_clear_anc_tx_hold(struct tavil_priv *tavil)
+{
+ if (test_and_clear_bit(ANC_MIC_AMIC1, &tavil->status_mask))
+ tavil_codec_set_tx_hold(tavil->codec, WCD934X_ANA_AMIC1, false);
+ if (test_and_clear_bit(ANC_MIC_AMIC2, &tavil->status_mask))
+ tavil_codec_set_tx_hold(tavil->codec, WCD934X_ANA_AMIC2, false);
+ if (test_and_clear_bit(ANC_MIC_AMIC3, &tavil->status_mask))
+ tavil_codec_set_tx_hold(tavil->codec, WCD934X_ANA_AMIC3, false);
+ if (test_and_clear_bit(ANC_MIC_AMIC4, &tavil->status_mask))
+ tavil_codec_set_tx_hold(tavil->codec, WCD934X_ANA_AMIC4, false);
+}
+
static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol,
int event)
@@ -1900,6 +1988,7 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec);
struct tavil_dsd_config *dsd_conf = tavil->dsd_config;
+ int ret = 0;
dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
@@ -1908,6 +1997,11 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
if (TAVIL_IS_1_0(tavil->wcd9xxx))
snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL,
0x06, (0x03 << 1));
+
+ if ((!(strcmp(w->name, "ANC HPHR PA"))) &&
+ (test_bit(HPH_PA_DELAY, &tavil->status_mask)))
+ snd_soc_update_bits(codec, WCD934X_ANA_HPH, 0xC0, 0xC0);
+
set_bit(HPH_PA_DELAY, &tavil->status_mask);
if (dsd_conf &&
(snd_soc_read(codec, WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) {
@@ -1917,6 +2011,16 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
}
break;
case SND_SOC_DAPM_POST_PMU:
+ if ((!(strcmp(w->name, "ANC HPHR PA")))) {
+ if ((snd_soc_read(codec, WCD934X_ANA_HPH) & 0xC0)
+ != 0xC0)
+ /*
+ * If PA_EN is not set (potentially in ANC case)
+ * then do nothing for POST_PMU and let left
+ * channel handle everything.
+ */
+ break;
+ }
/*
* 7ms sleep is required after PA is enabled as per
* HW requirement. If compander is disabled, then
@@ -1929,6 +2033,12 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
usleep_range(7000, 7100);
clear_bit(HPH_PA_DELAY, &tavil->status_mask);
}
+ if (tavil->anc_func) {
+ /* Clear Tx FE HOLD if both PAs are enabled */
+ if ((snd_soc_read(tavil->codec, WCD934X_ANA_HPH) &
+ 0xC0) == 0xC0)
+ tavil_codec_clear_anc_tx_hold(tavil);
+ }
snd_soc_update_bits(codec, WCD934X_HPH_R_TEST, 0x01, 0x01);
@@ -1951,6 +2061,34 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
(snd_soc_read(codec, WCD934X_CDC_DSD1_PATH_CTL) & 0x01))
snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2,
0x04, 0x00);
+ if (!(strcmp(w->name, "ANC HPHR PA"))) {
+ pr_debug("%s:Do everything needed for left channel\n",
+ __func__);
+ /* Do everything needed for left channel */
+ snd_soc_update_bits(codec, WCD934X_HPH_L_TEST,
+ 0x01, 0x01);
+
+ /* Remove mute */
+ snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CTL,
+ 0x10, 0x00);
+
+ /* Remove mix path mute if it is enabled */
+ if ((snd_soc_read(codec,
+ WCD934X_CDC_RX1_RX_PATH_MIX_CTL)) &
+ 0x10)
+ snd_soc_update_bits(codec,
+ WCD934X_CDC_RX1_RX_PATH_MIX_CTL,
+ 0x10, 0x00);
+
+ if (dsd_conf && (snd_soc_read(codec,
+ WCD934X_CDC_DSD0_PATH_CTL) &
+ 0x01))
+ snd_soc_update_bits(codec,
+ WCD934X_CDC_DSD0_CFG2,
+ 0x04, 0x00);
+ /* Remove ANC Rx from reset */
+ ret = tavil_codec_enable_anc(w, kcontrol, event);
+ }
tavil_codec_override(codec, tavil->hph_mode, event);
break;
case SND_SOC_DAPM_PRE_PMD:
@@ -1967,6 +2105,8 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
0x10, 0x10);
snd_soc_update_bits(codec, WCD934X_CDC_RX2_RX_PATH_MIX_CTL,
0x10, 0x10);
+ if (!(strcmp(w->name, "ANC HPHR PA")))
+ snd_soc_update_bits(codec, WCD934X_ANA_HPH, 0x40, 0x00);
break;
case SND_SOC_DAPM_POST_PMD:
/*
@@ -1984,10 +2124,16 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
if (TAVIL_IS_1_0(tavil->wcd9xxx))
snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL,
0x06, 0x0);
+ if (!(strcmp(w->name, "ANC HPHR PA"))) {
+ ret = tavil_codec_enable_anc(w, kcontrol, event);
+ snd_soc_update_bits(codec,
+ WCD934X_CDC_RX2_RX_PATH_CFG0,
+ 0x10, 0x00);
+ }
break;
};
- return 0;
+ return ret;
}
static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
@@ -1997,6 +2143,7 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec);
struct tavil_dsd_config *dsd_conf = tavil->dsd_config;
+ int ret = 0;
dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
@@ -2005,6 +2152,10 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
if (TAVIL_IS_1_0(tavil->wcd9xxx))
snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL,
0x06, (0x03 << 1));
+ if ((!(strcmp(w->name, "ANC HPHL PA"))) &&
+ (test_bit(HPH_PA_DELAY, &tavil->status_mask)))
+ snd_soc_update_bits(codec, WCD934X_ANA_HPH,
+ 0xC0, 0xC0);
set_bit(HPH_PA_DELAY, &tavil->status_mask);
if (dsd_conf &&
(snd_soc_read(codec, WCD934X_CDC_DSD0_PATH_CTL) & 0x01)) {
@@ -2014,6 +2165,16 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
}
break;
case SND_SOC_DAPM_POST_PMU:
+ if (!(strcmp(w->name, "ANC HPHL PA"))) {
+ if ((snd_soc_read(codec, WCD934X_ANA_HPH) & 0xC0)
+ != 0xC0)
+ /*
+ * If PA_EN is not set (potentially in ANC
+ * case) then do nothing for POST_PMU and
+ * let right channel handle everything.
+ */
+ break;
+ }
/*
* 7ms sleep is required after PA is enabled as per
* HW requirement. If compander is disabled, then
@@ -2026,6 +2187,13 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
usleep_range(7000, 7100);
clear_bit(HPH_PA_DELAY, &tavil->status_mask);
}
+ if (tavil->anc_func) {
+ /* Clear Tx FE HOLD if both PAs are enabled */
+ if ((snd_soc_read(tavil->codec, WCD934X_ANA_HPH) &
+ 0xC0) == 0xC0)
+ tavil_codec_clear_anc_tx_hold(tavil);
+ }
+
snd_soc_update_bits(codec, WCD934X_HPH_L_TEST, 0x01, 0x01);
/* Remove Mute on primary path */
snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CTL,
@@ -2046,6 +2214,33 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
(snd_soc_read(codec, WCD934X_CDC_DSD0_PATH_CTL) & 0x01))
snd_soc_update_bits(codec, WCD934X_CDC_DSD0_CFG2,
0x04, 0x00);
+ if (!(strcmp(w->name, "ANC HPHL PA"))) {
+ pr_debug("%s:Do everything needed for right channel\n",
+ __func__);
+
+ /* Do everything needed for right channel */
+ snd_soc_update_bits(codec, WCD934X_HPH_R_TEST,
+ 0x01, 0x01);
+
+ /* Remove mute */
+ snd_soc_update_bits(codec, WCD934X_CDC_RX2_RX_PATH_CTL,
+ 0x10, 0x00);
+
+ /* Remove mix path mute if it is enabled */
+ if ((snd_soc_read(codec,
+ WCD934X_CDC_RX2_RX_PATH_MIX_CTL)) &
+ 0x10)
+ snd_soc_update_bits(codec,
+ WCD934X_CDC_RX2_RX_PATH_MIX_CTL,
+ 0x10, 0x00);
+ if (dsd_conf && (snd_soc_read(codec,
+ WCD934X_CDC_DSD1_PATH_CTL) & 0x01))
+ snd_soc_update_bits(codec,
+ WCD934X_CDC_DSD1_CFG2,
+ 0x04, 0x00);
+ /* Remove ANC Rx from reset */
+ ret = tavil_codec_enable_anc(w, kcontrol, event);
+ }
tavil_codec_override(codec, tavil->hph_mode, event);
break;
case SND_SOC_DAPM_PRE_PMD:
@@ -2063,6 +2258,9 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
0x10, 0x10);
snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_MIX_CTL,
0x10, 0x10);
+ if (!(strcmp(w->name, "ANC HPHL PA")))
+ snd_soc_update_bits(codec, WCD934X_ANA_HPH,
+ 0x80, 0x00);
break;
case SND_SOC_DAPM_POST_PMD:
/*
@@ -2080,10 +2278,15 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
if (TAVIL_IS_1_0(tavil->wcd9xxx))
snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL,
0x06, 0x0);
+ if (!(strcmp(w->name, "ANC HPHL PA"))) {
+ ret = tavil_codec_enable_anc(w, kcontrol, event);
+ snd_soc_update_bits(codec,
+ WCD934X_CDC_RX1_RX_PATH_CFG0, 0x10, 0x00);
+ }
break;
};
- return 0;
+ return ret;
}
static int tavil_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w,
@@ -2190,12 +2393,18 @@ static int tavil_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
int hph_mode = tavil->hph_mode;
u8 dem_inp;
struct tavil_dsd_config *dsd_conf = tavil->dsd_config;
+ int ret = 0;
dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__,
w->name, event, hph_mode);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
+ if (tavil->anc_func) {
+ ret = tavil_codec_enable_anc(w, kcontrol, event);
+ /* 40 msec delay is needed to avoid click and pop */
+ msleep(40);
+ }
/* Read DEM INP Select */
dem_inp = snd_soc_read(codec, WCD934X_CDC_RX2_RX_PATH_SEC0) &
0x03;
@@ -2226,6 +2435,10 @@ static int tavil_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
WCD_CLSH_EVENT_PRE_DAC,
WCD_CLSH_STATE_HPHR,
hph_mode);
+ if (tavil->anc_func)
+ snd_soc_update_bits(codec,
+ WCD934X_CDC_RX2_RX_PATH_CFG0,
+ 0x10, 0x10);
break;
case SND_SOC_DAPM_POST_PMD:
/* 1000us required as per HW requirement */
@@ -2269,6 +2482,11 @@ static int tavil_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
+ if (tavil->anc_func) {
+ ret = tavil_codec_enable_anc(w, kcontrol, event);
+ /* 40 msec delay is needed to avoid click and pop */
+ msleep(40);
+ }
/* Read DEM INP Select */
dem_inp = snd_soc_read(codec, WCD934X_CDC_RX1_RX_PATH_SEC0) &
0x03;
@@ -2300,6 +2518,11 @@ static int tavil_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
WCD_CLSH_STATE_HPHL,
hph_mode);
+ if (tavil->anc_func)
+ snd_soc_update_bits(codec,
+ WCD934X_CDC_RX1_RX_PATH_CFG0,
+ 0x10, 0x10);
+
ret = tavil_mbhc_get_impedance(tavil->mbhc,
&impedl, &impedr);
if (!ret) {
@@ -3184,6 +3407,15 @@ int tavil_codec_enable_interp_clk(struct snd_soc_codec *codec,
}
EXPORT_SYMBOL(tavil_codec_enable_interp_clk);
+static int tavil_anc_out_switch_cb(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+
+ tavil_codec_enable_interp_clk(codec, event, w->shift);
+
+ return 0;
+}
static int tavil_codec_set_idle_detect_thr(struct snd_soc_codec *codec,
int interp, int path_type)
{
@@ -3638,8 +3870,8 @@ static int tavil_codec_tx_adc_cfg(struct snd_soc_dapm_widget *w,
{
int adc_mux_n = w->shift;
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec);
int amic_n;
- u16 amic_reg;
dev_dbg(codec->dev, "%s: event: %d\n", __func__, event);
@@ -3647,8 +3879,13 @@ static int tavil_codec_tx_adc_cfg(struct snd_soc_dapm_widget *w,
case SND_SOC_DAPM_POST_PMU:
amic_n = tavil_codec_find_amic_input(codec, adc_mux_n);
if (amic_n) {
- amic_reg = WCD934X_ANA_AMIC1 + amic_n - 1;
- tavil_codec_set_tx_hold(codec, amic_reg, false);
+ /*
+ * Prevent ANC Rx pop by leaving Tx FE in HOLD
+ * state until PA is up. Track AMIC being used
+ * so we can release the HOLD later.
+ */
+ set_bit(ANC_MIC_AMIC1 + amic_n - 1,
+ &tavil->status_mask);
}
break;
default:
@@ -6471,6 +6708,12 @@ static const struct snd_kcontrol_new anc_ear_spkr_switch =
static const struct snd_kcontrol_new anc_spkr_pa_switch =
SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
+static const struct snd_kcontrol_new anc_hphl_pa_switch =
+ SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
+
+static const struct snd_kcontrol_new anc_hphr_pa_switch =
+ SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
+
static const struct snd_kcontrol_new mad_cpe1_switch =
SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
@@ -7110,6 +7353,14 @@ static const struct snd_soc_dapm_widget tavil_dapm_widgets[] = {
SND_SOC_DAPM_PGA_E("ANC SPK1 PA", SND_SOC_NOPM, 0, 0, NULL, 0,
tavil_codec_enable_spkr_anc,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PGA_E("ANC HPHL PA", SND_SOC_NOPM, 0, 0, NULL, 0,
+ tavil_codec_enable_hphl_pa,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PGA_E("ANC HPHR PA", SND_SOC_NOPM, 0, 0, NULL, 0,
+ tavil_codec_enable_hphr_pa,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_OUTPUT("EAR"),
SND_SOC_DAPM_OUTPUT("HPHL"),
@@ -7119,6 +7370,8 @@ static const struct snd_soc_dapm_widget tavil_dapm_widgets[] = {
SND_SOC_DAPM_OUTPUT("SPK1 OUT"),
SND_SOC_DAPM_OUTPUT("SPK2 OUT"),
SND_SOC_DAPM_OUTPUT("ANC EAR"),
+ SND_SOC_DAPM_OUTPUT("ANC HPHL"),
+ SND_SOC_DAPM_OUTPUT("ANC HPHR"),
SND_SOC_DAPM_SWITCH("ANC OUT EAR Enable", SND_SOC_NOPM, 0, 0,
&anc_ear_switch),
@@ -7127,6 +7380,13 @@ static const struct snd_soc_dapm_widget tavil_dapm_widgets[] = {
SND_SOC_DAPM_SWITCH("ANC SPKR PA Enable", SND_SOC_NOPM, 0, 0,
&anc_spkr_pa_switch),
+ SND_SOC_DAPM_SWITCH_E("ANC OUT HPHL Enable", SND_SOC_NOPM, INTERP_HPHL,
+ 0, &anc_hphl_pa_switch, tavil_anc_out_switch_cb,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_SWITCH_E("ANC OUT HPHR Enable", SND_SOC_NOPM, INTERP_HPHR,
+ 0, &anc_hphr_pa_switch, tavil_anc_out_switch_cb,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
+
SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
tavil_codec_enable_rx_bias,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
@@ -9030,6 +9290,10 @@ static int tavil_soc_codec_probe(struct snd_soc_codec *codec)
mutex_lock(&tavil->codec_mutex);
snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
snd_soc_dapm_disable_pin(dapm, "ANC EAR");
+ snd_soc_dapm_disable_pin(dapm, "ANC HPHL PA");
+ snd_soc_dapm_disable_pin(dapm, "ANC HPHR PA");
+ snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
+ snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
snd_soc_dapm_enable_pin(dapm, "ANC SPK1 PA");
mutex_unlock(&tavil->codec_mutex);
diff --git a/sound/soc/codecs/wcd_cpe_core.c b/sound/soc/codecs/wcd_cpe_core.c
index 2088698392de..2082c356203d 100644
--- a/sound/soc/codecs/wcd_cpe_core.c
+++ b/sound/soc/codecs/wcd_cpe_core.c
@@ -3029,7 +3029,7 @@ err_ret:
static int wcd_cpe_set_one_param(void *core_handle,
struct cpe_lsm_session *session, struct lsm_params_info *p_info,
- void *data, enum LSM_PARAM_TYPE param_type)
+ void *data, uint32_t param_type)
{
struct wcd_cpe_core *core = core_handle;
int rc = 0;
@@ -3044,25 +3044,9 @@ static int wcd_cpe_set_one_param(void *core_handle,
rc = wcd_cpe_send_param_epd_thres(core, session,
data, &ids);
break;
- case LSM_OPERATION_MODE: {
- struct cpe_lsm_ids connectport_ids;
-
- rc = wcd_cpe_send_param_opmode(core, session,
- data, &ids);
- if (rc)
- break;
-
- connectport_ids.module_id = LSM_MODULE_ID_FRAMEWORK;
- connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT;
-
- rc = wcd_cpe_send_param_connectport(core, session, NULL,
- &connectport_ids, CPE_AFE_PORT_1_TX);
- if (rc)
- dev_err(core->dev,
- "%s: send_param_connectport failed, err %d\n",
- __func__, rc);
+ case LSM_OPERATION_MODE:
+ rc = wcd_cpe_send_param_opmode(core, session, data, &ids);
break;
- }
case LSM_GAIN:
rc = wcd_cpe_send_param_gain(core, session, data, &ids);
break;
@@ -3081,13 +3065,13 @@ static int wcd_cpe_set_one_param(void *core_handle,
break;
default:
pr_err("%s: wrong param_type 0x%x\n",
- __func__, p_info->param_type);
+ __func__, param_type);
}
if (rc)
dev_err(core->dev,
"%s: send_param(%d) failed, err %d\n",
- __func__, p_info->param_type, rc);
+ __func__, param_type, rc);
return rc;
}
diff --git a/sound/soc/msm/msm-cpe-lsm.c b/sound/soc/msm/msm-cpe-lsm.c
index ffc6119e543d..b2008d6da2a1 100644
--- a/sound/soc/msm/msm-cpe-lsm.c
+++ b/sound/soc/msm/msm-cpe-lsm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016, Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1049,7 +1049,6 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream,
struct cpe_lsm_lab *lab_d = &lsm_d->lab;
struct snd_dma_buffer *dma_buf = &substream->dma_buffer;
struct msm_slim_dma_data *dma_data = NULL;
- struct snd_lsm_event_status *user;
struct snd_lsm_detection_params det_params;
int rc = 0;
@@ -1318,11 +1317,20 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream,
break;
case SNDRV_LSM_EVENT_STATUS:
+ case SNDRV_LSM_EVENT_STATUS_V3: {
+ struct snd_lsm_event_status *user;
+ struct snd_lsm_event_status_v3 *user_v3;
+
dev_dbg(rtd->dev,
"%s: %s\n",
- __func__, "SNDRV_LSM_EVENT_STATUS");
-
- user = arg;
+ __func__, "SNDRV_LSM_EVENT_STATUS(_V3)");
+ if (!arg) {
+ dev_err(rtd->dev,
+ "%s: Invalid argument to ioctl %s\n",
+ __func__,
+ "SNDRV_LSM_EVENT_STATUS(_V3)");
+ return -EINVAL;
+ }
/*
* Release the api lock before wait to allow
@@ -1343,31 +1351,62 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream,
if (atomic_read(&lsm_d->event_avail) == 1) {
rc = 0;
atomic_set(&lsm_d->event_avail, 0);
- if (lsm_d->ev_det_pld_size >
- user->payload_size) {
- dev_err(rtd->dev,
- "%s: avail pld_bytes = %u, needed = %u\n",
- __func__,
- user->payload_size,
- lsm_d->ev_det_pld_size);
- return -EINVAL;
- }
-
- user->status = lsm_d->ev_det_status;
- user->payload_size = lsm_d->ev_det_pld_size;
-
- memcpy(user->payload,
- lsm_d->ev_det_payload,
- lsm_d->ev_det_pld_size);
+ if (cmd == SNDRV_LSM_EVENT_STATUS) {
+ user = arg;
+ if (lsm_d->ev_det_pld_size >
+ user->payload_size) {
+ dev_err(rtd->dev,
+ "%s: avail pld_bytes = %u, needed = %u\n",
+ __func__,
+ user->payload_size,
+ lsm_d->ev_det_pld_size);
+ return -EINVAL;
+ }
+
+ user->status = lsm_d->ev_det_status;
+ user->payload_size =
+ lsm_d->ev_det_pld_size;
+ memcpy(user->payload,
+ lsm_d->ev_det_payload,
+ lsm_d->ev_det_pld_size);
+ } else {
+ user_v3 = arg;
+ if (lsm_d->ev_det_pld_size >
+ user_v3->payload_size) {
+ dev_err(rtd->dev,
+ "%s: avail pld_bytes = %u, needed = %u\n",
+ __func__,
+ user_v3->payload_size,
+ lsm_d->ev_det_pld_size);
+ return -EINVAL;
+ }
+ /* event status timestamp not supported
+ * on CPE mode. Set msw and lsw to 0.
+ */
+ user_v3->timestamp_lsw = 0;
+ user_v3->timestamp_msw = 0;
+ user_v3->status = lsm_d->ev_det_status;
+ user_v3->payload_size =
+ lsm_d->ev_det_pld_size;
+ memcpy(user_v3->payload,
+ lsm_d->ev_det_payload,
+ lsm_d->ev_det_pld_size);
+ }
} else if (atomic_read(&lsm_d->event_stop) == 1) {
dev_dbg(rtd->dev,
"%s: wait_aborted\n", __func__);
- user->payload_size = 0;
+ if (cmd == SNDRV_LSM_EVENT_STATUS) {
+ user = arg;
+ user->payload_size = 0;
+ } else {
+ user_v3 = arg;
+ user_v3->payload_size = 0;
+ }
rc = 0;
}
}
-
+ }
break;
case SNDRV_LSM_ABORT_EVENT:
@@ -1499,6 +1538,20 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream,
}
break;
+ case SNDRV_LSM_SET_PORT: {
+ u32 port_id = cpe->input_port_id;
+
+ dev_dbg(rtd->dev, "%s: %s\n", __func__, "SNDRV_LSM_SET_PORT");
+ rc = lsm_ops->lsm_set_port(cpe->core_handle, session, &port_id);
+ if (rc) {
+ dev_err(rtd->dev,
+ "%s: lsm_set_port failed, err = %d\n",
+ __func__, rc);
+ return rc;
+ }
+ }
+ break;
+
default:
dev_dbg(rtd->dev,
"%s: Default snd_lib_ioctl cmd 0x%x\n",
@@ -1510,7 +1563,7 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream,
}
static int msm_cpe_lsm_lab_start(struct snd_pcm_substream *substream,
- struct snd_lsm_event_status *event_status)
+ u16 event_det_status)
{
struct snd_soc_pcm_runtime *rtd;
struct cpe_lsm_data *lsm_d = NULL;
@@ -1563,7 +1616,7 @@ static int msm_cpe_lsm_lab_start(struct snd_pcm_substream *substream,
reinit_completion(&lab_d->thread_complete);
if (session->lab_enable &&
- event_status->status ==
+ event_det_status ==
LSM_VOICE_WAKEUP_STATUS_DETECTED) {
out_port = &session->afe_out_port_cfg;
out_port->port_id = session->afe_out_port_id;
@@ -2167,7 +2220,60 @@ static int msm_cpe_lsm_ioctl(struct snd_pcm_substream *substream,
goto done;
}
- msm_cpe_lsm_lab_start(substream, event_status);
+ msm_cpe_lsm_lab_start(substream, event_status->status);
+ msm_cpe_process_event_status_done(lsm_d);
+ kfree(event_status);
+ }
+ break;
+ case SNDRV_LSM_EVENT_STATUS_V3: {
+ struct snd_lsm_event_status_v3 u_event_status;
+ struct snd_lsm_event_status_v3 *event_status = NULL;
+ int u_pld_size = 0;
+
+ if (copy_from_user(&u_event_status, (void *)arg,
+ sizeof(struct snd_lsm_event_status_v3))) {
+ dev_err(rtd->dev,
+ "%s: event status copy from user failed, size %zd\n",
+ __func__,
+ sizeof(struct snd_lsm_event_status_v3));
+ err = -EFAULT;
+ goto done;
+ }
+
+ if (u_event_status.payload_size >
+ LISTEN_MAX_STATUS_PAYLOAD_SIZE) {
+ dev_err(rtd->dev,
+ "%s: payload_size %d is invalid, max allowed = %d\n",
+ __func__, u_event_status.payload_size,
+ LISTEN_MAX_STATUS_PAYLOAD_SIZE);
+ err = -EINVAL;
+ goto done;
+ }
+
+ u_pld_size = sizeof(struct snd_lsm_event_status_v3) +
+ u_event_status.payload_size;
+
+ event_status = kzalloc(u_pld_size, GFP_KERNEL);
+ if (!event_status) {
+ err = -ENOMEM;
+ goto done;
+ } else {
+ event_status->payload_size =
+ u_event_status.payload_size;
+ err = msm_cpe_lsm_ioctl_shared(substream,
+ cmd, event_status);
+ }
+
+ if (!err && copy_to_user(arg, event_status, u_pld_size)) {
+ dev_err(rtd->dev,
+ "%s: copy to user failed\n",
+ __func__);
+ kfree(event_status);
+ err = -EFAULT;
+ goto done;
+ }
+
+ msm_cpe_lsm_lab_start(substream, event_status->status);
msm_cpe_process_event_status_done(lsm_d);
kfree(event_status);
}
@@ -2297,7 +2403,7 @@ struct lsm_params_info_32 {
u32 param_id;
u32 param_size;
compat_uptr_t param_data;
- enum LSM_PARAM_TYPE param_type;
+ uint32_t param_type;
};
struct snd_lsm_module_params_32 {
@@ -2480,7 +2586,97 @@ static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream,
goto done;
}
- msm_cpe_lsm_lab_start(substream, event_status);
+ msm_cpe_lsm_lab_start(substream, event_status->status);
+ msm_cpe_process_event_status_done(lsm_d);
+ kfree(event_status);
+ kfree(udata_32);
+ }
+ break;
+ case SNDRV_LSM_EVENT_STATUS_V3: {
+ struct snd_lsm_event_status_v3 *event_status = NULL;
+ struct snd_lsm_event_status_v3 u_event_status32;
+ struct snd_lsm_event_status_v3 *udata_32 = NULL;
+ int u_pld_size = 0;
+
+ dev_dbg(rtd->dev,
+ "%s: ioctl %s\n", __func__,
+ "SNDRV_LSM_EVENT_STATUS_V3_32");
+
+ if (copy_from_user(&u_event_status32, (void *)arg,
+ sizeof(struct snd_lsm_event_status_v3))) {
+ dev_err(rtd->dev,
+ "%s: event status copy from user failed, size %zd\n",
+ __func__,
+ sizeof(struct snd_lsm_event_status_v3));
+ err = -EFAULT;
+ goto done;
+ }
+
+ if (u_event_status32.payload_size >
+ LISTEN_MAX_STATUS_PAYLOAD_SIZE) {
+ dev_err(rtd->dev,
+ "%s: payload_size %d is invalid, max allowed = %d\n",
+ __func__, u_event_status32.payload_size,
+ LISTEN_MAX_STATUS_PAYLOAD_SIZE);
+ err = -EINVAL;
+ goto done;
+ }
+
+ u_pld_size = sizeof(struct snd_lsm_event_status_v3) +
+ u_event_status32.payload_size;
+ event_status = kzalloc(u_pld_size, GFP_KERNEL);
+ if (!event_status) {
+ dev_err(rtd->dev,
+ "%s: No memory for event status\n",
+ __func__);
+ err = -ENOMEM;
+ goto done;
+ } else {
+ event_status->payload_size =
+ u_event_status32.payload_size;
+ err = msm_cpe_lsm_ioctl_shared(substream,
+ cmd, event_status);
+ if (err)
+ dev_err(rtd->dev,
+ "%s: %s failed, error = %d\n",
+ __func__,
+ "SNDRV_LSM_EVENT_STATUS_V3_32",
+ err);
+ }
+
+ if (!err) {
+ udata_32 = kzalloc(u_pld_size, GFP_KERNEL);
+ if (!udata_32) {
+ dev_err(rtd->dev,
+ "%s: nomem for udata\n",
+ __func__);
+ err = -EFAULT;
+ } else {
+ udata_32->timestamp_lsw =
+ event_status->timestamp_lsw;
+ udata_32->timestamp_msw =
+ event_status->timestamp_msw;
+ udata_32->status = event_status->status;
+ udata_32->payload_size =
+ event_status->payload_size;
+ memcpy(udata_32->payload,
+ event_status->payload,
+ u_pld_size);
+ }
+ }
+
+ if (!err && copy_to_user(arg, udata_32,
+ u_pld_size)) {
+ dev_err(rtd->dev,
+ "%s: copy to user failed\n",
+ __func__);
+ kfree(event_status);
+ kfree(udata_32);
+ err = -EFAULT;
+ goto done;
+ }
+
+ msm_cpe_lsm_lab_start(substream, event_status->status);
msm_cpe_process_event_status_done(lsm_d);
kfree(event_status);
kfree(udata_32);
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 6c1897340e74..44a6a245c7a2 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -2203,12 +2203,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.capture = {
.stream_name = "Listen 1 Audio Service Capture",
.aif_name = "LSM1_UL_HL",
- .rates = SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = (SNDRV_PCM_RATE_16000 |
+ SNDRV_PCM_RATE_48000),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
- .channels_max = 1,
+ .channels_max = 4,
.rate_min = 16000,
- .rate_max = 16000,
+ .rate_max = 48000,
},
.ops = &msm_fe_dai_ops,
.name = "LSM1",
@@ -2218,12 +2220,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.capture = {
.stream_name = "Listen 2 Audio Service Capture",
.aif_name = "LSM2_UL_HL",
- .rates = SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = (SNDRV_PCM_RATE_16000 |
+ SNDRV_PCM_RATE_48000),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
- .channels_max = 1,
+ .channels_max = 4,
.rate_min = 16000,
- .rate_max = 16000,
+ .rate_max = 48000,
},
.ops = &msm_fe_dai_ops,
.name = "LSM2",
@@ -2233,12 +2237,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.capture = {
.stream_name = "Listen 3 Audio Service Capture",
.aif_name = "LSM3_UL_HL",
- .rates = SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = (SNDRV_PCM_RATE_16000 |
+ SNDRV_PCM_RATE_48000),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
- .channels_max = 1,
+ .channels_max = 4,
.rate_min = 16000,
- .rate_max = 16000,
+ .rate_max = 48000,
},
.ops = &msm_fe_dai_ops,
.name = "LSM3",
@@ -2248,12 +2254,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.capture = {
.stream_name = "Listen 4 Audio Service Capture",
.aif_name = "LSM4_UL_HL",
- .rates = SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = (SNDRV_PCM_RATE_16000 |
+ SNDRV_PCM_RATE_48000),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
- .channels_max = 1,
+ .channels_max = 4,
.rate_min = 16000,
- .rate_max = 16000,
+ .rate_max = 48000,
},
.ops = &msm_fe_dai_ops,
.name = "LSM4",
@@ -2263,12 +2271,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.capture = {
.stream_name = "Listen 5 Audio Service Capture",
.aif_name = "LSM5_UL_HL",
- .rates = SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = (SNDRV_PCM_RATE_16000 |
+ SNDRV_PCM_RATE_48000),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
- .channels_max = 1,
+ .channels_max = 4,
.rate_min = 16000,
- .rate_max = 16000,
+ .rate_max = 48000,
},
.ops = &msm_fe_dai_ops,
.name = "LSM5",
@@ -2278,12 +2288,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.capture = {
.stream_name = "Listen 6 Audio Service Capture",
.aif_name = "LSM6_UL_HL",
- .rates = SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = (SNDRV_PCM_RATE_16000 |
+ SNDRV_PCM_RATE_48000),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
- .channels_max = 1,
+ .channels_max = 4,
.rate_min = 16000,
- .rate_max = 16000,
+ .rate_max = 48000,
},
.ops = &msm_fe_dai_ops,
.name = "LSM6",
@@ -2293,12 +2305,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.capture = {
.stream_name = "Listen 7 Audio Service Capture",
.aif_name = "LSM7_UL_HL",
- .rates = SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = (SNDRV_PCM_RATE_16000 |
+ SNDRV_PCM_RATE_48000),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
- .channels_max = 1,
+ .channels_max = 4,
.rate_min = 16000,
- .rate_max = 16000,
+ .rate_max = 48000,
},
.ops = &msm_fe_dai_ops,
.name = "LSM7",
@@ -2308,12 +2322,14 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.capture = {
.stream_name = "Listen 8 Audio Service Capture",
.aif_name = "LSM8_UL_HL",
- .rates = SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = (SNDRV_PCM_RATE_16000 |
+ SNDRV_PCM_RATE_48000),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE),
.channels_min = 1,
- .channels_max = 1,
+ .channels_max = 4,
.rate_min = 16000,
- .rate_max = 16000,
+ .rate_max = 48000,
},
.ops = &msm_fe_dai_ops,
.name = "LSM8",
diff --git a/sound/soc/msm/msm8998.c b/sound/soc/msm/msm8998.c
index 557c7946506a..391640d53d56 100644
--- a/sound/soc/msm/msm8998.c
+++ b/sound/soc/msm/msm8998.c
@@ -3383,12 +3383,12 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
snd_soc_dapm_ignore_suspend(dapm, "HPHR");
snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI");
snd_soc_dapm_ignore_suspend(dapm, "VIINPUT");
+ snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL");
+ snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR");
if (!strcmp(dev_name(codec_dai->dev), "tasha_codec")) {
snd_soc_dapm_ignore_suspend(dapm, "LINEOUT3");
snd_soc_dapm_ignore_suspend(dapm, "LINEOUT4");
- snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL");
- snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR");
snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT1");
snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT2");
}
diff --git a/sound/soc/msm/qdsp6v2/audio_cal_utils.c b/sound/soc/msm/qdsp6v2/audio_cal_utils.c
index 75af648baef3..b54cde4ef0c3 100644
--- a/sound/soc/msm/qdsp6v2/audio_cal_utils.c
+++ b/sound/soc/msm/qdsp6v2/audio_cal_utils.c
@@ -607,7 +607,6 @@ static struct cal_block_data *create_cal_block(struct cal_type_data *cal_type,
}
INIT_LIST_HEAD(&cal_block->list);
- list_add_tail(&cal_block->list, &cal_type->cal_blocks);
cal_block->map_data.ion_map_handle = basic_cal->cal_data.mem_handle;
if (basic_cal->cal_data.mem_handle > 0) {
@@ -639,6 +638,7 @@ static struct cal_block_data *create_cal_block(struct cal_type_data *cal_type,
goto err;
}
cal_block->buffer_number = basic_cal->cal_hdr.buffer_number;
+ list_add_tail(&cal_block->list, &cal_type->cal_blocks);
pr_debug("%s: created block for cal type %d, buf num %d, map handle %d, map size %zd paddr 0x%pK!\n",
__func__, cal_type->info.reg.cal_type,
cal_block->buffer_number,
@@ -648,6 +648,8 @@ static struct cal_block_data *create_cal_block(struct cal_type_data *cal_type,
done:
return cal_block;
err:
+ kfree(cal_block->cal_info);
+ kfree(cal_block->client_info);
kfree(cal_block);
cal_block = NULL;
return cal_block;
diff --git a/sound/soc/msm/qdsp6v2/msm-lsm-client.c b/sound/soc/msm/qdsp6v2/msm-lsm-client.c
index efb6644e551f..55ca659567f5 100644
--- a/sound/soc/msm/qdsp6v2/msm-lsm-client.c
+++ b/sound/soc/msm/qdsp6v2/msm-lsm-client.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015, Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -35,7 +35,7 @@
#define CAPTURE_MIN_NUM_PERIODS 2
#define CAPTURE_MAX_NUM_PERIODS 8
-#define CAPTURE_MAX_PERIOD_SIZE 4096
+#define CAPTURE_MAX_PERIOD_SIZE 61440
#define CAPTURE_MIN_PERIOD_SIZE 320
#define LISTEN_MAX_STATUS_PAYLOAD_SIZE 256
@@ -47,12 +47,14 @@ static struct snd_pcm_hardware msm_pcm_hardware_capture = {
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_16000,
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE),
+ .rates = (SNDRV_PCM_RATE_16000 |
+ SNDRV_PCM_RATE_48000),
.rate_min = 16000,
- .rate_max = 16000,
+ .rate_max = 48000,
.channels_min = 1,
- .channels_max = 1,
+ .channels_max = 4,
.buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS *
CAPTURE_MAX_PERIOD_SIZE,
.period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
@@ -64,7 +66,7 @@ static struct snd_pcm_hardware msm_pcm_hardware_capture = {
/* Conventional and unconventional sample rate supported */
static unsigned int supported_sample_rates[] = {
- 16000,
+ 16000, 48000,
};
static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
@@ -76,7 +78,7 @@ static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
struct lsm_priv {
struct snd_pcm_substream *substream;
struct lsm_client *lsm_client;
- struct snd_lsm_event_status *event_status;
+ struct snd_lsm_event_status_v3 *event_status;
spinlock_t event_lock;
wait_queue_head_t event_wait;
unsigned long event_avail;
@@ -88,6 +90,11 @@ struct lsm_priv {
int dma_write;
};
+enum { /* lsm session states */
+ IDLE = 0,
+ RUNNING,
+};
+
static int msm_lsm_queue_lab_buffer(struct lsm_priv *prtd, int i)
{
int rc = 0;
@@ -196,6 +203,8 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token,
uint16_t status = 0;
uint16_t payload_size = 0;
uint16_t index = 0;
+ uint32_t event_ts_lsw = 0;
+ uint32_t event_ts_msw = 0;
if (!substream || !substream->private_data) {
pr_err("%s: Invalid %s\n", __func__,
@@ -269,24 +278,44 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token,
"%s: event detect status = %d payload size = %d\n",
__func__, status , payload_size);
break;
+
+ case LSM_SESSION_EVENT_DETECTION_STATUS_V3:
+ event_ts_lsw = ((uint32_t *)payload)[0];
+ event_ts_msw = ((uint32_t *)payload)[1];
+ status = (uint16_t)((uint8_t *)payload)[8];
+ payload_size = (uint16_t)((uint8_t *)payload)[9];
+ index = 10;
+ dev_dbg(rtd->dev,
+ "%s: ts_msw = %u, ts_lsw = %u, event detect status = %d payload size = %d\n",
+ __func__, event_ts_msw, event_ts_lsw, status,
+ payload_size);
+ break;
+
default:
break;
}
if (opcode == LSM_SESSION_EVENT_DETECTION_STATUS ||
- opcode == LSM_SESSION_EVENT_DETECTION_STATUS_V2) {
+ opcode == LSM_SESSION_EVENT_DETECTION_STATUS_V2 ||
+ opcode == LSM_SESSION_EVENT_DETECTION_STATUS_V3) {
spin_lock_irqsave(&prtd->event_lock, flags);
prtd->event_status = krealloc(prtd->event_status,
- sizeof(struct snd_lsm_event_status) +
+ sizeof(struct snd_lsm_event_status_v3) +
payload_size, GFP_ATOMIC);
if (!prtd->event_status) {
dev_err(rtd->dev, "%s: no memory for event status\n",
__func__);
return;
}
-
+ /*
+ * event status timestamp will be non-zero and valid if
+ * opcode is LSM_SESSION_EVENT_DETECTION_STATUS_V3
+ */
+ prtd->event_status->timestamp_lsw = event_ts_lsw;
+ prtd->event_status->timestamp_msw = event_ts_msw;
prtd->event_status->status = status;
prtd->event_status->payload_size = payload_size;
+
if (likely(prtd->event_status)) {
memcpy(prtd->event_status->payload,
&((uint8_t *)payload)[index],
@@ -641,6 +670,54 @@ err_ret:
return rc;
}
+static int msm_lsm_set_poll_enable(struct snd_pcm_substream *substream,
+ struct lsm_params_info *p_info)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct lsm_priv *prtd = runtime->private_data;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_lsm_poll_enable poll_enable;
+ int rc = 0;
+
+ if (p_info->param_size != sizeof(poll_enable)) {
+ dev_err(rtd->dev,
+ "%s: Invalid param_size %d\n",
+ __func__, p_info->param_size);
+ rc = -EINVAL;
+ goto done;
+ }
+
+ if (copy_from_user(&poll_enable, p_info->param_data,
+ sizeof(poll_enable))) {
+ dev_err(rtd->dev,
+ "%s: copy_from_user failed, size = %zd\n",
+ __func__, sizeof(poll_enable));
+ rc = -EFAULT;
+ goto done;
+ }
+
+ if (prtd->lsm_client->poll_enable == poll_enable.poll_en) {
+ dev_dbg(rtd->dev,
+ "%s: Polling for session %d already %s\n",
+ __func__, prtd->lsm_client->session,
+ (poll_enable.poll_en ? "enabled" : "disabled"));
+ rc = 0;
+ goto done;
+ }
+
+ rc = q6lsm_set_one_param(prtd->lsm_client, p_info,
+ &poll_enable, LSM_POLLING_ENABLE);
+ if (!rc) {
+ prtd->lsm_client->poll_enable = poll_enable.poll_en;
+ } else {
+ dev_err(rtd->dev,
+ "%s: Failed to set poll enable, err = %d\n",
+ __func__, rc);
+ }
+done:
+ return rc;
+}
+
static int msm_lsm_process_params(struct snd_pcm_substream *substream,
struct snd_lsm_module_params *p_data,
void *params)
@@ -681,6 +758,9 @@ static int msm_lsm_process_params(struct snd_pcm_substream *substream,
case LSM_CUSTOM_PARAMS:
rc = msm_lsm_set_custom(substream, p_info);
break;
+ case LSM_POLLING_ENABLE:
+ rc = msm_lsm_set_poll_enable(substream, p_info);
+ break;
default:
dev_err(rtd->dev,
"%s: Invalid param_type %d\n",
@@ -710,10 +790,8 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream,
struct snd_lsm_session_data session_data;
int rc = 0;
int xchg = 0;
- u32 size = 0;
struct snd_pcm_runtime *runtime;
struct lsm_priv *prtd;
- struct snd_lsm_event_status *user = arg;
struct snd_lsm_detection_params det_params;
uint8_t *confidence_level = NULL;
@@ -870,6 +948,10 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream,
break;
case SNDRV_LSM_EVENT_STATUS:
+ case SNDRV_LSM_EVENT_STATUS_V3: {
+ uint32_t ts_lsw, ts_msw;
+ uint16_t status = 0, payload_size = 0;
+
dev_dbg(rtd->dev, "%s: Get event status\n", __func__);
atomic_set(&prtd->event_wait_stop, 0);
rc = wait_event_freezable(prtd->event_wait,
@@ -882,9 +964,12 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream,
dev_dbg(rtd->dev, "%s: New event available %ld\n",
__func__, prtd->event_avail);
spin_lock_irqsave(&prtd->event_lock, flags);
+
if (prtd->event_status) {
- size = sizeof(*(prtd->event_status)) +
- prtd->event_status->payload_size;
+ payload_size = prtd->event_status->payload_size;
+ ts_lsw = prtd->event_status->timestamp_lsw;
+ ts_msw = prtd->event_status->timestamp_msw;
+ status = prtd->event_status->status;
spin_unlock_irqrestore(&prtd->event_lock,
flags);
} else {
@@ -896,15 +981,43 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream,
__func__);
break;
}
- if (user->payload_size <
- prtd->event_status->payload_size) {
- dev_dbg(rtd->dev,
- "%s: provided %d bytes isn't enough, needs %d bytes\n",
- __func__, user->payload_size,
- prtd->event_status->payload_size);
- rc = -ENOMEM;
+
+ if (cmd == SNDRV_LSM_EVENT_STATUS) {
+ struct snd_lsm_event_status *user = arg;
+
+ if (user->payload_size < payload_size) {
+ dev_dbg(rtd->dev,
+ "%s: provided %d bytes isn't enough, needs %d bytes\n",
+ __func__, user->payload_size,
+ payload_size);
+ rc = -ENOMEM;
+ } else {
+ user->status = status;
+ user->payload_size = payload_size;
+ memcpy(user->payload,
+ prtd->event_status->payload,
+ payload_size);
+ }
} else {
- memcpy(user, prtd->event_status, size);
+ struct snd_lsm_event_status_v3 *user_v3 = arg;
+
+ if (user_v3->payload_size < payload_size) {
+ dev_dbg(rtd->dev,
+ "%s: provided %d bytes isn't enough, needs %d bytes\n",
+ __func__, user_v3->payload_size,
+ payload_size);
+ rc = -ENOMEM;
+ } else {
+ user_v3->timestamp_lsw = ts_lsw;
+ user_v3->timestamp_msw = ts_msw;
+ user_v3->status = status;
+ user_v3->payload_size = payload_size;
+ memcpy(user_v3->payload,
+ prtd->event_status->payload,
+ payload_size);
+ }
+ }
+ if (!rc) {
if (prtd->lsm_client->lab_enable
&& !prtd->lsm_client->lab_started
&& prtd->event_status->status ==
@@ -929,6 +1042,7 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream,
rc = 0;
}
break;
+ }
case SNDRV_LSM_ABORT_EVENT:
dev_dbg(rtd->dev, "%s: Aborting event status wait\n",
@@ -1035,6 +1149,43 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream,
prtd->lsm_client->lab_started = false;
}
break;
+
+ case SNDRV_LSM_SET_PORT:
+ dev_dbg(rtd->dev, "%s: set LSM port\n", __func__);
+ rc = q6lsm_set_port_connected(prtd->lsm_client);
+ break;
+
+ case SNDRV_LSM_SET_FWK_MODE_CONFIG: {
+ u32 *mode = NULL;
+
+ if (!arg) {
+ dev_err(rtd->dev,
+ "%s: Invalid param arg for ioctl %s session %d\n",
+ __func__, "SNDRV_LSM_SET_FWK_MODE_CONFIG",
+ prtd->lsm_client->session);
+ rc = -EINVAL;
+ break;
+ }
+ mode = (u32 *)arg;
+ if (prtd->lsm_client->event_mode == *mode) {
+ dev_dbg(rtd->dev,
+ "%s: mode for %d already set to %d\n",
+ __func__, prtd->lsm_client->session, *mode);
+ rc = 0;
+ } else {
+ dev_dbg(rtd->dev, "%s: Event mode = %d\n",
+ __func__, *mode);
+ rc = q6lsm_set_fwk_mode_cfg(prtd->lsm_client, *mode);
+ if (!rc)
+ prtd->lsm_client->event_mode = *mode;
+ else
+ dev_err(rtd->dev,
+ "%s: set event mode failed %d\n",
+ __func__, rc);
+ }
+ break;
+ }
+
default:
dev_dbg(rtd->dev,
"%s: Falling into default snd_lib_ioctl cmd 0x%x\n",
@@ -1053,6 +1204,21 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream,
return rc;
}
#ifdef CONFIG_COMPAT
+
+struct snd_lsm_event_status32 {
+ u16 status;
+ u16 payload_size;
+ u8 payload[0];
+};
+
+struct snd_lsm_event_status_v3_32 {
+ u32 timestamp_lsw;
+ u32 timestamp_msw;
+ u16 status;
+ u16 payload_size;
+ u8 payload[0];
+};
+
struct snd_lsm_sound_model_v2_32 {
compat_uptr_t data;
compat_uptr_t confidence_level;
@@ -1074,7 +1240,7 @@ struct lsm_params_info_32 {
u32 param_id;
u32 param_size;
compat_uptr_t param_data;
- enum LSM_PARAM_TYPE param_type;
+ uint32_t param_type;
};
struct snd_lsm_module_params_32 {
@@ -1090,6 +1256,8 @@ enum {
_IOW('U', 0x0A, struct snd_lsm_detection_params_32),
SNDRV_LSM_SET_MODULE_PARAMS_32 =
_IOW('U', 0x0B, struct snd_lsm_module_params_32),
+ SNDRV_LSM_EVENT_STATUS_V3_32 =
+ _IOW('U', 0x0F, struct snd_lsm_event_status_v3_32),
};
static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream,
@@ -1178,6 +1346,73 @@ static int msm_lsm_ioctl_compat(struct snd_pcm_substream *substream,
break;
}
+ case SNDRV_LSM_EVENT_STATUS_V3_32: {
+ struct snd_lsm_event_status_v3_32 userarg32, *user32 = NULL;
+ struct snd_lsm_event_status_v3 *user = NULL;
+
+ if (copy_from_user(&userarg32, arg, sizeof(userarg32))) {
+ dev_err(rtd->dev, "%s: err copyuser ioctl %s\n",
+ __func__, "SNDRV_LSM_EVENT_STATUS_V3_32");
+ return -EFAULT;
+ }
+
+ if (userarg32.payload_size >
+ LISTEN_MAX_STATUS_PAYLOAD_SIZE) {
+ pr_err("%s: payload_size %d is invalid, max allowed = %d\n",
+ __func__, userarg32.payload_size,
+ LISTEN_MAX_STATUS_PAYLOAD_SIZE);
+ return -EINVAL;
+ }
+
+ size = sizeof(*user) + userarg32.payload_size;
+ user = kmalloc(size, GFP_KERNEL);
+ if (!user) {
+ dev_err(rtd->dev,
+ "%s: Allocation failed event status size %d\n",
+ __func__, size);
+ return -EFAULT;
+ }
+ cmd = SNDRV_LSM_EVENT_STATUS_V3;
+ user->payload_size = userarg32.payload_size;
+ err = msm_lsm_ioctl_shared(substream, cmd, user);
+
+ /* Update size with actual payload size */
+ size = sizeof(userarg32) + user->payload_size;
+ if (!err && !access_ok(VERIFY_WRITE, arg, size)) {
+ dev_err(rtd->dev,
+ "%s: write verify failed size %d\n",
+ __func__, size);
+ err = -EFAULT;
+ }
+ if (!err) {
+ user32 = kmalloc(size, GFP_KERNEL);
+ if (!user32) {
+ dev_err(rtd->dev,
+ "%s: Allocation event user status size %d\n",
+ __func__, size);
+ err = -EFAULT;
+ } else {
+ user32->timestamp_lsw = user->timestamp_lsw;
+ user32->timestamp_msw = user->timestamp_msw;
+ user32->status = user->status;
+ user32->payload_size = user->payload_size;
+ memcpy(user32->payload,
+ user->payload, user32->payload_size);
+ }
+ }
+ if (!err && (copy_to_user(arg, user32, size))) {
+ dev_err(rtd->dev, "%s: failed to copy payload %d",
+ __func__, size);
+ err = -EFAULT;
+ }
+ kfree(user);
+ kfree(user32);
+ if (err)
+ dev_err(rtd->dev, "%s: lsmevent failed %d",
+ __func__, err);
+ break;
+ }
+
case SNDRV_LSM_REG_SND_MODEL_V2_32: {
struct snd_lsm_sound_model_v2_32 snd_modelv232;
struct snd_lsm_sound_model_v2 snd_modelv2;
@@ -1573,6 +1808,67 @@ static int msm_lsm_ioctl(struct snd_pcm_substream *substream,
"%s: lsmevent failed %d", __func__, err);
return err;
}
+
+ case SNDRV_LSM_EVENT_STATUS_V3: {
+ struct snd_lsm_event_status_v3 *user = NULL;
+ struct snd_lsm_event_status_v3 userarg;
+
+ dev_dbg(rtd->dev,
+ "%s: SNDRV_LSM_EVENT_STATUS_V3\n", __func__);
+ if (!arg) {
+ dev_err(rtd->dev,
+ "%s: Invalid params event_status_v3\n",
+ __func__);
+ return -EINVAL;
+ }
+ if (copy_from_user(&userarg, arg, sizeof(userarg))) {
+ dev_err(rtd->dev,
+ "%s: err copyuser event_status_v3\n",
+ __func__);
+ return -EFAULT;
+ }
+
+ if (userarg.payload_size >
+ LISTEN_MAX_STATUS_PAYLOAD_SIZE) {
+ pr_err("%s: payload_size %d is invalid, max allowed = %d\n",
+ __func__, userarg.payload_size,
+ LISTEN_MAX_STATUS_PAYLOAD_SIZE);
+ return -EINVAL;
+ }
+
+ size = sizeof(struct snd_lsm_event_status_v3) +
+ userarg.payload_size;
+ user = kmalloc(size, GFP_KERNEL);
+ if (!user) {
+ dev_err(rtd->dev,
+ "%s: Allocation failed event status size %d\n",
+ __func__, size);
+ return -EFAULT;
+ }
+ user->payload_size = userarg.payload_size;
+ err = msm_lsm_ioctl_shared(substream, cmd, user);
+
+ /* Update size with actual payload size */
+ size = sizeof(*user) + user->payload_size;
+ if (!err && !access_ok(VERIFY_WRITE, arg, size)) {
+ dev_err(rtd->dev,
+ "%s: write verify failed size %d\n",
+ __func__, size);
+ err = -EFAULT;
+ }
+ if (!err && (copy_to_user(arg, user, size))) {
+ dev_err(rtd->dev,
+ "%s: failed to copy payload %d",
+ __func__, size);
+ err = -EFAULT;
+ }
+ kfree(user);
+ if (err)
+ dev_err(rtd->dev,
+ "%s: lsm_event_v3 failed %d", __func__, err);
+ break;
+ }
+
default:
err = msm_lsm_ioctl_shared(substream, cmd, arg);
break;
@@ -1640,6 +1936,11 @@ static int msm_lsm_open(struct snd_pcm_substream *substream)
return -ENOMEM;
}
prtd->lsm_client->opened = false;
+ prtd->lsm_client->session_state = IDLE;
+ prtd->lsm_client->poll_enable = true;
+ prtd->lsm_client->perf_mode = 0;
+ prtd->lsm_client->event_mode = LSM_EVENT_NON_TIME_STAMP_MODE;
+
return 0;
}
@@ -1648,6 +1949,7 @@ static int msm_lsm_prepare(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
struct lsm_priv *prtd = runtime->private_data;
struct snd_soc_pcm_runtime *rtd;
+ int ret = 0;
if (!substream->private_data) {
pr_err("%s: Invalid private_data", __func__);
@@ -1661,9 +1963,30 @@ static int msm_lsm_prepare(struct snd_pcm_substream *substream)
"%s: LSM client data ptr is NULL\n", __func__);
return -EINVAL;
}
+
+ if (q6lsm_set_media_fmt_params(prtd->lsm_client))
+ dev_dbg(rtd->dev,
+ "%s: failed to set lsm media fmt params\n", __func__);
+
+ if (prtd->lsm_client->session_state == IDLE) {
+ ret = msm_pcm_routing_reg_phy_compr_stream(
+ rtd->dai_link->be_id,
+ prtd->lsm_client->perf_mode,
+ prtd->lsm_client->session,
+ SNDRV_PCM_STREAM_CAPTURE,
+ LISTEN);
+ if (ret) {
+ dev_err(rtd->dev,
+ "%s: register phy compr stream failed %d\n",
+ __func__, ret);
+ return ret;
+ }
+ }
+
+ prtd->lsm_client->session_state = RUNNING;
prtd->lsm_client->started = false;
runtime->private_data = prtd;
- return 0;
+ return ret;
}
static int msm_lsm_close(struct snd_pcm_substream *substream)
@@ -1712,6 +2035,9 @@ static int msm_lsm_close(struct snd_pcm_substream *substream)
__func__);
}
+ msm_pcm_routing_dereg_phy_stream(rtd->dai_link->be_id,
+ SNDRV_PCM_STREAM_CAPTURE);
+
if (prtd->lsm_client->opened) {
q6lsm_close(prtd->lsm_client);
prtd->lsm_client->opened = false;
@@ -1733,7 +2059,7 @@ static int msm_lsm_hw_params(struct snd_pcm_substream *substream,
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct lsm_priv *prtd = runtime->private_data;
- struct lsm_lab_hw_params *hw_params = NULL;
+ struct lsm_hw_params *hw_params = NULL;
struct snd_soc_pcm_runtime *rtd;
if (!substream->private_data) {
@@ -1749,25 +2075,36 @@ static int msm_lsm_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
hw_params = &prtd->lsm_client->hw_params;
- hw_params->sample_rate = params_rate(params);
- hw_params->sample_size =
- (params_format(params) == SNDRV_PCM_FORMAT_S16_LE) ? 16 : 0;
+ hw_params->num_chs = params_channels(params);
hw_params->period_count = params_periods(params);
- if (hw_params->sample_rate != 16000 || hw_params->sample_size != 16 ||
- hw_params->period_count == 0) {
+ hw_params->sample_rate = params_rate(params);
+ if (((hw_params->sample_rate != 16000) &&
+ (hw_params->sample_rate != 48000)) ||
+ (hw_params->period_count == 0)) {
dev_err(rtd->dev,
- "%s: Invalid params sample rate %d sample size %d period count %d",
+ "%s: Invalid Params sample rate %d period count %d\n",
__func__, hw_params->sample_rate,
- hw_params->sample_size,
- hw_params->period_count);
+ hw_params->period_count);
return -EINVAL;
}
+
+ if (params_format(params) == SNDRV_PCM_FORMAT_S16_LE) {
+ hw_params->sample_size = 16;
+ } else if (params_format(params) == SNDRV_PCM_FORMAT_S24_LE) {
+ hw_params->sample_size = 24;
+ } else {
+ dev_err(rtd->dev, "%s: Invalid Format 0x%x\n",
+ __func__, params_format(params));
+ return -EINVAL;
+ }
+
hw_params->buf_sz = params_buffer_bytes(params) /
- hw_params->period_count;
+ hw_params->period_count;
dev_dbg(rtd->dev,
- "%s: sample rate %d sample size %d buffer size %d period count %d\n",
- __func__, hw_params->sample_rate, hw_params->sample_size,
- hw_params->buf_sz, hw_params->period_count);
+ "%s: channels %d sample rate %d sample size %d buffer size %d period count %d\n",
+ __func__, hw_params->num_chs, hw_params->sample_rate,
+ hw_params->sample_size, hw_params->buf_sz,
+ hw_params->period_count);
return 0;
}
@@ -1863,6 +2200,109 @@ static int msm_lsm_pcm_copy(struct snd_pcm_substream *substream, int ch,
return 0;
}
+static int msm_lsm_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ u64 fe_id = kcontrol->private_value;
+ int app_type;
+ int acdb_dev_id;
+ int sample_rate;
+
+ pr_debug("%s: fe_id- %llu\n", __func__, fe_id);
+ if ((fe_id < MSM_FRONTEND_DAI_LSM1) ||
+ (fe_id > MSM_FRONTEND_DAI_LSM8)) {
+ pr_err("%s: Received out of bounds fe_id %llu\n",
+ __func__, fe_id);
+ return -EINVAL;
+ }
+
+ app_type = ucontrol->value.integer.value[0];
+ acdb_dev_id = ucontrol->value.integer.value[1];
+ sample_rate = ucontrol->value.integer.value[2];
+
+ pr_debug("%s: app_type- %d acdb_dev_id- %d sample_rate- %d session_type- %d\n",
+ __func__, app_type, acdb_dev_id, sample_rate, SESSION_TYPE_TX);
+ msm_pcm_routing_reg_stream_app_type_cfg(fe_id, app_type,
+ acdb_dev_id, sample_rate, SESSION_TYPE_TX);
+
+ return 0;
+}
+
+static int msm_lsm_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ u64 fe_id = kcontrol->private_value;
+ int ret = 0;
+ int app_type;
+ int acdb_dev_id;
+ int sample_rate;
+
+ pr_debug("%s: fe_id- %llu\n", __func__, fe_id);
+ if ((fe_id < MSM_FRONTEND_DAI_LSM1) ||
+ (fe_id > MSM_FRONTEND_DAI_LSM8)) {
+ pr_err("%s: Received out of bounds fe_id %llu\n",
+ __func__, fe_id);
+ return -EINVAL;
+ }
+
+ ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, SESSION_TYPE_TX,
+ &app_type, &acdb_dev_id, &sample_rate);
+ if (ret < 0) {
+ pr_err("%s: msm_pcm_routing_get_stream_app_type_cfg failed returned %d\n",
+ __func__, ret);
+ goto done;
+ }
+
+ ucontrol->value.integer.value[0] = app_type;
+ ucontrol->value.integer.value[1] = acdb_dev_id;
+ ucontrol->value.integer.value[2] = sample_rate;
+ pr_debug("%s: fedai_id %llu, session_type %d, app_type %d, acdb_dev_id %d, sample_rate %d\n",
+ __func__, fe_id, SESSION_TYPE_TX,
+ app_type, acdb_dev_id, sample_rate);
+done:
+ return ret;
+}
+
+static int msm_lsm_add_app_type_controls(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_pcm *pcm = rtd->pcm;
+ struct snd_pcm_usr *app_type_info;
+ struct snd_kcontrol *kctl;
+ const char *mixer_ctl_name = "Listen Stream";
+ const char *deviceNo = "NN";
+ const char *suffix = "App Type Cfg";
+ int ctl_len, ret = 0;
+
+ ctl_len = strlen(mixer_ctl_name) + 1 +
+ strlen(deviceNo) + 1 + strlen(suffix) + 1;
+ pr_debug("%s: Listen app type cntrl add\n", __func__);
+ ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_CAPTURE,
+ NULL, 1, ctl_len, rtd->dai_link->be_id,
+ &app_type_info);
+ if (ret < 0) {
+ pr_err("%s: Listen app type cntrl add failed: %d\n",
+ __func__, ret);
+ return ret;
+ }
+ kctl = app_type_info->kctl;
+ snprintf(kctl->id.name, ctl_len, "%s %d %s",
+ mixer_ctl_name, rtd->pcm->device, suffix);
+ kctl->put = msm_lsm_app_type_cfg_ctl_put;
+ kctl->get = msm_lsm_app_type_cfg_ctl_get;
+ return 0;
+}
+
+static int msm_lsm_add_controls(struct snd_soc_pcm_runtime *rtd)
+{
+ int ret = 0;
+
+ ret = msm_lsm_add_app_type_controls(rtd);
+ if (ret)
+ pr_err("%s, add app type controls failed:%d\n", __func__, ret);
+
+ return ret;
+}
+
static struct snd_pcm_ops msm_lsm_ops = {
.open = msm_lsm_open,
.close = msm_lsm_close,
@@ -1877,11 +2317,16 @@ static struct snd_pcm_ops msm_lsm_ops = {
static int msm_asoc_lsm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
+ int ret = 0;
if (!card->dev->coherent_dma_mask)
card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
- return 0;
+ ret = msm_lsm_add_controls(rtd);
+ if (ret)
+ pr_err("%s, kctl add failed:%d\n", __func__, ret);
+
+ return ret;
}
static int msm_asoc_lsm_probe(struct snd_soc_platform *platform)
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 2d410170f48d..39fdd6b49357 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -72,9 +72,12 @@ static int tert_mi2s_switch_enable;
static int quat_mi2s_switch_enable;
static int fm_pcmrx_switch_enable;
static int usb_switch_enable;
-static int lsm_mux_slim_port;
+static int lsm_port_index;
static int slim0_rx_aanc_fb_port;
static int msm_route_ec_ref_rx;
+static int msm_ec_ref_ch = 4;
+static int msm_ec_ref_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_ec_ref_sampling_rate = 48000;
static uint32_t voc_session_id = ALL_SESSION_VSID;
static int msm_route_ext_ec_ref;
static bool is_custom_stereo_on;
@@ -88,6 +91,8 @@ enum {
MADSWAUDIO,
};
+#define ADM_LSM_PORT_INDEX 9
+
#define SLIMBUS_0_TX_TEXT "SLIMBUS_0_TX"
#define SLIMBUS_1_TX_TEXT "SLIMBUS_1_TX"
#define SLIMBUS_2_TX_TEXT "SLIMBUS_2_TX"
@@ -96,12 +101,14 @@ enum {
#define SLIMBUS_TX_VI_TEXT "SLIMBUS_TX_VI"
#define SLIMBUS_5_TX_TEXT "SLIMBUS_5_TX"
#define TERT_MI2S_TX_TEXT "TERT_MI2S_TX"
+#define QUAT_MI2S_TX_TEXT "QUAT_MI2S_TX"
+#define ADM_LSM_TX_TEXT "ADM_LSM_TX"
#define LSM_FUNCTION_TEXT "LSM Function"
-static const char * const mad_audio_mux_text[] = {
+static const char * const lsm_port_text[] = {
"None",
SLIMBUS_0_TX_TEXT, SLIMBUS_1_TX_TEXT, SLIMBUS_2_TX_TEXT,
- SLIMBUS_3_TX_TEXT, SLIMBUS_4_TX_TEXT, SLIMBUS_TX_VI_TEXT,
- SLIMBUS_5_TX_TEXT, TERT_MI2S_TX_TEXT
+ SLIMBUS_3_TX_TEXT, SLIMBUS_4_TX_TEXT, SLIMBUS_5_TX_TEXT,
+ TERT_MI2S_TX_TEXT, QUAT_MI2S_TX_TEXT, ADM_LSM_TX_TEXT
};
struct msm_pcm_route_bdai_pp_params {
@@ -270,254 +277,262 @@ static void msm_pcm_routng_cfg_matrix_map_pp(struct route_payload payload,
#define SLIMBUS_EXTPROC_RX AFE_PORT_INVALID
struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = {
- { PRIMARY_I2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_I2S_RX},
- { PRIMARY_I2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_I2S_TX},
- { SLIMBUS_0_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_0_RX},
- { SLIMBUS_0_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_0_TX},
- { HDMI_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_HDMI},
- { INT_BT_SCO_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_BT_SCO_RX},
- { INT_BT_SCO_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_BT_SCO_TX},
- { INT_FM_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_FM_RX},
- { INT_FM_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_FM_TX},
- { RT_PROXY_PORT_001_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_AFE_PCM_RX},
- { RT_PROXY_PORT_001_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_AFE_PCM_TX},
- { AFE_PORT_ID_PRIMARY_PCM_RX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { PRIMARY_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_I2S_RX},
+ { PRIMARY_I2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_PRI_I2S_TX},
+ { SLIMBUS_0_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_0_RX},
+ { SLIMBUS_0_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_0_TX},
+ { HDMI_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_HDMI},
+ { INT_BT_SCO_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_BT_SCO_RX},
+ { INT_BT_SCO_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_BT_SCO_TX},
+ { INT_FM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_FM_RX},
+ { INT_FM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_FM_TX},
+ { RT_PROXY_PORT_001_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
+ LPASS_BE_AFE_PCM_RX},
+ { RT_PROXY_PORT_001_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
+ LPASS_BE_AFE_PCM_TX},
+ { AFE_PORT_ID_PRIMARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_AUXPCM_RX},
- { AFE_PORT_ID_PRIMARY_PCM_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_PRIMARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_AUXPCM_TX},
- { VOICE_PLAYBACK_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { VOICE_PLAYBACK_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_VOICE_PLAYBACK_TX},
- { VOICE2_PLAYBACK_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { VOICE2_PLAYBACK_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_VOICE2_PLAYBACK_TX},
- { VOICE_RECORD_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INCALL_RECORD_RX},
- { VOICE_RECORD_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INCALL_RECORD_TX},
- { MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_MI2S_RX},
- { MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_MI2S_TX},
- { SECONDARY_I2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_I2S_RX},
- { SLIMBUS_1_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_1_RX},
- { SLIMBUS_1_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_1_TX},
- { SLIMBUS_2_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_2_RX},
- { SLIMBUS_2_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_2_TX},
- { SLIMBUS_3_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_3_RX},
- { SLIMBUS_3_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_3_TX},
- { SLIMBUS_4_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_RX},
- { SLIMBUS_4_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_TX},
- { SLIMBUS_5_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_5_RX},
- { SLIMBUS_5_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_5_TX},
- { SLIMBUS_6_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_6_RX},
- { SLIMBUS_6_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_6_TX},
- { SLIMBUS_7_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_7_RX},
- { SLIMBUS_7_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_7_TX},
- { SLIMBUS_8_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_RX},
- { SLIMBUS_8_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_TX},
- { SLIMBUS_EXTPROC_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_STUB_RX},
- { SLIMBUS_EXTPROC_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_STUB_TX},
- { SLIMBUS_EXTPROC_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_STUB_1_TX},
- { AFE_PORT_ID_QUATERNARY_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { VOICE_RECORD_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
+ LPASS_BE_INCALL_RECORD_RX},
+ { VOICE_RECORD_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
+ LPASS_BE_INCALL_RECORD_TX},
+ { MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_MI2S_RX},
+ { MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_MI2S_TX},
+ { SECONDARY_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SEC_I2S_RX},
+ { SLIMBUS_1_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_1_RX},
+ { SLIMBUS_1_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_1_TX},
+ { SLIMBUS_2_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_2_RX},
+ { SLIMBUS_2_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_2_TX},
+ { SLIMBUS_3_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_3_RX},
+ { SLIMBUS_3_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_3_TX},
+ { SLIMBUS_4_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_RX},
+ { SLIMBUS_4_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_TX},
+ { SLIMBUS_5_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_5_RX},
+ { SLIMBUS_5_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_5_TX},
+ { SLIMBUS_6_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_6_RX},
+ { SLIMBUS_6_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_6_TX},
+ { SLIMBUS_7_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_7_RX},
+ { SLIMBUS_7_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_7_TX},
+ { SLIMBUS_8_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_RX},
+ { SLIMBUS_8_TX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_TX},
+ { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_STUB_RX},
+ { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_STUB_TX},
+ { SLIMBUS_EXTPROC_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_STUB_1_TX},
+ { AFE_PORT_ID_QUATERNARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUAT_MI2S_RX},
- { AFE_PORT_ID_QUATERNARY_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_QUATERNARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUAT_MI2S_TX},
- { AFE_PORT_ID_SECONDARY_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SECONDARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SEC_MI2S_RX},
- { AFE_PORT_ID_SECONDARY_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SECONDARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SEC_MI2S_TX},
- { AFE_PORT_ID_PRIMARY_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_PRIMARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_PRI_MI2S_RX},
- { AFE_PORT_ID_PRIMARY_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_PRIMARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_PRI_MI2S_TX},
- { AFE_PORT_ID_TERTIARY_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_TERTIARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_TERT_MI2S_RX},
- { AFE_PORT_ID_TERTIARY_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_TERTIARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_TERT_MI2S_TX},
- { AUDIO_PORT_ID_I2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AUDIO_PORT_ID_I2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_AUDIO_I2S_RX},
- { AFE_PORT_ID_SECONDARY_PCM_RX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SECONDARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SEC_AUXPCM_RX},
- { AFE_PORT_ID_SECONDARY_PCM_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SECONDARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SEC_AUXPCM_TX},
- { AFE_PORT_ID_SPDIF_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SPDIF_RX},
- { AFE_PORT_ID_SECONDARY_MI2S_RX_SD1, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SPDIF_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SPDIF_RX},
+ { AFE_PORT_ID_SECONDARY_MI2S_RX_SD1, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SEC_MI2S_RX_SD1},
- { AFE_PORT_ID_QUINARY_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_QUINARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUIN_MI2S_RX},
- { AFE_PORT_ID_QUINARY_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_QUINARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUIN_MI2S_TX},
- { AFE_PORT_ID_SENARY_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SENARY_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SENARY_MI2S_TX},
- { AFE_PORT_ID_PRIMARY_TDM_RX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_PRIMARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_RX_0},
- { AFE_PORT_ID_PRIMARY_TDM_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_PRIMARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_TX_0},
- { AFE_PORT_ID_PRIMARY_TDM_RX_1, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_PRIMARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_RX_1},
- { AFE_PORT_ID_PRIMARY_TDM_TX_1, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_PRIMARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_TX_1},
- { AFE_PORT_ID_PRIMARY_TDM_RX_2, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_PRIMARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_RX_2},
- { AFE_PORT_ID_PRIMARY_TDM_TX_2, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_PRIMARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_TX_2},
- { AFE_PORT_ID_PRIMARY_TDM_RX_3, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_PRIMARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_RX_3},
- { AFE_PORT_ID_PRIMARY_TDM_TX_3, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_PRIMARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_TX_3},
- { AFE_PORT_ID_PRIMARY_TDM_RX_4, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_PRIMARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_RX_4},
- { AFE_PORT_ID_PRIMARY_TDM_TX_4, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_PRIMARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_TX_4},
- { AFE_PORT_ID_PRIMARY_TDM_RX_5, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_PRIMARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_RX_5},
- { AFE_PORT_ID_PRIMARY_TDM_TX_5, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_PRIMARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_TX_5},
- { AFE_PORT_ID_PRIMARY_TDM_RX_6, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_PRIMARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_RX_6},
- { AFE_PORT_ID_PRIMARY_TDM_TX_6, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_PRIMARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_TX_6},
- { AFE_PORT_ID_PRIMARY_TDM_RX_7, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_PRIMARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_RX_7},
- { AFE_PORT_ID_PRIMARY_TDM_TX_7, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_PRIMARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_PRI_TDM_TX_7},
- { AFE_PORT_ID_SECONDARY_TDM_RX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SECONDARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_RX_0},
- { AFE_PORT_ID_SECONDARY_TDM_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SECONDARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_TX_0},
- { AFE_PORT_ID_SECONDARY_TDM_RX_1, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SECONDARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_RX_1},
- { AFE_PORT_ID_SECONDARY_TDM_TX_1, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SECONDARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_TX_1},
- { AFE_PORT_ID_SECONDARY_TDM_RX_2, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SECONDARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_RX_2},
- { AFE_PORT_ID_SECONDARY_TDM_TX_2, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SECONDARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_TX_2},
- { AFE_PORT_ID_SECONDARY_TDM_RX_3, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SECONDARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_RX_3},
- { AFE_PORT_ID_SECONDARY_TDM_TX_3, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SECONDARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_TX_3},
- { AFE_PORT_ID_SECONDARY_TDM_RX_4, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SECONDARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_RX_4},
- { AFE_PORT_ID_SECONDARY_TDM_TX_4, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SECONDARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_TX_4},
- { AFE_PORT_ID_SECONDARY_TDM_RX_5, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SECONDARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_RX_5},
- { AFE_PORT_ID_SECONDARY_TDM_TX_5, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SECONDARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_TX_5},
- { AFE_PORT_ID_SECONDARY_TDM_RX_6, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SECONDARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_RX_6},
- { AFE_PORT_ID_SECONDARY_TDM_TX_6, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SECONDARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_TX_6},
- { AFE_PORT_ID_SECONDARY_TDM_RX_7, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SECONDARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_RX_7},
- { AFE_PORT_ID_SECONDARY_TDM_TX_7, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_SECONDARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_SEC_TDM_TX_7},
- { AFE_PORT_ID_TERTIARY_TDM_RX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_TERTIARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_RX_0},
- { AFE_PORT_ID_TERTIARY_TDM_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_TERTIARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_TX_0},
- { AFE_PORT_ID_TERTIARY_TDM_RX_1, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_TERTIARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_RX_1},
- { AFE_PORT_ID_TERTIARY_TDM_TX_1, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_TERTIARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_TX_1},
- { AFE_PORT_ID_TERTIARY_TDM_RX_2, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_TERTIARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_RX_2},
- { AFE_PORT_ID_TERTIARY_TDM_TX_2, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_TERTIARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_TX_2},
- { AFE_PORT_ID_TERTIARY_TDM_RX_3, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_TERTIARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_RX_3},
- { AFE_PORT_ID_TERTIARY_TDM_TX_3, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_TERTIARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_TX_3},
- { AFE_PORT_ID_TERTIARY_TDM_RX_4, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_TERTIARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_RX_4},
- { AFE_PORT_ID_TERTIARY_TDM_TX_4, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_TERTIARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_TX_4},
- { AFE_PORT_ID_TERTIARY_TDM_RX_5, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_TERTIARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_RX_5},
- { AFE_PORT_ID_TERTIARY_TDM_TX_5, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_TERTIARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_TX_5},
- { AFE_PORT_ID_TERTIARY_TDM_RX_6, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_TERTIARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_RX_6},
- { AFE_PORT_ID_TERTIARY_TDM_TX_6, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_TERTIARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_TX_6},
- { AFE_PORT_ID_TERTIARY_TDM_RX_7, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_TERTIARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_RX_7},
- { AFE_PORT_ID_TERTIARY_TDM_TX_7, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_TERTIARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_TERT_TDM_TX_7},
- { AFE_PORT_ID_QUATERNARY_TDM_RX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_QUATERNARY_TDM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_RX_0},
- { AFE_PORT_ID_QUATERNARY_TDM_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_QUATERNARY_TDM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_TX_0},
- { AFE_PORT_ID_QUATERNARY_TDM_RX_1, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_QUATERNARY_TDM_RX_1, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_RX_1},
- { AFE_PORT_ID_QUATERNARY_TDM_TX_1, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_QUATERNARY_TDM_TX_1, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_TX_1},
- { AFE_PORT_ID_QUATERNARY_TDM_RX_2, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_QUATERNARY_TDM_RX_2, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_RX_2},
- { AFE_PORT_ID_QUATERNARY_TDM_TX_2, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_QUATERNARY_TDM_TX_2, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_TX_2},
- { AFE_PORT_ID_QUATERNARY_TDM_RX_3, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_QUATERNARY_TDM_RX_3, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_RX_3},
- { AFE_PORT_ID_QUATERNARY_TDM_TX_3, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_QUATERNARY_TDM_TX_3, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_TX_3},
- { AFE_PORT_ID_QUATERNARY_TDM_RX_4, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_QUATERNARY_TDM_RX_4, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_RX_4},
- { AFE_PORT_ID_QUATERNARY_TDM_TX_4, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_QUATERNARY_TDM_TX_4, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_TX_4},
- { AFE_PORT_ID_QUATERNARY_TDM_RX_5, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_QUATERNARY_TDM_RX_5, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_RX_5},
- { AFE_PORT_ID_QUATERNARY_TDM_TX_5, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_QUATERNARY_TDM_TX_5, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_TX_5},
- { AFE_PORT_ID_QUATERNARY_TDM_RX_6, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_QUATERNARY_TDM_RX_6, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_RX_6},
- { AFE_PORT_ID_QUATERNARY_TDM_TX_6, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_QUATERNARY_TDM_TX_6, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_TX_6},
- { AFE_PORT_ID_QUATERNARY_TDM_RX_7, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_QUATERNARY_TDM_RX_7, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_RX_7},
- { AFE_PORT_ID_QUATERNARY_TDM_TX_7, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_QUATERNARY_TDM_TX_7, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUAT_TDM_TX_7},
- { INT_BT_A2DP_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_BT_A2DP_RX},
- { AFE_PORT_ID_USB_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_USB_AUDIO_RX},
- { AFE_PORT_ID_USB_TX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_USB_AUDIO_TX},
- { DISPLAY_PORT_RX, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_DISPLAY_PORT},
- { AFE_PORT_ID_TERTIARY_PCM_RX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { INT_BT_A2DP_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_INT_BT_A2DP_RX},
+ { AFE_PORT_ID_USB_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
+ LPASS_BE_USB_AUDIO_RX},
+ { AFE_PORT_ID_USB_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
+ LPASS_BE_USB_AUDIO_TX},
+ { DISPLAY_PORT_RX, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_DISPLAY_PORT},
+ { AFE_PORT_ID_TERTIARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_TERT_AUXPCM_RX},
- { AFE_PORT_ID_TERTIARY_PCM_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_TERTIARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_TERT_AUXPCM_TX},
- { AFE_PORT_ID_QUATERNARY_PCM_RX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_QUATERNARY_PCM_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUAT_AUXPCM_RX},
- { AFE_PORT_ID_QUATERNARY_PCM_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_QUATERNARY_PCM_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_QUAT_AUXPCM_TX},
- { AFE_PORT_ID_INT0_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_INT0_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_INT0_MI2S_RX},
- { AFE_PORT_ID_INT0_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_INT0_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_INT0_MI2S_TX},
- { AFE_PORT_ID_INT1_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_INT1_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_INT1_MI2S_RX},
- { AFE_PORT_ID_INT1_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_INT1_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_INT1_MI2S_TX},
- { AFE_PORT_ID_INT2_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_INT2_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_INT2_MI2S_RX},
- { AFE_PORT_ID_INT2_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_INT2_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_INT2_MI2S_TX},
- { AFE_PORT_ID_INT3_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_INT3_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_INT3_MI2S_RX},
- { AFE_PORT_ID_INT3_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_INT3_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_INT3_MI2S_TX},
- { AFE_PORT_ID_INT4_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_INT4_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_INT4_MI2S_RX},
- { AFE_PORT_ID_INT4_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_INT4_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_INT4_MI2S_TX},
- { AFE_PORT_ID_INT5_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_INT5_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_INT5_MI2S_RX},
- { AFE_PORT_ID_INT5_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_INT5_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_INT5_MI2S_TX},
- { AFE_PORT_ID_INT6_MI2S_RX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_INT6_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_INT6_MI2S_RX},
- { AFE_PORT_ID_INT6_MI2S_TX, 0, 0, {0}, 0, 0, 0, 0, 0,
+ { AFE_PORT_ID_INT6_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, 0,
LPASS_BE_INT6_MI2S_TX},
- { SLIMBUS_TX_VI, 0, 0, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_TX_VI},
+ { SLIMBUS_TX_VI, 0, {0}, {0}, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_TX_VI},
};
-/* Track ASM playback & capture sessions of DAI */
+/* Track ASM playback & capture sessions of DAI
+ * Track LSM listen sessions
+ */
static struct msm_pcm_routing_fdai_data
- fe_dai_map[MSM_FRONTEND_DAI_MM_SIZE][2] = {
+ fe_dai_map[MSM_FRONTEND_DAI_MAX][2] = {
/* MULTIMEDIA1 */
{{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
@@ -575,13 +590,80 @@ static struct msm_pcm_routing_fdai_data
/* MULTIMEDIA19 */
{{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* CS_VOICE */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* VOIP */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* AFE_RX */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* AFE_TX */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* VOICE_STUB */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* VOLTE */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* DTMF_RX */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* VOICE2 */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* QCHAT */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* VOLTE_STUB */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* LSM1 */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* LSM2 */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* LSM3 */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* LSM4 */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* LSM5 */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* LSM6 */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* LSM7 */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* LSM8 */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* VOICE2_STUB */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* VOWLAN */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* VOICEMMODE1 */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* VOICEMMODE2 */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
};
-static unsigned long session_copp_map[MSM_FRONTEND_DAI_MM_SIZE][2]
+static unsigned long session_copp_map[MSM_FRONTEND_DAI_MAX][2]
[MSM_BACKEND_DAI_MAX];
static struct msm_pcm_routing_app_type_data app_type_cfg[MAX_APP_TYPES];
+static struct msm_pcm_routing_app_type_data lsm_app_type_cfg[MAX_APP_TYPES];
static struct msm_pcm_stream_app_type_cfg
- fe_dai_app_type_cfg[MSM_FRONTEND_DAI_MM_SIZE][2];
+ fe_dai_app_type_cfg[MSM_FRONTEND_DAI_MAX][2];
/* The caller of this should aqcuire routing lock */
void msm_pcm_routing_get_bedai_info(int be_idx,
@@ -624,13 +706,39 @@ static int msm_pcm_routing_get_app_type_idx(int app_type)
return 0;
}
+static int msm_pcm_routing_get_lsm_app_type_idx(int app_type)
+{
+ int idx;
+
+ pr_debug("%s: app_type: %d\n", __func__, app_type);
+ for (idx = 0; idx < MAX_APP_TYPES; idx++) {
+ if (lsm_app_type_cfg[idx].app_type == app_type)
+ return idx;
+ }
+ pr_debug("%s: App type not available, fallback to default\n", __func__);
+ return 0;
+}
+
+static bool is_mm_lsm_fe_id(int fe_id)
+{
+ bool rc = true;
+
+ if (fe_id > MSM_FRONTEND_DAI_MM_MAX_ID &&
+ ((fe_id < MSM_FRONTEND_DAI_LSM1) ||
+ (fe_id > MSM_FRONTEND_DAI_LSM8))) {
+ rc = false;
+ }
+ return rc;
+}
+
+
void msm_pcm_routing_reg_stream_app_type_cfg(int fedai_id, int app_type,
int acdb_dev_id, int sample_rate, int session_type)
{
pr_debug("%s: fedai_id %d, session_type %d, app_type %d, acdb_dev_id %d, sample_rate %d\n",
__func__, fedai_id, session_type, app_type,
acdb_dev_id, sample_rate);
- if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
+ if (!is_mm_lsm_fe_id(fedai_id)) {
pr_err("%s: Invalid machine driver ID %d\n",
__func__, fedai_id);
return;
@@ -677,7 +785,7 @@ int msm_pcm_routing_get_stream_app_type_cfg(int fedai_id, int session_type,
pr_err("%s: NULL pointer sent for sample rate\n", __func__);
ret = -EINVAL;
goto done;
- } else if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
+ } else if (!is_mm_lsm_fe_id(fedai_id)) {
pr_err("%s: Invalid FE ID %d\n",
__func__, fedai_id);
ret = -EINVAL;
@@ -791,7 +899,8 @@ static uint8_t is_be_dai_extproc(int be_dai)
}
static void msm_pcm_routing_build_matrix(int fedai_id, int sess_type,
- int path_type, int perf_mode)
+ int path_type, int perf_mode,
+ uint32_t passthr_mode)
{
int i, port_type, j, num_copps = 0;
struct route_payload payload;
@@ -804,7 +913,7 @@ static void msm_pcm_routing_build_matrix(int fedai_id, int sess_type,
if (!is_be_dai_extproc(i) &&
(afe_get_port_type(msm_bedais[i].port_id) == port_type) &&
(msm_bedais[i].active) &&
- (test_bit(fedai_id, &msm_bedais[i].fe_sessions))) {
+ (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0]))) {
for (j = 0; j < MAX_COPPS_PER_PORT; j++) {
unsigned long copp =
session_copp_map[fedai_id][sess_type][i];
@@ -827,7 +936,7 @@ static void msm_pcm_routing_build_matrix(int fedai_id, int sess_type,
fe_dai_app_type_cfg[fedai_id][sess_type].acdb_dev_id;
payload.sample_rate =
fe_dai_app_type_cfg[fedai_id][sess_type].sample_rate;
- adm_matrix_map(path_type, payload, perf_mode);
+ adm_matrix_map(path_type, payload, perf_mode, passthr_mode);
msm_pcm_routng_cfg_matrix_map_pp(payload, path_type, perf_mode);
}
}
@@ -861,7 +970,7 @@ void msm_pcm_routing_reg_psthr_stream(int fedai_id, int dspst_id,
if (!is_be_dai_extproc(i) &&
(afe_get_port_type(msm_bedais[i].port_id) == port_type) &&
(msm_bedais[i].active) &&
- (test_bit(fedai_id, &msm_bedais[i].fe_sessions))) {
+ (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0]))) {
mode = afe_get_port_type(msm_bedais[i].port_id);
adm_connect_afe_port(mode, dspst_id,
msm_bedais[i].port_id);
@@ -871,28 +980,51 @@ void msm_pcm_routing_reg_psthr_stream(int fedai_id, int dspst_id,
mutex_unlock(&routing_lock);
}
+static bool route_check_fe_id_adm_support(int fe_id)
+{
+ bool rc = true;
+
+ if ((fe_id >= MSM_FRONTEND_DAI_LSM1) &&
+ (fe_id <= MSM_FRONTEND_DAI_LSM8)) {
+ /* fe id is listen while port is set to afe */
+ if (lsm_port_index != ADM_LSM_PORT_INDEX) {
+ pr_debug("%s: fe_id %d, lsm mux slim port %d\n",
+ __func__, fe_id, lsm_port_index);
+ rc = false;
+ }
+ }
+
+ return rc;
+}
+
int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
int dspst_id, int stream_type,
- uint32_t compr_passthr_mode)
+ uint32_t passthr_mode)
{
int i, j, session_type, path_type, port_type, topology, num_copps = 0;
struct route_payload payload;
u32 channels, sample_rate;
u16 bit_width = 16;
+ bool is_lsm;
pr_debug("%s:fe_id[%d] perf_mode[%d] id[%d] stream_type[%d] passt[%d]",
__func__, fe_id, perf_mode, dspst_id,
- stream_type, compr_passthr_mode);
-
- if (fe_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
+ stream_type, passthr_mode);
+ if (!is_mm_lsm_fe_id(fe_id)) {
/* bad ID assigned in machine driver */
pr_err("%s: bad MM ID %d\n", __func__, fe_id);
return -EINVAL;
}
+ if (!route_check_fe_id_adm_support(fe_id)) {
+ /* ignore adm open if not supported for fe_id */
+ pr_debug("%s: No ADM support for fe id %d\n", __func__, fe_id);
+ return 0;
+ }
+
if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) {
session_type = SESSION_TYPE_RX;
- if (compr_passthr_mode != LEGACY_PCM)
+ if (passthr_mode != LEGACY_PCM)
path_type = ADM_PATH_COMPRESSED_RX;
else
path_type = ADM_PATH_PLAYBACK;
@@ -906,6 +1038,8 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
return -EINVAL;
}
+ is_lsm = (fe_id >= MSM_FRONTEND_DAI_LSM1) &&
+ (fe_id <= MSM_FRONTEND_DAI_LSM8);
mutex_lock(&routing_lock);
payload.num_copps = 0; /* only RX needs to use payload */
@@ -913,14 +1047,14 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
/* re-enable EQ if active */
msm_qti_pp_send_eq_values(fe_id);
for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
- if (test_bit(fe_id, &msm_bedais[i].fe_sessions))
- msm_bedais[i].compr_passthr_mode = compr_passthr_mode;
+ if (test_bit(fe_id, &msm_bedais[i].fe_sessions[0]))
+ msm_bedais[i].passthr_mode = passthr_mode;
if (!is_be_dai_extproc(i) &&
(afe_get_port_type(msm_bedais[i].port_id) ==
port_type) &&
(msm_bedais[i].active) &&
- (test_bit(fe_id, &msm_bedais[i].fe_sessions))) {
+ (test_bit(fe_id, &msm_bedais[i].fe_sessions[0]))) {
int app_type, app_type_idx, copp_idx, acdb_dev_id;
/*
@@ -936,7 +1070,15 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
msm_bedais[i].format);
app_type =
fe_dai_app_type_cfg[fe_id][session_type].app_type;
- if (app_type) {
+ if (app_type && is_lsm) {
+ app_type_idx =
+ msm_pcm_routing_get_lsm_app_type_idx(app_type);
+ sample_rate =
+ fe_dai_app_type_cfg[fe_id][session_type].
+ sample_rate;
+ bit_width =
+ lsm_app_type_cfg[app_type_idx].bit_width;
+ } else if (app_type) {
app_type_idx =
msm_pcm_routing_get_app_type_idx(
app_type);
@@ -951,9 +1093,10 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
fe_dai_app_type_cfg[fe_id][session_type].acdb_dev_id;
topology = msm_routing_get_adm_topology(path_type,
fe_id, session_type);
- if (compr_passthr_mode == COMPRESSED_PASSTHROUGH_DSD)
+
+ if (passthr_mode == COMPRESSED_PASSTHROUGH_DSD)
topology = COMPRESS_PASSTHROUGH_NONE_TOPOLOGY;
- pr_err("%s: Before adm open topology %d\n", __func__,
+ pr_debug("%s: Before adm open topology %d\n", __func__,
topology);
copp_idx =
@@ -990,7 +1133,7 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
num_copps++;
}
}
- if (compr_passthr_mode != COMPRESSED_PASSTHROUGH_DSD) {
+ if (passthr_mode != COMPRESSED_PASSTHROUGH_DSD) {
msm_routing_send_device_pp_params(
msm_bedais[i].port_id,
copp_idx);
@@ -1004,7 +1147,9 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
fe_dai_app_type_cfg[fe_id][session_type].app_type;
payload.acdb_dev_id =
fe_dai_app_type_cfg[fe_id][session_type].acdb_dev_id;
- adm_matrix_map(path_type, payload, perf_mode);
+ payload.sample_rate =
+ fe_dai_app_type_cfg[fe_id][session_type].sample_rate;
+ adm_matrix_map(path_type, payload, perf_mode, passthr_mode);
msm_pcm_routng_cfg_matrix_map_pp(payload, path_type, perf_mode);
}
mutex_unlock(&routing_lock);
@@ -1055,6 +1200,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode,
struct route_payload payload;
u32 channels, sample_rate;
uint16_t bits_per_sample = 16;
+ uint32_t passthr_mode = LEGACY_PCM;
if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
/* bad ID assigned in machine driver */
@@ -1084,7 +1230,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode,
if (!is_be_dai_extproc(i) &&
(afe_get_port_type(msm_bedais[i].port_id) == port_type) &&
(msm_bedais[i].active) &&
- (test_bit(fedai_id, &msm_bedais[i].fe_sessions))) {
+ (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0]))) {
int app_type, app_type_idx, copp_idx, acdb_dev_id;
/*
* check if ADM needs to be configured with different
@@ -1094,7 +1240,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode,
channels = msm_bedais[i].channel;
else
channels = msm_bedais[i].adm_override_ch;
- msm_bedais[i].compr_passthr_mode =
+ msm_bedais[i].passthr_mode =
LEGACY_PCM;
bits_per_sample = msm_routing_get_bit_width(
@@ -1151,7 +1297,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode,
}
}
if ((perf_mode == LEGACY_PCM_MODE) &&
- (msm_bedais[i].compr_passthr_mode ==
+ (msm_bedais[i].passthr_mode ==
LEGACY_PCM))
msm_pcm_routing_cfg_pp(msm_bedais[i].port_id,
copp_idx, topology,
@@ -1167,7 +1313,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode,
fe_dai_app_type_cfg[fedai_id][session_type].acdb_dev_id;
payload.sample_rate =
fe_dai_app_type_cfg[fedai_id][session_type].sample_rate;
- adm_matrix_map(path_type, payload, perf_mode);
+ adm_matrix_map(path_type, payload, perf_mode, passthr_mode);
msm_pcm_routng_cfg_matrix_map_pp(payload, path_type, perf_mode);
}
mutex_unlock(&routing_lock);
@@ -1196,7 +1342,7 @@ void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type)
int i, port_type, session_type, path_type, topology;
struct msm_pcm_routing_fdai_data *fdai;
- if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
+ if (!is_mm_lsm_fe_id(fedai_id)) {
/* bad ID assigned in machine driver */
pr_err("%s: bad MM ID\n", __func__);
return;
@@ -1217,7 +1363,7 @@ void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type)
if (!is_be_dai_extproc(i) &&
(afe_get_port_type(msm_bedais[i].port_id) == port_type) &&
(msm_bedais[i].active) &&
- (test_bit(fedai_id, &msm_bedais[i].fe_sessions))) {
+ (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0]))) {
int idx;
unsigned long copp =
session_copp_map[fedai_id][session_type][i];
@@ -1242,7 +1388,7 @@ void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type)
if ((DOLBY_ADM_COPP_TOPOLOGY_ID == topology ||
DS2_ADM_COPP_TOPOLOGY_ID == topology) &&
(fdai->perf_mode == LEGACY_PCM_MODE) &&
- (msm_bedais[i].compr_passthr_mode ==
+ (msm_bedais[i].passthr_mode ==
LEGACY_PCM))
msm_pcm_routing_deinit_pp(msm_bedais[i].port_id,
topology);
@@ -1259,13 +1405,13 @@ static bool msm_pcm_routing_route_is_set(u16 be_id, u16 fe_id)
{
bool rc = false;
- if (fe_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
+ if (!is_mm_lsm_fe_id(fe_id)) {
/* recheck FE ID in the mixer control defined in this file */
pr_err("%s: bad MM ID\n", __func__);
return rc;
}
- if (test_bit(fe_id, &msm_bedais[be_id].fe_sessions))
+ if (test_bit(fe_id, &msm_bedais[be_id].fe_sessions[0]))
rc = true;
return rc;
@@ -1277,19 +1423,27 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
u32 channels, sample_rate;
uint16_t bits_per_sample = 16;
struct msm_pcm_routing_fdai_data *fdai;
+ uint32_t passthr_mode = msm_bedais[reg].passthr_mode;
+ bool is_lsm;
pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
- if (val > MSM_FRONTEND_DAI_MM_MAX_ID) {
+ if (!is_mm_lsm_fe_id(val)) {
/* recheck FE ID in the mixer control defined in this file */
pr_err("%s: bad MM ID\n", __func__);
return;
}
+ if (!route_check_fe_id_adm_support(val)) {
+ /* ignore adm open if not supported for fe_id */
+ pr_debug("%s: No ADM support for fe id %d\n", __func__, val);
+ return;
+ }
+
if (afe_get_port_type(msm_bedais[reg].port_id) ==
MSM_AFE_PORT_TYPE_RX) {
session_type = SESSION_TYPE_RX;
- if (msm_bedais[reg].compr_passthr_mode != LEGACY_PCM)
+ if (passthr_mode != LEGACY_PCM)
path_type = ADM_PATH_COMPRESSED_RX;
else
path_type = ADM_PATH_PLAYBACK;
@@ -1297,15 +1451,17 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
session_type = SESSION_TYPE_TX;
path_type = ADM_PATH_LIVE_REC;
}
+ is_lsm = (val >= MSM_FRONTEND_DAI_LSM1) &&
+ (val <= MSM_FRONTEND_DAI_LSM8);
mutex_lock(&routing_lock);
if (set) {
- if (!test_bit(val, &msm_bedais[reg].fe_sessions) &&
+ if (!test_bit(val, &msm_bedais[reg].fe_sessions[0]) &&
((msm_bedais[reg].port_id == VOICE_PLAYBACK_TX) ||
(msm_bedais[reg].port_id == VOICE2_PLAYBACK_TX)))
voc_start_playback(set, msm_bedais[reg].port_id);
- set_bit(val, &msm_bedais[reg].fe_sessions);
+ set_bit(val, &msm_bedais[reg].fe_sessions[0]);
fdai = &fe_dai_map[val][session_type];
if (msm_bedais[reg].active && fdai->strm_id !=
INVALID_SESSION) {
@@ -1336,7 +1492,15 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
app_type =
fe_dai_app_type_cfg[val][session_type].app_type;
- if (app_type) {
+ if (app_type && is_lsm) {
+ app_type_idx =
+ msm_pcm_routing_get_lsm_app_type_idx(app_type);
+ sample_rate =
+ fe_dai_app_type_cfg[val][session_type].
+ sample_rate;
+ bits_per_sample =
+ lsm_app_type_cfg[app_type_idx].bit_width;
+ } else if (app_type) {
app_type_idx =
msm_pcm_routing_get_app_type_idx(app_type);
sample_rate =
@@ -1381,20 +1545,20 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
msm_pcm_routing_build_matrix(val, session_type,
path_type,
- fdai->perf_mode);
+ fdai->perf_mode,
+ passthr_mode);
if ((fdai->perf_mode == LEGACY_PCM_MODE) &&
- (msm_bedais[reg].compr_passthr_mode ==
- LEGACY_PCM))
+ (passthr_mode == LEGACY_PCM))
msm_pcm_routing_cfg_pp(msm_bedais[reg].port_id,
copp_idx, topology,
channels);
}
} else {
- if (test_bit(val, &msm_bedais[reg].fe_sessions) &&
+ if (test_bit(val, &msm_bedais[reg].fe_sessions[0]) &&
((msm_bedais[reg].port_id == VOICE_PLAYBACK_TX) ||
(msm_bedais[reg].port_id == VOICE2_PLAYBACK_TX)))
voc_start_playback(set, msm_bedais[reg].port_id);
- clear_bit(val, &msm_bedais[reg].fe_sessions);
+ clear_bit(val, &msm_bedais[reg].fe_sessions[0]);
fdai = &fe_dai_map[val][session_type];
if (msm_bedais[reg].active && fdai->strm_id !=
INVALID_SESSION) {
@@ -1419,14 +1583,14 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
if ((DOLBY_ADM_COPP_TOPOLOGY_ID == topology ||
DS2_ADM_COPP_TOPOLOGY_ID == topology) &&
(fdai->perf_mode == LEGACY_PCM_MODE) &&
- (msm_bedais[reg].compr_passthr_mode ==
- LEGACY_PCM))
+ (passthr_mode == LEGACY_PCM))
msm_pcm_routing_deinit_pp(
msm_bedais[reg].port_id,
topology);
msm_pcm_routing_build_matrix(val, session_type,
path_type,
- fdai->perf_mode);
+ fdai->perf_mode,
+ passthr_mode);
}
}
if ((msm_bedais[reg].port_id == VOICE_RECORD_RX)
@@ -1442,7 +1606,7 @@ static int msm_routing_get_audio_mixer(struct snd_kcontrol *kcontrol,
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
- if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions))
+ if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0]))
ucontrol->value.integer.value[0] = 1;
else
ucontrol->value.integer.value[0] = 0;
@@ -1476,6 +1640,51 @@ static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol,
return 1;
}
+static int msm_routing_get_listen_mixer(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+
+ if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0]))
+ ucontrol->value.integer.value[0] = 1;
+ else
+ ucontrol->value.integer.value[0] = 0;
+
+ pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
+ ucontrol->value.integer.value[0]);
+
+ return 0;
+}
+
+static int msm_routing_put_listen_mixer(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dapm_widget_list *wlist =
+ dapm_kcontrol_get_wlist(kcontrol);
+ struct snd_soc_dapm_widget *widget = wlist->widgets[0];
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+ struct snd_soc_dapm_update *update = NULL;
+
+ pr_debug("%s: reg %x shift %x val %ld\n", __func__, mc->reg, mc->shift,
+ ucontrol->value.integer.value[0]);
+
+ if (ucontrol->value.integer.value[0]) {
+ if (msm_pcm_routing_route_is_set(mc->reg, mc->shift) == false)
+ msm_pcm_routing_process_audio(mc->reg, mc->shift, 1);
+ snd_soc_dapm_mixer_update_power(widget->dapm,
+ kcontrol, 1, update);
+ } else if (!ucontrol->value.integer.value[0]) {
+ if (msm_pcm_routing_route_is_set(mc->reg, mc->shift) == true)
+ msm_pcm_routing_process_audio(mc->reg, mc->shift, 0);
+ snd_soc_dapm_mixer_update_power(widget->dapm,
+ kcontrol, 0, update);
+ }
+
+ return 1;
+}
+
static void msm_pcm_routing_process_voice(u16 reg, u16 val, int set)
{
u32 session_id = 0;
@@ -1492,9 +1701,9 @@ static void msm_pcm_routing_process_voice(u16 reg, u16 val, int set)
mutex_lock(&routing_lock);
if (set)
- set_bit(val, &msm_bedais[reg].fe_sessions);
+ set_bit(val, &msm_bedais[reg].fe_sessions[0]);
else
- clear_bit(val, &msm_bedais[reg].fe_sessions);
+ clear_bit(val, &msm_bedais[reg].fe_sessions[0]);
if (val == MSM_FRONTEND_DAI_DTMF_RX &&
afe_get_port_type(msm_bedais[reg].port_id) ==
@@ -1553,7 +1762,7 @@ static int msm_routing_get_voice_mixer(struct snd_kcontrol *kcontrol,
mutex_lock(&routing_lock);
- if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions))
+ if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0]))
ucontrol->value.integer.value[0] = 1;
else
ucontrol->value.integer.value[0] = 0;
@@ -1595,7 +1804,7 @@ static int msm_routing_get_voice_stub_mixer(struct snd_kcontrol *kcontrol,
mutex_lock(&routing_lock);
- if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions))
+ if (test_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0]))
ucontrol->value.integer.value[0] = 1;
else
ucontrol->value.integer.value[0] = 0;
@@ -1620,13 +1829,13 @@ static int msm_routing_put_voice_stub_mixer(struct snd_kcontrol *kcontrol,
if (ucontrol->value.integer.value[0]) {
mutex_lock(&routing_lock);
- set_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions);
+ set_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0]);
mutex_unlock(&routing_lock);
snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, update);
} else {
mutex_lock(&routing_lock);
- clear_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions);
+ clear_bit(mc->shift, &msm_bedais[mc->reg].fe_sessions[0]);
mutex_unlock(&routing_lock);
snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, update);
@@ -1928,23 +2137,19 @@ static int msm_routing_put_fm_pcmrx_switch_mixer(struct snd_kcontrol *kcontrol,
return 1;
}
-static int msm_routing_lsm_mux_get(struct snd_kcontrol *kcontrol,
+static int msm_routing_lsm_port_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- ucontrol->value.integer.value[0] = lsm_mux_slim_port;
+ ucontrol->value.integer.value[0] = lsm_port_index;
return 0;
}
-static int msm_routing_lsm_mux_put(struct snd_kcontrol *kcontrol,
+static int msm_routing_lsm_port_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_dapm_widget_list *wlist =
- dapm_kcontrol_get_wlist(kcontrol);
- struct snd_soc_dapm_widget *widget = wlist->widgets[0];
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
int mux = ucontrol->value.enumerated.item[0];
int lsm_port = AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX;
- struct snd_soc_dapm_update *update = NULL;
if (mux >= e->items) {
pr_err("%s: Invalid mux value %d\n", __func__, mux);
@@ -1975,19 +2180,18 @@ static int msm_routing_lsm_mux_put(struct snd_kcontrol *kcontrol,
case 7:
lsm_port = AFE_PORT_ID_TERTIARY_MI2S_TX;
break;
+ case 8:
+ lsm_port = AFE_PORT_ID_QUATERNARY_MI2S_TX;
+ break;
+ case 9:
+ lsm_port = ADM_LSM_PORT_ID;
+ break;
default:
pr_err("Default lsm port");
break;
}
set_lsm_port(lsm_port);
-
- if (ucontrol->value.integer.value[0]) {
- lsm_mux_slim_port = ucontrol->value.integer.value[0];
- snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, mux, e, update);
- } else {
- snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, mux, e, update);
- lsm_mux_slim_port = ucontrol->value.integer.value[0];
- }
+ lsm_port_index = ucontrol->value.integer.value[0];
return 0;
}
@@ -2000,23 +2204,27 @@ static int msm_routing_lsm_func_get(struct snd_kcontrol *kcontrol,
enum afe_mad_type mad_type;
pr_debug("%s: enter\n", __func__);
- for (i = 0; i < ARRAY_SIZE(mad_audio_mux_text); i++)
- if (!strncmp(kcontrol->id.name, mad_audio_mux_text[i],
- strlen(mad_audio_mux_text[i])))
+ for (i = 0; i < ARRAY_SIZE(lsm_port_text); i++)
+ if (!strnstr(kcontrol->id.name, lsm_port_text[i],
+ strlen(lsm_port_text[i])))
break;
- if (i-- == ARRAY_SIZE(mad_audio_mux_text)) {
+ if (i-- == ARRAY_SIZE(lsm_port_text)) {
WARN(1, "Invalid id name %s\n", kcontrol->id.name);
return -EINVAL;
}
/*Check for Tertiary TX port*/
- if (!strcmp(kcontrol->id.name, mad_audio_mux_text[7])) {
+ if (!strcmp(kcontrol->id.name, lsm_port_text[7])) {
ucontrol->value.integer.value[0] = MADSWAUDIO;
return 0;
}
port_id = i * 2 + 1 + SLIMBUS_0_RX;
+
+ if (!strcmp(kcontrol->id.name, lsm_port_text[8]))
+ port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX;
+
mad_type = afe_port_get_mad_type(port_id);
pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id,
mad_type);
@@ -2051,12 +2259,12 @@ static int msm_routing_lsm_func_put(struct snd_kcontrol *kcontrol,
enum afe_mad_type mad_type;
pr_debug("%s: enter\n", __func__);
- for (i = 0; i < ARRAY_SIZE(mad_audio_mux_text); i++)
- if (!strncmp(kcontrol->id.name, mad_audio_mux_text[i],
- strlen(mad_audio_mux_text[i])))
+ for (i = 0; i < ARRAY_SIZE(lsm_port_text); i++)
+ if (strnstr(kcontrol->id.name, lsm_port_text[i],
+ strlen(lsm_port_text[i])))
break;
- if (i-- == ARRAY_SIZE(mad_audio_mux_text)) {
+ if (i-- == ARRAY_SIZE(lsm_port_text)) {
WARN(1, "Invalid id name %s\n", kcontrol->id.name);
return -EINVAL;
}
@@ -2084,11 +2292,16 @@ static int msm_routing_lsm_func_put(struct snd_kcontrol *kcontrol,
}
/*Check for Tertiary TX port*/
- if (!strcmp(kcontrol->id.name, mad_audio_mux_text[7])) {
+ if (strnstr(kcontrol->id.name, lsm_port_text[7],
+ strlen(lsm_port_text[7]))) {
port_id = AFE_PORT_ID_TERTIARY_MI2S_TX;
mad_type = MAD_SW_AUDIO;
}
+ if (strnstr(kcontrol->id.name, lsm_port_text[8],
+ strlen(lsm_port_text[8])))
+ port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX;
+
pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id,
mad_type);
return afe_port_set_mad_type(port_id, mad_type);
@@ -2253,6 +2466,144 @@ static int msm_routing_put_port_mixer(struct snd_kcontrol *kcontrol,
return 1;
}
+static int msm_ec_ref_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = msm_ec_ref_ch;
+ pr_debug("%s: msm_ec_ref_ch = %ld\n", __func__,
+ ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_ec_ref_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_ec_ref_ch = ucontrol->value.integer.value[0];
+ pr_debug("%s: msm_ec_ref_ch = %d\n", __func__, msm_ec_ref_ch);
+ adm_num_ec_ref_rx_chans(msm_ec_ref_ch);
+ return 0;
+}
+
+static const char *const ec_ref_ch_text[] = {"Zero", "One", "Two", "Three",
+ "Four", "Five", "Six", "Seven", "Eight"};
+
+static int msm_ec_ref_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_ec_ref_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 2;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_ec_ref_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_ec_ref_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ u16 bit_width = 0;
+
+ switch (ucontrol->value.integer.value[0]) {
+ case 2:
+ msm_ec_ref_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 1:
+ msm_ec_ref_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ default:
+ msm_ec_ref_bit_format = 0;
+ break;
+ }
+
+ if (msm_ec_ref_bit_format == SNDRV_PCM_FORMAT_S16_LE)
+ bit_width = 16;
+ else if (msm_ec_ref_bit_format == SNDRV_PCM_FORMAT_S24_LE)
+ bit_width = 24;
+
+ pr_debug("%s: msm_ec_ref_bit_format = %d\n",
+ __func__, msm_ec_ref_bit_format);
+ adm_ec_ref_rx_bit_width(bit_width);
+ return 0;
+}
+
+static char const *ec_ref_bit_format_text[] = {"0", "S16_LE", "S24_LE"};
+
+static int msm_ec_ref_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = msm_ec_ref_sampling_rate;
+ pr_debug("%s: msm_ec_ref_sampling_rate = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_ec_ref_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 0:
+ msm_ec_ref_sampling_rate = 0;
+ break;
+ case 1:
+ msm_ec_ref_sampling_rate = 8000;
+ break;
+ case 2:
+ msm_ec_ref_sampling_rate = 16000;
+ break;
+ case 3:
+ msm_ec_ref_sampling_rate = 32000;
+ break;
+ case 4:
+ msm_ec_ref_sampling_rate = 44100;
+ break;
+ case 5:
+ msm_ec_ref_sampling_rate = 48000;
+ break;
+ case 6:
+ msm_ec_ref_sampling_rate = 96000;
+ break;
+ case 7:
+ msm_ec_ref_sampling_rate = 192000;
+ break;
+ case 8:
+ msm_ec_ref_sampling_rate = 384000;
+ break;
+ default:
+ msm_ec_ref_sampling_rate = 48000;
+ break;
+ }
+ pr_debug("%s: msm_ec_ref_sampling_rate = %d\n",
+ __func__, msm_ec_ref_sampling_rate);
+ adm_ec_ref_rx_sampling_rate(msm_ec_ref_sampling_rate);
+ return 0;
+}
+
+static const char *const ec_ref_rate_text[] = {"0", "8000", "16000",
+ "32000", "44100", "48000", "96000", "192000", "384000"};
+
+static const struct soc_enum msm_route_ec_ref_params_enum[] = {
+ SOC_ENUM_SINGLE_EXT(9, ec_ref_ch_text),
+ SOC_ENUM_SINGLE_EXT(3, ec_ref_bit_format_text),
+ SOC_ENUM_SINGLE_EXT(9, ec_ref_rate_text),
+};
+
+static const struct snd_kcontrol_new ec_ref_param_controls[] = {
+ SOC_ENUM_EXT("EC Reference Channels", msm_route_ec_ref_params_enum[0],
+ msm_ec_ref_ch_get, msm_ec_ref_ch_put),
+ SOC_ENUM_EXT("EC Reference Bit Format", msm_route_ec_ref_params_enum[1],
+ msm_ec_ref_bit_format_get, msm_ec_ref_bit_format_put),
+ SOC_ENUM_EXT("EC Reference SampleRate", msm_route_ec_ref_params_enum[2],
+ msm_ec_ref_rate_get, msm_ec_ref_rate_put),
+};
+
static int msm_routing_ec_ref_rx_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -4164,6 +4515,159 @@ static const struct snd_kcontrol_new pri_tdm_rx_0_mixer_controls[] = {
msm_routing_put_audio_mixer),
};
+static const struct snd_kcontrol_new pri_tdm_rx_1_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new pri_tdm_rx_2_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new pri_tdm_rx_3_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
static const struct snd_kcontrol_new pri_tdm_tx_0_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_TDM_TX_0,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
@@ -4266,6 +4770,159 @@ static const struct snd_kcontrol_new sec_tdm_rx_0_mixer_controls[] = {
msm_routing_put_audio_mixer),
};
+static const struct snd_kcontrol_new sec_tdm_rx_1_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new sec_tdm_rx_2_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new sec_tdm_rx_3_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
static const struct snd_kcontrol_new sec_tdm_tx_0_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_TDM_TX_0,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
@@ -4894,6 +5551,30 @@ static const struct snd_kcontrol_new mmul1_mixer_controls[] = {
SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
@@ -4966,6 +5647,30 @@ static const struct snd_kcontrol_new mmul2_mixer_controls[] = {
SOC_SINGLE_EXT("QUIN_MI2S_TX", MSM_BACKEND_DAI_QUINARY_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0,
MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
@@ -5038,6 +5743,30 @@ static const struct snd_kcontrol_new mmul3_mixer_controls[] = {
SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0,
MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
@@ -5089,6 +5818,30 @@ static const struct snd_kcontrol_new mmul4_mixer_controls[] = {
SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0,
MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1,
MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
@@ -5170,6 +5923,30 @@ static const struct snd_kcontrol_new mmul5_mixer_controls[] = {
SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
@@ -5248,6 +6025,30 @@ static const struct snd_kcontrol_new mmul6_mixer_controls[] = {
SOC_SINGLE_EXT("QUAT_AUXPCM_UL_TX", MSM_BACKEND_DAI_QUAT_AUXPCM_TX,
MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0,
MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
@@ -5317,6 +6118,30 @@ static const struct snd_kcontrol_new mmul8_mixer_controls[] = {
SOC_SINGLE_EXT("SLIM_6_TX", MSM_BACKEND_DAI_SLIMBUS_6_TX,
MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0,
MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
@@ -7146,6 +7971,542 @@ static const struct snd_kcontrol_new quat_mi2s_rx_port_mixer_controls[] = {
msm_routing_put_port_mixer),
};
+static const struct snd_kcontrol_new pri_tdm_rx_0_port_mixer_controls[] = {
+ SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ MSM_BACKEND_DAI_INT_FM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ MSM_BACKEND_DAI_AUXPCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+};
+
+static const struct snd_kcontrol_new pri_tdm_rx_1_port_mixer_controls[] = {
+ SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_BACKEND_DAI_INT_FM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_BACKEND_DAI_AUXPCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+};
+
+static const struct snd_kcontrol_new pri_tdm_rx_2_port_mixer_controls[] = {
+ SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_BACKEND_DAI_INT_FM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_BACKEND_DAI_AUXPCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+};
+
+static const struct snd_kcontrol_new pri_tdm_rx_3_port_mixer_controls[] = {
+ SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_BACKEND_DAI_INT_FM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_BACKEND_DAI_AUXPCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+};
+
+static const struct snd_kcontrol_new sec_tdm_rx_0_port_mixer_controls[] = {
+ SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0,
+ MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0,
+ MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0,
+ MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0,
+ MSM_BACKEND_DAI_INT_FM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0,
+ MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0,
+ MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0,
+ MSM_BACKEND_DAI_AUXPCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_0,
+ MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_0,
+ MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_0,
+ MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_0,
+ MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_0,
+ MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_0,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_0,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_0,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_0,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+};
+
+static const struct snd_kcontrol_new sec_tdm_rx_1_port_mixer_controls[] = {
+ SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_BACKEND_DAI_INT_FM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_BACKEND_DAI_AUXPCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+};
+
+static const struct snd_kcontrol_new sec_tdm_rx_2_port_mixer_controls[] = {
+ SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_BACKEND_DAI_INT_FM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_BACKEND_DAI_AUXPCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+};
+
+static const struct snd_kcontrol_new sec_tdm_rx_3_port_mixer_controls[] = {
+ SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_BACKEND_DAI_INT_FM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_BACKEND_DAI_INT_BT_SCO_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_BACKEND_DAI_AFE_PCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_BACKEND_DAI_AUXPCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_BACKEND_DAI_SEC_TDM_TX_0, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_BACKEND_DAI_SEC_TDM_TX_1, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_BACKEND_DAI_SEC_TDM_TX_2, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_BACKEND_DAI_SEC_TDM_TX_3, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_1, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_2, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_BACKEND_DAI_QUAT_TDM_TX_3, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+};
+
static const struct snd_kcontrol_new tert_tdm_rx_0_port_mixer_controls[] = {
SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_TERT_TDM_RX_0,
MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0,
@@ -7721,6 +9082,198 @@ static const struct snd_kcontrol_new sec_mi2s_rx_port_mixer_controls[] = {
msm_routing_put_port_mixer),
};
+static const struct snd_kcontrol_new lsm1_mixer_controls[] = {
+ SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX,
+ MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX,
+ MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX,
+ MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
+ MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
+ MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+};
+
+static const struct snd_kcontrol_new lsm2_mixer_controls[] = {
+ SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX,
+ MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX,
+ MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX,
+ MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
+ MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
+ MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+};
+
+static const struct snd_kcontrol_new lsm3_mixer_controls[] = {
+ SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX,
+ MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX,
+ MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX,
+ MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
+ MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
+ MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+};
+
+static const struct snd_kcontrol_new lsm4_mixer_controls[] = {
+ SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX,
+ MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX,
+ MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX,
+ MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
+ MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
+ MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+};
+
+static const struct snd_kcontrol_new lsm5_mixer_controls[] = {
+ SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX,
+ MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX,
+ MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX,
+ MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
+ MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
+ MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+};
+
+static const struct snd_kcontrol_new lsm6_mixer_controls[] = {
+ SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX,
+ MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX,
+ MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX,
+ MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
+ MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
+ MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+};
+
+static const struct snd_kcontrol_new lsm7_mixer_controls[] = {
+ SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX,
+ MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX,
+ MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX,
+ MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
+ MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
+ MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+};
+
+static const struct snd_kcontrol_new lsm8_mixer_controls[] = {
+ SOC_SINGLE_EXT("SLIMBUS_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_1_TX", MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_3_TX", MSM_BACKEND_DAI_SLIMBUS_3_TX,
+ MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_4_TX", MSM_BACKEND_DAI_SLIMBUS_4_TX,
+ MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("SLIMBUS_5_TX", MSM_BACKEND_DAI_SLIMBUS_5_TX,
+ MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
+ MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
+ MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+};
+
static const struct snd_kcontrol_new slim_fm_switch_mixer_controls =
SOC_SINGLE_EXT("Switch", SND_SOC_NOPM,
0, 1, 0, msm_routing_get_switch_mixer,
@@ -7806,53 +9359,17 @@ static const struct snd_kcontrol_new usb_switch_mixer_controls =
0, 1, 0, msm_routing_get_usb_switch_mixer,
msm_routing_put_usb_switch_mixer);
-static const struct soc_enum lsm_mux_enum =
- SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mad_audio_mux_text), mad_audio_mux_text);
-
-static const struct snd_kcontrol_new lsm1_mux =
- SOC_DAPM_ENUM_EXT("LSM1 MUX", lsm_mux_enum,
- msm_routing_lsm_mux_get,
- msm_routing_lsm_mux_put);
-
-static const struct snd_kcontrol_new lsm2_mux =
- SOC_DAPM_ENUM_EXT("LSM2 MUX", lsm_mux_enum,
- msm_routing_lsm_mux_get,
- msm_routing_lsm_mux_put);
-static const struct snd_kcontrol_new lsm3_mux =
- SOC_DAPM_ENUM_EXT("LSM3 MUX", lsm_mux_enum,
- msm_routing_lsm_mux_get,
- msm_routing_lsm_mux_put);
-
-static const struct snd_kcontrol_new lsm4_mux =
- SOC_DAPM_ENUM_EXT("LSM4 MUX", lsm_mux_enum,
- msm_routing_lsm_mux_get,
- msm_routing_lsm_mux_put);
-static const struct snd_kcontrol_new lsm5_mux =
- SOC_DAPM_ENUM_EXT("LSM5 MUX", lsm_mux_enum,
- msm_routing_lsm_mux_get,
- msm_routing_lsm_mux_put);
-
-static const struct snd_kcontrol_new lsm6_mux =
- SOC_DAPM_ENUM_EXT("LSM6 MUX", lsm_mux_enum,
- msm_routing_lsm_mux_get,
- msm_routing_lsm_mux_put);
-static const struct snd_kcontrol_new lsm7_mux =
- SOC_DAPM_ENUM_EXT("LSM7 MUX", lsm_mux_enum,
- msm_routing_lsm_mux_get,
- msm_routing_lsm_mux_put);
-
-static const struct snd_kcontrol_new lsm8_mux =
- SOC_DAPM_ENUM_EXT("LSM8 MUX", lsm_mux_enum,
- msm_routing_lsm_mux_get,
- msm_routing_lsm_mux_put);
-
+static const struct soc_enum lsm_port_enum =
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lsm_port_text), lsm_port_text);
static const char * const lsm_func_text[] = {
"None", "AUDIO", "BEACON", "ULTRASOUND", "SWAUDIO",
};
static const struct soc_enum lsm_func_enum =
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lsm_func_text), lsm_func_text);
-static const struct snd_kcontrol_new lsm_function[] = {
+
+static const struct snd_kcontrol_new lsm_controls[] = {
+ /* kcontrol of lsm_function */
SOC_ENUM_EXT(SLIMBUS_0_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum,
msm_routing_lsm_func_get, msm_routing_lsm_func_put),
SOC_ENUM_EXT(SLIMBUS_1_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum,
@@ -7867,6 +9384,33 @@ static const struct snd_kcontrol_new lsm_function[] = {
msm_routing_lsm_func_get, msm_routing_lsm_func_put),
SOC_ENUM_EXT(TERT_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum,
msm_routing_lsm_func_get, msm_routing_lsm_func_put),
+ SOC_ENUM_EXT(QUAT_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum,
+ msm_routing_lsm_func_get, msm_routing_lsm_func_put),
+ /* kcontrol of lsm_port */
+ SOC_ENUM_EXT("LSM1 Port", lsm_port_enum,
+ msm_routing_lsm_port_get,
+ msm_routing_lsm_port_put),
+ SOC_ENUM_EXT("LSM2 Port", lsm_port_enum,
+ msm_routing_lsm_port_get,
+ msm_routing_lsm_port_put),
+ SOC_ENUM_EXT("LSM3 Port", lsm_port_enum,
+ msm_routing_lsm_port_get,
+ msm_routing_lsm_port_put),
+ SOC_ENUM_EXT("LSM4 Port", lsm_port_enum,
+ msm_routing_lsm_port_get,
+ msm_routing_lsm_port_put),
+ SOC_ENUM_EXT("LSM5 Port", lsm_port_enum,
+ msm_routing_lsm_port_get,
+ msm_routing_lsm_port_put),
+ SOC_ENUM_EXT("LSM6 Port", lsm_port_enum,
+ msm_routing_lsm_port_get,
+ msm_routing_lsm_port_put),
+ SOC_ENUM_EXT("LSM7 Port", lsm_port_enum,
+ msm_routing_lsm_port_get,
+ msm_routing_lsm_port_put),
+ SOC_ENUM_EXT("LSM8 Port", lsm_port_enum,
+ msm_routing_lsm_port_get,
+ msm_routing_lsm_port_put),
};
static const char * const aanc_slim_0_rx_text[] = {
@@ -7923,7 +9467,7 @@ static int msm_routing_put_stereo_to_custom_stereo_control(
(port_id != AFE_PORT_ID_INT4_MI2S_RX))
continue;
- for_each_set_bit(i, &msm_bedais[be_index].fe_sessions,
+ for_each_set_bit(i, &msm_bedais[be_index].fe_sessions[0],
MSM_FRONTEND_DAI_MM_SIZE) {
if (fe_dai_map[i][SESSION_TYPE_RX].perf_mode !=
LEGACY_PCM_MODE)
@@ -8029,6 +9573,45 @@ static const struct snd_kcontrol_new app_type_cfg_controls[] = {
msm_routing_put_app_type_cfg_control),
};
+static int msm_routing_get_lsm_app_type_cfg_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return 0;
+}
+
+static int msm_routing_put_lsm_app_type_cfg_control(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int i = 0, j;
+ int num_app_types = ucontrol->value.integer.value[i++];
+
+ memset(lsm_app_type_cfg, 0, MAX_APP_TYPES*
+ sizeof(struct msm_pcm_routing_app_type_data));
+ if (num_app_types > MAX_APP_TYPES) {
+ pr_err("%s: number of app types exceed the max supported\n",
+ __func__);
+ return -EINVAL;
+ }
+ for (j = 0; j < num_app_types; j++) {
+ lsm_app_type_cfg[j].app_type =
+ ucontrol->value.integer.value[i++];
+ lsm_app_type_cfg[j].sample_rate =
+ ucontrol->value.integer.value[i++];
+ lsm_app_type_cfg[j].bit_width =
+ ucontrol->value.integer.value[i++];
+ }
+
+ return 0;
+}
+
+static const struct snd_kcontrol_new lsm_app_type_cfg_controls[] = {
+ SOC_SINGLE_MULTI_EXT("Listen App Type Config", SND_SOC_NOPM, 0,
+ 0xFFFFFFFF, 0, 128, msm_routing_get_lsm_app_type_cfg_control,
+ msm_routing_put_lsm_app_type_cfg_control),
+};
+
static int msm_routing_get_use_ds1_or_ds2_control(
struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -8224,7 +9807,7 @@ static int msm_audio_get_copp_idx_from_port_id(int port_id, int session_type,
goto done;
}
- for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions,
+ for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions[0],
MSM_FRONTEND_DAI_MM_SIZE) {
for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) {
copp = session_copp_map[i]
@@ -9298,16 +10881,6 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
SND_SOC_DAPM_SWITCH("USB_DL_HL", SND_SOC_NOPM, 0, 0,
&usb_switch_mixer_controls),
- /* Mux Definitions */
- SND_SOC_DAPM_MUX("LSM1 MUX", SND_SOC_NOPM, 0, 0, &lsm1_mux),
- SND_SOC_DAPM_MUX("LSM2 MUX", SND_SOC_NOPM, 0, 0, &lsm2_mux),
- SND_SOC_DAPM_MUX("LSM3 MUX", SND_SOC_NOPM, 0, 0, &lsm3_mux),
- SND_SOC_DAPM_MUX("LSM4 MUX", SND_SOC_NOPM, 0, 0, &lsm4_mux),
- SND_SOC_DAPM_MUX("LSM5 MUX", SND_SOC_NOPM, 0, 0, &lsm5_mux),
- SND_SOC_DAPM_MUX("LSM6 MUX", SND_SOC_NOPM, 0, 0, &lsm6_mux),
- SND_SOC_DAPM_MUX("LSM7 MUX", SND_SOC_NOPM, 0, 0, &lsm7_mux),
- SND_SOC_DAPM_MUX("LSM8 MUX", SND_SOC_NOPM, 0, 0, &lsm8_mux),
-
/* Mixer definitions */
SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
pri_i2s_rx_mixer_controls, ARRAY_SIZE(pri_i2s_rx_mixer_controls)),
@@ -9356,12 +10929,30 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
SND_SOC_DAPM_MIXER("PRI_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0,
pri_tdm_rx_0_mixer_controls,
ARRAY_SIZE(pri_tdm_rx_0_mixer_controls)),
+ SND_SOC_DAPM_MIXER("PRI_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ pri_tdm_rx_1_mixer_controls,
+ ARRAY_SIZE(pri_tdm_rx_1_mixer_controls)),
+ SND_SOC_DAPM_MIXER("PRI_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ pri_tdm_rx_2_mixer_controls,
+ ARRAY_SIZE(pri_tdm_rx_2_mixer_controls)),
+ SND_SOC_DAPM_MIXER("PRI_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ pri_tdm_rx_3_mixer_controls,
+ ARRAY_SIZE(pri_tdm_rx_3_mixer_controls)),
SND_SOC_DAPM_MIXER("PRI_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0,
pri_tdm_tx_0_mixer_controls,
ARRAY_SIZE(pri_tdm_tx_0_mixer_controls)),
SND_SOC_DAPM_MIXER("SEC_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0,
sec_tdm_rx_0_mixer_controls,
ARRAY_SIZE(sec_tdm_rx_0_mixer_controls)),
+ SND_SOC_DAPM_MIXER("SEC_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ sec_tdm_rx_1_mixer_controls,
+ ARRAY_SIZE(sec_tdm_rx_1_mixer_controls)),
+ SND_SOC_DAPM_MIXER("SEC_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ sec_tdm_rx_2_mixer_controls,
+ ARRAY_SIZE(sec_tdm_rx_2_mixer_controls)),
+ SND_SOC_DAPM_MIXER("SEC_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ sec_tdm_rx_3_mixer_controls,
+ ARRAY_SIZE(sec_tdm_rx_3_mixer_controls)),
SND_SOC_DAPM_MIXER("SEC_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0,
sec_tdm_tx_0_mixer_controls,
ARRAY_SIZE(sec_tdm_tx_0_mixer_controls)),
@@ -9626,6 +11217,30 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
SND_SOC_DAPM_MIXER("QUAT_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0,
quat_mi2s_rx_port_mixer_controls,
ARRAY_SIZE(quat_mi2s_rx_port_mixer_controls)),
+ SND_SOC_DAPM_MIXER("PRI_TDM_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0,
+ pri_tdm_rx_0_port_mixer_controls,
+ ARRAY_SIZE(pri_tdm_rx_0_port_mixer_controls)),
+ SND_SOC_DAPM_MIXER("PRI_TDM_RX_1 Port Mixer", SND_SOC_NOPM, 0, 0,
+ pri_tdm_rx_1_port_mixer_controls,
+ ARRAY_SIZE(pri_tdm_rx_1_port_mixer_controls)),
+ SND_SOC_DAPM_MIXER("PRI_TDM_RX_2 Port Mixer", SND_SOC_NOPM, 0, 0,
+ pri_tdm_rx_2_port_mixer_controls,
+ ARRAY_SIZE(pri_tdm_rx_2_port_mixer_controls)),
+ SND_SOC_DAPM_MIXER("PRI_TDM_RX_3 Port Mixer", SND_SOC_NOPM, 0, 0,
+ pri_tdm_rx_3_port_mixer_controls,
+ ARRAY_SIZE(pri_tdm_rx_3_port_mixer_controls)),
+ SND_SOC_DAPM_MIXER("SEC_TDM_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0,
+ sec_tdm_rx_0_port_mixer_controls,
+ ARRAY_SIZE(sec_tdm_rx_0_port_mixer_controls)),
+ SND_SOC_DAPM_MIXER("SEC_TDM_RX_1 Port Mixer", SND_SOC_NOPM, 0, 0,
+ sec_tdm_rx_1_port_mixer_controls,
+ ARRAY_SIZE(sec_tdm_rx_1_port_mixer_controls)),
+ SND_SOC_DAPM_MIXER("SEC_TDM_RX_2 Port Mixer", SND_SOC_NOPM, 0, 0,
+ sec_tdm_rx_2_port_mixer_controls,
+ ARRAY_SIZE(sec_tdm_rx_2_port_mixer_controls)),
+ SND_SOC_DAPM_MIXER("SEC_TDM_RX_3 Port Mixer", SND_SOC_NOPM, 0, 0,
+ sec_tdm_rx_3_port_mixer_controls,
+ ARRAY_SIZE(sec_tdm_rx_3_port_mixer_controls)),
SND_SOC_DAPM_MIXER("TERT_TDM_RX_0 Port Mixer", SND_SOC_NOPM, 0, 0,
tert_tdm_rx_0_port_mixer_controls,
ARRAY_SIZE(tert_tdm_rx_0_port_mixer_controls)),
@@ -9665,6 +11280,23 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
SND_SOC_DAPM_MIXER("USB_AUDIO_RX Port Mixer",
SND_SOC_NOPM, 0, 0, usb_rx_port_mixer_controls,
ARRAY_SIZE(usb_rx_port_mixer_controls)),
+ /* lsm mixer definitions */
+ SND_SOC_DAPM_MIXER("LSM1 Mixer", SND_SOC_NOPM, 0, 0,
+ lsm1_mixer_controls, ARRAY_SIZE(lsm1_mixer_controls)),
+ SND_SOC_DAPM_MIXER("LSM2 Mixer", SND_SOC_NOPM, 0, 0,
+ lsm2_mixer_controls, ARRAY_SIZE(lsm2_mixer_controls)),
+ SND_SOC_DAPM_MIXER("LSM3 Mixer", SND_SOC_NOPM, 0, 0,
+ lsm3_mixer_controls, ARRAY_SIZE(lsm3_mixer_controls)),
+ SND_SOC_DAPM_MIXER("LSM4 Mixer", SND_SOC_NOPM, 0, 0,
+ lsm4_mixer_controls, ARRAY_SIZE(lsm4_mixer_controls)),
+ SND_SOC_DAPM_MIXER("LSM5 Mixer", SND_SOC_NOPM, 0, 0,
+ lsm5_mixer_controls, ARRAY_SIZE(lsm5_mixer_controls)),
+ SND_SOC_DAPM_MIXER("LSM6 Mixer", SND_SOC_NOPM, 0, 0,
+ lsm6_mixer_controls, ARRAY_SIZE(lsm6_mixer_controls)),
+ SND_SOC_DAPM_MIXER("LSM7 Mixer", SND_SOC_NOPM, 0, 0,
+ lsm7_mixer_controls, ARRAY_SIZE(lsm7_mixer_controls)),
+ SND_SOC_DAPM_MIXER("LSM8 Mixer", SND_SOC_NOPM, 0, 0,
+ lsm8_mixer_controls, ARRAY_SIZE(lsm8_mixer_controls)),
/* Virtual Pins to force backends ON atm */
SND_SOC_DAPM_OUTPUT("BE_OUT"),
SND_SOC_DAPM_INPUT("BE_IN"),
@@ -10109,6 +11741,60 @@ static const struct snd_soc_dapm_route intercon[] = {
{"PRI_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"},
{"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Audio Mixer"},
+ {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"},
+ {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1 Audio Mixer"},
+
+ {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"},
+ {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2 Audio Mixer"},
+
+ {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"},
+ {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Audio Mixer"},
+
{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"},
{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"},
{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"},
@@ -10145,6 +11831,60 @@ static const struct snd_soc_dapm_route intercon[] = {
{"SEC_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"},
{"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Audio Mixer"},
+ {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia9", "MM_DL9"},
+ {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1 Audio Mixer"},
+
+ {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia9", "MM_DL9"},
+ {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2 Audio Mixer"},
+
+ {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia9", "MM_DL9"},
+ {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Audio Mixer"},
+
{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"},
{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"},
{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"},
@@ -10392,6 +12132,14 @@ static const struct snd_soc_dapm_route intercon[] = {
{"MultiMedia6 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
{"MultiMedia6 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
+ {"MultiMedia1 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
+ {"MultiMedia1 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
+ {"MultiMedia1 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"MultiMedia1 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
+ {"MultiMedia1 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"},
+ {"MultiMedia1 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"},
+ {"MultiMedia1 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"},
+ {"MultiMedia1 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"},
{"MultiMedia1 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
{"MultiMedia1 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"},
{"MultiMedia1 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"},
@@ -10401,6 +12149,14 @@ static const struct snd_soc_dapm_route intercon[] = {
{"MultiMedia1 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
{"MultiMedia1 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"MultiMedia2 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
+ {"MultiMedia2 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
+ {"MultiMedia2 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"MultiMedia2 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
+ {"MultiMedia2 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"},
+ {"MultiMedia2 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"},
+ {"MultiMedia2 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"},
+ {"MultiMedia2 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"},
{"MultiMedia2 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
{"MultiMedia2 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"},
{"MultiMedia2 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"},
@@ -10410,6 +12166,14 @@ static const struct snd_soc_dapm_route intercon[] = {
{"MultiMedia2 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
{"MultiMedia2 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"MultiMedia3 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
+ {"MultiMedia3 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
+ {"MultiMedia3 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"MultiMedia3 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
+ {"MultiMedia3 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"},
+ {"MultiMedia3 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"},
+ {"MultiMedia3 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"},
+ {"MultiMedia3 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"},
{"MultiMedia3 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
{"MultiMedia3 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"},
{"MultiMedia3 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"},
@@ -10419,6 +12183,14 @@ static const struct snd_soc_dapm_route intercon[] = {
{"MultiMedia3 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
{"MultiMedia3 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"MultiMedia4 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
+ {"MultiMedia4 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
+ {"MultiMedia4 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"MultiMedia4 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
+ {"MultiMedia4 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"},
+ {"MultiMedia4 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"},
+ {"MultiMedia4 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"},
+ {"MultiMedia4 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"},
{"MultiMedia4 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
{"MultiMedia4 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"},
{"MultiMedia4 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"},
@@ -10428,6 +12200,14 @@ static const struct snd_soc_dapm_route intercon[] = {
{"MultiMedia4 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
{"MultiMedia4 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"MultiMedia5 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
+ {"MultiMedia5 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
+ {"MultiMedia5 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"MultiMedia5 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
+ {"MultiMedia5 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"},
+ {"MultiMedia5 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"},
+ {"MultiMedia5 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"},
+ {"MultiMedia5 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"},
{"MultiMedia5 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
{"MultiMedia5 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"},
{"MultiMedia5 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"},
@@ -10437,6 +12217,14 @@ static const struct snd_soc_dapm_route intercon[] = {
{"MultiMedia5 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
{"MultiMedia5 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"MultiMedia6 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
+ {"MultiMedia6 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
+ {"MultiMedia6 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"MultiMedia6 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
+ {"MultiMedia6 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"},
+ {"MultiMedia6 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"},
+ {"MultiMedia6 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"},
+ {"MultiMedia6 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"},
{"MultiMedia6 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
{"MultiMedia6 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"},
{"MultiMedia6 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"},
@@ -10446,6 +12234,14 @@ static const struct snd_soc_dapm_route intercon[] = {
{"MultiMedia6 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
{"MultiMedia6 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"MultiMedia8 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
+ {"MultiMedia8 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
+ {"MultiMedia8 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"MultiMedia8 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
+ {"MultiMedia8 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"},
+ {"MultiMedia8 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"},
+ {"MultiMedia8 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"},
+ {"MultiMedia8 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"},
{"MultiMedia8 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
{"MultiMedia8 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"},
{"MultiMedia8 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"},
@@ -11124,70 +12920,77 @@ static const struct snd_soc_dapm_route intercon[] = {
{"SLIM4_UL_HL", NULL, "SLIMBUS_4_TX"},
{"SLIM8_UL_HL", NULL, "SLIMBUS_8_TX"},
- {"LSM1 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
- {"LSM1 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
- {"LSM1 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
- {"LSM1 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
- {"LSM1 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
- {"LSM1 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"},
- {"LSM1_UL_HL", NULL, "LSM1 MUX"},
-
- {"LSM2 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
- {"LSM2 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
- {"LSM2 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
- {"LSM2 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
- {"LSM2 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
- {"LSM2 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"},
- {"LSM2_UL_HL", NULL, "LSM2 MUX"},
-
-
- {"LSM3 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
- {"LSM3 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
- {"LSM3 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
- {"LSM3 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
- {"LSM3 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
- {"LSM3 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"},
- {"LSM3_UL_HL", NULL, "LSM3 MUX"},
-
-
- {"LSM4 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
- {"LSM4 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
- {"LSM4 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
- {"LSM4 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
- {"LSM4 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
- {"LSM4 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"},
- {"LSM4_UL_HL", NULL, "LSM4 MUX"},
-
- {"LSM5 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
- {"LSM5 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
- {"LSM5 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
- {"LSM5 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
- {"LSM5 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
- {"LSM5 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"},
- {"LSM5_UL_HL", NULL, "LSM5 MUX"},
-
- {"LSM6 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
- {"LSM6 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
- {"LSM6 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
- {"LSM6 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
- {"LSM6 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
- {"LSM6_UL_HL", NULL, "LSM6 MUX"},
-
-
- {"LSM7 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
- {"LSM7 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
- {"LSM7 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
- {"LSM7 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
- {"LSM7 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
- {"LSM7_UL_HL", NULL, "LSM7 MUX"},
-
-
- {"LSM8 MUX", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
- {"LSM8 MUX", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
- {"LSM8 MUX", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
- {"LSM8 MUX", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
- {"LSM8 MUX", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
- {"LSM8_UL_HL", NULL, "LSM8 MUX"},
+
+ {"LSM1 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
+ {"LSM1 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
+ {"LSM1 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
+ {"LSM1 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
+ {"LSM1 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
+ {"LSM1 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
+ {"LSM1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"LSM1_UL_HL", NULL, "LSM1 Mixer"},
+
+ {"LSM2 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
+ {"LSM2 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
+ {"LSM2 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
+ {"LSM2 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
+ {"LSM2 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
+ {"LSM2 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
+ {"LSM2 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"LSM2_UL_HL", NULL, "LSM2 Mixer"},
+
+
+ {"LSM3 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
+ {"LSM3 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
+ {"LSM3 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
+ {"LSM3 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
+ {"LSM3 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
+ {"LSM3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
+ {"LSM3 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"LSM3_UL_HL", NULL, "LSM3 Mixer"},
+
+
+ {"LSM4 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
+ {"LSM4 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
+ {"LSM4 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
+ {"LSM4 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
+ {"LSM4 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
+ {"LSM4 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
+ {"LSM4 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"LSM4_UL_HL", NULL, "LSM4 Mixer"},
+
+ {"LSM5 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
+ {"LSM5 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
+ {"LSM5 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
+ {"LSM5 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
+ {"LSM5 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
+ {"LSM5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
+ {"LSM5 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"LSM5_UL_HL", NULL, "LSM5 Mixer"},
+
+ {"LSM6 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
+ {"LSM6 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
+ {"LSM6 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
+ {"LSM6 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
+ {"LSM6 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
+ {"LSM6 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"LSM6_UL_HL", NULL, "LSM6 Mixer"},
+
+ {"LSM7 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
+ {"LSM7 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
+ {"LSM7 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
+ {"LSM7 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
+ {"LSM7 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
+ {"LSM7 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"LSM7_UL_HL", NULL, "LSM7 Mixer"},
+
+ {"LSM8 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
+ {"LSM8 Mixer", "SLIMBUS_1_TX", "SLIMBUS_1_TX"},
+ {"LSM8 Mixer", "SLIMBUS_3_TX", "SLIMBUS_3_TX"},
+ {"LSM8 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
+ {"LSM8 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
+ {"LSM8 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"LSM8_UL_HL", NULL, "LSM8 Mixer"},
{"CPE_LSM_UL_HL", NULL, "BE_IN"},
@@ -11251,17 +13054,29 @@ static const struct snd_soc_dapm_route intercon[] = {
{"QUAT_MI2S_UL_HL", NULL, "QUAT_MI2S_TX"},
{"PRI_TDM_TX_0_UL_HL", NULL, "PRI_TDM_TX_0"},
+ {"PRI_TDM_TX_1_UL_HL", NULL, "PRI_TDM_TX_1"},
+ {"PRI_TDM_TX_2_UL_HL", NULL, "PRI_TDM_TX_2"},
+ {"PRI_TDM_TX_3_UL_HL", NULL, "PRI_TDM_TX_3"},
{"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0_DL_HL"},
+ {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1_DL_HL"},
+ {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2_DL_HL"},
+ {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3_DL_HL"},
{"SEC_TDM_TX_0_UL_HL", NULL, "SEC_TDM_TX_0"},
+ {"SEC_TDM_TX_1_UL_HL", NULL, "SEC_TDM_TX_1"},
+ {"SEC_TDM_TX_2_UL_HL", NULL, "SEC_TDM_TX_2"},
+ {"SEC_TDM_TX_3_UL_HL", NULL, "SEC_TDM_TX_3"},
{"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0_DL_HL"},
+ {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1_DL_HL"},
+ {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2_DL_HL"},
+ {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3_DL_HL"},
{"TERT_TDM_TX_0_UL_HL", NULL, "TERT_TDM_TX_0"},
{"TERT_TDM_TX_1_UL_HL", NULL, "TERT_TDM_TX_1"},
{"TERT_TDM_TX_2_UL_HL", NULL, "TERT_TDM_TX_2"},
{"TERT_TDM_TX_3_UL_HL", NULL, "TERT_TDM_TX_3"},
{"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0_DL_HL"},
- {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_0_DL_HL"},
- {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_0_DL_HL"},
- {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_0_DL_HL"},
+ {"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1_DL_HL"},
+ {"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2_DL_HL"},
+ {"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3_DL_HL"},
{"QUAT_TDM_TX_0_UL_HL", NULL, "QUAT_TDM_TX_0"},
{"QUAT_TDM_TX_1_UL_HL", NULL, "QUAT_TDM_TX_1"},
{"QUAT_TDM_TX_2_UL_HL", NULL, "QUAT_TDM_TX_2"},
@@ -11271,6 +13086,150 @@ static const struct snd_soc_dapm_route intercon[] = {
{"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2_DL_HL"},
{"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3_DL_HL"},
+ {"PRI_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
+ {"PRI_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
+ {"PRI_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"PRI_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
+ {"PRI_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
+ {"PRI_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"},
+ {"PRI_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
+ {"PRI_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
+ {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
+ {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
+ {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"PRI_TDM_RX_0 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
+ {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"},
+ {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"},
+ {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
+ {"PRI_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Port Mixer"},
+
+ {"PRI_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
+ {"PRI_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
+ {"PRI_TDM_RX_1 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"PRI_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
+ {"PRI_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
+ {"PRI_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"},
+ {"PRI_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
+ {"PRI_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
+ {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
+ {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
+ {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"PRI_TDM_RX_1 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
+ {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"},
+ {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"},
+ {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
+ {"PRI_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1 Port Mixer"},
+
+ {"PRI_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
+ {"PRI_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
+ {"PRI_TDM_RX_2 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"PRI_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
+ {"PRI_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
+ {"PRI_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"},
+ {"PRI_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
+ {"PRI_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
+ {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
+ {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
+ {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"PRI_TDM_RX_2 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
+ {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"},
+ {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"},
+ {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
+ {"PRI_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2 Port Mixer"},
+
+ {"PRI_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
+ {"PRI_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
+ {"PRI_TDM_RX_3 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"PRI_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
+ {"PRI_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
+ {"PRI_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"},
+ {"PRI_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
+ {"PRI_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
+ {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
+ {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
+ {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"PRI_TDM_RX_3 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
+ {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"},
+ {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"},
+ {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
+ {"PRI_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Port Mixer"},
+
+ {"SEC_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
+ {"SEC_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
+ {"SEC_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"SEC_TDM_RX_0 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
+ {"SEC_TDM_RX_0 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
+ {"SEC_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"},
+ {"SEC_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
+ {"SEC_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
+ {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"},
+ {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"},
+ {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"},
+ {"SEC_TDM_RX_0 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"},
+ {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"},
+ {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"},
+ {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
+ {"SEC_TDM_RX_0 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Port Mixer"},
+
+ {"SEC_TDM_RX_1 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
+ {"SEC_TDM_RX_1 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
+ {"SEC_TDM_RX_1 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"SEC_TDM_RX_1 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
+ {"SEC_TDM_RX_1 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
+ {"SEC_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"},
+ {"SEC_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
+ {"SEC_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
+ {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"},
+ {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"},
+ {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"},
+ {"SEC_TDM_RX_1 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"},
+ {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"},
+ {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"},
+ {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
+ {"SEC_TDM_RX_1 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1 Port Mixer"},
+
+ {"SEC_TDM_RX_2 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
+ {"SEC_TDM_RX_2 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
+ {"SEC_TDM_RX_2 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"SEC_TDM_RX_2 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
+ {"SEC_TDM_RX_2 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
+ {"SEC_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"},
+ {"SEC_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
+ {"SEC_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
+ {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"},
+ {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"},
+ {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"},
+ {"SEC_TDM_RX_2 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"},
+ {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"},
+ {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"},
+ {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
+ {"SEC_TDM_RX_2 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2 Port Mixer"},
+
+ {"SEC_TDM_RX_3 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
+ {"SEC_TDM_RX_3 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
+ {"SEC_TDM_RX_3 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"SEC_TDM_RX_3 Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
+ {"SEC_TDM_RX_3 Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
+ {"SEC_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"},
+ {"SEC_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
+ {"SEC_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
+ {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"},
+ {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"},
+ {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"},
+ {"SEC_TDM_RX_3 Port Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"},
+ {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"},
+ {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"},
+ {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
+ {"SEC_TDM_RX_3 Port Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Port Mixer"},
+
{"TERT_TDM_RX_0 Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"TERT_TDM_RX_0 Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
{"TERT_TDM_RX_0 Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
@@ -11690,7 +13649,13 @@ static const struct snd_soc_dapm_route intercon[] = {
{"BE_OUT", NULL, "VOICE_PLAYBACK_TX"},
{"BE_OUT", NULL, "VOICE2_PLAYBACK_TX"},
{"BE_OUT", NULL, "PRI_TDM_RX_0"},
+ {"BE_OUT", NULL, "PRI_TDM_RX_1"},
+ {"BE_OUT", NULL, "PRI_TDM_RX_2"},
+ {"BE_OUT", NULL, "PRI_TDM_RX_3"},
{"BE_OUT", NULL, "SEC_TDM_RX_0"},
+ {"BE_OUT", NULL, "SEC_TDM_RX_1"},
+ {"BE_OUT", NULL, "SEC_TDM_RX_2"},
+ {"BE_OUT", NULL, "SEC_TDM_RX_3"},
{"BE_OUT", NULL, "TERT_TDM_RX_0"},
{"BE_OUT", NULL, "TERT_TDM_RX_1"},
{"BE_OUT", NULL, "TERT_TDM_RX_2"},
@@ -11746,7 +13711,13 @@ static const struct snd_soc_dapm_route intercon[] = {
{"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_VI_FB_MONO_CH_MUX"},
{"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_VI_FB_STEREO_CH_MUX"},
{"PRI_TDM_TX_0", NULL, "BE_IN"},
+ {"PRI_TDM_TX_1", NULL, "BE_IN"},
+ {"PRI_TDM_TX_2", NULL, "BE_IN"},
+ {"PRI_TDM_TX_3", NULL, "BE_IN"},
{"SEC_TDM_TX_0", NULL, "BE_IN"},
+ {"SEC_TDM_TX_1", NULL, "BE_IN"},
+ {"SEC_TDM_TX_2", NULL, "BE_IN"},
+ {"SEC_TDM_TX_3", NULL, "BE_IN"},
{"TERT_TDM_TX_0", NULL, "BE_IN"},
{"TERT_TDM_TX_1", NULL, "BE_IN"},
{"TERT_TDM_TX_2", NULL, "BE_IN"},
@@ -11804,7 +13775,9 @@ static int msm_pcm_routing_close(struct snd_pcm_substream *substream)
path_type = ADM_PATH_LIVE_REC;
mutex_lock(&routing_lock);
- for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_SIZE) {
+ for_each_set_bit(i, &bedai->fe_sessions[0], MSM_FRONTEND_DAI_MAX) {
+ if (!is_mm_lsm_fe_id(i))
+ continue;
fdai = &fe_dai_map[i][session_type];
if (fdai->strm_id != INVALID_SESSION) {
int idx;
@@ -11825,13 +13798,12 @@ static int msm_pcm_routing_close(struct snd_pcm_substream *substream)
clear_bit(idx,
&session_copp_map[i][session_type][be_id]);
if ((fdai->perf_mode == LEGACY_PCM_MODE) &&
- (bedai->compr_passthr_mode == LEGACY_PCM))
+ (bedai->passthr_mode == LEGACY_PCM))
msm_pcm_routing_deinit_pp(bedai->port_id,
topology);
}
}
- bedai->compr_passthr_mode = LEGACY_PCM;
bedai->active = 0;
bedai->sample_rate = 0;
bedai->channel = 0;
@@ -11851,6 +13823,7 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
struct msm_pcm_routing_fdai_data *fdai;
u32 session_id;
struct media_format_info voc_be_media_format;
+ bool is_lsm;
pr_debug("%s: substream->pcm->id:%s\n",
__func__, substream->pcm->id);
@@ -11863,7 +13836,7 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
bedai = &msm_bedais[be_id];
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (bedai->compr_passthr_mode != LEGACY_PCM)
+ if (bedai->passthr_mode != LEGACY_PCM)
path_type = ADM_PATH_COMPRESSED_RX;
else
path_type = ADM_PATH_PLAYBACK;
@@ -11884,7 +13857,13 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
*/
bedai->active = 1;
- for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_SIZE) {
+ for_each_set_bit(i, &bedai->fe_sessions[0], MSM_FRONTEND_DAI_MAX) {
+ if (!(is_mm_lsm_fe_id(i) &&
+ route_check_fe_id_adm_support(i)))
+ continue;
+
+ is_lsm = (i >= MSM_FRONTEND_DAI_LSM1) &&
+ (i <= MSM_FRONTEND_DAI_LSM8);
fdai = &fe_dai_map[i][session_type];
if (fdai->strm_id != INVALID_SESSION) {
int app_type, app_type_idx, copp_idx, acdb_dev_id;
@@ -11906,7 +13885,15 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
app_type =
fe_dai_app_type_cfg[i][session_type].app_type;
- if (app_type) {
+ if (app_type && is_lsm) {
+ app_type_idx =
+ msm_pcm_routing_get_lsm_app_type_idx(app_type);
+ sample_rate =
+ fe_dai_app_type_cfg[i][session_type].
+ sample_rate;
+ bits_per_sample =
+ lsm_app_type_cfg[app_type_idx].bit_width;
+ } else if (app_type) {
app_type_idx =
msm_pcm_routing_get_app_type_idx(app_type);
sample_rate =
@@ -11951,16 +13938,16 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
bedai->sample_rate);
msm_pcm_routing_build_matrix(i, session_type, path_type,
- fdai->perf_mode);
+ fdai->perf_mode,
+ bedai->passthr_mode);
if ((fdai->perf_mode == LEGACY_PCM_MODE) &&
- (bedai->compr_passthr_mode ==
- LEGACY_PCM))
+ (bedai->passthr_mode == LEGACY_PCM))
msm_pcm_routing_cfg_pp(bedai->port_id, copp_idx,
topology, channels);
}
}
- for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MAX) {
+ for_each_set_bit(i, &bedai->fe_sessions[0], MSM_FRONTEND_DAI_MAX) {
session_id = msm_pcm_routing_get_voc_sessionid(i);
if (session_id) {
pr_debug("%s voice session_id: 0x%x\n", __func__,
@@ -12025,6 +14012,7 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx)
unsigned long pp_config = 0;
bool mute_on;
int latency;
+ bool compr_passthr_mode = true;
pr_debug("%s: port_id %d, copp_idx %d\n", __func__, port_id, copp_idx);
@@ -12061,14 +14049,16 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx)
return -EINVAL;
}
+ if ((msm_bedais[be_idx].passthr_mode == LEGACY_PCM) ||
+ (msm_bedais[be_idx].passthr_mode == LISTEN))
+ compr_passthr_mode = false;
+
pp_config = msm_bedais_pp_params[index].pp_params_config;
if (test_bit(ADM_PP_PARAM_MUTE_BIT, &pp_config)) {
pr_debug("%s: ADM_PP_PARAM_MUTE\n", __func__);
clear_bit(ADM_PP_PARAM_MUTE_BIT, &pp_config);
mute_on = msm_bedais_pp_params[index].mute_on;
- if ((msm_bedais[be_idx].active) &&
- (msm_bedais[be_idx].compr_passthr_mode !=
- LEGACY_PCM))
+ if ((msm_bedais[be_idx].active) && compr_passthr_mode)
adm_send_compressed_device_mute(port_id,
copp_idx,
mute_on);
@@ -12078,9 +14068,7 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx)
clear_bit(ADM_PP_PARAM_LATENCY_BIT,
&pp_config);
latency = msm_bedais_pp_params[index].latency;
- if ((msm_bedais[be_idx].active) &&
- (msm_bedais[be_idx].compr_passthr_mode !=
- LEGACY_PCM))
+ if ((msm_bedais[be_idx].active) && compr_passthr_mode)
adm_send_compressed_device_latency(port_id,
copp_idx,
latency);
@@ -12096,6 +14084,7 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol,
int index, be_idx, i, topo_id, idx;
bool mute;
int latency;
+ bool compr_passthr_mode = true;
pr_debug("%s: pp_id: 0x%x\n", __func__, pp_id);
@@ -12120,7 +14109,11 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol,
return -EINVAL;
}
- for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions,
+ if ((msm_bedais[be_idx].passthr_mode == LEGACY_PCM) ||
+ (msm_bedais[be_idx].passthr_mode == LISTEN))
+ compr_passthr_mode = false;
+
+ for_each_set_bit(i, &msm_bedais[be_idx].fe_sessions[0],
MSM_FRONTEND_DAI_MM_SIZE) {
for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) {
unsigned long copp =
@@ -12134,7 +14127,7 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol,
continue;
pr_debug("%s: port: 0x%x, copp %ld, be active: %d, passt: %d\n",
__func__, port_id, copp, msm_bedais[be_idx].active,
- msm_bedais[be_idx].compr_passthr_mode);
+ msm_bedais[be_idx].passthr_mode);
switch (pp_id) {
case ADM_PP_PARAM_MUTE_ID:
pr_debug("%s: ADM_PP_PARAM_MUTE\n", __func__);
@@ -12142,9 +14135,7 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol,
msm_bedais_pp_params[index].mute_on = mute;
set_bit(ADM_PP_PARAM_MUTE_BIT,
&msm_bedais_pp_params[index].pp_params_config);
- if ((msm_bedais[be_idx].active) &&
- (msm_bedais[be_idx].compr_passthr_mode !=
- LEGACY_PCM))
+ if ((msm_bedais[be_idx].active) && compr_passthr_mode)
adm_send_compressed_device_mute(port_id,
idx, mute);
break;
@@ -12156,9 +14147,7 @@ static int msm_routing_put_device_pp_params_mixer(struct snd_kcontrol *kcontrol,
&msm_bedais_pp_params[index].pp_params_config);
latency = msm_bedais_pp_params[index].latency =
ucontrol->value.integer.value[1];
- if ((msm_bedais[be_idx].active) &&
- (msm_bedais[be_idx].compr_passthr_mode !=
- LEGACY_PCM))
+ if ((msm_bedais[be_idx].active) && compr_passthr_mode)
adm_send_compressed_device_latency(port_id,
idx, latency);
break;
@@ -12228,8 +14217,8 @@ static int msm_routing_probe(struct snd_soc_platform *platform)
snd_soc_dapm_new_widgets(platform->component.dapm.card);
- snd_soc_add_platform_controls(platform, lsm_function,
- ARRAY_SIZE(lsm_function));
+ snd_soc_add_platform_controls(platform, lsm_controls,
+ ARRAY_SIZE(lsm_controls));
snd_soc_add_platform_controls(platform, aanc_slim_0_rx_mux,
ARRAY_SIZE(aanc_slim_0_rx_mux));
@@ -12240,10 +14229,16 @@ static int msm_routing_probe(struct snd_soc_platform *platform)
snd_soc_add_platform_controls(platform, app_type_cfg_controls,
ARRAY_SIZE(app_type_cfg_controls));
+ snd_soc_add_platform_controls(platform, lsm_app_type_cfg_controls,
+ ARRAY_SIZE(lsm_app_type_cfg_controls));
+
snd_soc_add_platform_controls(platform,
stereo_to_custom_stereo_controls,
ARRAY_SIZE(stereo_to_custom_stereo_controls));
+ snd_soc_add_platform_controls(platform, ec_ref_param_controls,
+ ARRAY_SIZE(ec_ref_param_controls));
+
msm_qti_pp_add_controls(platform);
msm_dts_srs_tm_add_controls(platform);
@@ -12326,7 +14321,7 @@ int msm_routing_check_backend_enabled(int fedai_id)
return 0;
}
for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
- if (test_bit(fedai_id, &msm_bedais[i].fe_sessions))
+ if (test_bit(fedai_id, &msm_bedais[i].fe_sessions[0]))
return msm_bedais[i].active;
}
return 0;
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
index 0bb069154512..a066e9afc9e5 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -392,6 +392,7 @@ enum {
#define ADM_PP_PARAM_LATENCY_ID 1
#define ADM_PP_PARAM_LATENCY_BIT 2
#define BE_DAI_PORT_SESSIONS_IDX_MAX 4
+#define BE_DAI_FE_SESSIONS_IDX_MAX 2
struct msm_pcm_routing_evt {
void (*event_func)(enum msm_pcm_routing_event, void *);
@@ -401,7 +402,9 @@ struct msm_pcm_routing_evt {
struct msm_pcm_routing_bdai_data {
u16 port_id; /* AFE port ID */
u8 active; /* track if this backend is enabled */
- unsigned long fe_sessions; /* Front-end sessions */
+
+ /* Front-end sessions */
+ unsigned long fe_sessions[BE_DAI_FE_SESSIONS_IDX_MAX];
/*
* Track Tx BE ports -> Rx BE ports.
* port_sessions[0] used to track BE 0 to BE 63.
@@ -415,7 +418,7 @@ struct msm_pcm_routing_bdai_data {
unsigned int channel;
unsigned int format;
unsigned int adm_override_ch;
- u32 compr_passthr_mode;
+ u32 passthr_mode;
char *name;
};
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index 32826d38f65a..16ae05034662 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -2574,7 +2574,6 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
return copp_idx;
}
-
void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate)
{
struct audproc_mfc_output_media_fmt mfc_cfg;
@@ -2677,8 +2676,43 @@ fail_cmd:
return;
}
+static void route_set_opcode_matrix_id(
+ struct adm_cmd_matrix_map_routings_v5 **route_addr,
+ int path, uint32_t passthr_mode)
+{
+ struct adm_cmd_matrix_map_routings_v5 *route = *route_addr;
-int adm_matrix_map(int path, struct route_payload payload_map, int perf_mode)
+ switch (path) {
+ case ADM_PATH_PLAYBACK:
+ route->hdr.opcode = ADM_CMD_MATRIX_MAP_ROUTINGS_V5;
+ route->matrix_id = ADM_MATRIX_ID_AUDIO_RX;
+ break;
+ case ADM_PATH_LIVE_REC:
+ if (passthr_mode == LISTEN) {
+ route->hdr.opcode =
+ ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5;
+ route->matrix_id = ADM_MATRIX_ID_LISTEN_TX;
+ break;
+ }
+ /* fall through to set matrix id for non-listen case */
+ case ADM_PATH_NONLIVE_REC:
+ route->hdr.opcode = ADM_CMD_MATRIX_MAP_ROUTINGS_V5;
+ route->matrix_id = ADM_MATRIX_ID_AUDIO_TX;
+ break;
+ case ADM_PATH_COMPRESSED_RX:
+ route->hdr.opcode = ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5;
+ route->matrix_id = ADM_MATRIX_ID_COMPRESSED_AUDIO_RX;
+ break;
+ default:
+ pr_err("%s: Wrong path set[%d]\n", __func__, path);
+ break;
+ }
+ pr_debug("%s: opcode 0x%x, matrix id %d\n",
+ __func__, route->hdr.opcode, route->matrix_id);
+}
+
+int adm_matrix_map(int path, struct route_payload payload_map, int perf_mode,
+ uint32_t passthr_mode)
{
struct adm_cmd_matrix_map_routings_v5 *route;
struct adm_session_map_node_v5 *node;
@@ -2711,32 +2745,9 @@ int adm_matrix_map(int path, struct route_payload payload_map, int perf_mode)
route->hdr.dest_domain = APR_DOMAIN_ADSP;
route->hdr.dest_port = 0; /* Ignored */;
route->hdr.token = 0;
- if (path == ADM_PATH_COMPRESSED_RX) {
- pr_debug("%s: ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5 0x%x\n",
- __func__, ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5);
- route->hdr.opcode = ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5;
- } else {
- pr_debug("%s: DM_CMD_MATRIX_MAP_ROUTINGS_V5 0x%x\n",
- __func__, ADM_CMD_MATRIX_MAP_ROUTINGS_V5);
- route->hdr.opcode = ADM_CMD_MATRIX_MAP_ROUTINGS_V5;
- }
route->num_sessions = 1;
+ route_set_opcode_matrix_id(&route, path, passthr_mode);
- switch (path) {
- case ADM_PATH_PLAYBACK:
- route->matrix_id = ADM_MATRIX_ID_AUDIO_RX;
- break;
- case ADM_PATH_LIVE_REC:
- case ADM_PATH_NONLIVE_REC:
- route->matrix_id = ADM_MATRIX_ID_AUDIO_TX;
- break;
- case ADM_PATH_COMPRESSED_RX:
- route->matrix_id = ADM_MATRIX_ID_COMPRESSED_AUDIO_RX;
- break;
- default:
- pr_err("%s: Wrong path set[%d]\n", __func__, path);
- break;
- }
payload = ((u8 *)matrix_map +
sizeof(struct adm_cmd_matrix_map_routings_v5));
node = (struct adm_session_map_node_v5 *)payload;
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index f1607b8e5d66..9a141a11d002 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -145,7 +145,7 @@ int afe_get_topology(int port_id)
int topology;
int port_index = afe_get_port_index(port_id);
- if ((port_index < 0) || (port_index > AFE_MAX_PORTS)) {
+ if ((port_index < 0) || (port_index >= AFE_MAX_PORTS)) {
pr_err("%s: Invalid port index %d\n", __func__, port_index);
topology = -EINVAL;
goto done;
@@ -726,7 +726,7 @@ static int afe_send_cal_block(u16 port_id, struct cal_block_data *cal_block)
}
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
result = -EINVAL;
@@ -870,7 +870,7 @@ static int afe_spk_ramp_dn_cfg(int port)
goto fail_cmd;
}
index = q6audio_get_port_index(port);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
ret = -EINVAL;
@@ -951,7 +951,7 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id,
goto fail_cmd;
}
index = q6audio_get_port_index(src_port);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
ret = -EINVAL;
@@ -1196,7 +1196,7 @@ static int afe_send_hw_delay(u16 port_id, u32 rate)
}
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
ret = -EINVAL;
@@ -1318,7 +1318,7 @@ static int afe_send_port_topology_id(u16 port_id)
u32 topology_id = 0;
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS - 1) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -1675,7 +1675,7 @@ static int afe_send_slimbus_slave_port_cfg(
pr_debug("%s: enter, port_id = 0x%x\n", __func__, port_id);
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -1729,7 +1729,7 @@ static int afe_aanc_port_cfg(void *apr, uint16_t tx_port, uint16_t rx_port)
}
index = q6audio_get_port_index(tx_port);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -1814,7 +1814,7 @@ static int afe_aanc_mod_enable(void *apr, uint16_t tx_port, uint16_t enable)
}
index = q6audio_get_port_index(tx_port);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -2036,7 +2036,7 @@ int afe_send_spdif_clk_cfg(struct afe_param_id_spdif_clk_cfg *cfg,
return ret;
}
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -2122,7 +2122,7 @@ int afe_send_spdif_ch_status_cfg(struct afe_param_id_spdif_ch_status_cfg
return ret;
}
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -2196,7 +2196,7 @@ static int afe_send_cmd_port_start(u16 port_id)
pr_debug("%s: enter\n", __func__);
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -2267,7 +2267,7 @@ int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port,
pr_debug("%s: port id: 0x%x\n", __func__, port_id);
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -2342,7 +2342,7 @@ int afe_send_slot_mapping_cfg(
pr_debug("%s: port id: 0x%x\n", __func__, port_id);
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -2421,7 +2421,7 @@ int afe_send_custom_tdm_header_cfg(
pr_debug("%s: port id: 0x%x\n", __func__, port_id);
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -2501,7 +2501,7 @@ int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port,
pr_debug("%s: port id: 0x%x\n", __func__, port_id);
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -2623,7 +2623,7 @@ int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config)
goto exit;
}
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid! for port ID 0x%x\n",
__func__, index, port_id);
ret = -EINVAL;
@@ -2824,7 +2824,7 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config,
pr_debug("%s: port id: 0x%x\n", __func__, port_id);
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -3383,7 +3383,7 @@ int afe_open(u16 port_id,
pr_err("%s: port_id 0x%x rate %d\n", __func__, port_id, rate);
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -3551,7 +3551,7 @@ int afe_loopback(u16 enable, u16 rx_port, u16 tx_port)
}
index = q6audio_get_port_index(rx_port);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -3617,7 +3617,7 @@ int afe_loopback_gain(u16 port_id, u16 volume)
goto fail_cmd;
}
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -3720,7 +3720,7 @@ int afe_start_pseudo_port(u16 port_id)
}
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -3763,7 +3763,7 @@ int afe_pseudo_port_stop_nowait(u16 port_id)
return -EINVAL;
}
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -3924,7 +3924,7 @@ int afe_stop_pseudo_port(u16 port_id)
}
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -4213,7 +4213,7 @@ int afe_cmd_memory_map_nowait(int port_id, phys_addr_t dma_addr_p,
rtac_set_afe_handle(this_afe.apr);
}
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -4477,7 +4477,7 @@ int afe_unregister_get_events(u16 port_id)
}
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -4821,7 +4821,7 @@ int afe_dtmf_generate_rx(int64_t duration_in_ms,
goto fail_cmd;
}
index = q6audio_get_port_index(this_afe.dtmf_gen_rx_portid);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
ret = -EINVAL;
@@ -5059,7 +5059,7 @@ int afe_sidetone_enable(u16 tx_port_id, u16 rx_port_id, bool enable)
int index;
index = q6audio_get_port_index(rx_port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
ret = -EINVAL;
@@ -5072,7 +5072,7 @@ int afe_sidetone_enable(u16 tx_port_id, u16 rx_port_id, bool enable)
goto done;
}
index = q6audio_get_port_index(tx_port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
ret = -EINVAL;
@@ -5367,7 +5367,7 @@ int afe_close(int port_id)
port_id = q6audio_convert_virtual_to_portid(port_id);
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -5525,7 +5525,7 @@ int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg)
return ret;
}
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -5691,7 +5691,7 @@ int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg)
int ret = 0;
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -5724,7 +5724,7 @@ int afe_set_lpass_internal_digital_codec_clock(u16 port_id,
return ret;
}
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -5805,7 +5805,7 @@ int afe_enable_lpass_core_shared_clock(u16 port_id, u32 enable)
int ret = 0;
index = q6audio_get_port_index(port_id);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
@@ -6084,7 +6084,7 @@ int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp)
goto fail_cmd;
}
index = q6audio_get_port_index(port);
- if (index < 0 || index > AFE_MAX_PORTS) {
+ if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
ret = -EINVAL;
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 2c501ce3d6ff..74fbe984e6e9 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -8343,14 +8343,17 @@ int q6asm_get_apr_service_id(int session_id)
int q6asm_get_asm_topology(int session_id)
{
- int topology;
+ int topology = -EINVAL;
if (session_id <= 0 || session_id > ASM_ACTIVE_STREAMS_ALLOWED) {
pr_err("%s: invalid session_id = %d\n", __func__, session_id);
- topology = -EINVAL;
goto done;
}
-
+ if (session[session_id] == NULL) {
+ pr_err("%s: session not created for session id = %d\n",
+ __func__, session_id);
+ goto done;
+ }
topology = session[session_id]->topology;
done:
return topology;
@@ -8358,14 +8361,17 @@ done:
int q6asm_get_asm_app_type(int session_id)
{
- int app_type;
+ int app_type = -EINVAL;
if (session_id <= 0 || session_id > ASM_ACTIVE_STREAMS_ALLOWED) {
pr_err("%s: invalid session_id = %d\n", __func__, session_id);
- app_type = -EINVAL;
goto done;
}
-
+ if (session[session_id] == NULL) {
+ pr_err("%s: session not created for session id = %d\n",
+ __func__, session_id);
+ goto done;
+ }
app_type = session[session_id]->app_type;
done:
return app_type;
diff --git a/sound/soc/msm/qdsp6v2/q6lsm.c b/sound/soc/msm/qdsp6v2/q6lsm.c
index 2bf0c490e834..525ec1c30f48 100644
--- a/sound/soc/msm/qdsp6v2/q6lsm.c
+++ b/sound/soc/msm/qdsp6v2/q6lsm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016, Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -38,6 +38,8 @@
#define LSM_ALIGN_BOUNDARY 512
#define LSM_SAMPLE_RATE 16000
#define QLSM_PARAM_ID_MINOR_VERSION 1
+#define QLSM_PARAM_ID_MINOR_VERSION_2 2
+
static int lsm_afe_port;
enum {
@@ -707,29 +709,28 @@ static int q6lsm_send_confidence_levels(
return rc;
}
-static int q6lsm_send_params(struct lsm_client *client,
+static int q6lsm_send_param_opmode(struct lsm_client *client,
struct lsm_module_param_ids *opmode_ids,
- struct lsm_module_param_ids *connectport_ids,
u32 set_param_opcode)
{
int rc;
- struct lsm_cmd_set_opmode_connectport opmode_connectport;
+ struct lsm_cmd_set_params_opmode opmode_params;
struct apr_hdr *msg_hdr;
- struct lsm_param_connect_to_port *connect_to_port;
+
struct lsm_param_op_mode *op_mode;
u32 data_payload_size, param_size;
- msg_hdr = &opmode_connectport.msg_hdr;
+ msg_hdr = &opmode_params.msg_hdr;
q6lsm_add_hdr(client, msg_hdr,
- sizeof(opmode_connectport), true);
+ sizeof(opmode_params), true);
msg_hdr->opcode = set_param_opcode;
- data_payload_size = sizeof(opmode_connectport) -
+ data_payload_size = sizeof(opmode_params) -
sizeof(*msg_hdr) -
- sizeof(opmode_connectport.params_hdr);
- q6lsm_set_param_hdr_info(&opmode_connectport.params_hdr,
+ sizeof(opmode_params.params_hdr);
+ q6lsm_set_param_hdr_info(&opmode_params.params_hdr,
data_payload_size, 0, 0, 0);
- connect_to_port = &opmode_connectport.connect_to_port;
- op_mode = &opmode_connectport.op_mode;
+ op_mode = &opmode_params.op_mode;
+
param_size = sizeof(struct lsm_param_op_mode) -
sizeof(op_mode->common);
@@ -741,10 +742,61 @@ static int q6lsm_send_params(struct lsm_client *client,
op_mode->reserved = 0;
pr_debug("%s: mode = 0x%x", __func__, op_mode->mode);
+ rc = q6lsm_apr_send_pkt(client, client->apr,
+ &opmode_params, true, NULL);
+ if (rc)
+ pr_err("%s: Failed set_params opcode 0x%x, rc %d\n",
+ __func__, msg_hdr->opcode, rc);
+
+ pr_debug("%s: leave %d\n", __func__, rc);
+ return rc;
+}
+
+void set_lsm_port(int lsm_port)
+{
+ lsm_afe_port = lsm_port;
+}
+
+int get_lsm_port(void)
+{
+ return lsm_afe_port;
+}
+
+int q6lsm_set_port_connected(struct lsm_client *client)
+{
+ int rc;
+ struct lsm_cmd_set_connectport connectport;
+ struct lsm_module_param_ids connectport_ids;
+ struct apr_hdr *msg_hdr;
+ struct lsm_param_connect_to_port *connect_to_port;
+ u32 data_payload_size, param_size, set_param_opcode;
+
+ if (client->use_topology) {
+ set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2;
+ connectport_ids.module_id = LSM_MODULE_ID_FRAMEWORK;
+ connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT;
+ } else {
+ set_param_opcode = LSM_SESSION_CMD_SET_PARAMS;
+ connectport_ids.module_id = LSM_MODULE_ID_VOICE_WAKEUP;
+ connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT;
+ }
+ client->connect_to_port = get_lsm_port();
+
+ msg_hdr = &connectport.msg_hdr;
+ q6lsm_add_hdr(client, msg_hdr,
+ sizeof(connectport), true);
+ msg_hdr->opcode = set_param_opcode;
+ data_payload_size = sizeof(connectport) -
+ sizeof(*msg_hdr) -
+ sizeof(connectport.params_hdr);
+ q6lsm_set_param_hdr_info(&connectport.params_hdr,
+ data_payload_size, 0, 0, 0);
+ connect_to_port = &connectport.connect_to_port;
+
param_size = (sizeof(struct lsm_param_connect_to_port) -
sizeof(connect_to_port->common));
q6lsm_set_param_common(&connect_to_port->common,
- connectport_ids, param_size,
+ &connectport_ids, param_size,
set_param_opcode);
connect_to_port->minor_version = QLSM_PARAM_ID_MINOR_VERSION;
connect_to_port->port_id = client->connect_to_port;
@@ -752,23 +804,191 @@ static int q6lsm_send_params(struct lsm_client *client,
pr_debug("%s: port= %d", __func__, connect_to_port->port_id);
rc = q6lsm_apr_send_pkt(client, client->apr,
- &opmode_connectport, true, NULL);
+ &connectport, true, NULL);
+ if (rc)
+ pr_err("%s: Failed set_params opcode 0x%x, rc %d\n",
+ __func__, msg_hdr->opcode, rc);
+
+ return rc;
+}
+static int q6lsm_send_param_polling_enable(struct lsm_client *client,
+ bool poll_en,
+ struct lsm_module_param_ids *poll_enable_ids,
+ u32 set_param_opcode)
+{
+ int rc = 0;
+ struct lsm_cmd_poll_enable cmd;
+ struct apr_hdr *msg_hdr;
+ struct lsm_param_poll_enable *poll_enable;
+ u32 data_payload_size, param_size;
+
+ msg_hdr = &cmd.msg_hdr;
+ q6lsm_add_hdr(client, msg_hdr,
+ sizeof(struct lsm_cmd_poll_enable), true);
+ msg_hdr->opcode = set_param_opcode;
+ data_payload_size = sizeof(struct lsm_cmd_poll_enable) -
+ sizeof(struct apr_hdr) -
+ sizeof(struct lsm_set_params_hdr);
+ q6lsm_set_param_hdr_info(&cmd.params_hdr,
+ data_payload_size, 0, 0, 0);
+ poll_enable = &cmd.poll_enable;
+
+ param_size = (sizeof(struct lsm_param_poll_enable) -
+ sizeof(poll_enable->common));
+ q6lsm_set_param_common(&poll_enable->common,
+ poll_enable_ids, param_size,
+ set_param_opcode);
+ poll_enable->minor_version = QLSM_PARAM_ID_MINOR_VERSION;
+ poll_enable->polling_enable = (poll_en) ? 1 : 0;
+ pr_debug("%s: poll enable= %d", __func__, poll_enable->polling_enable);
+
+ rc = q6lsm_apr_send_pkt(client, client->apr,
+ &cmd, true, NULL);
if (rc)
pr_err("%s: Failed set_params opcode 0x%x, rc %d\n",
__func__, msg_hdr->opcode, rc);
- pr_debug("%s: leave %d\n", __func__, rc);
return rc;
}
-void set_lsm_port(int lsm_port)
+int q6lsm_set_fwk_mode_cfg(struct lsm_client *client,
+ uint32_t event_mode)
{
- lsm_afe_port = lsm_port;
+ int rc = 0;
+ struct lsm_cmd_set_fwk_mode_cfg cmd;
+ struct lsm_module_param_ids fwk_mode_cfg_ids;
+ struct apr_hdr *msg_hdr;
+ struct lsm_param_fwk_mode_cfg *fwk_mode_cfg;
+ u32 data_payload_size, param_size, set_param_opcode;
+
+ if (client->use_topology) {
+ set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2;
+ fwk_mode_cfg_ids.module_id = LSM_MODULE_ID_FRAMEWORK;
+ fwk_mode_cfg_ids.param_id = LSM_PARAM_ID_FWK_MODE_CONFIG;
+ } else {
+ pr_debug("%s: Ignore sending event mode\n", __func__);
+ return rc;
+ }
+
+ msg_hdr = &cmd.msg_hdr;
+ q6lsm_add_hdr(client, msg_hdr,
+ sizeof(struct lsm_cmd_set_fwk_mode_cfg), true);
+ msg_hdr->opcode = set_param_opcode;
+ data_payload_size = sizeof(struct lsm_cmd_set_fwk_mode_cfg) -
+ sizeof(struct apr_hdr) -
+ sizeof(struct lsm_set_params_hdr);
+ q6lsm_set_param_hdr_info(&cmd.params_hdr,
+ data_payload_size, 0, 0, 0);
+ fwk_mode_cfg = &cmd.fwk_mode_cfg;
+
+ param_size = (sizeof(struct lsm_param_fwk_mode_cfg) -
+ sizeof(fwk_mode_cfg->common));
+ q6lsm_set_param_common(&fwk_mode_cfg->common,
+ &fwk_mode_cfg_ids, param_size,
+ set_param_opcode);
+
+ fwk_mode_cfg->minor_version = QLSM_PARAM_ID_MINOR_VERSION;
+ fwk_mode_cfg->mode = event_mode;
+ pr_debug("%s: mode = %d\n", __func__, fwk_mode_cfg->mode);
+
+ rc = q6lsm_apr_send_pkt(client, client->apr,
+ &cmd, true, NULL);
+ if (rc)
+ pr_err("%s: Failed set_params opcode 0x%x, rc %d\n",
+ __func__, msg_hdr->opcode, rc);
+ return rc;
}
-int get_lsm_port()
+static int q6lsm_arrange_mch_map(struct lsm_param_media_fmt *media_fmt,
+ int channel_count)
{
- return lsm_afe_port;
+ int rc = 0;
+
+ memset(media_fmt->channel_mapping, 0, LSM_MAX_NUM_CHANNELS);
+
+ switch (channel_count) {
+ case 1:
+ media_fmt->channel_mapping[0] = PCM_CHANNEL_FC;
+ break;
+ case 2:
+ media_fmt->channel_mapping[0] = PCM_CHANNEL_FL;
+ media_fmt->channel_mapping[1] = PCM_CHANNEL_FR;
+ break;
+ case 3:
+ media_fmt->channel_mapping[0] = PCM_CHANNEL_FL;
+ media_fmt->channel_mapping[1] = PCM_CHANNEL_FR;
+ media_fmt->channel_mapping[2] = PCM_CHANNEL_FC;
+ break;
+ case 4:
+ media_fmt->channel_mapping[0] = PCM_CHANNEL_FL;
+ media_fmt->channel_mapping[1] = PCM_CHANNEL_FR;
+ media_fmt->channel_mapping[2] = PCM_CHANNEL_LS;
+ media_fmt->channel_mapping[3] = PCM_CHANNEL_RS;
+ break;
+ default:
+ pr_err("%s: invalid num_chan %d\n", __func__, channel_count);
+ rc = -EINVAL;
+ break;
+ }
+ return rc;
+}
+
+int q6lsm_set_media_fmt_params(struct lsm_client *client)
+{
+ int rc = 0;
+ struct lsm_cmd_set_media_fmt cmd;
+ struct lsm_module_param_ids media_fmt_ids;
+ struct apr_hdr *msg_hdr;
+ struct lsm_param_media_fmt *media_fmt;
+ u32 data_payload_size, param_size, set_param_opcode;
+ struct lsm_hw_params param = client->hw_params;
+
+ if (client->use_topology) {
+ set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2;
+ media_fmt_ids.module_id = LSM_MODULE_ID_FRAMEWORK;
+ media_fmt_ids.param_id = LSM_PARAM_ID_MEDIA_FMT;
+ } else {
+ pr_debug("%s: Ignore sending media format\n", __func__);
+ goto err_ret;
+ }
+
+ msg_hdr = &cmd.msg_hdr;
+ q6lsm_add_hdr(client, msg_hdr,
+ sizeof(struct lsm_cmd_set_media_fmt), true);
+ msg_hdr->opcode = set_param_opcode;
+ data_payload_size = sizeof(struct lsm_cmd_set_media_fmt) -
+ sizeof(struct apr_hdr) -
+ sizeof(struct lsm_set_params_hdr);
+ q6lsm_set_param_hdr_info(&cmd.params_hdr,
+ data_payload_size, 0, 0, 0);
+ media_fmt = &cmd.media_fmt;
+
+ param_size = (sizeof(struct lsm_param_media_fmt) -
+ sizeof(media_fmt->common));
+ q6lsm_set_param_common(&media_fmt->common,
+ &media_fmt_ids, param_size,
+ set_param_opcode);
+
+ media_fmt->minor_version = QLSM_PARAM_ID_MINOR_VERSION_2;
+ media_fmt->sample_rate = param.sample_rate;
+ media_fmt->num_channels = param.num_chs;
+ media_fmt->bit_width = param.sample_size;
+
+ rc = q6lsm_arrange_mch_map(media_fmt, media_fmt->num_channels);
+ if (rc)
+ goto err_ret;
+
+ pr_debug("%s: sample rate= %d, channels %d bit width %d\n",
+ __func__, media_fmt->sample_rate, media_fmt->num_channels,
+ media_fmt->bit_width);
+
+ rc = q6lsm_apr_send_pkt(client, client->apr,
+ &cmd, true, NULL);
+ if (rc)
+ pr_err("%s: Failed set_params opcode 0x%x, rc %d\n",
+ __func__, msg_hdr->opcode, rc);
+err_ret:
+ return rc;
}
int q6lsm_set_data(struct lsm_client *client,
@@ -776,7 +996,7 @@ int q6lsm_set_data(struct lsm_client *client,
bool detectfailure)
{
int rc = 0;
- struct lsm_module_param_ids opmode_ids, connectport_ids;
+ struct lsm_module_param_ids opmode_ids;
struct lsm_module_param_ids conf_levels_ids;
if (!client->confidence_levels) {
@@ -800,16 +1020,12 @@ int q6lsm_set_data(struct lsm_client *client,
goto err_ret;
}
client->mode |= detectfailure << 2;
- client->connect_to_port = get_lsm_port();
opmode_ids.module_id = LSM_MODULE_ID_VOICE_WAKEUP;
opmode_ids.param_id = LSM_PARAM_ID_OPERATION_MODE;
- connectport_ids.module_id = LSM_MODULE_ID_VOICE_WAKEUP;
- connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT;
-
- rc = q6lsm_send_params(client, &opmode_ids, &connectport_ids,
- LSM_SESSION_CMD_SET_PARAMS);
+ rc = q6lsm_send_param_opmode(client, &opmode_ids,
+ LSM_SESSION_CMD_SET_PARAMS);
if (rc) {
pr_err("%s: Failed to set lsm config params %d\n",
__func__, rc);
@@ -1390,7 +1606,7 @@ static int q6lsm_send_param_gain(
int q6lsm_set_one_param(struct lsm_client *client,
struct lsm_params_info *p_info, void *data,
- enum LSM_PARAM_TYPE param_type)
+ uint32_t param_type)
{
int rc = 0, pkt_sz;
struct lsm_module_param_ids ids;
@@ -1409,7 +1625,6 @@ int q6lsm_set_one_param(struct lsm_client *client,
case LSM_OPERATION_MODE: {
struct snd_lsm_detect_mode *det_mode = data;
struct lsm_module_param_ids opmode_ids;
- struct lsm_module_param_ids connectport_ids;
if (det_mode->mode == LSM_MODE_KEYWORD_ONLY_DETECTION) {
client->mode = 0x01;
@@ -1422,16 +1637,12 @@ int q6lsm_set_one_param(struct lsm_client *client,
}
client->mode |= det_mode->detect_failure << 2;
- client->connect_to_port = get_lsm_port();
opmode_ids.module_id = p_info->module_id;
opmode_ids.param_id = p_info->param_id;
- connectport_ids.module_id = LSM_MODULE_ID_FRAMEWORK;
- connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT;
-
- rc = q6lsm_send_params(client, &opmode_ids, &connectport_ids,
- LSM_SESSION_CMD_SET_PARAMS_V2);
+ rc = q6lsm_send_param_opmode(client, &opmode_ids,
+ LSM_SESSION_CMD_SET_PARAMS_V2);
if (rc)
pr_err("%s: OPERATION_MODE failed, rc %d\n",
__func__, rc);
@@ -1458,6 +1669,20 @@ int q6lsm_set_one_param(struct lsm_client *client,
pr_err("%s: CONFIDENCE_LEVELS cmd failed, rc %d\n",
__func__, rc);
break;
+ case LSM_POLLING_ENABLE: {
+ struct snd_lsm_poll_enable *lsm_poll_enable =
+ (struct snd_lsm_poll_enable *) data;
+ ids.module_id = p_info->module_id;
+ ids.param_id = p_info->param_id;
+ rc = q6lsm_send_param_polling_enable(client,
+ lsm_poll_enable->poll_en, &ids,
+ LSM_SESSION_CMD_SET_PARAMS_V2);
+ if (rc)
+ pr_err("%s: POLLING ENABLE cmd failed, rc %d\n",
+ __func__, rc);
+ break;
+ }
+
case LSM_REG_SND_MODEL: {
struct lsm_cmd_set_params model_param;
u32 payload_size;
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index e7619c0ca0dd..d352133b7c32 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -3990,6 +3990,10 @@ static int voice_send_cvp_media_fmt_info_cmd(struct voice_data *v)
{
int ret;
+ ret = voice_send_cvp_device_channels_cmd(v);
+ if (ret < 0)
+ goto done;
+
if (voice_get_cvd_int_version(common.cvd_version) >=
CVD_INT_VERSION_2_3) {
ret = voice_send_cvp_media_format_cmd(v, RX_PATH);
@@ -4002,8 +4006,6 @@ static int voice_send_cvp_media_fmt_info_cmd(struct voice_data *v)
if (common.ec_ref_ext)
ret = voice_send_cvp_media_format_cmd(v, EC_REF_PATH);
- } else {
- ret = voice_send_cvp_device_channels_cmd(v);
}
done:
diff --git a/sound/soc/msm/sdm660-internal.c b/sound/soc/msm/sdm660-internal.c
index 28728a186f92..8b0a12a46338 100644
--- a/sound/soc/msm/sdm660-internal.c
+++ b/sound/soc/msm/sdm660-internal.c
@@ -910,9 +910,6 @@ static const struct snd_kcontrol_new msm_sdw_controls[] = {
SOC_ENUM_EXT("INT4_MI2S_RX SampleRate", int4_mi2s_rx_sample_rate,
int_mi2s_sample_rate_get,
int_mi2s_sample_rate_put),
- SOC_ENUM_EXT("INT4_MI2S_RX SampleRate", int4_mi2s_rx_sample_rate,
- int_mi2s_sample_rate_get,
- int_mi2s_sample_rate_put),
SOC_ENUM_EXT("INT4_MI2S_RX Channels", int4_mi2s_rx_chs,
int_mi2s_ch_get, int_mi2s_ch_put),
SOC_ENUM_EXT("VI_FEED_TX Channels", int5_mi2s_tx_chs,
@@ -2316,7 +2313,7 @@ static struct snd_soc_dai_link msm_int_be_dai[] = {
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE |
ASYNC_DPCM_SND_SOC_HW_PARAMS,
.be_id = MSM_BACKEND_DAI_INT3_MI2S_TX,
- .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .be_hw_params_fixup = int_mi2s_be_hw_params_fixup,
.ops = &msm_int_mi2s_be_ops,
.ignore_suspend = 1,
},